PageSourceSearch

https://www.afaindia.com/js/theme.plugins.js

js afaindia.com collected 2026-10-10 00:45:06 UTC 40,122 bytes, 1,259 lines download raw bytes

1/*
2Plugin Name: 	scrollToTop for jQuery.
3Written by: 	Okler Themes - (http://www.okler.net)
4Version: 		3.1.0
5*/
6// Theme
7window.theme = {};
8
9(function($) {
10	$.extend({
11
12		scrollToTop: function() {
13
14			var _isScrolling = false;
15
16			// Append Button
17			$("body").append($("<a />")
18							.addClass("scroll-to-top")
19							.attr({
20								"href": "#",
21								"id": "scrollToTop"
22							})
23							.append(
24								$("<i />")
25									.addClass("icon icon-chevron-up icon-white")
26							));
27
28			$("#scrollToTop").click(function(e) {
29
30				e.preventDefault();
31				$("body, html").animate({scrollTop : 0}, 500);
32				return false;
33
34			});
35
36			// Show/Hide Button on Window Scroll event.
37			$(window).scroll(function() {
38
39				if(!_isScrolling) {
40
41					_isScrolling = true;
42
43					if($(window).scrollTop() > 150) {
44
45						$("#scrollToTop").stop(true, true).addClass("visible");
46						_isScrolling = false;
47
48					} else {
49
50						$("#scrollToTop").stop(true, true).removeClass("visible");
51						_isScrolling = false;
52
53					}
54
55				}
56
57			});
58
59		}
60
61	});
62})(jQuery);
63
64
65/*
66Plugin Name: 	BrowserSelector
67Written by: 	Okler Themes - (http://www.okler.net)
68*/
69
70(function($) {
71	$.extend({
72
73		browserSelector: function() {
74
75			var u = navigator.userAgent,
76				ua = u.toLowerCase(),
77				is = function (t) {
78					return ua.indexOf(t) > -1;
79				},
80				g = 'gecko',
81				w = 'webkit',
82				s = 'safari',
83				o = 'opera',
84				h = document.documentElement,
85				b = [(!(/opera|webtv/i.test(ua)) && /msie\s(\d)/.test(ua)) ? ('ie ie' + parseFloat(navigator.appVersion.split("MSIE")[1])) : is('firefox/2') ? g + ' ff2' : is('firefox/3.5') ? g + ' ff3 ff3_5' : is('firefox/3') ? g + ' ff3' : is('gecko/') ? g : is('opera') ? o + (/version\/(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery1 : (/opera(\s|\/)(\d+)/.test(ua) ? ' ' + o + RegExp.jQuery2 : '')) : is('konqueror') ? 'konqueror' : is('chrome') ? w + ' chrome' : is('iron') ? w + ' iron' : is('applewebkit/') ? w + ' ' + s + (/version\/(\d+)/.test(ua) ? ' ' + s + RegExp.jQuery1 : '') : is('mozilla/') ? g : '', is('j2me') ? 'mobile' : is('iphone') ? 'iphone' : is('ipod') ? 'ipod' : is('mac') ? 'mac' : is('darwin') ? 'mac' : is('webtv') ? 'webtv' : is('win') ? 'win' : is('freebsd') ? 'freebsd' : (is('x11') || is('linux')) ? 'linux' : '', 'js'];
86
87			c = b.join(' ');
88			h.className += ' ' + c;
89
90			var isIE11 = !(window.ActiveXObject) && "ActiveXObject" in window;
91
92			if (isIE11) {
93				$('html').removeClass('gecko').addClass('ie ie11');
94				return;
95			}
96
97		}
98
99	});
100})(jQuery);
101
102/*
103Plugin Name: 	waitForImages jQuery Plugin - v1.5.0 - 2013-07-20
104Written by: 	https://github.com/alexanderdickson/waitForImages
105
106*/
107
108;(function ($) {
109    // Namespace all events.
110    var eventNamespace = 'waitForImages';
111
112    // CSS properties which contain references to images.
113    $.waitForImages = {
114        hasImageProperties: ['backgroundImage', 'listStyleImage', 'borderImage', 'borderCornerImage', 'cursor']
115    };
116
117    // Custom selector to find `img` elements that have a valid `src` attribute and have not already loaded.
118    $.expr[':'].uncached = function (obj) {
119        // Ensure we are dealing with an `img` element with a valid `src` attribute.
120        if (!$(obj).is('img[src!=""]')) {
121            return false;
122        }
123
124        // Firefox's `complete` property will always be `true` even if the image has not been downloaded.
125        // Doing it this way works in Firefox.
126        var img = new Image();
127        img.src = obj.src;
128        return !img.complete;
129    };
130
131    $.fn.waitForImages = function (finishedCallback, eachCallback, waitForAll) {
132
133        var allImgsLength = 0;
134        var allImgsLoaded = 0;
135
136        // Handle options object.
137        if ($.isPlainObject(arguments[0])) {
138            waitForAll = arguments[0].waitForAll;
139            eachCallback = arguments[0].each;
140			// This must be last as arguments[0]
141			// is aliased with finishedCallback.
142            finishedCallback = arguments[0].finished;
143        }
144
145        // Handle missing callbacks.
146        finishedCallback = finishedCallback || $.noop;
147        eachCallback = eachCallback || $.noop;
148
149        // Convert waitForAll to Boolean
150        waitForAll = !! waitForAll;
151
152        // Ensure callbacks are functions.
153        if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) {
154            throw new TypeError('An invalid callback was supplied.');
155        }
156
157        return this.each(function () {
158            // Build a list of all imgs, dependent on what images will be considered.
159            var obj = $(this);
160            var allImgs = [];
161            // CSS properties which may contain an image.
162            var hasImgProperties = $.waitForImages.hasImageProperties || [];
163            // To match `url()` references.
164            // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri
165            var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g;
166
167            if (waitForAll) {
168
169                // Get all elements (including the original), as any one of them could have a background image.
170                obj.find('*').addBack().each(function () {
171                    var element = $(this);
172
173                    // If an `img` element, add it. But keep iterating in case it has a background image too.
174                    if (element.is('img:uncached')) {
175                        allImgs.push({
176                            src: element.attr('src'),
177                            element: element[0]
178                        });
179                    }
180
181                    $.each(hasImgProperties, function (i, property) {
182                        var propertyValue = element.css(property);
183                        var match;
184
185                        // If it doesn't contain this property, skip.
186                        if (!propertyValue) {
187                            return true;
188                        }
189
190                        // Get all url() of this element.
191                        while (match = matchUrl.exec(propertyValue)) {
192                            allImgs.push({
193                                src: match[2],
194                                element: element[0]
195                            });
196                        }
197                    });
198                });
199            } else {
200                // For images only, the task is simpler.
201                obj.find('img:uncached')
202                    .each(function () {
203                    allImgs.push({
204                        src: this.src,
205                        element: this
206                    });
207                });
208            }
209
210            allImgsLength = allImgs.length;
211            allImgsLoaded = 0;
212
213            // If no images found, don't bother.
214            if (allImgsLength === 0) {
215                finishedCallback.call(obj[0]);
216            }
217
218            $.each(allImgs, function (i, img) {
219
220                var image = new Image();
221
222                // Handle the image loading and error with the same callback.
223                $(image).on('load.' + eventNamespace + ' error.' + eventNamespace, function (event) {
224                    allImgsLoaded++;
225
226                    // If an error occurred with loading the image, set the third argument accordingly.
227                    eachCallback.call(img.element, allImgsLoaded, allImgsLength, event.type == 'load');
228
229                    if (allImgsLoaded == allImgsLength) {
230                        finishedCallback.call(obj[0]);
231                        return false;
232                    }
233
234                });
235
236                image.src = img.src;
237            });
238        });
239    };
240}(jQuery));
241
242/*
243Plugin Name: 	Count To
244Written by: 	Matt Huggins - https://github.com/mhuggins/jquery-countTo
245
246*/
247
248(function ($) {
249	$.fn.countTo = function (options) {
250		options = options || {};
251
252		return $(this).each(function () {
253			// set options for current element
254			var settings = $.extend({}, $.fn.countTo.defaults, {
255				from:            $(this).data('from'),
256				to:              $(this).data('to'),
257				speed:           $(this).data('speed'),
258				refreshInterval: $(this).data('refresh-interval'),
259				decimals:        $(this).data('decimals')
260			}, options);
261
262			// how many times to update the value, and how much to increment the value on each update
263			var loops = Math.ceil(settings.speed / settings.refreshInterval),
264				increment = (settings.to - settings.from) / loops;
265
266			// references & variables that will change with each update
267			var self = this,
268				$self = $(this),
269				loopCount = 0,
270				value = settings.from,
271				data = $self.data('countTo') || {};
272
273			$self.data('countTo', data);
274
275			// if an existing interval can be found, clear it first
276			if (data.interval) {
277				clearInterval(data.interval);
278			}
279			data.interval = setInterval(updateTimer, settings.refreshInterval);
280
281			// initialize the element with the starting value
282			render(value);
283
284			function updateTimer() {
285				value += increment;
286				loopCount++;
287
288				render(value);
289
290				if (typeof(settings.onUpdate) == 'function') {
291					settings.onUpdate.call(self, value);
292				}
293
294				if (loopCount >= loops) {
295					// remove the interval
296					$self.removeData('countTo');
297					clearInterval(data.interval);
298					value = settings.to;
299
300					if (typeof(settings.onComplete) == 'function') {
301						settings.onComplete.call(self, value);
302					}
303				}
304			}
305
306			function render(value) {
307				var formattedValue = settings.formatter.call(self, value, settings);
308				$self.html(formattedValue);
309			}
310		});
311	};
312
313	$.fn.countTo.defaults = {
314		from: 0,               // the number the element should start at
315		to: 0,                 // the number the element should end at
316		speed: 1000,           // how long it should take to count between the target numbers
317		refreshInterval: 100,  // how often the element should be updated
318		decimals: 0,           // the number of decimal places to show
319		formatter: formatter,  // handler for formatting the value before rendering
320		onUpdate: null,        // callback method for every time the element is updated
321		onComplete: null       // callback method for when the element finishes updating
322	};
323
324	function formatter(value, settings) {
325		return value.toFixed(settings.decimals);
326	}
327}(jQuery));
328
329/*
330Plugin Name: 	afterResize.js
331Written by: 	https://github.com/mcshaman/afterResize.js
332Description: 	Simple jQuery plugin designed to emulate an 'after resize' event.
333
334*/
335
336( function( $ ) {
337	"use strict";
338	
339	// Define default settings
340	var defaults = {
341		action: function() {},
342		runOnLoad: false,
343		duration: 500
344	};
345	
346	// Define global variables
347	var settings = defaults,
348		running = false,
349		start;
350	
351	var methods = {};
352	
353	// Initial plugin configuration
354	methods.init = function() {
355		
356		// Allocate passed arguments to settings based on type
357		for( var i = 0; i <= arguments.length; i++ ) {
358			var arg = arguments[i];
359			switch ( typeof arg ) {
360				case "function":
361					settings.action = arg;
362					break;
363				case "boolean":
364					settings.runOnLoad = arg;
365					break;
366				case "number":
367					settings.duration = arg;
368					break;
369			}
370		}
371	
372		// Process each matching jQuery object
373		return this.each(function() {
374		
375			if( settings.runOnLoad ) { settings.action(); }
376			
377			$(this).resize( function() {
378				
379				methods.timedAction.call( this );
380				
381			} );
382		
383		} );
384	};
385	
386	methods.timedAction = function( code, millisec ) {
387		
388		var doAction = function() {
389			var remaining = settings.duration;
390			
391			if( running ) {
392				var elapse = new Date() - start;
393				remaining = settings.duration - elapse;
394				if( remaining <= 0 ) {
395					// Clear timeout and reset running variable
396					clearTimeout(running);
397					running = false;
398					// Perform user defined function
399					settings.action();
400				
401					return;
402				}
403			}
404			wait( remaining );
405		};
406		
407		var wait = function( time ) {
408			running = setTimeout( doAction, time );
409		};
410		
411		// Define new action starting time
412		start = new Date();
413		
414		// Define runtime settings if function is run directly
415		if( typeof millisec === 'number' ) { settings.duration = millisec; }
416		if( typeof code === 'function' ) { settings.action = code; }
417		
418		// Only run timed loop if not already running
419		if( !running ) { doAction(); }
420		
421	};
422
423	
424	$.fn.afterResize = function( method ) {
425		
426		if( methods[method] ) {
427			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ) );
428		} else {
429			return methods.init.apply( this, arguments );
430		}
431		
432	};
433	
434})(jQuery);
435
436/*
437Plugin Name: 	smoothScroll for jQuery.
438Written by: 	Okler Themes - (http://www.okler.net)
439Version: 		3.1.0
440
441Based on:
442
443	SmoothScroll v1.2.1
444	Licensed under the terms of the MIT license.
445
446	People involved
447	 - Balazs Galambosi (maintainer)
448	 - Patrick Brunner  (original idea)
449	 - Michael Herf     (Pulse Algorithm)
450
451*/
452
453(function($) {
454	$.extend({
455
456		smoothScroll: function() {
457
458			// Scroll Variables (tweakable)
459			var defaultOptions = {
460
461				// Scrolling Core
462				frameRate        : 60, // [Hz]
463				animationTime    : 700, // [px]
464				stepSize         : 120, // [px]
465
466				// Pulse (less tweakable)
467				// ratio of "tail" to "acceleration"
468				pulseAlgorithm   : true,
469				pulseScale       : 10,
470				pulseNormalize   : 1,
471
472				// Acceleration
473				accelerationDelta : 20,  // 20
474				accelerationMax   : 1,   // 1
475
476				// Keyboard Settings
477				keyboardSupport   : true,  // option
478				arrowScroll       : 50,     // [px]
479
480				// Other
481				touchpadSupport   : true,
482				fixedBackground   : true,
483				excluded          : ""
484			};
485
486			var options = defaultOptions;
487
488			// Other Variables
489			var isExcluded = false;
490			var isFrame = false;
491			var direction = { x: 0, y: 0 };
492			var initDone  = false;
493			var root = document.documentElement;
494			var activeElement;
495			var observer;
496			var deltaBuffer = [ 120, 120, 120 ];
497
498			var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32,
499						pageup: 33, pagedown: 34, end: 35, home: 36 };
500
501
502			/***********************************************
503			 * INITIALIZE
504			 ***********************************************/
505
506			/**
507			 * Tests if smooth scrolling is allowed. Shuts down everything if not.
508			 */
509			function initTest() {
510
511				var disableKeyboard = false;
512
513				// disable keys for google reader (spacebar conflict)
514				if (document.URL.indexOf("google.com/reader/view") > -1) {
515					disableKeyboard = true;
516				}
517
518				// disable everything if the page is blacklisted
519				if (options.excluded) {
520					var domains = options.excluded.split(/[,\n] ?/);
521					domains.push("mail.google.com"); // exclude Gmail for now
522					for (var i = domains.length; i--;) {
523						if (document.URL.indexOf(domains[i]) > -1) {
524							observer && observer.disconnect();
525							removeEvent("mousewheel", wheel);
526							disableKeyboard = true;
527							isExcluded = true;
528							break;
529						}
530					}
531				}
532
533				// disable keyboard support if anything above requested it
534				if (disableKeyboard) {
535					removeEvent("keydown", keydown);
536				}
537
538				if (options.keyboardSupport && !disableKeyboard) {
539					addEvent("keydown", keydown);
540				}
541			}
542
543			/**
544			 * Sets up scrolls array, determines if frames are involved.
545			 */
546			function init() {
547
548				if (!document.body) return;
549
550				var body = document.body;
551				var html = document.documentElement;
552				var windowHeight = window.innerHeight;
553				var scrollHeight = body.scrollHeight;
554
555				// check compat mode for root element
556				root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
557				activeElement = body;
558
559				initTest();
560				initDone = true;
561
562				// Checks if this script is running in a frame
563				if (top != self) {
564					isFrame = true;
565				}
566
567				/**
568				 * This fixes a bug where the areas left and right to
569				 * the content does not trigger the onmousewheel event
570				 * on some pages. e.g.: html, body { height: 100% }
571				 */
572				else if (scrollHeight > windowHeight &&
573						(body.offsetHeight <= windowHeight ||
574						 html.offsetHeight <= windowHeight)) {
575
576					// DOMChange (throttle): fix height
577					var pending = false;
578					var refresh = function () {
579						if (!pending && html.scrollHeight != document.height) {
580							pending = true; // add a new pending action
581							setTimeout(function () {
582								html.style.height = document.height + 'px';
583								pending = false;
584							}, 500); // act rarely to stay fast
585						}
586					};
587					html.style.height = 'auto';
588					setTimeout(refresh, 10);
589
590					var config = {
591						attributes: true,
592						childList: true,
593						characterData: false
594					};
595
596					observer = new MutationObserver(refresh);
597					observer.observe(body, config);
598
599					// clearfix
600					if (root.offsetHeight <= windowHeight) {
601						var underlay = document.createElement("div");
602						underlay.style.clear = "both";
603						body.appendChild(underlay);
604					}
605				}
606
607				// gmail performance fix
608				if (document.URL.indexOf("mail.google.com") > -1) {
609					var s = document.createElement("style");
610					s.innerHTML = ".iu { visibility: hidden }";
611					(document.getElementsByTagName("head")[0] || html).appendChild(s);
612				}
613				// facebook better home timeline performance
614				// all the HTML resized images make rendering CPU intensive
615				else if (document.URL.indexOf("www.facebook.com") > -1) {
616					var home_stream = document.getElementById("home_stream");
617					home_stream && (home_stream.style.webkitTransform = "translateZ(0)");
618				}
619				// disable fixed background
620				if (!options.fixedBackground && !isExcluded) {
621					body.style.backgroundAttachment = "scroll";
622					html.style.backgroundAttachment = "scroll";
623				}
624			}
625
626
627			/************************************************
628			 * SCROLLING
629			 ************************************************/
630
631			var que = [];
632			var pending = false;
633			var lastScroll = +new Date;
634
635			/**
636			 * Pushes scroll actions to the scrolling queue.
637			 */
638			function scrollArray(elem, left, top, delay) {
639
640				delay || (delay = 1000);
641				directionCheck(left, top);
642
643				if (options.accelerationMax != 1) {
644					var now = +new Date;
645					var elapsed = now - lastScroll;
646					if (elapsed < options.accelerationDelta) {
647						var factor = (1 + (30 / elapsed)) / 2;
648						if (factor > 1) {
649							factor = Math.min(factor, options.accelerationMax);
650							left *= factor;
651							top  *= factor;
652						}
653					}
654					lastScroll = +new Date;
655				}
656
657				// push a scroll command
658				que.push({
659					x: left,
660					y: top,
661					lastX: (left < 0) ? 0.99 : -0.99,
662					lastY: (top  < 0) ? 0.99 : -0.99,
663					start: +new Date
664				});
665
666				// don't act if there's a pending queue
667				if (pending) {
668					return;
669				}
670
671				var scrollWindow = (elem === document.body);
672
673				var step = function (time) {
674
675					var now = +new Date;
676					var scrollX = 0;
677					var scrollY = 0;
678
679					for (var i = 0; i < que.length; i++) {
680
681						var item = que[i];
682						var elapsed  = now - item.start;
683						var finished = (elapsed >= options.animationTime);
684
685						// scroll position: [0, 1]
686						var position = (finished) ? 1 : elapsed / options.animationTime;
687
688						// easing [optional]
689						if (options.pulseAlgorithm) {
690							position = pulse(position);
691						}
692
693						// only need the difference
694						var x = (item.x * position - item.lastX) >> 0;
695						var y = (item.y * position - item.lastY) >> 0;
696
697						// add this to the total scrolling
698						scrollX += x;
699						scrollY += y;
700
701						// update last values
702						item.lastX += x;
703						item.lastY += y;
704
705						// delete and step back if it's over
706						if (finished) {
707							que.splice(i, 1); i--;
708						}
709					}
710
711					// scroll left and top
712					if (scrollWindow) {
713						window.scrollBy(scrollX, scrollY);
714					}
715					else {
716						if (scrollX) elem.scrollLeft += scrollX;
717						if (scrollY) elem.scrollTop  += scrollY;
718					}
719
720					// clean up if there's nothing left to do
721					if (!left && !top) {
722						que = [];
723					}
724
725					if (que.length) {
726						requestFrame(step, elem, (delay / options.frameRate + 1));
727					} else {
728						pending = false;
729					}
730				};
731
732				// start a new queue of actions
733				requestFrame(step, elem, 0);
734				pending = true;
735			}
736
737
738			/***********************************************
739			 * EVENTS
740			 ***********************************************/
741
742			/**
743			 * Mouse wheel handler.
744			 * @param {Object} event
745			 */
746			function wheel(event) {
747
748				if (!initDone) {
749					init();
750				}
751
752				var target = event.target;
753				var overflowing = overflowingAncestor(target);
754
755				// use default if there's no overflowing
756				// element or default action is prevented
757				if (!overflowing || event.defaultPrevented ||
758					isNodeName(activeElement, "embed") ||
759				   (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) {
760					return true;
761				}
762
763				var deltaX = event.wheelDeltaX || 0;
764				var deltaY = event.wheelDeltaY || 0;
765
766				// use wheelDelta if deltaX/Y is not available
767				if (!deltaX && !deltaY) {
768					deltaY = event.wheelDelta || 0;
769				}
770
771				// check if it's a touchpad scroll that should be ignored
772				if (!options.touchpadSupport && isTouchpad(deltaY)) {
773					return true;
774				}
775
776				// scale by step size
777				// delta is 120 most of the time
778				// synaptics seems to send 1 sometimes
779				if (Math.abs(deltaX) > 1.2) {
780					deltaX *= options.stepSize / 120;
781				}
782				if (Math.abs(deltaY) > 1.2) {
783					deltaY *= options.stepSize / 120;
784				}
785
786				scrollArray(overflowing, -deltaX, -deltaY);
787				event.preventDefault();
788			}
789
790			/**
791			 * Keydown event handler.
792			 * @param {Object} event
793			 */
794			function keydown(event) {
795
796				var target   = event.target;
797				var modifier = event.ctrlKey || event.altKey || event.metaKey ||
798							  (event.shiftKey && event.keyCode !== key.spacebar);
799
800				// do nothing if user is editing text
801				// or using a modifier key (except shift)
802				// or in a dropdown
803				if ( /input|textarea|select|embed/i.test(target.nodeName) ||
804					 target.isContentEditable ||
805					 event.defaultPrevented   ||
806					 modifier ) {
807				  return true;
808				}
809				// spacebar should trigger button press
810				if (isNodeName(target, "button") &&
811					event.keyCode === key.spacebar) {
812				  return true;
813				}
814
815				var shift, x = 0, y = 0;
816				var elem = overflowingAncestor(activeElement);
817				var clientHeight = elem.clientHeight;
818
819				if (elem == document.body) {
820					clientHeight = window.innerHeight;
821				}
822
823				switch (event.keyCode) {
824					case key.up:
825						y = -options.arrowScroll;
826						break;
827					case key.down:
828						y = options.arrowScroll;
829						break;
830					case key.spacebar: // (+ shift)
831						shift = event.shiftKey ? 1 : -1;
832						y = -shift * clientHeight * 0.9;
833						break;
834					case key.pageup:
835						y = -clientHeight * 0.9;
836						break;
837					case key.pagedown:
838						y = clientHeight * 0.9;
839						break;
840					case key.home:
841						y = -elem.scrollTop;
842						break;
843					case key.end:
844						var damt = elem.scrollHeight - elem.scrollTop - clientHeight;
845						y = (damt > 0) ? damt+10 : 0;
846						break;
847					case key.left:
848						x = -options.arrowScroll;
849						break;
850					case key.right:
851						x = options.arrowScroll;
852						break;
853					default:
854						return true; // a key we don't care about
855				}
856
857				scrollArray(elem, x, y);
858				event.preventDefault();
859			}
860
861			/**
862			 * Mousedown event only for updating activeElement
863			 */
864			function mousedown(event) {
865				activeElement = event.target;
866			}
867
868
869			/***********************************************
870			 * OVERFLOW
871			 ***********************************************/
872
873			var cache = {}; // cleared out every once in while
874			setInterval(function () { cache = {}; }, 10 * 1000);
875
876			var uniqueID = (function () {
877				var i = 0;
878				return function (el) {
879					return el.uniqueID || (el.uniqueID = i++);
880				};
881			})();
882
883			function setCache(elems, overflowing) {
884				for (var i = elems.length; i--;)
885					cache[uniqueID(elems[i])] = overflowing;
886				return overflowing;
887			}
888
889			function overflowingAncestor(el) {
890				var elems = [];
891				var rootScrollHeight = root.scrollHeight;
892				do {
893					var cached = cache[uniqueID(el)];
894					if (cached) {
895						return setCache(elems, cached);
896					}
897					elems.push(el);
898					if (rootScrollHeight === el.scrollHeight) {
899						if (!isFrame || root.clientHeight + 10 < rootScrollHeight) {
900							return setCache(elems, document.body); // scrolling root in WebKit
901						}
902					} else if (el.clientHeight + 10 < el.scrollHeight) {
903						overflow = getComputedStyle(el, "").getPropertyValue("overflow-y");
904						if (overflow === "scroll" || overflow === "auto") {
905							return setCache(elems, el);
906						}
907					}
908				} while (el = el.parentNode);
909			}
910
911
912			/***********************************************
913			 * HELPERS
914			 ***********************************************/
915
916			function addEvent(type, fn, bubble) {
917				window.addEventListener(type, fn, (bubble||false));
918			}
919
920			function removeEvent(type, fn, bubble) {
921				window.removeEventListener(type, fn, (bubble||false));
922			}
923
924			function isNodeName(el, tag) {
925				return (el.nodeName||"").toLowerCase() === tag.toLowerCase();
926			}
927
928			function directionCheck(x, y) {
929				x = (x > 0) ? 1 : -1;
930				y = (y > 0) ? 1 : -1;
931				if (direction.x !== x || direction.y !== y) {
932					direction.x = x;
933					direction.y = y;
934					que = [];
935					lastScroll = 0;
936				}
937			}
938
939			var deltaBufferTimer;
940
941			function isTouchpad(deltaY) {
942				if (!deltaY) return;
943				deltaY = Math.abs(deltaY)
944				deltaBuffer.push(deltaY);
945				deltaBuffer.shift();
946				clearTimeout(deltaBufferTimer);
947				var allEquals    = (deltaBuffer[0] == deltaBuffer[1] &&
948									deltaBuffer[1] == deltaBuffer[2]);
949				var allDivisable = (isDivisible(deltaBuffer[0], 120) &&
950									isDivisible(deltaBuffer[1], 120) &&
951									isDivisible(deltaBuffer[2], 120));
952				return !(allEquals || allDivisable);
953			}
954
955			function isDivisible(n, divisor) {
956				return (Math.floor(n / divisor) == n / divisor);
957			}
958
959			var requestFrame = (function () {
960				  return  window.requestAnimationFrame       ||
961						  window.webkitRequestAnimationFrame ||
962						  function (callback, element, delay) {
963							  window.setTimeout(callback, delay || (1000/60));
964						  };
965			})();
966
967			var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
968
969
970			/***********************************************
971			 * PULSE
972			 ***********************************************/
973
974			/**
975			 * Viscous fluid with a pulse for part and decay for the rest.
976			 * - Applies a fixed force over an interval (a damped acceleration), and
977			 * - Lets the exponential bleed away the velocity over a longer interval
978			 * - Michael Herf, http://stereopsis.com/stopping/
979			 */
980			function pulse_(x) {
981				var val, start, expx;
982				// test
983				x = x * options.pulseScale;
984				if (x < 1) { // acceleartion
985					val = x - (1 - Math.exp(-x));
986				} else {     // tail
987					// the previous animation ended here:
988					start = Math.exp(-1);
989					// simple viscous drag
990					x -= 1;
991					expx = 1 - Math.exp(-x);
992					val = start + (expx * (1 - start));
993				}
994				return val * options.pulseNormalize;
995			}
996
997			function pulse(x) {
998				if (x >= 1) return 1;
999				if (x <= 0) return 0;
1000
1001				if (options.pulseNormalize == 1) {
1002					options.pulseNormalize /= pulse_(1);
1003				}
1004				return pulse_(x);
1005			}
1006
1007			addEvent("mousedown", mousedown);
1008			addEvent("mousewheel", wheel);
1009			addEvent("load", init);
1010
1011		}
1012
1013	});
1014})(jQuery);
1015
1016/*
1017Plugin Name:  Lity - v3.0.0-dev - 2017-07-17
1018Written by : http://sorgalla.com/lity/ 
1019*/
1020(function ($) {
1021    "use strict";
1022!function(a,b){"function"==typeof define&&define.amd?define(["jquery"],function(c){return b(a,c)}):"object"==typeof module&&"object"==typeof module.exports?module.exports=b(a,require("jquery")):a.lity=b(a,a.jQuery||a.Zepto)}("undefined"!=typeof window?window:this,function(a,b){"use strict";function c(a){var b=C();return O&&a.length?(a.one(O,b.resolve),setTimeout(b.resolve,500)):b.resolve(),b.promise()}function d(a,c,d){if(1===arguments.length)return b.extend({},a);if("string"==typeof c){if(void 0===d)return void 0===a[c]?null:a[c];a[c]=d}else b.extend(a,c);return this}function e(a){var b=a.indexOf("?");b>-1&&(a=a.substr(b+1));for(var c,d=decodeURI(a.split("#")[0]).split("&"),e={},f=0,g=d.length;f<g;f++)d[f]&&(c=d[f].split("="),e[c[0]]=c[1]);return e}function f(a,c){if(!c)return a;
1022if("string"===b.type(c)&&(c=e(c)),a.indexOf("?")>-1){var d=a.split("?");a=d.shift(),c=b.extend({},e(d[0]),c)}return a+"?"+b.param(c)}function g(a,b){var c=a.indexOf("#");return-1===c?b:(c>0&&(a=a.substr(c)),b+a)}function h(a,b,c,d){return b&&b.element().addClass("lity-iframe"),c&&(a=f(a,c)),d&&(a=g(d,a)),'<div class="lity-iframe-container"><iframe frameborder="0" allowfullscreen src="'+a+'"/></div>'}function i(a){return b('<span class="lity-error"/>').append(a)}function j(a,c){var d=c.opener()&&c.opener().data("lity-desc")||"Image with no description",e=b('<img src="'+a+'" alt="'+d+'"/>'),f=C(),g=function(){f.reject(i("Failed loading image"))};return e.on("load",function(){if(0===this.naturalWidth)return g();f.resolve(e)}).on("error",g),f.promise()}function k(a,c){var d,e,f;try{d=b(a)}catch(a){return!1}return!!d.length&&(e=b('<i style="display:none !important"/>'),f=d.hasClass("lity-hide"),c.element().one("lity:remove",function(){e.before(d).remove(),f&&!d.closest(".lity-content").length&&d.addClass("lity-hide")}),d.removeClass("lity-hide").after(e))}function l(a,b){var c=K.exec(a);return!!c&&h("https://www.youtube"+(c[2]||"")+".com/embed/"+c[4]+"?autoplay=1",b,c[5],a)}function m(a,b){var c=L.exec(a);return!!c&&h("https://player.vimeo.com/video/"+c[3]+"?autoplay=1",b,c[4],a)}function n(a,b){var c=N.exec(a);return!!c&&(0!==a.indexOf("http")&&(a="https:"+a),h("https://www.facebook.com/plugins/video.php?href="+a+"&autoplay=1",b,c[4],a))}function o(a,b){var c=M.exec(a);return!!c&&h("https://www.google."+c[3]+"/maps?"+c[6],b,{output:c[6].indexOf("layer=c")>0?"svembed":"embed"},a)}function p(a,b){return h(a,b)}function q(){return A.documentElement.clientHeight?A.documentElement.clientHeight:Math.round(B.height())}function r(a){var b=w();b&&(27===a.keyCode&&b.options("esc")&&b.close(),9===a.keyCode&&s(a,b))}function s(a,b){var c=b.element().find(H),d=c.index(A.activeElement);a.shiftKey&&d<=0?(c.get(c.length-1).focus(),a.preventDefault()):a.shiftKey||d!==c.length-1||(c.get(0).focus(),a.preventDefault())}function t(){b.each(E,function(a,b){b.resize()})}function u(a){1===E.unshift(a)&&(D.addClass("lity-active"),B.on({resize:t,keydown:r})),b("body > *").not(a.element()).addClass("lity-hidden").each(function(){var a=b(this);void 0===a.data(G)&&a.data(G,a.attr(F)||null)}).attr(F,"true")}function v(a){var c;a.element().attr(F,"true"),1===E.length&&(D.removeClass("lity-active"),B.off({resize:t,keydown:r})),E=b.grep(E,function(b){return a!==b}),c=E.length?E[0].element():b(".lity-hidden"),c.removeClass("lity-hidden").each(function(){var a=b(this),c=a.data(G);c?a.attr(F,c):a.removeAttr(F),a.removeData(G)})}function w(){return 0===E.length?null:E[0]}function x(a,c,d,e){var f,g="inline",h=b.extend({},d);return e&&h[e]?(f=h[e](a,c),g=e):(b.each(["inline","iframe"],function(a,b){delete h[b],h[b]=d[b]}),b.each(h,function(b,d){return!d||(!(!d.test||d.test(a,c))||(f=d(a,c),!1!==f?(g=b,!1):void 0))})),{handler:g,content:f||""}}function y(a,e,f,g){function h(a){k=b(a).css("max-height",q()+"px"),j.find(".lity-loader").each(function(){var a=b(this);c(a).always(function(){a.remove()})}),j.removeClass("lity-loading").find(".lity-content").empty().append(k),m=!0,k.trigger("lity:ready",[l])}var i,j,k,l=this,m=!1,n=!1;e=b.extend({},I,e),j=b(e.template),l.element=function(){return j},l.opener=function(){return f},l.content=function(){return k},l.options=b.proxy(d,l,e),l.handlers=b.proxy(d,l,e.handlers),l.resize=function(){m&&!n&&k.css("max-height",q()+"px").trigger("lity:resize",[l])},l.close=function(){if(m&&!n){n=!0,v(l);var a=C();if(g&&(A.activeElement===j[0]||b.contains(j[0],A.activeElement)))try{g.focus()}catch(a){}return k.trigger("lity:close",[l]),j.removeClass("lity-opened").addClass("lity-closed"),c(k.add(j)).always(function(){k.trigger("lity:remove",[l]),j.remove(),j=void 0,a.resolve()}),a.promise()}},i=x(a,l,e.handlers,e.handler),j.attr(F,"false").addClass("lity-loading lity-opened lity-"+i.handler).appendTo("body").focus().on("click","[data-lity-close]",function(a){b(a.target).is("[data-lity-close]")&&l.close()}).trigger("lity:open",[l]),u(l),b.when(i.content).always(h)}function z(a,c,d){a.preventDefault?(a.preventDefault(),d=b(this),a=d.data("lity-target")||d.attr("href")||d.attr("src")):d=b(d);var e=new y(a,b.extend({},d.data("lity-options")||d.data("lity"),c),d,A.activeElement);if(!a.preventDefault)return e}var A=a.document,B=b(a),C=b.Deferred,D=b("html"),E=[],F="aria-hidden",G="lity-"+F,H='a[href],area[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),button:not([disabled]),iframe,object,embed,[contenteditable],[tabindex]:not
1022([tabindex^="-"])',I={esc:!0,handler:null,handlers:{image:j,inline:k,youtube:l,vimeo:m,googlemaps:o,facebookvideo:n,iframe:p},template:'<div class="lity" role="dialog" aria-label="Dialog Window (Press escape to close)" tabindex="-1"><div class="lity-wrap" data-lity-close role="document"><div class="lity-loader" aria-hidden="true">Loading...</div><div class="lity-container"><div class="lity-content"></div><button class="lity-close" type="button" aria-label="Close (Press escape to close)" data-lity-close>&times;</button></div></div></div>'},J=/(^data:image\/)|(\.(png|jpe?g|gif|svg|webp|bmp|ico|tiff?)(\?\S*)?$)/i,K=/(youtube(-nocookie)?\.com|youtu\.be)\/(watch\?v=|v\/|u\/|embed\/?)?([\w-]{11})(.*)?/i,L=/(vimeo(pro)?\.com)\/(?:[^\d]+)?(\d+)\??(.*)?$/,M=/((maps|www)\.)?google\.([^\/\?]+)\/?((maps\/?)?\?)(.*)/i,N=/(facebook\.com)\/([a-z0-9_-]*)\/videos\/([0-9]*)(.*)?$/i,O=function(){var a=A.createElement("div"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return b[c];return!1}();return j.test=function(a){return J.test(a)},z.version="3.0.0-dev",z.options=b.proxy(d,z,I),z.handlers=b.proxy(d,z,I.handlers),z.current=w,z.iframe=h,b(A).on("click.lity","[data-lity]",z),z});
1023
1024
1025}).apply(this, [jQuery]);
1026
1027/*
1028Plugin Name: 	jQuery.pin
1029Written by: 	Okler Themes - (http://www.okler.net)
1030Version: 		4.2.0
1031
1032Based on:
1033
1034	https://github.com/webpop/jquery.pin
1035	Licensed under the terms of the MIT license.
1036
1037*/
1038(function ($) {
1039    "use strict";
1040    $.fn.pin = function (options) {
1041        var scrollY = 0, elements = [], disabled = false, $window = $(window);
1042
1043        options = options || {};
1044
1045        var recalculateLimits = function () {
1046            for (var i=0, len=elements.length; i<len; i++) {
1047                var $this = elements[i];
1048
1049                if (options.minWidth && $window.width() <= options.minWidth) {
1050                    if ($this.parent().is(".pin-wrapper")) { $this.unwrap(); }
1051                    $this.css({width: "", left: "", top: "", position: ""});
1052                    if (options.activeClass) { $this.removeClass(options.activeClass); }
1053                    disabled = true;
1054                    continue;
1055                } else {
1056                    disabled = false;
1057                }
1058
1059                var $container = options.containerSelector ? $this.closest(options.containerSelector) : $(document.body);
1060                var offset = $this.offset();
1061                var containerOffset = $container.offset();
1062                var parentOffset = $this.parent().offset();
1063
1064                if (!$this.parent().is(".pin-wrapper")) {
1065                    $this.wrap("<div class='pin-wrapper'>");
1066                }
1067
1068                var pad = $.extend({
1069                  top: 0,
1070                  bottom: 0
1071                }, options.padding || {});
1072
1073                $this.data("pin", {
1074                    pad: pad,
1075                    from: (options.containerSelector ? containerOffset.top : offset.top) - pad.top,
1076                    to: containerOffset.top + $container.height() - $this.outerHeight() - pad.bottom,
1077                    end: containerOffset.top + $container.height(),
1078                    parentTop: parentOffset.top
1079                });
1080
1081                $this.css({width: $this.outerWidth()});
1082                $this.parent().css("height", $this.outerHeight());
1083            }
1084        };
1085
1086        var onScroll = function () {
1087            if (disabled) { return; }
1088
1089            scrollY = $window.scrollTop();
1090
1091            var elmts = [];
1092            for (var i=0, len=elements.length; i<len; i++) {          
1093                var $this = $(elements[i]),
1094                    data  = $this.data("pin");
1095
1096                if (!data) { // Removed element
1097                  continue;
1098                }
1099
1100                elmts.push($this); 
1101                  
1102                var from = data.from - data.pad.bottom,
1103                    to = data.to - data.pad.top;
1104              
1105                if (from + $this.outerHeight() > data.end) {
1106                    $this.css('position', '');
1107                    continue;
1108                }
1109              
1110                if (from < scrollY && to > scrollY) {
1111                    !($this.css("position") == "fixed") && $this.css({
1112                        left: $this.offset().left,
1113                        top: data.pad.top
1114                    }).css("position", "fixed");
1115                    if (options.activeClass) { $this.addClass(options.activeClass); }
1116                } else if (scrollY >= to) {
1117                    $this.css({
1118                        left: "",
1119                        top: to - data.parentTop + data.pad.top
1120                    }).css("position", "absolute");
1121                    if (options.activeClass) { $this.addClass(options.activeClass); }
1122                } else {
1123                    $this.css({position: "", top: "", left: ""});
1124                    if (options.activeClass) { $this.removeClass(options.activeClass); }
1125                }
1126          }
1127          elements = elmts;
1128        };
1129
1130        var update = function () { recalculateLimits(); onScroll(); };
1131
1132        this.each(function () {
1133            var $this = $(this), 
1134                data  = $(this).data('pin') || {};
1135
1136            if (data && data.update) { return; }
1137            elements.push($this);
1138            $("img", this).one("load", recalculateLimits);
1139            data.update = update;
1140            $(this).data('pin', data);
1141        });
1142
1143        $window.scroll(onScroll);
1144        $window.resize(function () { recalculateLimits(); });
1145        recalculateLimits();
1146
1147        $window.load(update);
1148
1149        return this;
1150      };
1151})(jQuery);
1152
1153
1154// Sticky
1155(function(theme, $) {
1156	
1157	theme = theme || {};
1158	
1159	var instanceName = '__sticky';
1160
1161	var PluginSticky = function($el, opts) {
1162		return this.initialize($el, opts);
1163	};
1164
1165	PluginSticky.defaults = {
1166		minWidth: 991,
1167		activeClass: 'sticky-active'
1168	};
1169
1170	PluginSticky.prototype = {
1171		initialize: function($el, opts) {
1172			if ( $el.data( instanceName ) ) {
1173				return this;
1174			}
1175
1176			this.$el = $el;
1177
1178			this
1179				.setData()
1180				.setOptions(opts)
1181				.build();
1182
1183			return this;
1184		},
1185
1186		setData: function() {
1187			this.$el.data(instanceName, this);
1188
1189			return this;
1190		},
1191
1192		setOptions: function(opts) {
1193			this.options = $.extend(true, {}, PluginSticky.defaults, opts, {
1194				wrapper: this.$el
1195			});
1196
1197			return this;
1198		},
1199
1200		build: function() {
1201			if (!($.isFunction($.fn.pin))) {
1202				return this;
1203			}
1204
1205			this.options.wrapper.pin(this.options);
1206
1207			return this;
1208		}
1209	};
1210
1211	// expose to scope
1212	$.extend(theme, {
1213		PluginSticky: PluginSticky
1214	});
1215
1216	// jquery plugin
1217	$.fn.themePluginSticky = function(opts) {
1218		return this.map(function() {
1219			var $this = $(this);
1220
1221			if ($this.data(instanceName)) {
1222				return $this.data(instanceName);
1223			} else {
1224				return new PluginSticky($this, opts);
1225			}
1226			
1227		});
1228	}
1229
1230}).apply(this, [ window.theme, jQuery ]);
1231
1232
1233
1234
1235
1236// Sticky
1237(function($) {
1238
1239	'use strict';
1240
1241	if ($.isFunction($.fn['themePluginSticky'])) {
1242
1243		$(function() {
1244			$('[data-plugin-sticky]:not(.manual)').each(function() {
1245				var $this = $(this),
1246					opts;
1247
1248				var pluginOptions = $this.data('plugin-options');
1249				if (pluginOptions)
1250					opts = pluginOptions;
1251
1252				$this.themePluginSticky(opts);
1253			});
1254		});
1255
1256	}
1257
1258}).apply(this, [jQuery]);
1259

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.