PageSourceSearch

https://intranet.kirche-annaberg-buchholz.de/js/favico/favico.js

js kirche-annaberg-buchholz.de collected 2026-10-08 04:27:14 UTC 22,737 bytes, 947 lines download raw bytes

1/**
2 * @license MIT or GPL-2.0
3 * @fileOverview Favico animations
4 * @author Miroslav Magda, http://blog.ejci.net
5 * @source: https://github.com/ejci/favico.js
6 * @version 0.3.10
7 */
8
9/**
10 * Create new favico instance
11 * @param {Object} Options
12 * @return {Object} Favico object
13 * @example
14 * var favico = new Favico({
15 *    bgColor : '#d00',
16 *    textColor : '#fff',
17 *    fontFamily : 'sans-serif',
18 *    fontStyle : 'bold',
19 *    type : 'circle',
20 *    position : 'down',
21 *    animation : 'slide',
22 *    elementId: false,
23 *    element: null,
24 *    dataUrl: function(url){},
25 *    win: window
26 * });
27 */
28(function () {
29    // canvas size
30    let size = 32 * (Math.ceil(window.devicePixelRatio) || 1);
31
32	var Favico = (function (opt) {
33		'use strict';
34		opt = (opt) ? opt : {};
35		var _def = {
36			bgColor: '#d00',
37			textColor: '#fff',
38			fontFamily: 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,...
39			fontStyle: 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900
40			type: 'rectangle',
41			position: 'down', // down, up, left, leftup (upleft)
42			animation: 'none',
43			elementId: false,
44			element: null,
45			dataUrl: false,
46			win: window
47		};
48		var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser, _animTimeout, _drawTimeout, _doc;
49
50		var ua = (function () {
51			var agent = navigator.userAgent.toLowerCase();
52			// New function has access to 'agent' via closure
53			return function (browser) {
54				return agent.indexOf(browser) !== -1;
55			};
56		}());
57
58		_browser = {
59		};
60		_browser.ff = typeof InstallTrigger != 'undefined';
61		_browser.opera = !!window.opera || ua('opera');
62		_browser.safari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
63		_browser.ie = ua('trident');
64		_browser.edge = ua('edge');
65		_browser.chrome = !!window.chrome && !_browser.edge;
66		_browser.supported = (_browser.chrome || _browser.ff || _browser.opera);
67
68		var _queue = [];
69		_readyCb = function () {
70		};
71		_ready = _stop = false;
72		/**
73		 * Initialize favico
74		 */
75		var init = function () {
76			//merge initial options
77			_opt = merge(_def, opt);
78			_opt.bgColor = hexToRgb(_opt.bgColor);
79			_opt.textColor = hexToRgb(_opt.textColor);
80			_opt.position = _opt.position.toLowerCase();
81			_opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation;
82
83			_doc = _opt.win.document;
84
85			var isUp = _opt.position.indexOf('up') > -1;
86			var isLeft = _opt.position.indexOf('left') > -1;
87
88			//transform the animations
89			if (isUp || isLeft) {
90				for (var a in animation.types) {
91					for (var i = 0; i < animation.types[a].length; i++) {
92						var step = animation.types[a][i];
93
94						if (isUp) {
95							if (step.y < 0.6) {
96								step.y = step.y - 0.4;
97							} else {
98								step.y = step.y - 2 * step.y + (1 - step.w);
99							}
100						}
101
102						if (isLeft) {
103							if (step.x < 0.6) {
104								step.x = step.x - 0.4;
105							} else {
106								step.x = step.x - 2 * step.x + (1 - step.h);
107							}
108						}
109
110						animation.types[a][i] = step;
111					}
112				}
113			}
114			_opt.type = (type['' + _opt.type]) ? _opt.type : _def.type;
115
116			_orig = link. getIcons();
117			//create temp canvas
118			_canvas = document.createElement('canvas');
119			//create temp image
120			_img = document.createElement('img');
121			var lastIcon = _orig[_orig.length - 1];
122			if (lastIcon.hasAttribute('href')) {
123				_img.setAttribute('crossOrigin', 'anonymous');
124				//get width/height
125				_img.onload = function () {
126					_h = size; // (_img.height > 0) ? _img.height : 32;
127					_w = size; // (_img.width > 0) ? _img.width : 32;
128					_canvas.height = _h;
129					_canvas.width = _w;
130                    _context = _canvas.getContext('2d');
131					icon.ready();
132				};
133				_img.setAttribute('src', lastIcon.getAttribute('href'));
134			} else {
135				_h = size; // 32
136				_w = size; // 32
137				_img.height = _h;
138				_img.width = _w;
139				_canvas.height = _h;
140				_canvas.width = _w;
141				_context = _canvas.getContext('2d');
142				icon.ready();
143			}
144
145		};
146
147        var getFormatedNumber = function( number )
148        {
149            if( number < 999 )
150            {
151                return number;
152            }
153
154            return ( number > 9999 ? 9 : Math.floor( number / 1000 ) ) + 'k+';
155        };
156
157        var updateTitle = function(label) {
158            // Grab the current title that we can prefix with the label
159            var originalTitle = document.title;
160
161            // Strip out the old label if there is one
162            if (originalTitle[0] === '(') {
163                originalTitle = originalTitle.slice(originalTitle.indexOf(' '));
164            }
165
166            if ((label + '').length > 0) {
167                document.title = '(' + getFormatedNumber(label) + ') ' + originalTitle;
168            } else {
169                document.title = originalTitle;
170            }
171        };
172
173		/**
174		 * Icon namespace
175		 */
176		var icon = {};
177		/**
178		 * Icon is ready (reset icon) and start animation (if ther is any)
179		 */
180		icon.ready = function () {
181			_ready = true;
182			icon.reset();
183			_readyCb();
184		};
185		/**
186		 * Reset icon to default state
187		 */
188		icon.reset = function () {
189			//reset
190			if (!_ready) {
191				return;
192			}
193			_queue = [];
194			_lastBadge = false;
vendor: 4,798 bytes, lines 195-336
195			_running = false;
196			_context.clearRect(0, 0, _w, _h);
197			_context.drawImage(_img, 0, 0, _w, _h);
198			//_stop=true;
199			link.setIcon(_canvas);
200			//webcam('stop');
201			//video('stop');
202			window.clearTimeout(_animTimeout);
203			window.clearTimeout(_drawTimeout);
204		};
205		/**
206		 * Start animation
207		 */
208		icon.start = function () {
209			if (!_ready || _running) {
210				return;
211			}
212			var finished = function () {
213				_lastBadge = _queue[0];
214				_running = false;
215				if (_queue.length > 0) {
216					_queue.shift();
217					icon.start();
218				}
219			};
220			if (_queue.length > 0) {
221                if (!_context || !_browser.supported) {
222                    updateTitle(_queue[0].options.n);
223                    finished();
224
225                    return;
226                }
227
228				_running = true;
229				var run = function () {
230					// apply options for this animation
231					['type', 'animation', 'bgColor', 'textColor', 'fontFamily', 'fontStyle'].forEach(function (a) {
232						if (a in _queue[0].options) {
233							_opt[a] = _queue[0].options[a];
234						}
235					});
236					animation.run(_queue[0].options, function () {
237						finished();
238					}, false);
239				};
240				if (_lastBadge) {
241					animation.run(_lastBadge.options, function () {
242						run();
243					}, true);
244				} else {
245					run();
246				}
247			}
248		};
249
250		/**
251		 * Badge types
252		 */
253		var type = {};
254		var options = function (opt) {
255			opt.n = ((typeof opt.n) === 'number') ? Math.abs(opt.n | 0) : opt.n;
256			opt.x = _w * opt.x;
257			opt.y = _h * opt.y;
258			opt.w = _w * opt.w;
259			opt.h = _h * opt.h;
260			opt.len = ("" + opt.n).length;
261			return opt;
262		};
263		/**
264		 * Generate circle
265		 * @param {Object} opt Badge options
266		 */
267		type.circle = function (opt) {
268			opt = options(opt);
269			var more = false;
270			if (opt.len === 2) {
271				opt.x = opt.x - opt.w * 0.4;
272				opt.w = opt.w * 1.4;
273				more = true;
274			} else if (opt.len >= 3) {
275				opt.x = opt.x - opt.w * 0.65;
276				opt.w = opt.w * 1.65;
277				more = true;
278			}
279			_context.clearRect(0, 0, _w, _h);
280			_context.drawImage(_img, 0, 0, _w, _h);
281			_context.beginPath();
282			_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily;
283			_context.textAlign = 'center';
284			if (more) {
285				_context.moveTo(opt.x + opt.w / 2, opt.y);
286				_context.lineTo(opt.x + opt.w - opt.h / 2, opt.y);
287				_context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2);
288				_context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2);
289				_context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h);
290				_context.lineTo(opt.x + opt.h / 2, opt.y + opt.h);
291				_context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2);
292				_context.lineTo(opt.x, opt.y + opt.h / 2);
293				_context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y);
294			} else {
295				_context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI);
296			}
297			_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
298			_context.fill();
299			_context.closePath();
300			_context.beginPath();
301			_context.stroke();
302			_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
303			//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
304			if ((typeof opt.n) === 'number' && opt.n > 999) {
305				_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
306			} else {
307				_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
308			}
309			_context.closePath();
310		};
311		/**
312		 * Generate rectangle
313		 * @param {Object} opt Badge options
314		 */
315		type.rectangle = function (opt) {
316			opt = options(opt);
317			var more = false;
318			if (opt.len === 2) {
319				opt.x = opt.x - opt.w * 0.4;
320				opt.w = opt.w * 1.4;
321				more = true;
322			} else if (opt.len >= 3) {
323				opt.x = opt.x - opt.w * 0.65;
324				opt.w = opt.w * 1.65;
325				more = true;
326			}
327			_context.clearRect(0, 0, _w, _h);
328			_context.drawImage(_img, 0, 0, _w, _h);
329			_context.beginPath();
330			_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px " + _opt.fontFamily;
331			_context.textAlign = 'center';
332			_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
333			_context.fillRect(opt.x, opt.y, opt.w, opt.h);
334			_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
335			//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
336			if ((typeof opt.n) === 'number' && opt.n > 999) {
337				_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000)) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
338			} else {
339				_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
340			}
341			_context.closePath();
342		};
343
344		/**
345		 * Set badge
346		 */
347		var badge = function (number, opts) {
348			opts = ((typeof opts) === 'string' ? {
349				animation: opts
350			} : opts) || {};
351			_readyCb = function () {
352				try {
353					if (typeof (number) === 'number' ? (number > 0) : (number !== '')) {
354						var q = {
355							type: 'badge',
356							options: {
357								n: number
358							}
359						};
360						if ('animation' in opts && animation.types['' + opts.animation]) {
361							q.options.animation = '' + opts.animation;
362						}
363						if ('type' in opts && type['' + opts.type]) {
364							q.options.type = '' + opts.type;
365						}
366						['bgColor', 'textColor'].forEach(function (o) {
367							if (o in opts) {
368								q.options[o] = hexToRgb(opts[o]);
369							}
370						});
371						['fontStyle', 'fontFamily'].forEach(function (o) {
372							if (o in opts) {
373								q.options[o] = opts[o];
374							}
375						});
376						_queue.push(q);
377						if (_queue.length > 100) {
378							throw new Error('Too many badges requests in queue.');
379						}
380						icon.start();
381					} else {
382						icon.reset();
383					}
384				} catch (e) {
385					throw new Error('Error setting badge. Message: ' + e.message);
386				}
387			};
388			if (_ready) {
389				_readyCb();
390			}
391		};
392
393		/**
394		 * Set image as icon
395		 */
396		var image = function (imageElement) {
397			_readyCb = function () {
398				try {
399					var w = imageElement.width;
400					var h = imageElement.height;
401					var newImg = document.createElement('img');
402					var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
403					newImg.setAttribute('crossOrigin', 'anonymous');
404					newImg.onload=function(){
405						_context.clearRect(0, 0, _w, _h);
406						_context.drawImage(newImg, 0, 0, _w, _h);
407						link.setIcon(_canvas);
408					};
409					newImg.setAttribute('src', imageElement.getAttribute('src'));
410					newImg.height = (h / ratio);
411					newImg.width = (w / ratio);
412				} catch (e) {
413					throw new Error('Error setting image. Message: ' + e.message);
414				}
415			};
416			if (_ready) {
417				_readyCb();
418			}
419		};
420		/**
421		 * Set the icon from a source url. Won't work with badges.
422		 */
423		var rawImageSrc = function (url) {
424			_readyCb = function() {
425				link.setIconSrc(url);
426			};
427			if (_ready) {
428				_readyCb();
429			}
430		};
431		/**
432		 * Set video as icon
433		 */
434		var video = function (videoElement) {
435			_readyCb = function () {
436				try {
437					if (videoElement === 'stop') {
438						_stop = true;
439						icon.reset();
440						_stop = false;
441						return;
442					}
443					//var w = videoElement.width;
444					//var h = videoElement.height;
445					//var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
446					videoElement.addEventListener('play', function () {
447						drawVideo(this);
448					}, false);
449
450				} catch (e) {
451					throw new Error('Error setting video. Message: ' + e.message);
452				}
453			};
454			if (_ready) {
455				_readyCb();
456			}
457		};
458		/**
459		 * Set video as icon
460		 */
461		var webcam = function (action) {
462			//UR
463			if (!window.URL || !window.URL.createObjectURL) {
464				window.URL = window.URL || {};
465				window.URL.createObjectURL = function (obj) {
466					return obj;
467				};
468			}
469			if (_browser.supported) {
470				var newVideo = false;
471				navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
472				_readyCb = function () {
473					try {
474						if (action === 'stop') {
475							_stop = true;
476							icon.reset();
477							_stop = false;
478							return;
479						}
480						newVideo = document.createElement('video');
481						newVideo.width = _w;
482						newVideo.height = _h;
483						navigator.getUserMedia({
484							video: true,
485							audio: false
486						}, function (stream) {
487							newVideo.src = URL.createObjectURL(stream);
488							newVideo.play();
489							drawVideo(newVideo);
490						}, function () {
491						});
492					} catch (e) {
493						throw new Error('Error setting webcam. Message: ' + e.message);
494					}
495				};
496				if (_ready) {
497					_readyCb();
498				}
499			}
500
501		};
502
503		var setOpt = function (key, value) {
504			var opts = key;
505			if (!(value == null && Object.prototype.toString.call(key) == '[object Object]')) {
506				opts = {};
507				opts[key] = value;
508			}
509
510			var keys = Object.keys(opts);
511			for (var i = 0; i < keys.length; i++) {
512				if (keys[i] == 'bgColor' || keys[i] == 'textColor') {
513					_opt[keys[i]] = hexToRgb(opts[keys[i]]);
514				} else {
515					_opt[keys[i]] = opts[keys[i]];
516				}
517			}
518
519			_queue.push(_lastBadge);
520			icon.start();
521		};
522
523		/**
524		 * Draw video to context and repeat :)
525		 */
526		function drawVideo(video) {
527			if (video.paused || video.ended || _stop) {
528				return false;
529			}
530			//nasty hack for FF webcam (Thanks to Julian Ćwirko, [email protected])
531			try {
532				_context.clearRect(0, 0, _w, _h);
533				_context.drawImage(video, 0, 0, _w, _h);
534			} catch (e) {
535
536			}
537			_drawTimeout = setTimeout(function () {
538				drawVideo(video);
539			}, animation.duration);
540			link.setIcon(_canvas);
541		}
542
543		var link = {};
544		/**
545		 * Get icons from HEAD tag or create a new <link> element
546		 */
547		link.getIcons = function () {
548			var elms = [];
549			//get link element
550			var getLinks = function () {
551				var icons = [];
552				var links = _doc.getElementsByTagName('head')[0].getElementsByTagName('link');
553				for (var i = 0; i < links.length; i++) {
554					if ((/(^|\s)icon(\s|$)/i).test(links[i].getAttribute('rel'))) {
555						icons.push(links[i]);
556					}
557				}
558				return icons;
559			};
560			if (_opt.element) {
561				elms = [_opt.element];
562			} else if (_opt.elementId) {
563				//if img element identified by elementId
564				elms = [_doc.getElementById(_opt.elementId)];
565				elms[0].setAttribute('href', elms[0].getAttribute('src'));
566			} else {
567				//if link element
568				elms = getLinks();
569				if (elms.length === 0) {
570					elms = [_doc.createElement('link')];
571					elms[0].setAttribute('rel', 'icon');
572					_doc.getElementsByTagName('head')[0].appendChild(elms[0]);
573				}
574			}
575			elms.forEach(function(item) {
576				item.setAttribute('type', 'image/png');
577			});
578			return elms;
579		};
580		link.setIcon = function (canvas) {
581			var url = canvas.toDataURL('image/png');
582			link.setIconSrc(url);
583		};
584		link.setIconSrc = function (url) {
585			if (_opt.dataUrl) {
586				//if using custom exporter
587				_opt.dataUrl(url);
588			}
589			if (_opt.element) {
590				_opt.element.setAttribute('href', url);
591				_opt.element.setAttribute('src', url);
592			} else if (_opt.elementId) {
593				//if is attached to element (image)
594				var elm = _doc.getElementById(_opt.elementId);
595				elm.setAttribute('href', url);
596				elm.setAttribute('src', url);
597			} else {
598				//if is attached to fav icon
599				if (_browser.ff || _browser.opera) {
600					//for FF we need to "recreate" element, atach to dom and remove old <link>
601					//var originalType = _orig.getAttribute('rel');
602					var old = _orig[_orig.length - 1];
603					var newIcon = _doc.createElement('link');
604					_orig = [newIcon];
605					//_orig.setAttribute('rel', originalType);
606					if (_browser.opera) {
607						newIcon.setAttribute('rel', 'icon');
608					}
609					newIcon.setAttribute('rel', 'icon');
610					newIcon.setAttribute('type', 'image/png');
611					_doc.getElementsByTagName('head')[0].appendChild(newIcon);
612					newIcon.setAttribute('href', url);
613					if (old.parentNode) {
614						old.parentNode.removeChild(old);
615					}
616				} else {
617					_orig.forEach(function(icon) {
618						icon.setAttribute('href', url);
619					});
620				}
621			}
622		};
623
624		//http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
625		//HEX to RGB convertor
626		function hexToRgb(hex) {
627			var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
628			hex = hex.replace(shorthandRegex, function (m, r, g, b) {
629				return r + r + g + g + b + b;
630			});
631			var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
632			return result ? {
633				r: parseInt(result[1], 16),
634				g: parseInt(result[2], 16),
635				b: parseInt(result[3], 16)
636			} : false;
637		}
638
639		/**
640		 * Merge options
641		 */
642		function merge(def, opt) {
643			var mergedOpt = {};
644			var attrname;
645			for (attrname in def) {
646				mergedOpt[attrname] = def[attrname];
647			}
648			for (attrname in opt) {
649				mergedOpt[attrname] = opt[attrname];
650			}
651			return mergedOpt;
652		}
653
654		/**
655		 * Cross-browser page visibility shim
656		 * http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible
657		 */
658		function isPageHidden() {
659			return _doc.hidden || _doc.msHidden || _doc.webkitHidden || _doc.mozHidden;
660		}
661
662		/**
663		 * @namespace animation
664		 */
665		var animation = {};
666		/**
667		 * Animation "frame" duration
668		 */
669		animation.duration = 40;
670		/**
671		 * Animation types (none,fade,pop,slide)
672		 */
673		animation.types = {};
674		animation.types.fade = [{
675			x: 0.4,
676			y: 0.4,
677			w: 0.6,
678			h: 0.6,
679			o: 0.0
680		}, {
681				x: 0.4,
682				y: 0.4,
683				w: 0.6,
684				h: 0.6,
685				o: 0.1
686			}, {
687				x: 0.4,
688				y: 0.4,
689				w: 0.6,
690				h: 0.6,
691				o: 0.2
692			}, {
693				x: 0.4,
694				y: 0.4,
695				w: 0.6,
696				h: 0.6,
697				o: 0.3
698			}, {
699				x: 0.4,
700				y: 0.4,
701				w: 0.6,
702				h: 0.6,
703				o: 0.4
704			}, {
705				x: 0.4,
706				y: 0.4,
707				w: 0.6,
708				h: 0.6,
709				o: 0.5
710			}, {
711				x: 0.4,
712				y: 0.4,
713				w: 0.6,
714				h: 0.6,
715				o: 0.6
716			}, {
717				x: 0.4,
718				y: 0.4,
719				w: 0.6,
720				h: 0.6,
721				o: 0.7
722			}, {
723				x: 0.4,
724				y: 0.4,
725				w: 0.6,
726				h: 0.6,
727				o: 0.8
728			}, {
729				x: 0.4,
730				y: 0.4,
731				w: 0.6,
732				h: 0.6,
733				o: 0.9
734			}, {
735				x: 0.4,
736				y: 0.4,
737				w: 0.6,
738				h: 0.6,
739				o: 1.0
740			}];
741		animation.types.none = [{
742			x: 0.4,
743			y: 0.4,
744			w: 0.6,
745			h: 0.6,
746			o: 1
747		}];
748		animation.types.pop = [{
749			x: 1,
750			y: 1,
751			w: 0,
752			h: 0,
753			o: 1
754		}, {
755				x: 0.9,
756				y: 0.9,
757				w: 0.1,
758				h: 0.1,
759				o: 1
760			}, {
761				x: 0.8,
762				y: 0.8,
763				w: 0.2,
764				h: 0.2,
765				o: 1
766			}, {
767				x: 0.7,
768				y: 0.7,
769				w: 0.3,
770				h: 0.3,
771				o: 1
772			}, {
773				x: 0.6,
774				y: 0.6,
775				w: 0.4,
776				h: 0.4,
777				o: 1
778			}, {
779				x: 0.5,
780				y: 0.5,
781				w: 0.5,
782				h: 0.5,
783				o: 1
784			}, {
785				x: 0.4,
786				y: 0.4,
787				w: 0.6,
788				h: 0.6,
789				o: 1
790			}];
791		animation.types.popFade = [{
792			x: 0.75,
793			y: 0.75,
794			w: 0,
795			h: 0,
796			o: 0
797		}, {
798				x: 0.65,
799				y: 0.65,
800				w: 0.1,
801				h: 0.1,
802				o: 0.2
803			}, {
804				x: 0.6,
805				y: 0.6,
806				w: 0.2,
807				h: 0.2,
808				o: 0.4
809			}, {
810				x: 0.55,
811				y: 0.55,
812				w: 0.3,
813				h: 0.3,
814				o: 0.6
815			}, {
816				x: 0.50,
817				y: 0.50,
818				w: 0.4,
819				h: 0.4,
820				o: 0.8
821			}, {
822				x: 0.45,
823				y: 0.45,
824				w: 0.5,
825				h: 0.5,
826				o: 0.9
827			}, {
828				x: 0.4,
829				y: 0.4,
830				w: 0.6,
831				h: 0.6,
832				o: 1
833			}];
834		animation.types.slide = [{
835			x: 0.4,
836			y: 1,
837			w: 0.6,
838			h: 0.6,
839			o: 1
840		}, {
841				x: 0.4,
842				y: 0.9,
843				w: 0.6,
844				h: 0.6,
845				o: 1
846			}, {
847				x: 0.4,
848				y: 0.9,
849				w: 0.6,
850				h: 0.6,
851				o: 1
852			}, {
853				x: 0.4,
854				y: 0.8,
855				w: 0.6,
856				h: 0.6,
857				o: 1
858			}, {
859				x: 0.4,
860				y: 0.7,
861				w: 0.6,
862				h: 0.6,
863				o: 1
864			}, {
865				x: 0.4,
866				y: 0.6,
867				w: 0.6,
868				h: 0.6,
869				o: 1
870			}, {
871				x: 0.4,
872				y: 0.5,
873				w: 0.6,
874				h: 0.6,
875				o: 1
876			}, {
877				x: 0.4,
878				y: 0.4,
879				w: 0.6,
880				h: 0.6,
881				o: 1
882			}];
883		/**
884		 * Run animation
885		 * @param {Object} opt Animation options
886		 * @param {Object} cb Callabak after all steps are done
887		 * @param {Object} revert Reverse order? true|false
888		 * @param {Object} step Optional step number (frame bumber)
889		 */
890		animation.run = function (opt, cb, revert, step) {
891			var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation];
892			if (revert === true) {
893				step = (typeof step !== 'undefined') ? step : animationType.length - 1;
894			} else {
895				step = (typeof step !== 'undefined') ? step : 0;
896			}
897			cb = (cb) ? cb : function () {
898			};
899			if ((step < animationType.length) && (step >= 0)) {
900				type[_opt.type](merge(opt, animationType[step]));
901				_animTimeout = setTimeout(function () {
902					if (revert) {
903						step = step - 1;
904					} else {
905						step = step + 1;
906					}
907					animation.run(opt, cb, revert, step);
908				}, animation.duration);
909
910				link.setIcon(_canvas);
911			} else {
912				cb();
913				return;
914			}
915		};
916		//auto init
917		init();
918		return {
919			badge: badge,
920			video: video,
921			image: image,
922			rawImageSrc: rawImageSrc,
923			webcam: webcam,
924			setOpt: setOpt,
925			reset: icon.reset,
926			browser: {
927				supported: _browser.supported
928			}
929		};
930	});
931
932	// AMD / RequireJS
933	if (typeof define !== 'undefined' && define.amd) {
934		define([], function () {
935			return Favico;
936		});
937	}
938	// CommonJS
939	else if (typeof module !== 'undefined' && module.exports) {
940		module.exports = Favico;
941	}
942	// included directly via <script> tag
943	else {
944		this.Favico = Favico;
945	}
946
947})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.