PageSourceSearch

https://concept360.ru/bitrix/cache/js/s5/universe_s5/template_9ef2…d9a6df0a6d3340dac56_v1.js?17864335291001963

js concept360.ru collected 2026-10-09 17:46:26 UTC 1,001,963 bytes, 29,529 lines download raw bytes

1
2; /* Start:"a:4:{s:4:"full";s:77:"/bitrix/templates/universe_s5/plugins/jquery/jquery-2.2.4.js?1676870894257601";s:6:"source";s:60:"/bitrix/templates/universe_s5/plugins/jquery/jquery-2.2.4.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
vendor: 254,976 bytes, lines 2-9719
2
3/*!
4 * jQuery JavaScript Library v2.2.4
5 * http://jquery.com/
6 *
7 * Includes Sizzle.js
8 * http://sizzlejs.com/
9 *
10 * Copyright jQuery Foundation and other contributors
11 * Released under the MIT license
12 * http://jquery.org/license
13 *
14 * Date: 2016-05-20T17:23Z
15 */
16
17(function( global, factory ) {
18
19	if ( typeof module === "object" && typeof module.exports === "object" ) {
20		// For CommonJS and CommonJS-like environments where a proper `window`
21		// is present, execute the factory and get jQuery.
22		// For environments that do not have a `window` with a `document`
23		// (such as Node.js), expose a factory as module.exports.
24		// This accentuates the need for the creation of a real `window`.
25		// e.g. var jQuery = require("jquery")(window);
26		// See ticket #14549 for more info.
27		module.exports = global.document ?
28			factory( global, true ) :
29			function( w ) {
30				if ( !w.document ) {
31					throw new Error( "jQuery requires a window with a document" );
32				}
33				return factory( w );
34			};
35	} else {
36		factory( global );
37	}
38
39// Pass this if window is not defined yet
40}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
41
42// Support: Firefox 18+
43// Can't be in strict mode, several libs including ASP.NET trace
44// the stack via arguments.caller.callee and Firefox dies if
45// you try to trace through "use strict" call chains. (#13335)
46//"use strict";
47var arr = [];
48
49var document = window.document;
50
51var slice = arr.slice;
52
53var concat = arr.concat;
54
55var push = arr.push;
56
57var indexOf = arr.indexOf;
58
59var class2type = {};
60
61var toString = class2type.toString;
62
63var hasOwn = class2type.hasOwnProperty;
64
65var support = {};
66
67
68
69var
70	version = "2.2.4",
71
72	// Define a local copy of jQuery
73	jQuery = function( selector, context ) {
74
75		// The jQuery object is actually just the init constructor 'enhanced'
76		// Need init if jQuery is called (just allow error to be thrown if not included)
77		return new jQuery.fn.init( selector, context );
78	},
79
80	// Support: Android<4.1
81	// Make sure we trim BOM and NBSP
82	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
83
84	// Matches dashed string for camelizing
85	rmsPrefix = /^-ms-/,
86	rdashAlpha = /-([\da-z])/gi,
87
88	// Used by jQuery.camelCase as callback to replace()
89	fcamelCase = function( all, letter ) {
90		return letter.toUpperCase();
91	};
92
93jQuery.fn = jQuery.prototype = {
94
95	// The current version of jQuery being used
96	jquery: version,
97
98	constructor: jQuery,
99
100	// Start with an empty selector
101	selector: "",
102
103	// The default length of a jQuery object is 0
104	length: 0,
105
106	toArray: function() {
107		return slice.call( this );
108	},
109
110	// Get the Nth element in the matched element set OR
111	// Get the whole matched element set as a clean array
112	get: function( num ) {
113		return num != null ?
114
115			// Return just the one element from the set
116			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
117
118			// Return all the elements in a clean array
119			slice.call( this );
120	},
121
122	// Take an array of elements and push it onto the stack
123	// (returning the new matched element set)
124	pushStack: function( elems ) {
125
126		// Build a new jQuery matched element set
127		var ret = jQuery.merge( this.constructor(), elems );
128
129		// Add the old object onto the stack (as a reference)
130		ret.prevObject = this;
131		ret.context = this.context;
132
133		// Return the newly-formed element set
134		return ret;
135	},
136
137	// Execute a callback for every element in the matched set.
138	each: function( callback ) {
139		return jQuery.each( this, callback );
140	},
141
142	map: function( callback ) {
143		return this.pushStack( jQuery.map( this, function( elem, i ) {
144			return callback.call( elem, i, elem );
145		} ) );
146	},
147
148	slice: function() {
149		return this.pushStack( slice.apply( this, arguments ) );
150	},
151
152	first: function() {
153		return this.eq( 0 );
154	},
155
156	last: function() {
157		return this.eq( -1 );
158	},
159
160	eq: function( i ) {
161		var len = this.length,
162			j = +i + ( i < 0 ? len : 0 );
163		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
164	},
165
166	end: function() {
167		return this.prevObject || this.constructor();
168	},
169
170	// For internal use only.
171	// Behaves like an Array's method, not like a jQuery method.
172	push: push,
173	sort: arr.sort,
174	splice: arr.splice
175};
176
177jQuery.extend = jQuery.fn.extend = function() {
178	var options, name, src, copy, copyIsArray, clone,
179		target = arguments[ 0 ] || {},
180		i = 1,
181		length = arguments.length,
182		deep = false;
183
184	// Handle a deep copy situation
185	if ( typeof target === "boolean" ) {
186		deep = target;
187
188		// Skip the boolean and the target
189		target = arguments[ i ] || {};
190		i++;
191	}
192
193	// Handle case when target is a string or something (possible in deep copy)
194	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
195		target = {};
196	}
197
198	// Extend jQuery itself if only one argument is passed
199	if ( i === length ) {
200		target = this;
201		i--;
202	}
203
204	for ( ; i < length; i++ ) {
205
206		// Only deal with non-null/undefined values
207		if ( ( options = arguments[ i ] ) != null ) {
208
209			// Extend the base object
210			for ( name in options ) {
211				src = target[ name ];
212				copy = options[ name ];
213
214				// Prevent never-ending loop
215				if ( target === copy ) {
216					continue;
217				}
218
219				// Recurse if we're merging plain objects or arrays
220				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
221					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
222
223					if ( copyIsArray ) {
224						copyIsArray = false;
225						clone = src && jQuery.isArray( src ) ? src : [];
226
227					} else {
228						clone = src && jQuery.isPlainObject( src ) ? src : {};
229					}
230
231					// Never move original objects, clone them
232					target[ name ] = jQuery.extend( deep, clone, copy );
233
234				// Don't bring in undefined values
235				} else if ( copy !== undefined ) {
236					target[ name ] = copy;
237				}
238			}
239		}
240	}
241
242	// Return the modified object
243	return target;
244};
245
246jQuery.extend( {
247
248	// Unique for each copy of jQuery on the page
249	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
250
251	// Assume jQuery is ready without the ready module
252	isReady: true,
253
254	error: function( msg ) {
255		throw new Error( msg );
256	},
257
258	noop: function() {},
259
260	isFunction: function( obj ) {
261		return jQuery.type( obj ) === "function";
262	},
263
264	isArray: Array.isArray,
265
266	isWindow: function( obj ) {
267		return obj != null && obj === obj.window;
268	},
269
270	isNumeric: function( obj ) {
271
272		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
273		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
274		// subtraction forces infinities to NaN
275		// adding 1 corrects loss of precision from parseFloat (#15100)
276		var realStringObj = obj && obj.toString();
277		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
278	},
279
280	isPlainObject: function( obj ) {
281		var key;
282
283		// Not plain objects:
284		// - Any object or value whose internal [[Class]] property is not "[object Object]"
285		// - DOM nodes
286		// - window
287		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
288			return false;
289		}
290
291		// Not own constructor property must be Object
292		if ( obj.constructor &&
293				!hasOwn.call( obj, "constructor" ) &&
294				!hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
295			return false;
296		}
297
298		// Own properties are enumerated firstly, so to speed up,
299		// if last one is own, then all properties are own
300		for ( key in obj ) {}
301
302		return key === undefined || hasOwn.call( obj, key );
303	},
304
305	isEmptyObject: function( obj ) {
306		var name;
307		for ( name in obj ) {
308			return false;
309		}
310		return true;
311	},
312
313	type: function( obj ) {
314		if ( obj == null ) {
315			return obj + "";
316		}
317
318		// Support: Android<4.0, iOS<6 (functionish RegExp)
319		return typeof obj === "object" || typeof obj === "function" ?
320			class2type[ toString.call( obj ) ] || "object" :
321			typeof obj;
322	},
323
324	// Evaluates a script in a global context
325	globalEval: function( code ) {
326		var script,
327			indirect = eval;
328
329		code = jQuery.trim( code );
330
331		if ( code ) {
332
333			// If the code includes a valid, prologue position
334			// strict mode pragma, execute code by injecting a
335			// script tag into the document.
336			if ( code.indexOf( "use strict" ) === 1 ) {
337				script = document.createElement( "script" );
338				script.text = code;
339				document.head.appendChild( script ).parentNode.removeChild( script );
340			} else {
341
342				// Otherwise, avoid the DOM node creation, insertion
343				// and removal by using an indirect global eval
344
345				indirect( code );
346			}
347		}
348	},
349
350	// Convert dashed to camelCase; used by the css and data modules
351	// Support: IE9-11+
352	// Microsoft forgot to hump their vendor prefix (#9572)
353	camelCase: function( string ) {
354		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
355	},
356
357	nodeName: function( elem, name ) {
358		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
359	},
360
361	each: function( obj, callback ) {
362		var length, i = 0;
363
364		if ( isArrayLike( obj ) ) {
365			length = obj.length;
366			for ( ; i < length; i++ ) {
367				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
368					break;
369				}
370			}
371		} else {
372			for ( i in obj ) {
373				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
374					break;
375				}
376			}
377		}
378
379		return obj;
380	},
381
382	// Support: Android<4.1
383	trim: function( text ) {
384		return text == null ?
385			"" :
386			( text + "" ).replace( rtrim, "" );
387	},
388
389	// results is for internal usage only
390	makeArray: function( arr, results ) {
391		var ret = results || [];
392
393		if ( arr != null ) {
394			if ( isArrayLike( Object( arr ) ) ) {
395				jQuery.merge( ret,
396					typeof arr === "string" ?
397					[ arr ] : arr
398				);
399			} else {
400				push.call( ret, arr );
401			}
402		}
403
404		return ret;
405	},
406
407	inArray: function( elem, arr, i ) {
408		return arr == null ? -1 : indexOf.call( arr, elem, i );
409	},
410
411	merge: function( first, second ) {
412		var len = +second.length,
413			j = 0,
414			i = first.length;
415
416		for ( ; j < len; j++ ) {
417			first[ i++ ] = second[ j ];
418		}
419
420		first.length = i;
421
422		return first;
423	},
424
425	grep: function( elems, callback, invert ) {
426		var callbackInverse,
427			matches = [],
428			i = 0,
429			length = elems.length,
430			callbackExpect = !invert;
431
432		// Go through the array, only saving the items
433		// that pass the validator function
434		for ( ; i < length; i++ ) {
435			callbackInverse = !callback( elems[ i ], i );
436			if ( callbackInverse !== callbackExpect ) {
437				matches.push( elems[ i ] );
438			}
439		}
440
441		return matches;
442	},
443
444	// arg is for internal usage only
445	map: function( elems, callback, arg ) {
446		var length, value,
447			i = 0,
448			ret = [];
449
450		// Go through the array, translating each of the items to their new values
451		if ( isArrayLike( elems ) ) {
452			length = elems.length;
453			for ( ; i < length; i++ ) {
454				value = callback( elems[ i ], i, arg );
455
456				if ( value != null ) {
457					ret.push( value );
458				}
459			}
460
461		// Go through every key on the object,
462		} else {
463			for ( i in elems ) {
464				value = callback( elems[ i ], i, arg );
465
466				if ( value != null ) {
467					ret.push( value );
468				}
469			}
470		}
471
472		// Flatten any nested arrays
473		return concat.apply( [], ret );
474	},
475
476	// A global GUID counter for objects
477	guid: 1,
478
479	// Bind a function to a context, optionally partially applying any
480	// arguments.
481	proxy: function( fn, context ) {
482		var tmp, args, proxy;
483
484		if ( typeof context === "string" ) {
485			tmp = fn[ context ];
486			context = fn;
487			fn = tmp;
488		}
489
490		// Quick check to determine if target is callable, in the spec
491		// this throws a TypeError, but we will just return undefined.
492		if ( !jQuery.isFunction( fn ) ) {
493			return undefined;
494		}
495
496		// Simulated bind
497		args = slice.call( arguments, 2 );
498		proxy = function() {
499			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
500		};
501
502		// Set the guid of unique handler to the same of original handler, so it can be removed
503		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
504
505		return proxy;
506	},
507
508	now: Date.now,
509
510	// jQuery.support is not used in Core but other projects attach their
511	// properties to it so it needs to exist.
512	support: support
513} );
514
515// JSHint would error on this code due to the Symbol not being defined in ES5.
516// Defining this global in .jshintrc would create a danger of using the global
517// unguarded in another place, it seems safer to just disable JSHint for these
518// three lines.
519/* jshint ignore: start */
520if ( typeof Symbol === "function" ) {
521	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
522}
523/* jshint ignore: end */
524
525// Populate the class2type map
526jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
527function( i, name ) {
528	class2type[ "[object " + name + "]" ] = name.toLowerCase();
529} );
530
531function isArrayLike( obj ) {
532
533	// Support: iOS 8.2 (not reproducible in simulator)
534	// `in` check used to prevent JIT error (gh-2145)
535	// hasOwn isn't used here due to false negatives
536	// regarding Nodelist length in IE
537	var length = !!obj && "length" in obj && obj.length,
538		type = jQuery.type( obj );
539
540	if ( type === "function" || jQuery.isWindow( obj ) ) {
541		return false;
542	}
543
544	return type === "array" || length === 0 ||
545		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
546}
547var Sizzle =
548/*!
549 * Sizzle CSS Selector Engine v2.2.1
550 * http://sizzlejs.com/
551 *
552 * Copyright jQuery Foundation and other contributors
553 * Released under the MIT license
554 * http://jquery.org/license
555 *
556 * Date: 2015-10-17
557 */
558(function( window ) {
559
560var i,
561	support,
562	Expr,
563	getText,
564	isXML,
565	tokenize,
566	compile,
567	select,
568	outermostContext,
569	sortInput,
570	hasDuplicate,
571
572	// Local document vars
573	setDocument,
574	document,
575	docElem,
576	documentIsHTML,
577	rbuggyQSA,
578	rbuggyMatches,
579	matches,
580	contains,
581
582	// Instance-specific data
583	expando = "sizzle" + 1 * new Date(),
584	preferredDoc = window.document,
585	dirruns = 0,
586	done = 0,
587	classCache = createCache(),
588	tokenCache = createCache(),
589	compilerCache = createCache(),
590	sortOrder = function( a, b ) {
591		if ( a === b ) {
592			hasDuplicate = true;
593		}
594		return 0;
595	},
596
597	// General-purpose constants
598	MAX_NEGATIVE = 1 << 31,
599
600	// Instance methods
601	hasOwn = ({}).hasOwnProperty,
602	arr = [],
603	pop = arr.pop,
604	push_native = arr.push,
605	push = arr.push,
606	slice = arr.slice,
607	// Use a stripped-down indexOf as it's faster than native
608	// http://jsperf.com/thor-indexof-vs-for/5
609	indexOf = function( list, elem ) {
610		var i = 0,
611			len = list.length;
612		for ( ; i < len; i++ ) {
613			if ( list[i] === elem ) {
614				return i;
615			}
616		}
617		return -1;
618	},
619
620	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
621
622	// Regular expressions
623
624	// http://www.w3.org/TR/css3-selectors/#whitespace
625	whitespace = "[\\x20\\t\\r\\n\\f]",
626
627	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
628	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
629
630	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
631	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
632		// Operator (capture 2)
633		"*([*^$|!~]?=)" + whitespace +
634		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
635		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
636		"*\\]",
637
638	pseudos = ":(" + identifier + ")(?:\\((" +
639		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
640		// 1. quoted (capture 3; capture 4 or capture 5)
641		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
642		// 2. simple (capture 6)
643		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
644		// 3. anything else (capture 2)
645		".*" +
646		")\\)|)",
647
648	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
649	rwhitespace = new RegExp( whitespace + "+", "g" ),
650	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
651
652	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
653	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
654
655	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
656
657	rpseudo = new RegExp( pseudos ),
658	ridentifier = new RegExp( "^" + identifier + "$" ),
659
660	matchExpr = {
661		"ID": new RegExp( "^#(" + identifier + ")" ),
662		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
663		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
664		"ATTR": new RegExp( "^" + attributes ),
665		"PSEUDO": new RegExp( "^" + pseudos ),
666		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
667			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
668			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
669		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
670		// For use in libraries implementing .is()
671		// We use this for POS matching in `select`
672		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
673			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
674	},
675
676	rinputs = /^(?:input|select|textarea|button)$/i,
677	rheader = /^h\d$/i,
678
679	rnative = /^[^{]+\{\s*\[native \w/,
680
681	// Easily-parseable/retrievable ID or TAG or CLASS selectors
682	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
683
684	rsibling = /[+~]/,
685	rescape = /'|\\/g,
686
687	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
688	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
689	funescape = function( _, escaped, escapedWhitespace ) {
690		var high = "0x" + escaped - 0x10000;
691		// NaN means non-codepoint
692		// Support: Firefox<24
693		// Workaround erroneous numeric interpretation of +"0x"
694		return high !== high || escapedWhitespace ?
695			escaped :
696			high < 0 ?
697				// BMP codepoint
698				String.fromCharCode( high + 0x10000 ) :
699				// Supplemental Plane codepoint (surrogate pair)
700				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
701	},
702
703	// Used for iframes
704	// See setDocument()
705	// Removing the function wrapper causes a "Permission Denied"
706	// error in IE
707	unloadHandler = function() {
708		setDocument();
709	};
710
711// Optimize for push.apply( _, NodeList )
712try {
713	push.apply(
714		(arr = slice.call( preferredDoc.childNodes )),
715		preferredDoc.childNodes
716	);
717	// Support: Android<4.0
718	// Detect silently failing push.apply
719	arr[ preferredDoc.childNodes.length ].nodeType;
720} catch ( e ) {
721	push = { apply: arr.length ?
722
723		// Leverage slice if possible
724		function( target, els ) {
725			push_native.apply( target, slice.call(els) );
726		} :
727
728		// Support: IE<9
729		// Otherwise append directly
730		function( target, els ) {
731			var j = target.length,
732				i = 0;
733			// Can't trust NodeList.length
734			while ( (target[j++] = els[i++]) ) {}
735			target.length = j - 1;
736		}
737	};
738}
739
740function Sizzle( selector, context, results, seed ) {
741	var m, i, elem, nid, nidselect, match, groups, newSelector,
742		newContext = context && context.ownerDocument,
743
744		// nodeType defaults to 9, since context defaults to document
745		nodeType = context ? context.nodeType : 9;
746
747	results = results || [];
748
749	// Return early from calls with invalid selector or context
750	if ( typeof selector !== "string" || !selector ||
751		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
752
753		return results;
754	}
755
756	// Try to shortcut find operations (as opposed to filters) in HTML documents
757	if ( !seed ) {
758
759		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
760			setDocument( context );
761		}
762		context = context || document;
763
764		if ( documentIsHTML ) {
765
766			// If the selector is sufficiently simple, try using a "get*By*" DOM method
767			// (excepting DocumentFragment context, where the methods don't exist)
768			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
769
770				// ID selector
771				if ( (m = match[1]) ) {
772
773					// Document context
774					if ( nodeType === 9 ) {
775						if ( (elem = context.getElementById( m )) ) {
776
777							// Support: IE, Opera, Webkit
778							// TODO: identify versions
779							// getElementById can match elements by name instead of ID
780							if ( elem.id === m ) {
781								results.push( elem );
782								return results;
783							}
784						} else {
785							return results;
786						}
787
788					// Element context
789					} else {
790
791						// Support: IE, Opera, Webkit
792						// TODO: identify versions
793						// getElementById can match elements by name instead of ID
794						if ( newContext && (elem = newContext.getElementById( m )) &&
795							contains( context, elem ) &&
796							elem.id === m ) {
797
798							results.push( elem );
799							return results;
800						}
801					}
802
803				// Type selector
804				} else if ( match[2] ) {
805					push.apply( results, context.getElementsByTagName( selector ) );
806					return results;
807
808				// Class selector
809				} else if ( (m = match[3]) && support.getElementsByClassName &&
810					context.getElementsByClassName ) {
811
812					push.apply( results, context.getElementsByClassName( m ) );
813					return results;
814				}
815			}
816
817			// Take advantage of querySelectorAll
818			if ( support.qsa &&
819				!compilerCache[ selector + " " ] &&
820				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
821
822				if ( nodeType !== 1 ) {
823					newContext = context;
824					newSelector = selector;
825
826				// qSA looks outside Element context, which is not what we want
827				// Thanks to Andrew Dupont for this workaround technique
828				// Support: IE <=8
829				// Exclude object elements
830				} else if ( context.nodeName.toLowerCase() !== "object" ) {
831
832					// Capture the context ID, setting it first if necessary
833					if ( (nid = context.getAttribute( "id" )) ) {
834						nid = nid.replace( rescape, "\\$&" );
835					} else {
836						context.setAttribute( "id", (nid = expando) );
837					}
838
839					// Prefix every selector in the list
840					groups = tokenize( selector );
841					i = groups.length;
842					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
843					while ( i-- ) {
844						groups[i] = nidselect + " " + toSelector( groups[i] );
845					}
846					newSelector = groups.join( "," );
847
848					// Expand context for sibling selectors
849					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
850						context;
851				}
852
853				if ( newSelector ) {
854					try {
855						push.apply( results,
856							newContext.querySelectorAll( newSelector )
857						);
858						return results;
859					} catch ( qsaError ) {
860					} finally {
861						if ( nid === expando ) {
862							context.removeAttribute( "id" );
863						}
864					}
865				}
866			}
867		}
868	}
869
870	// All others
871	return select( selector.replace( rtrim, "$1" ), context, results, seed );
872}
873
874/**
875 * Create key-value caches of limited size
876 * @returns {function(string, object)} Returns the Object data after storing it on itself with
877 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
878 *	deleting the oldest entry
879 */
880function createCache() {
881	var keys = [];
882
883	function cache( key, value ) {
884		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
885		if ( keys.push( key + " " ) > Expr.cacheLength ) {
886			// Only keep the most recent entries
887			delete cache[ keys.shift() ];
888		}
889		return (cache[ key + " " ] = value);
890	}
891	return cache;
892}
893
894/**
895 * Mark a function for special use by Sizzle
896 * @param {Function} fn The function to mark
897 */
898function markFunction( fn ) {
899	fn[ expando ] = true;
900	return fn;
901}
902
903/**
904 * Support testing using an element
905 * @param {Function} fn Passed the created div and expects a boolean result
906 */
907function assert( fn ) {
908	var div = document.createElement("div");
909
910	try {
911		return !!fn( div );
912	} catch (e) {
913		return false;
914	} finally {
915		// Remove from its parent by default
916		if ( div.parentNode ) {
917			div.parentNode.removeChild( div );
918		}
919		// release memory in IE
920		div = null;
921	}
922}
923
924/**
925 * Adds the same handler for all of the specified attrs
926 * @param {String} attrs Pipe-separated list of attributes
927 * @param {Function} handler The method that will be applied
928 */
929function addHandle( attrs, handler ) {
930	var arr = attrs.split("|"),
931		i = arr.length;
932
933	while ( i-- ) {
934		Expr.attrHandle[ arr[i] ] = handler;
935	}
936}
937
938/**
939 * Checks document order of two siblings
940 * @param {Element} a
941 * @param {Element} b
942 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
943 */
944function siblingCheck( a, b ) {
945	var cur = b && a,
946		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
947			( ~b.sourceIndex || MAX_NEGATIVE ) -
948			( ~a.sourceIndex || MAX_NEGATIVE );
949
950	// Use IE sourceIndex if available on both nodes
951	if ( diff ) {
952		return diff;
953	}
954
955	// Check if b follows a
956	if ( cur ) {
957		while ( (cur = cur.nextSibling) ) {
958			if ( cur === b ) {
959				return -1;
960			}
961		}
962	}
963
964	return a ? 1 : -1;
965}
966
967/**
968 * Returns a function to use in pseudos for input types
969 * @param {String} type
970 */
971function createInputPseudo( type ) {
972	return function( elem ) {
973		var name = elem.nodeName.toLowerCase();
974		return name === "input" && elem.type === type;
975	};
976}
977
978/**
979 * Returns a function to use in pseudos for buttons
980 * @param {String} type
981 */
982function createButtonPseudo( type ) {
983	return function( elem ) {
984		var name = elem.nodeName.toLowerCase();
985		return (name === "input" || name === "button") && elem.type === type;
986	};
987}
988
989/**
990 * Returns a function to use in pseudos for positionals
991 * @param {Function} fn
992 */
993function createPositionalPseudo( fn ) {
994	return markFunction(function( argument ) {
995		argument = +argument;
996		return markFunction(function( seed, matches ) {
997			var j,
998				matchIndexes = fn( [], seed.length, argument ),
999				i = matchIndexes.length;
1000
1001			// Match elements found at the specified indexes
1002			while ( i-- ) {
1003				if ( seed[ (j = matchIndexes[i]) ] ) {
1004					seed[j] = !(matches[j] = seed[j]);
1005				}
1006			}
1007		});
1008	});
1009}
1010
1011/**
1012 * Checks a node for validity as a Sizzle context
1013 * @param {Element|Object=} context
1014 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1015 */
1016function testContext( context ) {
1017	return context && typeof context.getElementsByTagName !== "undefined" && context;
1018}
1019
1020// Expose support vars for convenience
1021support = Sizzle.support = {};
1022
1023/**
1024 * Detects XML nodes
1025 * @param {Element|Object} elem An element or a document
1026 * @returns {Boolean} True iff elem is a non-HTML XML node
1027 */
1028isXML = Sizzle.isXML = function( elem ) {
1029	// documentElement is verified for cases where it doesn't yet exist
1030	// (such as loading iframes in IE - #4833)
1031	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1032	return documentElement ? documentElement.nodeName !== "HTML" : false;
1033};
1034
1035/**
1036 * Sets document-related variables once based on the current document
1037 * @param {Element|Object} [doc] An element or document object to use to set the document
1038 * @returns {Object} Returns the current document
1039 */
1040setDocument = Sizzle.setDocument = function( node ) {
1041	var hasCompare, parent,
1042		doc = node ? node.ownerDocument || node : preferredDoc;
1043
1044	// Return early if doc is invalid or already selected
1045	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1046		return document;
1047	}
1048
1049	// Update global variables
1050	document = doc;
1051	docElem = document.documentElement;
1052	documentIsHTML = !isXML( document );
1053
1054	// Support: IE 9-11, Edge
1055	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1056	if ( (parent = document.defaultView) && parent.top !== parent ) {
1057		// Support: IE 11
1058		if ( parent.addEventListener ) {
1059			parent.addEventListener( "unload", unloadHandler, false );
1060
1061		// Support: IE 9 - 10 only
1062		} else if ( parent.attachEvent ) {
1063			parent.attachEvent( "onunload", unloadHandler );
1064		}
1065	}
1066
1067	/* Attributes
1068	---------------------------------------------------------------------- */
1069
1070	// Support: IE<8
1071	// Verify that getAttribute really returns attributes and not properties
1072	// (excepting IE8 booleans)
1073	support.attributes = assert(function( div ) {
1074		div.className = "i";
1075		return !div.getAttribute("className");
1076	});
1077
1078	/* getElement(s)By*
1079	---------------------------------------------------------------------- */
1080
1081	// Check if getElementsByTagName("*") returns only elements
1082	support.getElementsByTagName = assert(function( div ) {
1083		div.appendChild( document.createComment("") );
1084		return !div.getElementsByTagName("*").length;
1085	});
1086
1087	// Support: IE<9
1088	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1089
1090	// Support: IE<10
1091	// Check if getElementById returns elements by name
1092	// The broken getElementById methods don't pick up programatically-set names,
1093	// so use a roundabout getElementsByName test
1094	support.getById = assert(function( div ) {
1095		docElem.appendChild( div ).id = expando;
1096		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1097	});
1098
1099	// ID find and filter
1100	if ( support.getById ) {
1101		Expr.find["ID"] = function( id, context ) {
1102			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1103				var m = context.getElementById( id );
1104				return m ? [ m ] : [];
1105			}
1106		};
1107		Expr.filter["ID"] = function( id ) {
1108			var attrId = id.replace( runescape, funescape );
1109			return function( elem ) {
1110				return elem.getAttribute("id") === attrId;
1111			};
1112		};
1113	} else {
1114		// Support: IE6/7
1115		// getElementById is not reliable as a find shortcut
1116		delete Expr.find["ID"];
1117
1118		Expr.filter["ID"] =  function( id ) {
1119			var attrId = id.replace( runescape, funescape );
1120			return function( elem ) {
1121				var node = typeof elem.getAttributeNode !== "undefined" &&
1122					elem.getAttributeNode("id");
1123				return node && node.value === attrId;
1124			};
1125		};
1126	}
1127
1128	// Tag
1129	Expr.find["TAG"] = support.getElementsByTagName ?
1130		function( tag, context ) {
1131			if ( typeof context.getElementsByTagName !== "undefined" ) {
1132				return context.getElementsByTagName( tag );
1133
1134			// DocumentFragment nodes don't have gEBTN
1135			} else if ( support.qsa ) {
1136				return context.querySelectorAll( tag );
1137			}
1138		} :
1139
1140		function( tag, context ) {
1141			var elem,
1142				tmp = [],
1143				i = 0,
1144				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1145				results = context.getElementsByTagName( tag );
1146
1147			// Filter out possible comments
1148			if ( tag === "*" ) {
1149				while ( (elem = results[i++]) ) {
1150					if ( elem.nodeType === 1 ) {
1151						tmp.push( elem );
1152					}
1153				}
1154
1155				return tmp;
1156			}
1157			return results;
1158		};
1159
1160	// Class
1161	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1162		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1163			return context.getElementsByClassName( className );
1164		}
1165	};
1166
1167	/* QSA/matchesSelector
1168	---------------------------------------------------------------------- */
1169
1170	// QSA and matchesSelector support
1171
1172	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1173	rbuggyMatches = [];
1174
1175	// qSa(:focus) reports false when true (Chrome 21)
1176	// We allow this because of a bug in IE8/9 that throws an error
1177	// whenever `document.activeElement` is accessed on an iframe
1178	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1179	// See http://bugs.jquery.com/ticket/13378
1180	rbuggyQSA = [];
1181
1182	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1183		// Build QSA regex
1184		// Regex strategy adopted from Diego Perini
1185		assert(function( div ) {
1186			// Select is set to empty string on purpose
1187			// This is to test IE's treatment of not explicitly
1188			// setting a boolean content attribute,
1189			// since its presence should be enough
1190			// http://bugs.jquery.com/ticket/12359
1191			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1192				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1193				"<option selected=''></option></select>";
1194
1195			// Support: IE8, Opera 11-12.16
1196			// Nothing should be selected when empty strings follow ^= or $= or *=
1197			// The test attribute must be unknown in Opera but "safe" for WinRT
1198			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1199			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1200				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1201			}
1202
1203			// Support: IE8
1204			// Boolean attributes and "value" are not treated correctly
1205			if ( !div.querySelectorAll("[selected]").length ) {
1206				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1207			}
1208
1209			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1210			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1211				rbuggyQSA.push("~=");
1212			}
1213
1214			// Webkit/Opera - :checked should return selected option elements
1215			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1216			// IE8 throws error here and will not see later tests
1217			if ( !div.querySelectorAll(":checked").length ) {
1218				rbuggyQSA.push(":checked");
1219			}
1220
1221			// Support: Safari 8+, iOS 8+
1222			// https://bugs.webkit.org/show_bug.cgi?id=136851
1223			// In-page `selector#id sibing-combinator selector` fails
1224			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1225				rbuggyQSA.push(".#.+[+~]");
1226			}
1227		});
1228
1229		assert(function( div ) {
1230			// Support: Windows 8 Native Apps
1231			// The type and name attributes are restricted during .innerHTML assignment
1232			var input = document.createElement("input");
1233			input.setAttribute( "type", "hidden" );
1234			div.appendChild( input ).setAttribute( "name", "D" );
1235
1236			// Support: IE8
1237			// Enforce case-sensitivity of name attribute
1238			if ( div.querySelectorAll("[name=d]").length ) {
1239				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1240			}
1241
1242			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1243			// IE8 throws error here and will not see later tests
1244			if ( !div.querySelectorAll(":enabled").length ) {
1245				rbuggyQSA.push( ":enabled", ":disabled" );
1246			}
1247
1248			// Opera 10-11 does not throw on post-comma invalid pseudos
1249			div.querySelectorAll("*,:x");
1250			rbuggyQSA.push(",.*:");
1251		});
1252	}
1253
1254	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1255		docElem.webkitMatchesSelector ||
1256		docElem.mozMatchesSelector ||
1257		docElem.oMatchesSelector ||
1258		docElem.msMatchesSelector) )) ) {
1259
1260		assert(function( div ) {
1261			// Check to see if it's possible to do matchesSelector
1262			// on a disconnected node (IE 9)
1263			support.disconnectedMatch = matches.call( div, "div" );
1264
1265			// This should fail with an exception
1266			// Gecko does not error, returns false instead
1267			matches.call( div, "[s!='']:x" );
1268			rbuggyMatches.push( "!=", pseudos );
1269		});
1270	}
1271
1272	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1273	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1274
1275	/* Contains
1276	---------------------------------------------------------------------- */
1277	hasCompare = rnative.test( docElem.compareDocumentPosition );
1278
1279	// Element contains another
1280	// Purposefully self-exclusive
1281	// As in, an element does not contain itself
1282	contains = hasCompare || rnative.test( docElem.contains ) ?
1283		function( a, b ) {
1284			var adown = a.nodeType === 9 ? a.documentElement : a,
1285				bup = b && b.parentNode;
1286			return a === bup || !!( bup && bup.nodeType === 1 && (
1287				adown.contains ?
1288					adown.contains( bup ) :
1289					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1290			));
1291		} :
1292		function( a, b ) {
1293			if ( b ) {
1294				while ( (b = b.parentNode) ) {
1295					if ( b === a ) {
1296						return true;
1297					}
1298				}
1299			}
1300			return false;
1301		};
1302
1303	/* Sorting
1304	---------------------------------------------------------------------- */
1305
1306	// Document order sorting
1307	sortOrder = hasCompare ?
1308	function( a, b ) {
1309
1310		// Flag for duplicate removal
1311		if ( a === b ) {
1312			hasDuplicate = true;
1313			return 0;
1314		}
1315
1316		// Sort on method existence if only one input has compareDocumentPosition
1317		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1318		if ( compare ) {
1319			return compare;
1320		}
1321
1322		// Calculate position if both inputs belong to the same document
1323		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1324			a.compareDocumentPosition( b ) :
1325
1326			// Otherwise we know they are disconnected
1327			1;
1328
1329		// Disconnected nodes
1330		if ( compare & 1 ||
1331			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1332
1333			// Choose the first element that is related to our preferred document
1334			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1335				return -1;
1336			}
1337			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1338				return 1;
1339			}
1340
1341			// Maintain original order
1342			return sortInput ?
1343				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1344				0;
1345		}
1346
1347		return compare & 4 ? -1 : 1;
1348	} :
1349	function( a, b ) {
1350		// Exit early if the nodes are identical
1351		if ( a === b ) {
1352			hasDuplicate = true;
1353			return 0;
1354		}
1355
1356		var cur,
1357			i = 0,
1358			aup = a.parentNode,
1359			bup = b.parentNode,
1360			ap = [ a ],
1361			bp = [ b ];
1362
1363		// Parentless nodes are either documents or disconnected
1364		if ( !aup || !bup ) {
1365			return a === document ? -1 :
1366				b === document ? 1 :
1367				aup ? -1 :
1368				bup ? 1 :
1369				sortInput ?
1370				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1371				0;
1372
1373		// If the nodes are siblings, we can do a quick check
1374		} else if ( aup === bup ) {
1375			return siblingCheck( a, b );
1376		}
1377
1378		// Otherwise we need full lists of their ancestors for comparison
1379		cur = a;
1380		while ( (cur = cur.parentNode) ) {
1381			ap.unshift( cur );
1382		}
1383		cur = b;
1384		while ( (cur = cur.parentNode) ) {
1385			bp.unshift( cur );
1386		}
1387
1388		// Walk down the tree looking for a discrepancy
1389		while ( ap[i] === bp[i] ) {
1390			i++;
1391		}
1392
1393		return i ?
1394			// Do a sibling check if the nodes have a common ancestor
1395			siblingCheck( ap[i], bp[i] ) :
1396
1397			// Otherwise nodes in our document sort first
1398			ap[i] === preferredDoc ? -1 :
1399			bp[i] === preferredDoc ? 1 :
1400			0;
1401	};
1402
1403	return document;
1404};
1405
1406Sizzle.matches = function( expr, elements ) {
1407	return Sizzle( expr, null, null, elements );
1408};
1409
1410Sizzle.matchesSelector = function( elem, expr ) {
1411	// Set document vars if needed
1412	if ( ( elem.ownerDocument || elem ) !== document ) {
1413		setDocument( elem );
1414	}
1415
1416	// Make sure that attribute selectors are quoted
1417	expr = expr.replace( rattributeQuotes, "='$1']" );
1418
1419	if ( support.matchesSelector && documentIsHTML &&
1420		!compilerCache[ expr + " " ] &&
1421		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1422		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1423
1424		try {
1425			var ret = matches.call( elem, expr );
1426
1427			// IE 9's matchesSelector returns false on disconnected nodes
1428			if ( ret || support.disconnectedMatch ||
1429					// As well, disconnected nodes are said to be in a document
1430					// fragment in IE 9
1431					elem.document && elem.document.nodeType !== 11 ) {
1432				return ret;
1433			}
1434		} catch (e) {}
1435	}
1436
1437	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1438};
1439
1440Sizzle.contains = function( context, elem ) {
1441	// Set document vars if needed
1442	if ( ( context.ownerDocument || context ) !== document ) {
1443		setDocument( context );
1444	}
1445	return contains( context, elem );
1446};
1447
1448Sizzle.attr = function( elem, name ) {
1449	// Set document vars if needed
1450	if ( ( elem.ownerDocument || elem ) !== document ) {
1451		setDocument( elem );
1452	}
1453
1454	var fn = Expr.attrHandle[ name.toLowerCase() ],
1455		// Don't get fooled by Object.prototype properties (jQuery #13807)
1456		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1457			fn( elem, name, !documentIsHTML ) :
1458			undefined;
1459
1460	return val !== undefined ?
1461		val :
1462		support.attributes || !documentIsHTML ?
1463			elem.getAttribute( name ) :
1464			(val = elem.getAttributeNode(name)) && val.specified ?
1465				val.value :
1466				null;
1467};
1468
1469Sizzle.error = function( msg ) {
1470	throw new Error( "Syntax error, unrecognized expression: " + msg );
1471};
1472
1473/**
1474 * Document sorting and removing duplicates
1475 * @param {ArrayLike} results
1476 */
1477Sizzle.uniqueSort = function( results ) {
1478	var elem,
1479		duplicates = [],
1480		j = 0,
1481		i = 0;
1482
1483	// Unless we *know* we can detect duplicates, assume their presence
1484	hasDuplicate = !support.detectDuplicates;
1485	sortInput = !support.sortStable && results.slice( 0 );
1486	results.sort( sortOrder );
1487
1488	if ( hasDuplicate ) {
1489		while ( (elem = results[i++]) ) {
1490			if ( elem === results[ i ] ) {
1491				j = duplicates.push( i );
1492			}
1493		}
1494		while ( j-- ) {
1495			results.splice( duplicates[ j ], 1 );
1496		}
1497	}
1498
1499	// Clear input after sorting to release objects
1500	// See https://github.com/jquery/sizzle/pull/225
1501	sortInput = null;
1502
1503	return results;
1504};
1505
1506/**
1507 * Utility function for retrieving the text value of an array of DOM nodes
1508 * @param {Array|Element} elem
1509 */
1510getText = Sizzle.getText = function( elem ) {
1511	var node,
1512		ret = "",
1513		i = 0,
1514		nodeType = elem.nodeType;
1515
1516	if ( !nodeType ) {
1517		// If no nodeType, this is expected to be an array
1518		while ( (node = elem[i++]) ) {
1519			// Do not traverse comment nodes
1520			ret += getText( node );
1521		}
1522	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1523		// Use textContent for elements
1524		// innerText usage removed for consistency of new lines (jQuery #11153)
1525		if ( typeof elem.textContent === "string" ) {
1526			return elem.textContent;
1527		} else {
1528			// Traverse its children
1529			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1530				ret += getText( elem );
1531			}
1532		}
1533	} else if ( nodeType === 3 || nodeType === 4 ) {
1534		return elem.nodeValue;
1535	}
1536	// Do not include comment or processing instruction nodes
1537
1538	return ret;
1539};
1540
1541Expr = Sizzle.selectors = {
1542
1543	// Can be adjusted by the user
1544	cacheLength: 50,
1545
1546	createPseudo: markFunction,
1547
1548	match: matchExpr,
1549
1550	attrHandle: {},
1551
1552	find: {},
1553
1554	relative: {
1555		">": { dir: "parentNode", first: true },
1556		" ": { dir: "parentNode" },
1557		"+": { dir: "previousSibling", first: true },
1558		"~": { dir: "previousSibling" }
1559	},
1560
1561	preFilter: {
1562		"ATTR": function( match ) {
1563			match[1] = match[1].replace( runescape, funescape );
1564
1565			// Move the given value to match[3] whether quoted or unquoted
1566			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1567
1568			if ( match[2] === "~=" ) {
1569				match[3] = " " + match[3] + " ";
1570			}
1571
1572			return match.slice( 0, 4 );
1573		},
1574
1575		"CHILD": function( match ) {
1576			/* matches from matchExpr["CHILD"]
1577				1 type (only|nth|...)
1578				2 what (child|of-type)
1579				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1580				4 xn-component of xn+y argument ([+-]?\d*n|)
1581				5 sign of xn-component
1582				6 x of xn-component
1583				7 sign of y-component
1584				8 y of y-component
1585			*/
1586			match[1] = match[1].toLowerCase();
1587
1588			if ( match[1].slice( 0, 3 ) === "nth" ) {
1589				// nth-* requires argument
1590				if ( !match[3] ) {
1591					Sizzle.error( match[0] );
1592				}
1593
1594				// numeric x and y parameters for Expr.filter.CHILD
1595				// remember that false/true cast respectively to 0/1
1596				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1597				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1598
1599			// other types prohibit arguments
1600			} else if ( match[3] ) {
1601				Sizzle.error( match[0] );
1602			}
1603
1604			return match;
1605		},
1606
1607		"PSEUDO": function( match ) {
1608			var excess,
1609				unquoted = !match[6] && match[2];
1610
1611			if ( matchExpr["CHILD"].test( match[0] ) ) {
1612				return null;
1613			}
1614
1615			// Accept quoted arguments as-is
1616			if ( match[3] ) {
1617				match[2] = match[4] || match[5] || "";
1618
1619			// Strip excess characters from unquoted arguments
1620			} else if ( unquoted && rpseudo.test( unquoted ) &&
1621				// Get excess from tokenize (recursively)
1622				(excess = tokenize( unquoted, true )) &&
1623				// advance to the next closing parenthesis
1624				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1625
1626				// excess is a negative index
1627				match[0] = match[0].slice( 0, excess );
1628				match[2] = unquoted.slice( 0, excess );
1629			}
1630
1631			// Return only captures needed by the pseudo filter method (type and argument)
1632			return match.slice( 0, 3 );
1633		}
1634	},
1635
1636	filter: {
1637
1638		"TAG": function( nodeNameSelector ) {
1639			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1640			return nodeNameSelector === "*" ?
1641				function() { return true; } :
1642				function( elem ) {
1643					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1644				};
1645		},
1646
1647		"CLASS": function( className ) {
1648			var pattern = classCache[ className + " " ];
1649
1650			return pattern ||
1651				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1652				classCache( className, function( elem ) {
1653					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1654				});
1655		},
1656
1657		"ATTR": function( name, operator, check ) {
1658			return function( elem ) {
1659				var result = Sizzle.attr( elem, name );
1660
1661				if ( result == null ) {
1662					return operator === "!=";
1663				}
1664				if ( !operator ) {
1665					return true;
1666				}
1667
1668				result += "";
1669
1670				return operator === "=" ? result === check :
1671					operator === "!=" ? result !== check :
1672					operator === "^=" ? check && result.indexOf( check ) === 0 :
1673					operator === "*=" ? check && result.indexOf( check ) > -1 :
1674					operator === "$=" ? check && result.slice( -check.length ) === check :
1675					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1676					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1677					false;
1678			};
1679		},
1680
1681		"CHILD": function( type, what, argument, first, last ) {
1682			var simple = type.slice( 0, 3 ) !== "nth",
1683				forward = type.slice( -4 ) !== "last",
1684				ofType = what === "of-type";
1685
1686			return first === 1 && last === 0 ?
1687
1688				// Shortcut for :nth-*(n)
1689				function( elem ) {
1690					return !!elem.parentNode;
1691				} :
1692
1693				function( elem, context, xml ) {
1694					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1695						dir = simple !== forward ? "nextSibling" : "previousSibling",
1696						parent = elem.parentNode,
1697						name = ofType && elem.nodeName.toLowerCase(),
1698						useCache = !xml && !ofType,
1699						diff = false;
1700
1701					if ( parent ) {
1702
1703						// :(first|last|only)-(child|of-type)
1704						if ( simple ) {
1705							while ( dir ) {
1706								node = elem;
1707								while ( (node = node[ dir ]) ) {
1708									if ( ofType ?
1709										node.nodeName.toLowerCase() === name :
1710										node.nodeType === 1 ) {
1711
1712										return false;
1713									}
1714								}
1715								// Reverse direction for :only-* (if we haven't yet done so)
1716								start = dir = type === "only" && !start && "nextSibling";
1717							}
1718							return true;
1719						}
1720
1721						start = [ forward ? parent.firstChild : parent.lastChild ];
1722
1723						// non-xml :nth-child(...) stores cache data on `parent`
1724						if ( forward && useCache ) {
1725
1726							// Seek `elem` from a previously-cached index
1727
1728							// ...in a gzip-friendly way
1729							node = parent;
1730							outerCache = node[ expando ] || (node[ expando ] = {});
1731
1732							// Support: IE <9 only
1733							// Defend against cloned attroperties (jQuery gh-1709)
1734							uniqueCache = outerCache[ node.uniqueID ] ||
1735								(outerCache[ node.uniqueID ] = {});
1736
1737							cache = uniqueCache[ type ] || [];
1738							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1739							diff = nodeIndex && cache[ 2 ];
1740							node = nodeIndex && parent.childNodes[ nodeIndex ];
1741
1742							while ( (node = ++nodeIndex && node && node[ dir ] ||
1743
1744								// Fallback to seeking `elem` from the start
1745								(diff = nodeIndex = 0) || start.pop()) ) {
1746
1747								// When found, cache indexes on `parent` and break
1748								if ( node.nodeType === 1 && ++diff && node === elem ) {
1749									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1750									break;
1751								}
1752							}
1753
1754						} else {
1755							// Use previously-cached element index if available
1756							if ( useCache ) {
1757								// ...in a gzip-friendly way
1758								node = elem;
1759								outerCache = node[ expando ] || (node[ expando ] = {});
1760
1761								// Support: IE <9 only
1762								// Defend against cloned attroperties (jQuery gh-1709)
1763								uniqueCache = outerCache[ node.uniqueID ] ||
1764									(outerCache[ node.uniqueID ] = {});
1765
1766								cache = uniqueCache[ type ] || [];
1767								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1768								diff = nodeIndex;
1769							}
1770
1771							// xml :nth-child(...)
1772							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1773							if ( diff === false ) {
1774								// Use the same loop as above to seek `elem` from the start
1775								while ( (node = ++nodeIndex && node && node[ dir ] ||
1776									(diff = nodeIndex = 0) || start.pop()) ) {
1777
1778									if ( ( ofType ?
1779										node.nodeName.toLowerCase() === name :
1780										node.nodeType === 1 ) &&
1781										++diff ) {
1782
1783										// Cache the index of each encountered element
1784										if ( useCache ) {
1785											outerCache = node[ expando ] || (node[ expando ] = {});
1786
1787											// Support: IE <9 only
1788											// Defend against cloned attroperties (jQuery gh-1709)
1789											uniqueCache = outerCache[ node.uniqueID ] ||
1790												(outerCache[ node.uniqueID ] = {});
1791
1792											uniqueCache[ type ] = [ dirruns, diff ];
1793										}
1794
1795										if ( node === elem ) {
1796											break;
1797										}
1798									}
1799								}
1800							}
1801						}
1802
1803						// Incorporate the offset, then check against cycle size
1804						diff -= last;
1805						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1806					}
1807				};
1808		},
1809
1810		"PSEUDO": function( pseudo, argument ) {
1811			// pseudo-class names are case-insensitive
1812			// http://www.w3.org/TR/selectors/#pseudo-classes
1813			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1814			// Remember that setFilters inherits from pseudos
1815			var args,
1816				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1817					Sizzle.error( "unsupported pseudo: " + pseudo );
1818
1819			// The user may use createPseudo to indicate that
1820			// arguments are needed to create the filter function
1821			// just as Sizzle does
1822			if ( fn[ expando ] ) {
1823				return fn( argument );
1824			}
1825
1826			// But maintain support for old signatures
1827			if ( fn.length > 1 ) {
1828				args = [ pseudo, pseudo, "", argument ];
1829				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1830					markFunction(function( seed, matches ) {
1831						var idx,
1832							matched = fn( seed, argument ),
1833							i = matched.length;
1834						while ( i-- ) {
1835							idx = indexOf( seed, matched[i] );
1836							seed[ idx ] = !( matches[ idx ] = matched[i] );
1837						}
1838					}) :
1839					function( elem ) {
1840						return fn( elem, 0, args );
1841					};
1842			}
1843
1844			return fn;
1845		}
1846	},
1847
1848	pseudos: {
1849		// Potentially complex pseudos
1850		"not": markFunction(function( selector ) {
1851			// Trim the selector passed to compile
1852			// to avoid treating leading and trailing
1853			// spaces as combinators
1854			var input = [],
1855				results = [],
1856				matcher = compile( selector.replace( rtrim, "$1" ) );
1857
1858			return matcher[ expando ] ?
1859				markFunction(function( seed, matches, context, xml ) {
1860					var elem,
1861						unmatched = matcher( seed, null, xml, [] ),
1862						i = seed.length;
1863
1864					// Match elements unmatched by `matcher`
1865					while ( i-- ) {
1866						if ( (elem = unmatched[i]) ) {
1867							seed[i] = !(matches[i] = elem);
1868						}
1869					}
1870				}) :
1871				function( elem, context, xml ) {
1872					input[0] = elem;
1873					matcher( input, null, xml, results );
1874					// Don't keep the element (issue #299)
1875					input[0] = null;
1876					return !results.pop();
1877				};
1878		}),
1879
1880		"has": markFunction(function( selector ) {
1881			return function( elem ) {
1882				return Sizzle( selector, elem ).length > 0;
1883			};
1884		}),
1885
1886		"contains": markFunction(function( text ) {
1887			text = text.replace( runescape, funescape );
1888			return function( elem ) {
1889				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1890			};
1891		}),
1892
1893		// "Whether an element is represented by a :lang() selector
1894		// is based solely on the element's language value
1895		// being equal to the identifier C,
1896		// or beginning with the identifier C immediately followed by "-".
1897		// The matching of C against the element's language value is performed case-insensitively.
1898		// The identifier C does not have to be a valid language name."
1899		// http://www.w3.org/TR/selectors/#lang-pseudo
1900		"lang": markFunction( function( lang ) {
1901			// lang value must be a valid identifier
1902			if ( !ridentifier.test(lang || "") ) {
1903				Sizzle.error( "unsupported lang: " + lang );
1904			}
1905			lang = lang.replace( runescape, funescape ).toLowerCase();
1906			return function( elem ) {
1907				var elemLang;
1908				do {
1909					if ( (elemLang = documentIsHTML ?
1910						elem.lang :
1911						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1912
1913						elemLang = elemLang.toLowerCase();
1914						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1915					}
1916				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1917				return false;
1918			};
1919		}),
1920
1921		// Miscellaneous
1922		"target": function( elem ) {
1923			var hash = window.location && window.location.hash;
1924			return hash && hash.slice( 1 ) === elem.id;
1925		},
1926
1927		"root": function( elem ) {
1928			return elem === docElem;
1929		},
1930
1931		"focus": function( elem ) {
1932			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1933		},
1934
1935		// Boolean properties
1936		"enabled": function( elem ) {
1937			return elem.disabled === false;
1938		},
1939
1940		"disabled": function( elem ) {
1941			return elem.disabled === true;
1942		},
1943
1944		"checked": function( elem ) {
1945			// In CSS3, :checked should return both checked and selected elements
1946			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1947			var nodeName = elem.nodeName.toLowerCase();
1948			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1949		},
1950
1951		"selected": function( elem ) {
1952			// Accessing this property makes selected-by-default
1953			// options in Safari work properly
1954			if ( elem.parentNode ) {
1955				elem.parentNode.selectedIndex;
1956			}
1957
1958			return elem.selected === true;
1959		},
1960
1961		// Contents
1962		"empty": function( elem ) {
1963			// http://www.w3.org/TR/selectors/#empty-pseudo
1964			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1965			//   but not by others (comment: 8; processing instruction: 7; etc.)
1966			// nodeType < 6 works because attributes (2) do not appear as children
1967			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1968				if ( elem.nodeType < 6 ) {
1969					return false;
1970				}
1971			}
1972			return true;
1973		},
1974
1975		"parent": function( elem ) {
1976			return !Expr.pseudos["empty"]( elem );
1977		},
1978
1979		// Element/input types
1980		"header": function( elem ) {
1981			return rheader.test( elem.nodeName );
1982		},
1983
1984		"input": function( elem ) {
1985			return rinputs.test( elem.nodeName );
1986		},
1987
1988		"button": function( elem ) {
1989			var name = elem.nodeName.toLowerCase();
1990			return name === "input" && elem.type === "button" || name === "button";
1991		},
1992
1993		"text": function( elem ) {
1994			var attr;
1995			return elem.nodeName.toLowerCase() === "input" &&
1996				elem.type === "text" &&
1997
1998				// Support: IE<8
1999				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2000				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2001		},
2002
2003		// Position-in-collection
2004		"first": createPositionalPseudo(function() {
2005			return [ 0 ];
2006		}),
2007
2008		"last": createPositionalPseudo(function( matchIndexes, length ) {
2009			return [ length - 1 ];
2010		}),
2011
2012		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2013			return [ argument < 0 ? argument + length : argument ];
2014		}),
2015
2016		"even": createPositionalPseudo(function( matchIndexes, length ) {
2017			var i = 0;
2018			for ( ; i < length; i += 2 ) {
2019				matchIndexes.push( i );
2020			}
2021			return matchIndexes;
2022		}),
2023
2024		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2025			var i = 1;
2026			for ( ; i < length; i += 2 ) {
2027				matchIndexes.push( i );
2028			}
2029			return matchIndexes;
2030		}),
2031
2032		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2033			var i = argument < 0 ? argument + length : argument;
2034			for ( ; --i >= 0; ) {
2035				matchIndexes.push( i );
2036			}
2037			return matchIndexes;
2038		}),
2039
2040		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2041			var i = argument < 0 ? argument + length : argument;
2042			for ( ; ++i < length; ) {
2043				matchIndexes.push( i );
2044			}
2045			return matchIndexes;
2046		})
2047	}
2048};
2049
2050Expr.pseudos["nth"] = Expr.pseudos["eq"];
2051
2052// Add button/input type pseudos
2053for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2054	Expr.pseudos[ i ] = createInputPseudo( i );
2055}
2056for ( i in { submit: true, reset: true } ) {
2057	Expr.pseudos[ i ] = createButtonPseudo( i );
2058}
2059
2060// Easy API for creating new setFilters
2061function setFilters() {}
2062setFilters.prototype = Expr.filters = Expr.pseudos;
2063Expr.setFilters = new setFilters();
2064
2065tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2066	var matched, match, tokens, type,
2067		soFar, groups, preFilters,
2068		cached = tokenCache[ selector + " " ];
2069
2070	if ( cached ) {
2071		return parseOnly ? 0 : cached.slice( 0 );
2072	}
2073
2074	soFar = selector;
2075	groups = [];
2076	preFilters = Expr.preFilter;
2077
2078	while ( soFar ) {
2079
2080		// Comma and first run
2081		if ( !matched || (match = rcomma.exec( soFar )) ) {
2082			if ( match ) {
2083				// Don't consume trailing commas as valid
2084				soFar = soFar.slice( match[0].length ) || soFar;
2085			}
2086			groups.push( (tokens = []) );
2087		}
2088
2089		matched = false;
2090
2091		// Combinators
2092		if ( (match = rcombinators.exec( soFar )) ) {
2093			matched = match.shift();
2094			tokens.push({
2095				value: matched,
2096				// Cast descendant combinators to space
2097				type: match[0].replace( rtrim, " " )
2098			});
2099			soFar = soFar.slice( matched.length );
2100		}
2101
2102		// Filters
2103		for ( type in Expr.filter ) {
2104			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2105				(match = preFilters[ type ]( match ))) ) {
2106				matched = match.shift();
2107				tokens.push({
2108					value: matched,
2109					type: type,
2110					matches: match
2111				});
2112				soFar = soFar.slice( matched.length );
2113			}
2114		}
2115
2116		if ( !matched ) {
2117			break;
2118		}
2119	}
2120
2121	// Return the length of the invalid excess
2122	// if we're just parsing
2123	// Otherwise, throw an error or return tokens
2124	return parseOnly ?
2125		soFar.length :
2126		soFar ?
2127			Sizzle.error( selector ) :
2128			// Cache the tokens
2129			tokenCache( selector, groups ).slice( 0 );
2130};
2131
2132function toSelector( tokens ) {
2133	var i = 0,
2134		len = tokens.length,
2135		selector = "";
2136	for ( ; i < len; i++ ) {
2137		selector += tokens[i].value;
2138	}
2139	return selector;
2140}
2141
2142function addCombinator( matcher, combinator, base ) {
2143	var dir = combinator.dir,
2144		checkNonElements = base && dir === "parentNode",
2145		doneName = done++;
2146
2147	return combinator.first ?
2148		// Check against closest ancestor/preceding element
2149		function( elem, context, xml ) {
2150			while ( (elem = elem[ dir ]) ) {
2151				if ( elem.nodeType === 1 || checkNonElements ) {
2152					return matcher( elem, context, xml );
2153				}
2154			}
2155		} :
2156
2157		// Check against all ancestor/preceding elements
2158		function( elem, context, xml ) {
2159			var oldCache, uniqueCache, outerCache,
2160				newCache = [ dirruns, doneName ];
2161
2162			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2163			if ( xml ) {
2164				while ( (elem = elem[ dir ]) ) {
2165					if ( elem.nodeType === 1 || checkNonElements ) {
2166						if ( matcher( elem, context, xml ) ) {
2167							return true;
2168						}
2169					}
2170				}
2171			} else {
2172				while ( (elem = elem[ dir ]) ) {
2173					if ( elem.nodeType === 1 || checkNonElements ) {
2174						outerCache = elem[ expando ] || (elem[ expando ] = {});
2175
2176						// Support: IE <9 only
2177						// Defend against cloned attroperties (jQuery gh-1709)
2178						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2179
2180						if ( (oldCache = uniqueCache[ dir ]) &&
2181							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2182
2183							// Assign to newCache so results back-propagate to previous elements
2184							return (newCache[ 2 ] = oldCache[ 2 ]);
2185						} else {
2186							// Reuse newcache so results back-propagate to previous elements
2187							uniqueCache[ dir ] = newCache;
2188
2189							// A match means we're done; a fail means we have to keep checking
2190							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2191								return true;
2192							}
2193						}
2194					}
2195				}
2196			}
2197		};
2198}
2199
2200function elementMatcher( matchers ) {
2201	return matchers.length > 1 ?
2202		function( elem, context, xml ) {
2203			var i = matchers.length;
2204			while ( i-- ) {
2205				if ( !matchers[i]( elem, context, xml ) ) {
2206					return false;
2207				}
2208			}
2209			return true;
2210		} :
2211		matchers[0];
2212}
2213
2214function multipleContexts( selector, contexts, results ) {
2215	var i = 0,
2216		len = contexts.length;
2217	for ( ; i < len; i++ ) {
2218		Sizzle( selector, contexts[i], results );
2219	}
2220	return results;
2221}
2222
2223function condense( unmatched, map, filter, context, xml ) {
2224	var elem,
2225		newUnmatched = [],
2226		i = 0,
2227		len = unmatched.length,
2228		mapped = map != null;
2229
2230	for ( ; i < len; i++ ) {
2231		if ( (elem = unmatched[i]) ) {
2232			if ( !filter || filter( elem, context, xml ) ) {
2233				newUnmatched.push( elem );
2234				if ( mapped ) {
2235					map.push( i );
2236				}
2237			}
2238		}
2239	}
2240
2241	return newUnmatched;
2242}
2243
2244function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2245	if ( postFilter && !postFilter[ expando ] ) {
2246		postFilter = setMatcher( postFilter );
2247	}
2248	if ( postFinder && !postFinder[ expando ] ) {
2249		postFinder = setMatcher( postFinder, postSelector );
2250	}
2251	return markFunction(function( seed, results, context, xml ) {
2252		var temp, i, elem,
2253			preMap = [],
2254			postMap = [],
2255			preexisting = results.length,
2256
2257			// Get initial elements from seed or context
2258			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2259
2260			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2261			matcherIn = preFilter && ( seed || !selector ) ?
2262				condense( elems, preMap, preFilter, context, xml ) :
2263				elems,
2264
2265			matcherOut = matcher ?
2266				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2267				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2268
2269					// ...intermediate processing is necessary
2270					[] :
2271
2272					// ...otherwise use results directly
2273					results :
2274				matcherIn;
2275
2276		// Find primary matches
2277		if ( matcher ) {
2278			matcher( matcherIn, matcherOut, context, xml );
2279		}
2280
2281		// Apply postFilter
2282		if ( postFilter ) {
2283			temp = condense( matcherOut, postMap );
2284			postFilter( temp, [], context, xml );
2285
2286			// Un-match failing elements by moving them back to matcherIn
2287			i = temp.length;
2288			while ( i-- ) {
2289				if ( (elem = temp[i]) ) {
2290					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2291				}
2292			}
2293		}
2294
2295		if ( seed ) {
2296			if ( postFinder || preFilter ) {
2297				if ( postFinder ) {
2298					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2299					temp = [];
2300					i = matcherOut.length;
2301					while ( i-- ) {
2302						if ( (elem = matcherOut[i]) ) {
2303							// Restore matcherIn since elem is not yet a final match
2304							temp.push( (matcherIn[i] = elem) );
2305						}
2306					}
2307					postFinder( null, (matcherOut = []), temp, xml );
2308				}
2309
2310				// Move matched elements from seed to results to keep them synchronized
2311				i = matcherOut.length;
2312				while ( i-- ) {
2313					if ( (elem = matcherOut[i]) &&
2314						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2315
2316						seed[temp] = !(results[temp] = elem);
2317					}
2318				}
2319			}
2320
2321		// Add elements to results, through postFinder if defined
2322		} else {
2323			matcherOut = condense(
2324				matcherOut === results ?
2325					matcherOut.splice( preexisting, matcherOut.length ) :
2326					matcherOut
2327			);
2328			if ( postFinder ) {
2329				postFinder( null, results, matcherOut, xml );
2330			} else {
2331				push.apply( results, matcherOut );
2332			}
2333		}
2334	});
2335}
2336
2337function matcherFromTokens( tokens ) {
2338	var checkContext, matcher, j,
2339		len = tokens.length,
2340		leadingRelative = Expr.relative[ tokens[0].type ],
2341		implicitRelative = leadingRelative || Expr.relative[" "],
2342		i = leadingRelative ? 1 : 0,
2343
2344		// The foundational matcher ensures that elements are reachable from top-level context(s)
2345		matchContext = addCombinator( function( elem ) {
2346			return elem === checkContext;
2347		}, implicitRelative, true ),
2348		matchAnyContext = addCombinator( function( elem ) {
2349			return indexOf( checkContext, elem ) > -1;
2350		}, implicitRelative, true ),
2351		matchers = [ function( elem, context, xml ) {
2352			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2353				(checkContext = context).nodeType ?
2354					matchContext( elem, context, xml ) :
2355					matchAnyContext( elem, context, xml ) );
2356			// Avoid hanging onto element (issue #299)
2357			checkContext = null;
2358			return ret;
2359		} ];
2360
2361	for ( ; i < len; i++ ) {
2362		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2363			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2364		} else {
2365			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2366
2367			// Return special upon seeing a positional matcher
2368			if ( matcher[ expando ] ) {
2369				// Find the next relative operator (if any) for proper handling
2370				j = ++i;
2371				for ( ; j < len; j++ ) {
2372					if ( Expr.relative[ tokens[j].type ] ) {
2373						break;
2374					}
2375				}
2376				return setMatcher(
2377					i > 1 && elementMatcher( matchers ),
2378					i > 1 && toSelector(
2379						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2380						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2381					).replace( rtrim, "$1" ),
2382					matcher,
2383					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2384					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2385					j < len && toSelector( tokens )
2386				);
2387			}
2388			matchers.push( matcher );
2389		}
2390	}
2391
2392	return elementMatcher( matchers );
2393}
2394
2395function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2396	var bySet = setMatchers.length > 0,
2397		byElement = elementMatchers.length > 0,
2398		superMatcher = function( seed, context, xml, results, outermost ) {
2399			var elem, j, matcher,
2400				matchedCount = 0,
2401				i = "0",
2402				unmatched = seed && [],
2403				setMatched = [],
2404				contextBackup = outermostContext,
2405				// We must always have either seed elements or outermost context
2406				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2407				// Use integer dirruns iff this is the outermost matcher
2408				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2409				len = elems.length;
2410
2411			if ( outermost ) {
2412				outermostContext = context === document || context || outermost;
2413			}
2414
2415			// Add elements passing elementMatchers directly to results
2416			// Support: IE<9, Safari
2417			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2418			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2419				if ( byElement && elem ) {
2420					j = 0;
2421					if ( !context && elem.ownerDocument !== document ) {
2422						setDocument( elem );
2423						xml = !documentIsHTML;
2424					}
2425					while ( (matcher = elementMatchers[j++]) ) {
2426						if ( matcher( elem, context || document, xml) ) {
2427							results.push( elem );
2428							break;
2429						}
2430					}
2431					if ( outermost ) {
2432						dirruns = dirrunsUnique;
2433					}
2434				}
2435
2436				// Track unmatched elements for set filters
2437				if ( bySet ) {
2438					// They will have gone through all possible matchers
2439					if ( (elem = !matcher && elem) ) {
2440						matchedCount--;
2441					}
2442
2443					// Lengthen the array for every element, matched or not
2444					if ( seed ) {
2445						unmatched.push( elem );
2446					}
2447				}
2448			}
2449
2450			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2451			// makes the latter nonnegative.
2452			matchedCount += i;
2453
2454			// Apply set filters to unmatched elements
2455			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2456			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2457			// no element matchers and no seed.
2458			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2459			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2460			// numerically zero.
2461			if ( bySet && i !== matchedCount ) {
2462				j = 0;
2463				while ( (matcher = setMatchers[j++]) ) {
2464					matcher( unmatched, setMatched, context, xml );
2465				}
2466
2467				if ( seed ) {
2468					// Reintegrate element matches to eliminate the need for sorting
2469					if ( matchedCount > 0 ) {
2470						while ( i-- ) {
2471							if ( !(unmatched[i] || setMatched[i]) ) {
2472								setMatched[i] = pop.call( results );
2473							}
2474						}
2475					}
2476
2477					// Discard index placeholder values to get only actual matches
2478					setMatched = condense( setMatched );
2479				}
2480
2481				// Add matches to results
2482				push.apply( results, setMatched );
2483
2484				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2485				if ( outermost && !seed && setMatched.length > 0 &&
2486					( matchedCount + setMatchers.length ) > 1 ) {
2487
2488					Sizzle.uniqueSort( results );
2489				}
2490			}
2491
2492			// Override manipulation of globals by nested matchers
2493			if ( outermost ) {
2494				dirruns = dirrunsUnique;
2495				outermostContext = contextBackup;
2496			}
2497
2498			return unmatched;
2499		};
2500
2501	return bySet ?
2502		markFunction( superMatcher ) :
2503		superMatcher;
2504}
2505
2506compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2507	var i,
2508		setMatchers = [],
2509		elementMatchers = [],
2510		cached = compilerCache[ selector + " " ];
2511
2512	if ( !cached ) {
2513		// Generate a function of recursive functions that can be used to check each element
2514		if ( !match ) {
2515			match = tokenize( selector );
2516		}
2517		i = match.length;
2518		while ( i-- ) {
2519			cached = matcherFromTokens( match[i] );
2520			if ( cached[ expando ] ) {
2521				setMatchers.push( cached );
2522			} else {
2523				elementMatchers.push( cached );
2524			}
2525		}
2526
2527		// Cache the compiled function
2528		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2529
2530		// Save selector and tokenization
2531		cached.selector = selector;
2532	}
2533	return cached;
2534};
2535
2536/**
2537 * A low-level selection function that works with Sizzle's compiled
2538 *  selector functions
2539 * @param {String|Function} selector A selector or a pre-compiled
2540 *  selector function built with Sizzle.compile
2541 * @param {Element} context
2542 * @param {Array} [results]
2543 * @param {Array} [seed] A set of elements to match against
2544 */
2545select = Sizzle.select = function( selector, context, results, seed ) {
2546	var i, tokens, token, type, find,
2547		compiled = typeof selector === "function" && selector,
2548		match = !seed && tokenize( (selector = compiled.selector || selector) );
2549
2550	results = results || [];
2551
2552	// Try to minimize operations if there is only one selector in the list and no seed
2553	// (the latter of which guarantees us context)
2554	if ( match.length === 1 ) {
2555
2556		// Reduce context if the leading compound selector is an ID
2557		tokens = match[0] = match[0].slice( 0 );
2558		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2559				support.getById && context.nodeType === 9 && documentIsHTML &&
2560				Expr.relative[ tokens[1].type ] ) {
2561
2562			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2563			if ( !context ) {
2564				return results;
2565
2566			// Precompiled matchers will still verify ancestry, so step up a level
2567			} else if ( compiled ) {
2568				context = context.parentNode;
2569			}
2570
2571			selector = selector.slice( tokens.shift().value.length );
2572		}
2573
2574		// Fetch a seed set for right-to-left matching
2575		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2576		while ( i-- ) {
2577			token = tokens[i];
2578
2579			// Abort if we hit a combinator
2580			if ( Expr.relative[ (type = token.type) ] ) {
2581				break;
2582			}
2583			if ( (find = Expr.find[ type ]) ) {
2584				// Search, expanding context for leading sibling combinators
2585				if ( (seed = find(
2586					token.matches[0].replace( runescape, funescape ),
2587					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2588				)) ) {
2589
2590					// If seed is empty or no tokens remain, we can return early
2591					tokens.splice( i, 1 );
2592					selector = seed.length && toSelector( tokens );
2593					if ( !selector ) {
2594						push.apply( results, seed );
2595						return results;
2596					}
2597
2598					break;
2599				}
2600			}
2601		}
2602	}
2603
2604	// Compile and execute a filtering function if one is not provided
2605	// Provide `match` to avoid retokenization if we modified the selector above
2606	( compiled || compile( selector, match ) )(
2607		seed,
2608		context,
2609		!documentIsHTML,
2610		results,
2611		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2612	);
2613	return results;
2614};
2615
2616// One-time assignments
2617
2618// Sort stability
2619support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2620
2621// Support: Chrome 14-35+
2622// Always assume duplicates if they aren't passed to the comparison function
2623support.detectDuplicates = !!hasDuplicate;
2624
2625// Initialize against the default document
2626setDocument();
2627
2628// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2629// Detached nodes confoundingly follow *each other*
2630support.sortDetached = assert(function( div1 ) {
2631	// Should return 1, but returns 4 (following)
2632	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2633});
2634
2635// Support: IE<8
2636// Prevent attribute/property "interpolation"
2637// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2638if ( !assert(function( div ) {
2639	div.innerHTML = "<a href='#'></a>";
2640	return div.firstChild.getAttribute("href") === "#" ;
2641}) ) {
2642	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2643		if ( !isXML ) {
2644			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2645		}
2646	});
2647}
2648
2649// Support: IE<9
2650// Use defaultValue in place of getAttribute("value")
2651if ( !support.attributes || !assert(function( div ) {
2652	div.innerHTML = "<input/>";
2653	div.firstChild.setAttribute( "value", "" );
2654	return div.firstChild.getAttribute( "value" ) === "";
2655}) ) {
2656	addHandle( "value", function( elem, name, isXML ) {
2657		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2658			return elem.defaultValue;
2659		}
2660	});
2661}
2662
2663// Support: IE<9
2664// Use getAttributeNode to fetch booleans when getAttribute lies
2665if ( !assert(function( div ) {
2666	return div.getAttribute("disabled") == null;
2667}) ) {
2668	addHandle( booleans, function( elem, name, isXML ) {
2669		var val;
2670		if ( !isXML ) {
2671			return elem[ name ] === true ? name.toLowerCase() :
2672					(val = elem.getAttributeNode( name )) && val.specified ?
2673					val.value :
2674				null;
2675		}
2676	});
2677}
2678
2679return Sizzle;
2680
2681})( window );
2682
2683
2684
2685jQuery.find = Sizzle;
2686jQuery.expr = Sizzle.selectors;
2687jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2688jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2689jQuery.text = Sizzle.getText;
2690jQuery.isXMLDoc = Sizzle.isXML;
2691jQuery.contains = Sizzle.contains;
2692
2693
2694
2695var dir = function( elem, dir, until ) {
2696	var matched = [],
2697		truncate = until !== undefined;
2698
2699	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2700		if ( elem.nodeType === 1 ) {
2701			if ( truncate && jQuery( elem ).is( until ) ) {
2702				break;
2703			}
2704			matched.push( elem );
2705		}
2706	}
2707	return matched;
2708};
2709
2710
2711var siblings = function( n, elem ) {
2712	var matched = [];
2713
2714	for ( ; n; n = n.nextSibling ) {
2715		if ( n.nodeType === 1 && n !== elem ) {
2716			matched.push( n );
2717		}
2718	}
2719
2720	return matched;
2721};
2722
2723
2724var rneedsContext = jQuery.expr.match.needsContext;
2725
2726var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2727
2728
2729
2730var risSimple = /^.[^:#\[\.,]*$/;
2731
2732// Implement the identical functionality for filter and not
2733function winnow( elements, qualifier, not ) {
2734	if ( jQuery.isFunction( qualifier ) ) {
2735		return jQuery.grep( elements, function( elem, i ) {
2736			/* jshint -W018 */
2737			return !!qualifier.call( elem, i, elem ) !== not;
2738		} );
2739
2740	}
2741
2742	if ( qualifier.nodeType ) {
2743		return jQuery.grep( elements, function( elem ) {
2744			return ( elem === qualifier ) !== not;
2745		} );
2746
2747	}
2748
2749	if ( typeof qualifier === "string" ) {
2750		if ( risSimple.test( qualifier ) ) {
2751			return jQuery.filter( qualifier, elements, not );
2752		}
2753
2754		qualifier = jQuery.filter( qualifier, elements );
2755	}
2756
2757	return jQuery.grep( elements, function( elem ) {
2758		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2759	} );
2760}
2761
2762jQuery.filter = function( expr, elems, not ) {
2763	var elem = elems[ 0 ];
2764
2765	if ( not ) {
2766		expr = ":not(" + expr + ")";
2767	}
2768
2769	return elems.length === 1 && elem.nodeType === 1 ?
2770		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2771		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2772			return elem.nodeType === 1;
2773		} ) );
2774};
2775
2776jQuery.fn.extend( {
2777	find: function( selector ) {
2778		var i,
2779			len = this.length,
2780			ret = [],
2781			self = this;
2782
2783		if ( typeof selector !== "string" ) {
2784			return this.pushStack( jQuery( selector ).filter( function() {
2785				for ( i = 0; i < len; i++ ) {
2786					if ( jQuery.contains( self[ i ], this ) ) {
2787						return true;
2788					}
2789				}
2790			} ) );
2791		}
2792
2793		for ( i = 0; i < len; i++ ) {
2794			jQuery.find( selector, self[ i ], ret );
2795		}
2796
2797		// Needed because $( selector, context ) becomes $( context ).find( selector )
2798		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2799		ret.selector = this.selector ? this.selector + " " + selector : selector;
2800		return ret;
2801	},
2802	filter: function( selector ) {
2803		return this.pushStack( winnow( this, selector || [], false ) );
2804	},
2805	not: function( selector ) {
2806		return this.pushStack( winnow( this, selector || [], true ) );
2807	},
2808	is: function( selector ) {
2809		return !!winnow(
2810			this,
2811
2812			// If this is a positional/relative selector, check membership in the returned set
2813			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2814			typeof selector === "string" && rneedsContext.test( selector ) ?
2815				jQuery( selector ) :
2816				selector || [],
2817			false
2818		).length;
2819	}
2820} );
2821
2822
2823// Initialize a jQuery object
2824
2825
2826// A central reference to the root jQuery(document)
2827var rootjQuery,
2828
2829	// A simple way to check for HTML strings
2830	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2831	// Strict HTML recognition (#11290: must start with <)
2832	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2833
2834	init = jQuery.fn.init = function( selector, context, root ) {
2835		var match, elem;
2836
2837		// HANDLE: $(""), $(null), $(undefined), $(false)
2838		if ( !selector ) {
2839			return this;
2840		}
2841
2842		// Method init() accepts an alternate rootjQuery
2843		// so migrate can support jQuery.sub (gh-2101)
2844		root = root || rootjQuery;
2845
2846		// Handle HTML strings
2847		if ( typeof selector === "string" ) {
2848			if ( selector[ 0 ] === "<" &&
2849				selector[ selector.length - 1 ] === ">" &&
2850				selector.length >= 3 ) {
2851
2852				// Assume that strings that start and end with <> are HTML and skip the regex check
2853				match = [ null, selector, null ];
2854
2855			} else {
2856				match = rquickExpr.exec( selector );
2857			}
2858
2859			// Match html or make sure no context is specified for #id
2860			if ( match && ( match[ 1 ] || !context ) ) {
2861
2862				// HANDLE: $(html) -> $(array)
2863				if ( match[ 1 ] ) {
2864					context = context instanceof jQuery ? context[ 0 ] : context;
2865
2866					// Option to run scripts is true for back-compat
2867					// Intentionally let the error be thrown if parseHTML is not present
2868					jQuery.merge( this, jQuery.parseHTML(
2869						match[ 1 ],
2870						context && context.nodeType ? context.ownerDocument || context : document,
2871						true
2872					) );
2873
2874					// HANDLE: $(html, props)
2875					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2876						for ( match in context ) {
2877
2878							// Properties of context are called as methods if possible
2879							if ( jQuery.isFunction( this[ match ] ) ) {
2880								this[ match ]( context[ match ] );
2881
2882							// ...and otherwise set as attributes
2883							} else {
2884								this.attr( match, context[ match ] );
2885							}
2886						}
2887					}
2888
2889					return this;
2890
2891				// HANDLE: $(#id)
2892				} else {
2893					elem = document.getElementById( match[ 2 ] );
2894
2895					// Support: Blackberry 4.6
2896					// gEBID returns nodes no longer in the document (#6963)
2897					if ( elem && elem.parentNode ) {
2898
2899						// Inject the element directly into the jQuery object
2900						this.length = 1;
2901						this[ 0 ] = elem;
2902					}
2903
2904					this.context = document;
2905					this.selector = selector;
2906					return this;
2907				}
2908
2909			// HANDLE: $(expr, $(...))
2910			} else if ( !context || context.jquery ) {
2911				return ( context || root ).find( selector );
2912
2913			// HANDLE: $(expr, context)
2914			// (which is just equivalent to: $(context).find(expr)
2915			} else {
2916				return this.constructor( context ).find( selector );
2917			}
2918
2919		// HANDLE: $(DOMElement)
2920		} else if ( selector.nodeType ) {
2921			this.context = this[ 0 ] = selector;
2922			this.length = 1;
2923			return this;
2924
2925		// HANDLE: $(function)
2926		// Shortcut for document ready
2927		} else if ( jQuery.isFunction( selector ) ) {
2928			return root.ready !== undefined ?
2929				root.ready( selector ) :
2930
2931				// Execute immediately if ready is not present
2932				selector( jQuery );
2933		}
2934
2935		if ( selector.selector !== undefined ) {
2936			this.selector = selector.selector;
2937			this.context = selector.context;
2938		}
2939
2940		return jQuery.makeArray( selector, this );
2941	};
2942
2943// Give the init function the jQuery prototype for later instantiation
2944init.prototype = jQuery.fn;
2945
2946// Initialize central reference
2947rootjQuery = jQuery( document );
2948
2949
2950var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2951
2952	// Methods guaranteed to produce a unique set when starting from a unique set
2953	guaranteedUnique = {
2954		children: true,
2955		contents: true,
2956		next: true,
2957		prev: true
2958	};
2959
2960jQuery.fn.extend( {
2961	has: function( target ) {
2962		var targets = jQuery( target, this ),
2963			l = targets.length;
2964
2965		return this.filter( function() {
2966			var i = 0;
2967			for ( ; i < l; i++ ) {
2968				if ( jQuery.contains( this, targets[ i ] ) ) {
2969					return true;
2970				}
2971			}
2972		} );
2973	},
2974
2975	closest: function( selectors, context ) {
2976		var cur,
2977			i = 0,
2978			l = this.length,
2979			matched = [],
2980			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2981				jQuery( selectors, context || this.context ) :
2982				0;
2983
2984		for ( ; i < l; i++ ) {
2985			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
2986
2987				// Always skip document fragments
2988				if ( cur.nodeType < 11 && ( pos ?
2989					pos.index( cur ) > -1 :
2990
2991					// Don't pass non-elements to Sizzle
2992					cur.nodeType === 1 &&
2993						jQuery.find.matchesSelector( cur, selectors ) ) ) {
2994
2995					matched.push( cur );
2996					break;
2997				}
2998			}
2999		}
3000
3001		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3002	},
3003
3004	// Determine the position of an element within the set
3005	index: function( elem ) {
3006
3007		// No argument, return index in parent
3008		if ( !elem ) {
3009			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3010		}
3011
3012		// Index in selector
3013		if ( typeof elem === "string" ) {
3014			return indexOf.call( jQuery( elem ), this[ 0 ] );
3015		}
3016
3017		// Locate the position of the desired element
3018		return indexOf.call( this,
3019
3020			// If it receives a jQuery object, the first element is used
3021			elem.jquery ? elem[ 0 ] : elem
3022		);
3023	},
3024
3025	add: function( selector, context ) {
3026		return this.pushStack(
3027			jQuery.uniqueSort(
3028				jQuery.merge( this.get(), jQuery( selector, context ) )
3029			)
3030		);
3031	},
3032
3033	addBack: function( selector ) {
3034		return this.add( selector == null ?
3035			this.prevObject : this.prevObject.filter( selector )
3036		);
3037	}
3038} );
3039
3040function sibling( cur, dir ) {
3041	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3042	return cur;
3043}
3044
3045jQuery.each( {
3046	parent: function( elem ) {
3047		var parent = elem.parentNode;
3048		return parent && parent.nodeType !== 11 ? parent : null;
3049	},
3050	parents: function( elem ) {
3051		return dir( elem, "parentNode" );
3052	},
3053	parentsUntil: function( elem, i, until ) {
3054		return dir( elem, "parentNode", until );
3055	},
3056	next: function( elem ) {
3057		return sibling( elem, "nextSibling" );
3058	},
3059	prev: function( elem ) {
3060		return sibling( elem, "previousSibling" );
3061	},
3062	nextAll: function( elem ) {
3063		return dir( elem, "nextSibling" );
3064	},
3065	prevAll: function( elem ) {
3066		return dir( elem, "previousSibling" );
3067	},
3068	nextUntil: function( elem, i, until ) {
3069		return dir( elem, "nextSibling", until );
3070	},
3071	prevUntil: function( elem, i, until ) {
3072		return dir( elem, "previousSibling", until );
3073	},
3074	siblings: function( elem ) {
3075		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3076	},
3077	children: function( elem ) {
3078		return siblings( elem.firstChild );
3079	},
3080	contents: function( elem ) {
3081		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3082	}
3083}, function( name, fn ) {
3084	jQuery.fn[ name ] = function( until, selector ) {
3085		var matched = jQuery.map( this, fn, until );
3086
3087		if ( name.slice( -5 ) !== "Until" ) {
3088			selector = until;
3089		}
3090
3091		if ( selector && typeof selector === "string" ) {
3092			matched = jQuery.filter( selector, matched );
3093		}
3094
3095		if ( this.length > 1 ) {
3096
3097			// Remove duplicates
3098			if ( !guaranteedUnique[ name ] ) {
3099				jQuery.uniqueSort( matched );
3100			}
3101
3102			// Reverse order for parents* and prev-derivatives
3103			if ( rparentsprev.test( name ) ) {
3104				matched.reverse();
3105			}
3106		}
3107
3108		return this.pushStack( matched );
3109	};
3110} );
3111var rnotwhite = ( /\S+/g );
3112
3113
3114
3115// Convert String-formatted options into Object-formatted ones
3116function createOptions( options ) {
3117	var object = {};
3118	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3119		object[ flag ] = true;
3120	} );
3121	return object;
3122}
3123
3124/*
3125 * Create a callback list using the following parameters:
3126 *
3127 *	options: an optional list of space-separated options that will change how
3128 *			the callback list behaves or a more traditional option object
3129 *
3130 * By default a callback list will act like an event callback list and can be
3131 * "fired" multiple times.
3132 *
3133 * Possible options:
3134 *
3135 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3136 *
3137 *	memory:			will keep track of previous values and will call any callback added
3138 *					after the list has been fired right away with the latest "memorized"
3139 *					values (like a Deferred)
3140 *
3141 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3142 *
3143 *	stopOnFalse:	interrupt callings when a callback returns false
3144 *
3145 */
3146jQuery.Callbacks = function( options ) {
3147
3148	// Convert options from String-formatted to Object-formatted if needed
3149	// (we check in cache first)
3150	options = typeof options === "string" ?
3151		createOptions( options ) :
3152		jQuery.extend( {}, options );
3153
3154	var // Flag to know if list is currently firing
3155		firing,
3156
3157		// Last fire value for non-forgettable lists
3158		memory,
3159
3160		// Flag to know if list was already fired
3161		fired,
3162
3163		// Flag to prevent firing
3164		locked,
3165
3166		// Actual callback list
3167		list = [],
3168
3169		// Queue of execution data for repeatable lists
3170		queue = [],
3171
3172		// Index of currently firing callback (modified by add/remove as needed)
3173		firingIndex = -1,
3174
3175		// Fire callbacks
3176		fire = function() {
3177
3178			// Enforce single-firing
3179			locked = options.once;
3180
3181			// Execute callbacks for all pending executions,
3182			// respecting firingIndex overrides and runtime changes
3183			fired = firing = true;
3184			for ( ; queue.length; firingIndex = -1 ) {
3185				memory = queue.shift();
3186				while ( ++firingIndex < list.length ) {
3187
3188					// Run callback and check for early termination
3189					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3190						options.stopOnFalse ) {
3191
3192						// Jump to end and forget the data so .add doesn't re-fire
3193						firingIndex = list.length;
3194						memory = false;
3195					}
3196				}
3197			}
3198
3199			// Forget the data if we're done with it
3200			if ( !options.memory ) {
3201				memory = false;
3202			}
3203
3204			firing = false;
3205
3206			// Clean up if we're done firing for good
3207			if ( locked ) {
3208
3209				// Keep an empty list if we have data for future add calls
3210				if ( memory ) {
3211					list = [];
3212
3213				// Otherwise, this object is spent
3214				} else {
3215					list = "";
3216				}
3217			}
3218		},
3219
3220		// Actual Callbacks object
3221		self = {
3222
3223			// Add a callback or a collection of callbacks to the list
3224			add: function() {
3225				if ( list ) {
3226
3227					// If we have memory from a past run, we should fire after adding
3228					if ( memory && !firing ) {
3229						firingIndex = list.length - 1;
3230						queue.push( memory );
3231					}
3232
3233					( function add( args ) {
3234						jQuery.each( args, function( _, arg ) {
3235							if ( jQuery.isFunction( arg ) ) {
3236								if ( !options.unique || !self.has( arg ) ) {
3237									list.push( arg );
3238								}
3239							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3240
3241								// Inspect recursively
3242								add( arg );
3243							}
3244						} );
3245					} )( arguments );
3246
3247					if ( memory && !firing ) {
3248						fire();
3249					}
3250				}
3251				return this;
3252			},
3253
3254			// Remove a callback from the list
3255			remove: function() {
3256				jQuery.each( arguments, function( _, arg ) {
3257					var index;
3258					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3259						list.splice( index, 1 );
3260
3261						// Handle firing indexes
3262						if ( index <= firingIndex ) {
3263							firingIndex--;
3264						}
3265					}
3266				} );
3267				return this;
3268			},
3269
3270			// Check if a given callback is in the list.
3271			// If no argument is given, return whether or not list has callbacks attached.
3272			has: function( fn ) {
3273				return fn ?
3274					jQuery.inArray( fn, list ) > -1 :
3275					list.length > 0;
3276			},
3277
3278			// Remove all callbacks from the list
3279			empty: function() {
3280				if ( list ) {
3281					list = [];
3282				}
3283				return this;
3284			},
3285
3286			// Disable .fire and .add
3287			// Abort any current/pending executions
3288			// Clear all callbacks and values
3289			disable: function() {
3290				locked = queue = [];
3291				list = memory = "";
3292				return this;
3293			},
3294			disabled: function() {
3295				return !list;
3296			},
3297
3298			// Disable .fire
3299			// Also disable .add unless we have memory (since it would have no effect)
3300			// Abort any pending executions
3301			lock: function() {
3302				locked = queue = [];
3303				if ( !memory ) {
3304					list = memory = "";
3305				}
3306				return this;
3307			},
3308			locked: function() {
3309				return !!locked;
3310			},
3311
3312			// Call all callbacks with the given context and arguments
3313			fireWith: function( context, args ) {
3314				if ( !locked ) {
3315					args = args || [];
3316					args = [ context, args.slice ? args.slice() : args ];
3317					queue.push( args );
3318					if ( !firing ) {
3319						fire();
3320					}
3321				}
3322				return this;
3323			},
3324
3325			// Call all the callbacks with the given arguments
3326			fire: function() {
3327				self.fireWith( this, arguments );
3328				return this;
3329			},
3330
3331			// To know if the callbacks have already been called at least once
3332			fired: function() {
3333				return !!fired;
3334			}
3335		};
3336
3337	return self;
3338};
3339
3340
3341jQuery.extend( {
3342
3343	Deferred: function( func ) {
3344		var tuples = [
3345
3346				// action, add listener, listener list, final state
3347				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3348				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3349				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3350			],
3351			state = "pending",
3352			promise = {
3353				state: function() {
3354					return state;
3355				},
3356				always: function() {
3357					deferred.done( arguments ).fail( arguments );
3358					return this;
3359				},
3360				then: function( /* fnDone, fnFail, fnProgress */ ) {
3361					var fns = arguments;
3362					return jQuery.Deferred( function( newDefer ) {
3363						jQuery.each( tuples, function( i, tuple ) {
3364							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3365
3366							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3367							deferred[ tuple[ 1 ] ]( function() {
3368								var returned = fn && fn.apply( this, arguments );
3369								if ( returned && jQuery.isFunction( returned.promise ) ) {
3370									returned.promise()
3371										.progress( newDefer.notify )
3372										.done( newDefer.resolve )
3373										.fail( newDefer.reject );
3374								} else {
3375									newDefer[ tuple[ 0 ] + "With" ](
3376										this === promise ? newDefer.promise() : this,
3377										fn ? [ returned ] : arguments
3378									);
3379								}
3380							} );
3381						} );
3382						fns = null;
3383					} ).promise();
3384				},
3385
3386				// Get a promise for this deferred
3387				// If obj is provided, the promise aspect is added to the object
3388				promise: function( obj ) {
3389					return obj != null ? jQuery.extend( obj, promise ) : promise;
3390				}
3391			},
3392			deferred = {};
3393
3394		// Keep pipe for back-compat
3395		promise.pipe = promise.then;
3396
3397		// Add list-specific methods
3398		jQuery.each( tuples, function( i, tuple ) {
3399			var list = tuple[ 2 ],
3400				stateString = tuple[ 3 ];
3401
3402			// promise[ done | fail | progress ] = list.add
3403			promise[ tuple[ 1 ] ] = list.add;
3404
3405			// Handle state
3406			if ( stateString ) {
3407				list.add( function() {
3408
3409					// state = [ resolved | rejected ]
3410					state = stateString;
3411
3412				// [ reject_list | resolve_list ].disable; progress_list.lock
3413				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3414			}
3415
3416			// deferred[ resolve | reject | notify ]
3417			deferred[ tuple[ 0 ] ] = function() {
3418				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3419				return this;
3420			};
3421			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3422		} );
3423
3424		// Make the deferred a promise
3425		promise.promise( deferred );
3426
3427		// Call given func if any
3428		if ( func ) {
3429			func.call( deferred, deferred );
3430		}
3431
3432		// All done!
3433		return deferred;
3434	},
3435
3436	// Deferred helper
3437	when: function( subordinate /* , ..., subordinateN */ ) {
3438		var i = 0,
3439			resolveValues = slice.call( arguments ),
3440			length = resolveValues.length,
3441
3442			// the count of uncompleted subordinates
3443			remaining = length !== 1 ||
3444				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3445
3446			// the master Deferred.
3447			// If resolveValues consist of only a single Deferred, just use that.
3448			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3449
3450			// Update function for both resolve and progress values
3451			updateFunc = function( i, contexts, values ) {
3452				return function( value ) {
3453					contexts[ i ] = this;
3454					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3455					if ( values === progressValues ) {
3456						deferred.notifyWith( contexts, values );
3457					} else if ( !( --remaining ) ) {
3458						deferred.resolveWith( contexts, values );
3459					}
3460				};
3461			},
3462
3463			progressValues, progressContexts, resolveContexts;
3464
3465		// Add listeners to Deferred subordinates; treat others as resolved
3466		if ( length > 1 ) {
3467			progressValues = new Array( length );
3468			progressContexts = new Array( length );
3469			resolveContexts = new Array( length );
3470			for ( ; i < length; i++ ) {
3471				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3472					resolveValues[ i ].promise()
3473						.progress( updateFunc( i, progressContexts, progressValues ) )
3474						.done( updateFunc( i, resolveContexts, resolveValues ) )
3475						.fail( deferred.reject );
3476				} else {
3477					--remaining;
3478				}
3479			}
3480		}
3481
3482		// If we're not waiting on anything, resolve the master
3483		if ( !remaining ) {
3484			deferred.resolveWith( resolveContexts, resolveValues );
3485		}
3486
3487		return deferred.promise();
3488	}
3489} );
3490
3491
3492// The deferred used on DOM ready
3493var readyList;
3494
3495jQuery.fn.ready = function( fn ) {
3496
3497	// Add the callback
3498	jQuery.ready.promise().done( fn );
3499
3500	return this;
3501};
3502
3503jQuery.extend( {
3504
3505	// Is the DOM ready to be used? Set to true once it occurs.
3506	isReady: false,
3507
3508	// A counter to track how many items to wait for before
3509	// the ready event fires. See #6781
3510	readyWait: 1,
3511
3512	// Hold (or release) the ready event
3513	holdReady: function( hold ) {
3514		if ( hold ) {
3515			jQuery.readyWait++;
3516		} else {
3517			jQuery.ready( true );
3518		}
3519	},
3520
3521	// Handle when the DOM is ready
3522	ready: function( wait ) {
3523
3524		// Abort if there are pending holds or we're already ready
3525		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3526			return;
3527		}
3528
3529		// Remember that the DOM is ready
3530		jQuery.isReady = true;
3531
3532		// If a normal DOM Ready event fired, decrement, and wait if need be
3533		if ( wait !== true && --jQuery.readyWait > 0 ) {
3534			return;
3535		}
3536
3537		// If there are functions bound, to execute
3538		readyList.resolveWith( document, [ jQuery ] );
3539
3540		// Trigger any bound ready events
3541		if ( jQuery.fn.triggerHandler ) {
3542			jQuery( document ).triggerHandler( "ready" );
3543			jQuery( document ).off( "ready" );
3544		}
3545	}
3546} );
3547
3548/**
3549 * The ready event handler and self cleanup method
3550 */
3551function completed() {
3552	document.removeEventListener( "DOMContentLoaded", completed );
3553	window.removeEventListener( "load", completed );
3554	jQuery.ready();
3555}
3556
3557jQuery.ready.promise = function( obj ) {
3558	if ( !readyList ) {
3559
3560		readyList = jQuery.Deferred();
3561
3562		// Catch cases where $(document).ready() is called
3563		// after the browser event has already occurred.
3564		// Support: IE9-10 only
3565		// Older IE sometimes signals "interactive" too soon
3566		if ( document.readyState === "complete" ||
3567			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3568
3569			// Handle it asynchronously to allow scripts the opportunity to delay ready
3570			window.setTimeout( jQuery.ready );
3571
3572		} else {
3573
3574			// Use the handy event callback
3575			document.addEventListener( "DOMContentLoaded", completed );
3576
3577			// A fallback to window.onload, that will always work
3578			window.addEventListener( "load", completed );
3579		}
3580	}
3581	return readyList.promise( obj );
3582};
3583
3584// Kick off the DOM ready check even if the user does not
3585jQuery.ready.promise();
3586
3587
3588
3589
3590// Multifunctional method to get and set values of a collection
3591// The value/s can optionally be executed if it's a function
3592var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3593	var i = 0,
3594		len = elems.length,
3595		bulk = key == null;
3596
3597	// Sets many values
3598	if ( jQuery.type( key ) === "object" ) {
3599		chainable = true;
3600		for ( i in key ) {
3601			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3602		}
3603
3604	// Sets one value
3605	} else if ( value !== undefined ) {
3606		chainable = true;
3607
3608		if ( !jQuery.isFunction( value ) ) {
3609			raw = true;
3610		}
3611
3612		if ( bulk ) {
3613
3614			// Bulk operations run against the entire set
3615			if ( raw ) {
3616				fn.call( elems, value );
3617				fn = null;
3618
3619			// ...except when executing function values
3620			} else {
3621				bulk = fn;
3622				fn = function( elem, key, value ) {
3623					return bulk.call( jQuery( elem ), value );
3624				};
3625			}
3626		}
3627
3628		if ( fn ) {
3629			for ( ; i < len; i++ ) {
3630				fn(
3631					elems[ i ], key, raw ?
3632					value :
3633					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3634				);
3635			}
3636		}
3637	}
3638
3639	return chainable ?
3640		elems :
3641
3642		// Gets
3643		bulk ?
3644			fn.call( elems ) :
3645			len ? fn( elems[ 0 ], key ) : emptyGet;
3646};
3647var acceptData = function( owner ) {
3648
3649	// Accepts only:
3650	//  - Node
3651	//    - Node.ELEMENT_NODE
3652	//    - Node.DOCUMENT_NODE
3653	//  - Object
3654	//    - Any
3655	/* jshint -W018 */
3656	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3657};
3658
3659
3660
3661
3662function Data() {
3663	this.expando = jQuery.expando + Data.uid++;
3664}
3665
3666Data.uid = 1;
3667
3668Data.prototype = {
3669
3670	register: function( owner, initial ) {
3671		var value = initial || {};
3672
3673		// If it is a node unlikely to be stringify-ed or looped over
3674		// use plain assignment
3675		if ( owner.nodeType ) {
3676			owner[ this.expando ] = value;
3677
3678		// Otherwise secure it in a non-enumerable, non-writable property
3679		// configurability must be true to allow the property to be
3680		// deleted with the delete operator
3681		} else {
3682			Object.defineProperty( owner, this.expando, {
3683				value: value,
3684				writable: true,
3685				configurable: true
3686			} );
3687		}
3688		return owner[ this.expando ];
3689	},
3690	cache: function( owner ) {
3691
3692		// We can accept data for non-element nodes in modern browsers,
3693		// but we should not, see #8335.
3694		// Always return an empty object.
3695		if ( !acceptData( owner ) ) {
3696			return {};
3697		}
3698
3699		// Check if the owner object already has a cache
3700		var value = owner[ this.expando ];
3701
3702		// If not, create one
3703		if ( !value ) {
3704			value = {};
3705
3706			// We can accept data for non-element nodes in modern browsers,
3707			// but we should not, see #8335.
3708			// Always return an empty object.
3709			if ( acceptData( owner ) ) {
3710
3711				// If it is a node unlikely to be stringify-ed or looped over
3712				// use plain assignment
3713				if ( owner.nodeType ) {
3714					owner[ this.expando ] = value;
3715
3716				// Otherwise secure it in a non-enumerable property
3717				// configurable must be true to allow the property to be
3718				// deleted when data is removed
3719				} else {
3720					Object.defineProperty( owner, this.expando, {
3721						value: value,
3722						configurable: true
3723					} );
3724				}
3725			}
3726		}
3727
3728		return value;
3729	},
3730	set: function( owner, data, value ) {
3731		var prop,
3732			cache = this.cache( owner );
3733
3734		// Handle: [ owner, key, value ] args
3735		if ( typeof data === "string" ) {
3736			cache[ data ] = value;
3737
3738		// Handle: [ owner, { properties } ] args
3739		} else {
3740
3741			// Copy the properties one-by-one to the cache object
3742			for ( prop in data ) {
3743				cache[ prop ] = data[ prop ];
3744			}
3745		}
3746		return cache;
3747	},
3748	get: function( owner, key ) {
3749		return key === undefined ?
3750			this.cache( owner ) :
3751			owner[ this.expando ] && owner[ this.expando ][ key ];
3752	},
3753	access: function( owner, key, value ) {
3754		var stored;
3755
3756		// In cases where either:
3757		//
3758		//   1. No key was specified
3759		//   2. A string key was specified, but no value provided
3760		//
3761		// Take the "read" path and allow the get method to determine
3762		// which value to return, respectively either:
3763		//
3764		//   1. The entire cache object
3765		//   2. The data stored at the key
3766		//
3767		if ( key === undefined ||
3768				( ( key && typeof key === "string" ) && value === undefined ) ) {
3769
3770			stored = this.get( owner, key );
3771
3772			return stored !== undefined ?
3773				stored : this.get( owner, jQuery.camelCase( key ) );
3774		}
3775
3776		// When the key is not a string, or both a key and value
3777		// are specified, set or extend (existing objects) with either:
3778		//
3779		//   1. An object of properties
3780		//   2. A key and value
3781		//
3782		this.set( owner, key, value );
3783
3784		// Since the "set" path can have two possible entry points
3785		// return the expected data based on which path was taken[*]
3786		return value !== undefined ? value : key;
3787	},
3788	remove: function( owner, key ) {
3789		var i, name, camel,
3790			cache = owner[ this.expando ];
3791
3792		if ( cache === undefined ) {
3793			return;
3794		}
3795
3796		if ( key === undefined ) {
3797			this.register( owner );
3798
3799		} else {
3800
3801			// Support array or space separated string of keys
3802			if ( jQuery.isArray( key ) ) {
3803
3804				// If "name" is an array of keys...
3805				// When data is initially created, via ("key", "val") signature,
3806				// keys will be converted to camelCase.
3807				// Since there is no way to tell _how_ a key was added, remove
3808				// both plain key and camelCase key. #12786
3809				// This will only penalize the array argument path.
3810				name = key.concat( key.map( jQuery.camelCase ) );
3811			} else {
3812				camel = jQuery.camelCase( key );
3813
3814				// Try the string as a key before any manipulation
3815				if ( key in cache ) {
3816					name = [ key, camel ];
3817				} else {
3818
3819					// If a key with the spaces exists, use it.
3820					// Otherwise, create an array by matching non-whitespace
3821					name = camel;
3822					name = name in cache ?
3823						[ name ] : ( name.match( rnotwhite ) || [] );
3824				}
3825			}
3826
3827			i = name.length;
3828
3829			while ( i-- ) {
3830				delete cache[ name[ i ] ];
3831			}
3832		}
3833
3834		// Remove the expando if there's no more data
3835		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
3836
3837			// Support: Chrome <= 35-45+
3838			// Webkit & Blink performance suffers when deleting properties
3839			// from DOM nodes, so set to undefined instead
3840			// https://code.google.com/p/chromium/issues/detail?id=378607
3841			if ( owner.nodeType ) {
3842				owner[ this.expando ] = undefined;
3843			} else {
3844				delete owner[ this.expando ];
3845			}
3846		}
3847	},
3848	hasData: function( owner ) {
3849		var cache = owner[ this.expando ];
3850		return cache !== undefined && !jQuery.isEmptyObject( cache );
3851	}
3852};
3853var dataPriv = new Data();
3854
3855var dataUser = new Data();
3856
3857
3858
3859//	Implementation Summary
3860//
3861//	1. Enforce API surface and semantic compatibility with 1.9.x branch
3862//	2. Improve the module's maintainability by reducing the storage
3863//		paths to a single mechanism.
3864//	3. Use the same single mechanism to support "private" and "user" data.
3865//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3866//	5. Avoid exposing implementation details on user objects (eg. expando properties)
3867//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3868
3869var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3870	rmultiDash = /[A-Z]/g;
3871
3872function dataAttr( elem, key, data ) {
3873	var name;
3874
3875	// If nothing was found internally, try to fetch any
3876	// data from the HTML5 data-* attribute
3877	if ( data === undefined && elem.nodeType === 1 ) {
3878		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
3879		data = elem.getAttribute( name );
3880
3881		if ( typeof data === "string" ) {
3882			try {
3883				data = data === "true" ? true :
3884					data === "false" ? false :
3885					data === "null" ? null :
3886
3887					// Only convert to a number if it doesn't change the string
3888					+data + "" === data ? +data :
3889					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3890					data;
3891			} catch ( e ) {}
3892
3893			// Make sure we set the data so it isn't changed later
3894			dataUser.set( elem, key, data );
3895		} else {
3896			data = undefined;
3897		}
3898	}
3899	return data;
3900}
3901
3902jQuery.extend( {
3903	hasData: function( elem ) {
3904		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
3905	},
3906
3907	data: function( elem, name, data ) {
3908		return dataUser.access( elem, name, data );
3909	},
3910
3911	removeData: function( elem, name ) {
3912		dataUser.remove( elem, name );
3913	},
3914
3915	// TODO: Now that all calls to _data and _removeData have been replaced
3916	// with direct calls to dataPriv methods, these can be deprecated.
3917	_data: function( elem, name, data ) {
3918		return dataPriv.access( elem, name, data );
3919	},
3920
3921	_removeData: function( elem, name ) {
3922		dataPriv.remove( elem, name );
3923	}
3924} );
3925
3926jQuery.fn.extend( {
3927	data: function( key, value ) {
3928		var i, name, data,
3929			elem = this[ 0 ],
3930			attrs = elem && elem.attributes;
3931
3932		// Gets all values
3933		if ( key === undefined ) {
3934			if ( this.length ) {
3935				data = dataUser.get( elem );
3936
3937				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
3938					i = attrs.length;
3939					while ( i-- ) {
3940
3941						// Support: IE11+
3942						// The attrs elements can be null (#14894)
3943						if ( attrs[ i ] ) {
3944							name = attrs[ i ].name;
3945							if ( name.indexOf( "data-" ) === 0 ) {
3946								name = jQuery.camelCase( name.slice( 5 ) );
3947								dataAttr( elem, name, data[ name ] );
3948							}
3949						}
3950					}
3951					dataPriv.set( elem, "hasDataAttrs", true );
3952				}
3953			}
3954
3955			return data;
3956		}
3957
3958		// Sets multiple values
3959		if ( typeof key === "object" ) {
3960			return this.each( function() {
3961				dataUser.set( this, key );
3962			} );
3963		}
3964
3965		return access( this, function( value ) {
3966			var data, camelKey;
3967
3968			// The calling jQuery object (element matches) is not empty
3969			// (and therefore has an element appears at this[ 0 ]) and the
3970			// `value` parameter was not undefined. An empty jQuery object
3971			// will result in `undefined` for elem = this[ 0 ] which will
3972			// throw an exception if an attempt to read a data cache is made.
3973			if ( elem && value === undefined ) {
3974
3975				// Attempt to get data from the cache
3976				// with the key as-is
3977				data = dataUser.get( elem, key ) ||
3978
3979					// Try to find dashed key if it exists (gh-2779)
3980					// This is for 2.2.x only
3981					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
3982
3983				if ( data !== undefined ) {
3984					return data;
3985				}
3986
3987				camelKey = jQuery.camelCase( key );
3988
3989				// Attempt to get data from the cache
3990				// with the key camelized
3991				data = dataUser.get( elem, camelKey );
3992				if ( data !== undefined ) {
3993					return data;
3994				}
3995
3996				// Attempt to "discover" the data in
3997				// HTML5 custom data-* attrs
3998				data = dataAttr( elem, camelKey, undefined );
3999				if ( data !== undefined ) {
4000					return data;
4001				}
4002
4003				// We tried really hard, but the data doesn't exist.
4004				return;
4005			}
4006
4007			// Set the data...
4008			camelKey = jQuery.camelCase( key );
4009			this.each( function() {
4010
4011				// First, attempt to store a copy or reference of any
4012				// data that might've been store with a camelCased key.
4013				var data = dataUser.get( this, camelKey );
4014
4015				// For HTML5 data-* attribute interop, we have to
4016				// store property names with dashes in a camelCase form.
4017				// This might not apply to all properties...*
4018				dataUser.set( this, camelKey, value );
4019
4020				// *... In the case of properties that might _actually_
4021				// have dashes, we need to also store a copy of that
4022				// unchanged property.
4023				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
4024					dataUser.set( this, key, value );
4025				}
4026			} );
4027		}, null, value, arguments.length > 1, null, true );
4028	},
4029
4030	removeData: function( key ) {
4031		return this.each( function() {
4032			dataUser.remove( this, key );
4033		} );
4034	}
4035} );
4036
4037
4038jQuery.extend( {
4039	queue: function( elem, type, data ) {
4040		var queue;
4041
4042		if ( elem ) {
4043			type = ( type || "fx" ) + "queue";
4044			queue = dataPriv.get( elem, type );
4045
4046			// Speed up dequeue by getting out quickly if this is just a lookup
4047			if ( data ) {
4048				if ( !queue || jQuery.isArray( data ) ) {
4049					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4050				} else {
4051					queue.push( data );
4052				}
4053			}
4054			return queue || [];
4055		}
4056	},
4057
4058	dequeue: function( elem, type ) {
4059		type = type || "fx";
4060
4061		var queue = jQuery.queue( elem, type ),
4062			startLength = queue.length,
4063			fn = queue.shift(),
4064			hooks = jQuery._queueHooks( elem, type ),
4065			next = function() {
4066				jQuery.dequeue( elem, type );
4067			};
4068
4069		// If the fx queue is dequeued, always remove the progress sentinel
4070		if ( fn === "inprogress" ) {
4071			fn = queue.shift();
4072			startLength--;
4073		}
4074
4075		if ( fn ) {
4076
4077			// Add a progress sentinel to prevent the fx queue from being
4078			// automatically dequeued
4079			if ( type === "fx" ) {
4080				queue.unshift( "inprogress" );
4081			}
4082
4083			// Clear up the last queue stop function
4084			delete hooks.stop;
4085			fn.call( elem, next, hooks );
4086		}
4087
4088		if ( !startLength && hooks ) {
4089			hooks.empty.fire();
4090		}
4091	},
4092
4093	// Not public - generate a queueHooks object, or return the current one
4094	_queueHooks: function( elem, type ) {
4095		var key = type + "queueHooks";
4096		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4097			empty: jQuery.Callbacks( "once memory" ).add( function() {
4098				dataPriv.remove( elem, [ type + "queue", key ] );
4099			} )
4100		} );
4101	}
4102} );
4103
4104jQuery.fn.extend( {
4105	queue: function( type, data ) {
4106		var setter = 2;
4107
4108		if ( typeof type !== "string" ) {
4109			data = type;
4110			type = "fx";
4111			setter--;
4112		}
4113
4114		if ( arguments.length < setter ) {
4115			return jQuery.queue( this[ 0 ], type );
4116		}
4117
4118		return data === undefined ?
4119			this :
4120			this.each( function() {
4121				var queue = jQuery.queue( this, type, data );
4122
4123				// Ensure a hooks for this queue
4124				jQuery._queueHooks( this, type );
4125
4126				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4127					jQuery.dequeue( this, type );
4128				}
4129			} );
4130	},
4131	dequeue: function( type ) {
4132		return this.each( function() {
4133			jQuery.dequeue( this, type );
4134		} );
4135	},
4136	clearQueue: function( type ) {
4137		return this.queue( type || "fx", [] );
4138	},
4139
4140	// Get a promise resolved when queues of a certain type
4141	// are emptied (fx is the type by default)
4142	promise: function( type, obj ) {
4143		var tmp,
4144			count = 1,
4145			defer = jQuery.Deferred(),
4146			elements = this,
4147			i = this.length,
4148			resolve = function() {
4149				if ( !( --count ) ) {
4150					defer.resolveWith( elements, [ elements ] );
4151				}
4152			};
4153
4154		if ( typeof type !== "string" ) {
4155			obj = type;
4156			type = undefined;
4157		}
4158		type = type || "fx";
4159
4160		while ( i-- ) {
4161			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4162			if ( tmp && tmp.empty ) {
4163				count++;
4164				tmp.empty.add( resolve );
4165			}
4166		}
4167		resolve();
4168		return defer.promise( obj );
4169	}
4170} );
4171var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4172
4173var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4174
4175
4176var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4177
4178var isHidden = function( elem, el ) {
4179
4180		// isHidden might be called from jQuery#filter function;
4181		// in that case, element will be second argument
4182		elem = el || elem;
4183		return jQuery.css( elem, "display" ) === "none" ||
4184			!jQuery.contains( elem.ownerDocument, elem );
4185	};
4186
4187
4188
4189function adjustCSS( elem, prop, valueParts, tween ) {
4190	var adjusted,
4191		scale = 1,
4192		maxIterations = 20,
4193		currentValue = tween ?
4194			function() { return tween.cur(); } :
4195			function() { return jQuery.css( elem, prop, "" ); },
4196		initial = currentValue(),
4197		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4198
4199		// Starting value computation is required for potential unit mismatches
4200		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4201			rcssNum.exec( jQuery.css( elem, prop ) );
4202
4203	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4204
4205		// Trust units reported by jQuery.css
4206		unit = unit || initialInUnit[ 3 ];
4207
4208		// Make sure we update the tween properties later on
4209		valueParts = valueParts || [];
4210
4211		// Iteratively approximate from a nonzero starting point
4212		initialInUnit = +initial || 1;
4213
4214		do {
4215
4216			// If previous iteration zeroed out, double until we get *something*.
4217			// Use string for doubling so we don't accidentally see scale as unchanged below
4218			scale = scale || ".5";
4219
4220			// Adjust and apply
4221			initialInUnit = initialInUnit / scale;
4222			jQuery.style( elem, prop, initialInUnit + unit );
4223
4224		// Update scale, tolerating zero or NaN from tween.cur()
4225		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4226		} while (
4227			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4228		);
4229	}
4230
4231	if ( valueParts ) {
4232		initialInUnit = +initialInUnit || +initial || 0;
4233
4234		// Apply relative offset (+=/-=) if specified
4235		adjusted = valueParts[ 1 ] ?
4236			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4237			+valueParts[ 2 ];
4238		if ( tween ) {
4239			tween.unit = unit;
4240			tween.start = initialInUnit;
4241			tween.end = adjusted;
4242		}
4243	}
4244	return adjusted;
4245}
4246var rcheckableType = ( /^(?:checkbox|radio)$/i );
4247
4248var rtagName = ( /<([\w:-]+)/ );
4249
4250var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4251
4252
4253
4254// We have to close these tags to support XHTML (#13200)
4255var wrapMap = {
4256
4257	// Support: IE9
4258	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4259
4260	// XHTML parsers do not magically insert elements in the
4261	// same way that tag soup parsers do. So we cannot shorten
4262	// this by omitting <tbody> or other required elements.
4263	thead: [ 1, "<table>", "</table>" ],
4264	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4265	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4266	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4267
4268	_default: [ 0, "", "" ]
4269};
4270
4271// Support: IE9
4272wrapMap.optgroup = wrapMap.option;
4273
4274wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4275wrapMap.th = wrapMap.td;
4276
4277
4278function getAll( context, tag ) {
4279
4280	// Support: IE9-11+
4281	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4282	var ret = typeof context.getElementsByTagName !== "undefined" ?
4283			context.getElementsByTagName( tag || "*" ) :
4284			typeof context.querySelectorAll !== "undefined" ?
4285				context.querySelectorAll( tag || "*" ) :
4286			[];
4287
4288	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4289		jQuery.merge( [ context ], ret ) :
4290		ret;
4291}
4292
4293
4294// Mark scripts as having already been evaluated
4295function setGlobalEval( elems, refElements ) {
4296	var i = 0,
4297		l = elems.length;
4298
4299	for ( ; i < l; i++ ) {
4300		dataPriv.set(
4301			elems[ i ],
4302			"globalEval",
4303			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4304		);
4305	}
4306}
4307
4308
4309var rhtml = /<|&#?\w+;/;
4310
4311function buildFragment( elems, context, scripts, selection, ignored ) {
4312	var elem, tmp, tag, wrap, contains, j,
4313		fragment = context.createDocumentFragment(),
4314		nodes = [],
4315		i = 0,
4316		l = elems.length;
4317
4318	for ( ; i < l; i++ ) {
4319		elem = elems[ i ];
4320
4321		if ( elem || elem === 0 ) {
4322
4323			// Add nodes directly
4324			if ( jQuery.type( elem ) === "object" ) {
4325
4326				// Support: Android<4.1, PhantomJS<2
4327				// push.apply(_, arraylike) throws on ancient WebKit
4328				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4329
4330			// Convert non-html into a text node
4331			} else if ( !rhtml.test( elem ) ) {
4332				nodes.push( context.createTextNode( elem ) );
4333
4334			// Convert html into DOM nodes
4335			} else {
4336				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4337
4338				// Deserialize a standard representation
4339				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4340				wrap = wrapMap[ tag ] || wrapMap._default;
4341				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4342
4343				// Descend through wrappers to the right content
4344				j = wrap[ 0 ];
4345				while ( j-- ) {
4346					tmp = tmp.lastChild;
4347				}
4348
4349				// Support: Android<4.1, PhantomJS<2
4350				// push.apply(_, arraylike) throws on ancient WebKit
4351				jQuery.merge( nodes, tmp.childNodes );
4352
4353				// Remember the top-level container
4354				tmp = fragment.firstChild;
4355
4356				// Ensure the created nodes are orphaned (#12392)
4357				tmp.textContent = "";
4358			}
4359		}
4360	}
4361
4362	// Remove wrapper from fragment
4363	fragment.textContent = "";
4364
4365	i = 0;
4366	while ( ( elem = nodes[ i++ ] ) ) {
4367
4368		// Skip elements already in the context collection (trac-4087)
4369		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4370			if ( ignored ) {
4371				ignored.push( elem );
4372			}
4373			continue;
4374		}
4375
4376		contains = jQuery.contains( elem.ownerDocument, elem );
4377
4378		// Append to fragment
4379		tmp = getAll( fragment.appendChild( elem ), "script" );
4380
4381		// Preserve script evaluation history
4382		if ( contains ) {
4383			setGlobalEval( tmp );
4384		}
4385
4386		// Capture executables
4387		if ( scripts ) {
4388			j = 0;
4389			while ( ( elem = tmp[ j++ ] ) ) {
4390				if ( rscriptType.test( elem.type || "" ) ) {
4391					scripts.push( elem );
4392				}
4393			}
4394		}
4395	}
4396
4397	return fragment;
4398}
4399
4400
4401( function() {
4402	var fragment = document.createDocumentFragment(),
4403		div = fragment.appendChild( document.createElement( "div" ) ),
4404		input = document.createElement( "input" );
4405
4406	// Support: Android 4.0-4.3, Safari<=5.1
4407	// Check state lost if the name is set (#11217)
4408	// Support: Windows Web Apps (WWA)
4409	// `name` and `type` must use .setAttribute for WWA (#14901)
4410	input.setAttribute( "type", "radio" );
4411	input.setAttribute( "checked", "checked" );
4412	input.setAttribute( "name", "t" );
4413
4414	div.appendChild( input );
4415
4416	// Support: Safari<=5.1, Android<4.2
4417	// Older WebKit doesn't clone checked state correctly in fragments
4418	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4419
4420	// Support: IE<=11+
4421	// Make sure textarea (and checkbox) defaultValue is properly cloned
4422	div.innerHTML = "<textarea>x</textarea>";
4423	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4424} )();
4425
4426
4427var
4428	rkeyEvent = /^key/,
4429	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4430	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4431
4432function returnTrue() {
4433	return true;
4434}
4435
4436function returnFalse() {
4437	return false;
4438}
4439
4440// Support: IE9
4441// See #13393 for more info
4442function safeActiveElement() {
4443	try {
4444		return document.activeElement;
4445	} catch ( err ) { }
4446}
4447
4448function on( elem, types, selector, data, fn, one ) {
4449	var origFn, type;
4450
4451	// Types can be a map of types/handlers
4452	if ( typeof types === "object" ) {
4453
4454		// ( types-Object, selector, data )
4455		if ( typeof selector !== "string" ) {
4456
4457			// ( types-Object, data )
4458			data = data || selector;
4459			selector = undefined;
4460		}
4461		for ( type in types ) {
4462			on( elem, type, selector, data, types[ type ], one );
4463		}
4464		return elem;
4465	}
4466
4467	if ( data == null && fn == null ) {
4468
4469		// ( types, fn )
4470		fn = selector;
4471		data = selector = undefined;
4472	} else if ( fn == null ) {
4473		if ( typeof selector === "string" ) {
4474
4475			// ( types, selector, fn )
4476			fn = data;
4477			data = undefined;
4478		} else {
4479
4480			// ( types, data, fn )
4481			fn = data;
4482			data = selector;
4483			selector = undefined;
4484		}
4485	}
4486	if ( fn === false ) {
4487		fn = returnFalse;
4488	} else if ( !fn ) {
4489		return elem;
4490	}
4491
4492	if ( one === 1 ) {
4493		origFn = fn;
4494		fn = function( event ) {
4495
4496			// Can use an empty set, since event contains the info
4497			jQuery().off( event );
4498			return origFn.apply( this, arguments );
4499		};
4500
4501		// Use same guid so caller can remove using origFn
4502		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4503	}
4504	return elem.each( function() {
4505		jQuery.event.add( this, types, fn, data, selector );
4506	} );
4507}
4508
4509/*
4510 * Helper functions for managing events -- not part of the public interface.
4511 * Props to Dean Edwards' addEvent library for many of the ideas.
4512 */
4513jQuery.event = {
4514
4515	global: {},
4516
4517	add: function( elem, types, handler, data, selector ) {
4518
4519		var handleObjIn, eventHandle, tmp,
4520			events, t, handleObj,
4521			special, handlers, type, namespaces, origType,
4522			elemData = dataPriv.get( elem );
4523
4524		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4525		if ( !elemData ) {
4526			return;
4527		}
4528
4529		// Caller can pass in an object of custom data in lieu of the handler
4530		if ( handler.handler ) {
4531			handleObjIn = handler;
4532			handler = handleObjIn.handler;
4533			selector = handleObjIn.selector;
4534		}
4535
4536		// Make sure that the handler has a unique ID, used to find/remove it later
4537		if ( !handler.guid ) {
4538			handler.guid = jQuery.guid++;
4539		}
4540
4541		// Init the element's event structure and main handler, if this is the first
4542		if ( !( events = elemData.events ) ) {
4543			events = elemData.events = {};
4544		}
4545		if ( !( eventHandle = elemData.handle ) ) {
4546			eventHandle = elemData.handle = function( e ) {
4547
4548				// Discard the second event of a jQuery.event.trigger() and
4549				// when an event is called after a page has unloaded
4550				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4551					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4552			};
4553		}
4554
4555		// Handle multiple events separated by a space
4556		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4557		t = types.length;
4558		while ( t-- ) {
4559			tmp = rtypenamespace.exec( types[ t ] ) || [];
4560			type = origType = tmp[ 1 ];
4561			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4562
4563			// There *must* be a type, no attaching namespace-only handlers
4564			if ( !type ) {
4565				continue;
4566			}
4567
4568			// If event changes its type, use the special event handlers for the changed type
4569			special = jQuery.event.special[ type ] || {};
4570
4571			// If selector defined, determine special event api type, otherwise given type
4572			type = ( selector ? special.delegateType : special.bindType ) || type;
4573
4574			// Update special based on newly reset type
4575			special = jQuery.event.special[ type ] || {};
4576
4577			// handleObj is passed to all event handlers
4578			handleObj = jQuery.extend( {
4579				type: type,
4580				origType: origType,
4581				data: data,
4582				handler: handler,
4583				guid: handler.guid,
4584				selector: selector,
4585				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4586				namespace: namespaces.join( "." )
4587			}, handleObjIn );
4588
4589			// Init the event handler queue if we're the first
4590			if ( !( handlers = events[ type ] ) ) {
4591				handlers = events[ type ] = [];
4592				handlers.delegateCount = 0;
4593
4594				// Only use addEventListener if the special events handler returns false
4595				if ( !special.setup ||
4596					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4597
4598					if ( elem.addEventListener ) {
4599						elem.addEventListener( type, eventHandle );
4600					}
4601				}
4602			}
4603
4604			if ( special.add ) {
4605				special.add.call( elem, handleObj );
4606
4607				if ( !handleObj.handler.guid ) {
4608					handleObj.handler.guid = handler.guid;
4609				}
4610			}
4611
4612			// Add to the element's handler list, delegates in front
4613			if ( selector ) {
4614				handlers.splice( handlers.delegateCount++, 0, handleObj );
4615			} else {
4616				handlers.push( handleObj );
4617			}
4618
4619			// Keep track of which events have ever been used, for event optimization
4620			jQuery.event.global[ type ] = true;
4621		}
4622
4623	},
4624
4625	// Detach an event or set of events from an element
4626	remove: function( elem, types, handler, selector, mappedTypes ) {
4627
4628		var j, origCount, tmp,
4629			events, t, handleObj,
4630			special, handlers, type, namespaces, origType,
4631			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
4632
4633		if ( !elemData || !( events = elemData.events ) ) {
4634			return;
4635		}
4636
4637		// Once for each type.namespace in types; type may be omitted
4638		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4639		t = types.length;
4640		while ( t-- ) {
4641			tmp = rtypenamespace.exec( types[ t ] ) || [];
4642			type = origType = tmp[ 1 ];
4643			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4644
4645			// Unbind all events (on this namespace, if provided) for the element
4646			if ( !type ) {
4647				for ( type in events ) {
4648					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4649				}
4650				continue;
4651			}
4652
4653			special = jQuery.event.special[ type ] || {};
4654			type = ( selector ? special.delegateType : special.bindType ) || type;
4655			handlers = events[ type ] || [];
4656			tmp = tmp[ 2 ] &&
4657				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4658
4659			// Remove matching events
4660			origCount = j = handlers.length;
4661			while ( j-- ) {
4662				handleObj = handlers[ j ];
4663
4664				if ( ( mappedTypes || origType === handleObj.origType ) &&
4665					( !handler || handler.guid === handleObj.guid ) &&
4666					( !tmp || tmp.test( handleObj.namespace ) ) &&
4667					( !selector || selector === handleObj.selector ||
4668						selector === "**" && handleObj.selector ) ) {
4669					handlers.splice( j, 1 );
4670
4671					if ( handleObj.selector ) {
4672						handlers.delegateCount--;
4673					}
4674					if ( special.remove ) {
4675						special.remove.call( elem, handleObj );
4676					}
4677				}
4678			}
4679
4680			// Remove generic event handler if we removed something and no more handlers exist
4681			// (avoids potential for endless recursion during removal of special event handlers)
4682			if ( origCount && !handlers.length ) {
4683				if ( !special.teardown ||
4684					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4685
4686					jQuery.removeEvent( elem, type, elemData.handle );
4687				}
4688
4689				delete events[ type ];
4690			}
4691		}
4692
4693		// Remove data and the expando if it's no longer used
4694		if ( jQuery.isEmptyObject( events ) ) {
4695			dataPriv.remove( elem, "handle events" );
4696		}
4697	},
4698
4699	dispatch: function( event ) {
4700
4701		// Make a writable jQuery.Event from the native event object
4702		event = jQuery.event.fix( event );
4703
4704		var i, j, ret, matched, handleObj,
4705			handlerQueue = [],
4706			args = slice.call( arguments ),
4707			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
4708			special = jQuery.event.special[ event.type ] || {};
4709
4710		// Use the fix-ed jQuery.Event rather than the (read-only) native event
4711		args[ 0 ] = event;
4712		event.delegateTarget = this;
4713
4714		// Call the preDispatch hook for the mapped type, and let it bail if desired
4715		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4716			return;
4717		}
4718
4719		// Determine handlers
4720		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4721
4722		// Run delegates first; they may want to stop propagation beneath us
4723		i = 0;
4724		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
4725			event.currentTarget = matched.elem;
4726
4727			j = 0;
4728			while ( ( handleObj = matched.handlers[ j++ ] ) &&
4729				!event.isImmediatePropagationStopped() ) {
4730
4731				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
4732				// a subset or equal to those in the bound event (both can have no namespace).
4733				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
4734
4735					event.handleObj = handleObj;
4736					event.data = handleObj.data;
4737
4738					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
4739						handleObj.handler ).apply( matched.elem, args );
4740
4741					if ( ret !== undefined ) {
4742						if ( ( event.result = ret ) === false ) {
4743							event.preventDefault();
4744							event.stopPropagation();
4745						}
4746					}
4747				}
4748			}
4749		}
4750
4751		// Call the postDispatch hook for the mapped type
4752		if ( special.postDispatch ) {
4753			special.postDispatch.call( this, event );
4754		}
4755
4756		return event.result;
4757	},
4758
4759	handlers: function( event, handlers ) {
4760		var i, matches, sel, handleObj,
4761			handlerQueue = [],
4762			delegateCount = handlers.delegateCount,
4763			cur = event.target;
4764
4765		// Support (at least): Chrome, IE9
4766		// Find delegate handlers
4767		// Black-hole SVG <use> instance trees (#13180)
4768		//
4769		// Support: Firefox<=42+
4770		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
4771		if ( delegateCount && cur.nodeType &&
4772			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
4773
4774			for ( ; cur !== this; cur = cur.parentNode || this ) {
4775
4776				// Don't check non-elements (#13208)
4777				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4778				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
4779					matches = [];
4780					for ( i = 0; i < delegateCount; i++ ) {
4781						handleObj = handlers[ i ];
4782
4783						// Don't conflict with Object.prototype properties (#13203)
4784						sel = handleObj.selector + " ";
4785
4786						if ( matches[ sel ] === undefined ) {
4787							matches[ sel ] = handleObj.needsContext ?
4788								jQuery( sel, this ).index( cur ) > -1 :
4789								jQuery.find( sel, this, null, [ cur ] ).length;
4790						}
4791						if ( matches[ sel ] ) {
4792							matches.push( handleObj );
4793						}
4794					}
4795					if ( matches.length ) {
4796						handlerQueue.push( { elem: cur, handlers: matches } );
4797					}
4798				}
4799			}
4800		}
4801
4802		// Add the remaining (directly-bound) handlers
4803		if ( delegateCount < handlers.length ) {
4804			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
4805		}
4806
4807		return handlerQueue;
4808	},
4809
4810	// Includes some event props shared by KeyEvent and MouseEvent
4811	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
4812		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
4813
4814	fixHooks: {},
4815
4816	keyHooks: {
4817		props: "char charCode key keyCode".split( " " ),
4818		filter: function( event, original ) {
4819
4820			// Add which for key events
4821			if ( event.which == null ) {
4822				event.which = original.charCode != null ? original.charCode : original.keyCode;
4823			}
4824
4825			return event;
4826		}
4827	},
4828
4829	mouseHooks: {
4830		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
4831			"screenX screenY toElement" ).split( " " ),
4832		filter: function( event, original ) {
4833			var eventDoc, doc, body,
4834				button = original.button;
4835
4836			// Calculate pageX/Y if missing and clientX/Y available
4837			if ( event.pageX == null && original.clientX != null ) {
4838				eventDoc = event.target.ownerDocument || document;
4839				doc = eventDoc.documentElement;
4840				body = eventDoc.body;
4841
4842				event.pageX = original.clientX +
4843					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
4844					( doc && doc.clientLeft || body && body.clientLeft || 0 );
4845				event.pageY = original.clientY +
4846					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
4847					( doc && doc.clientTop  || body && body.clientTop  || 0 );
4848			}
4849
4850			// Add which for click: 1 === left; 2 === middle; 3 === right
4851			// Note: button is not normalized, so don't use it
4852			if ( !event.which && button !== undefined ) {
4853				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4854			}
4855
4856			return event;
4857		}
4858	},
4859
4860	fix: function( event ) {
4861		if ( event[ jQuery.expando ] ) {
4862			return event;
4863		}
4864
4865		// Create a writable copy of the event object and normalize some properties
4866		var i, prop, copy,
4867			type = event.type,
4868			originalEvent = event,
4869			fixHook = this.fixHooks[ type ];
4870
4871		if ( !fixHook ) {
4872			this.fixHooks[ type ] = fixHook =
4873				rmouseEvent.test( type ) ? this.mouseHooks :
4874				rkeyEvent.test( type ) ? this.keyHooks :
4875				{};
4876		}
4877		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4878
4879		event = new jQuery.Event( originalEvent );
4880
4881		i = copy.length;
4882		while ( i-- ) {
4883			prop = copy[ i ];
4884			event[ prop ] = originalEvent[ prop ];
4885		}
4886
4887		// Support: Cordova 2.5 (WebKit) (#13255)
4888		// All events should have a target; Cordova deviceready doesn't
4889		if ( !event.target ) {
4890			event.target = document;
4891		}
4892
4893		// Support: Safari 6.0+, Chrome<28
4894		// Target should not be a text node (#504, #13143)
4895		if ( event.target.nodeType === 3 ) {
4896			event.target = event.target.parentNode;
4897		}
4898
4899		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4900	},
4901
4902	special: {
4903		load: {
4904
4905			// Prevent triggered image.load events from bubbling to window.load
4906			noBubble: true
4907		},
4908		focus: {
4909
4910			// Fire native event if possible so blur/focus sequence is correct
4911			trigger: function() {
4912				if ( this !== safeActiveElement() && this.focus ) {
4913					this.focus();
4914					return false;
4915				}
4916			},
4917			delegateType: "focusin"
4918		},
4919		blur: {
4920			trigger: function() {
4921				if ( this === safeActiveElement() && this.blur ) {
4922					this.blur();
4923					return false;
4924				}
4925			},
4926			delegateType: "focusout"
4927		},
4928		click: {
4929
4930			// For checkbox, fire native event so checked state will be right
4931			trigger: function() {
4932				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4933					this.click();
4934					return false;
4935				}
4936			},
4937
4938			// For cross-browser consistency, don't fire native .click() on links
4939			_default: function( event ) {
4940				return jQuery.nodeName( event.target, "a" );
4941			}
4942		},
4943
4944		beforeunload: {
4945			postDispatch: function( event ) {
4946
4947				// Support: Firefox 20+
4948				// Firefox doesn't alert if the returnValue field is not set.
4949				if ( event.result !== undefined && event.originalEvent ) {
4950					event.originalEvent.returnValue = event.result;
4951				}
4952			}
4953		}
4954	}
4955};
4956
4957jQuery.removeEvent = function( elem, type, handle ) {
4958
4959	// This "if" is needed for plain objects
4960	if ( elem.removeEventListener ) {
4961		elem.removeEventListener( type, handle );
4962	}
4963};
4964
4965jQuery.Event = function( src, props ) {
4966
4967	// Allow instantiation without the 'new' keyword
4968	if ( !( this instanceof jQuery.Event ) ) {
4969		return new jQuery.Event( src, props );
4970	}
4971
4972	// Event object
4973	if ( src && src.type ) {
4974		this.originalEvent = src;
4975		this.type = src.type;
4976
4977		// Events bubbling up the document may have been marked as prevented
4978		// by a handler lower down the tree; reflect the correct value.
4979		this.isDefaultPrevented = src.defaultPrevented ||
4980				src.defaultPrevented === undefined &&
4981
4982				// Support: Android<4.0
4983				src.returnValue === false ?
4984			returnTrue :
4985			returnFalse;
4986
4987	// Event type
4988	} else {
4989		this.type = src;
4990	}
4991
4992	// Put explicitly provided properties onto the event object
4993	if ( props ) {
4994		jQuery.extend( this, props );
4995	}
4996
4997	// Create a timestamp if incoming event doesn't have one
4998	this.timeStamp = src && src.timeStamp || jQuery.now();
4999
5000	// Mark it as fixed
5001	this[ jQuery.expando ] = true;
5002};
5003
5004// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5005// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5006jQuery.Event.prototype = {
5007	constructor: jQuery.Event,
5008	isDefaultPrevented: returnFalse,
5009	isPropagationStopped: returnFalse,
5010	isImmediatePropagationStopped: returnFalse,
5011	isSimulated: false,
5012
5013	preventDefault: function() {
5014		var e = this.originalEvent;
5015
5016		this.isDefaultPrevented = returnTrue;
5017
5018		if ( e && !this.isSimulated ) {
5019			e.preventDefault();
5020		}
5021	},
5022	stopPropagation: function() {
5023		var e = this.originalEvent;
5024
5025		this.isPropagationStopped = returnTrue;
5026
5027		if ( e && !this.isSimulated ) {
5028			e.stopPropagation();
5029		}
5030	},
5031	stopImmediatePropagation: function() {
5032		var e = this.originalEvent;
5033
5034		this.isImmediatePropagationStopped = returnTrue;
5035
5036		if ( e && !this.isSimulated ) {
5037			e.stopImmediatePropagation();
5038		}
5039
5040		this.stopPropagation();
5041	}
5042};
5043
5044// Create mouseenter/leave events using mouseover/out and event-time checks
5045// so that event delegation works in jQuery.
5046// Do the same for pointerenter/pointerleave and pointerover/pointerout
5047//
5048// Support: Safari 7 only
5049// Safari sends mouseenter too often; see:
5050// https://code.google.com/p/chromium/issues/detail?id=470258
5051// for the description of the bug (it existed in older Chrome versions as well).
5052jQuery.each( {
5053	mouseenter: "mouseover",
5054	mouseleave: "mouseout",
5055	pointerenter: "pointerover",
5056	pointerleave: "pointerout"
5057}, function( orig, fix ) {
5058	jQuery.event.special[ orig ] = {
5059		delegateType: fix,
5060		bindType: fix,
5061
5062		handle: function( event ) {
5063			var ret,
5064				target = this,
5065				related = event.relatedTarget,
5066				handleObj = event.handleObj;
5067
5068			// For mouseenter/leave call the handler if related is outside the target.
5069			// NB: No relatedTarget if the mouse left/entered the browser window
5070			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5071				event.type = handleObj.origType;
5072				ret = handleObj.handler.apply( this, arguments );
5073				event.type = fix;
5074			}
5075			return ret;
5076		}
5077	};
5078} );
5079
5080jQuery.fn.extend( {
5081	on: function( types, selector, data, fn ) {
5082		return on( this, types, selector, data, fn );
5083	},
5084	one: function( types, selector, data, fn ) {
5085		return on( this, types, selector, data, fn, 1 );
5086	},
5087	off: function( types, selector, fn ) {
5088		var handleObj, type;
5089		if ( types && types.preventDefault && types.handleObj ) {
5090
5091			// ( event )  dispatched jQuery.Event
5092			handleObj = types.handleObj;
5093			jQuery( types.delegateTarget ).off(
5094				handleObj.namespace ?
5095					handleObj.origType + "." + handleObj.namespace :
5096					handleObj.origType,
5097				handleObj.selector,
5098				handleObj.handler
5099			);
5100			return this;
5101		}
5102		if ( typeof types === "object" ) {
5103
5104			// ( types-object [, selector] )
5105			for ( type in types ) {
5106				this.off( type, selector, types[ type ] );
5107			}
5108			return this;
5109		}
5110		if ( selector === false || typeof selector === "function" ) {
5111
5112			// ( types [, fn] )
5113			fn = selector;
5114			selector = undefined;
5115		}
5116		if ( fn === false ) {
5117			fn = returnFalse;
5118		}
5119		return this.each( function() {
5120			jQuery.event.remove( this, types, fn, selector );
5121		} );
5122	}
5123} );
5124
5125
5126var
5127	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5128
5129	// Support: IE 10-11, Edge 10240+
5130	// In IE/Edge using regex groups here causes severe slowdowns.
5131	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5132	rnoInnerhtml = /<script|<style|<link/i,
5133
5134	// checked="checked" or checked
5135	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5136	rscriptTypeMasked = /^true\/(.*)/,
5137	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5138
5139// Manipulating tables requires a tbody
5140function manipulationTarget( elem, content ) {
5141	return jQuery.nodeName( elem, "table" ) &&
5142		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5143
5144		elem.getElementsByTagName( "tbody" )[ 0 ] ||
5145			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5146		elem;
5147}
5148
5149// Replace/restore the type attribute of script elements for safe DOM manipulation
5150function disableScript( elem ) {
5151	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5152	return elem;
5153}
5154function restoreScript( elem ) {
5155	var match = rscriptTypeMasked.exec( elem.type );
5156
5157	if ( match ) {
5158		elem.type = match[ 1 ];
5159	} else {
5160		elem.removeAttribute( "type" );
5161	}
5162
5163	return elem;
5164}
5165
5166function cloneCopyEvent( src, dest ) {
5167	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5168
5169	if ( dest.nodeType !== 1 ) {
5170		return;
5171	}
5172
5173	// 1. Copy private data: events, handlers, etc.
5174	if ( dataPriv.hasData( src ) ) {
5175		pdataOld = dataPriv.access( src );
5176		pdataCur = dataPriv.set( dest, pdataOld );
5177		events = pdataOld.events;
5178
5179		if ( events ) {
5180			delete pdataCur.handle;
5181			pdataCur.events = {};
5182
5183			for ( type in events ) {
5184				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5185					jQuery.event.add( dest, type, events[ type ][ i ] );
5186				}
5187			}
5188		}
5189	}
5190
5191	// 2. Copy user data
5192	if ( dataUser.hasData( src ) ) {
5193		udataOld = dataUser.access( src );
5194		udataCur = jQuery.extend( {}, udataOld );
5195
5196		dataUser.set( dest, udataCur );
5197	}
5198}
5199
5200// Fix IE bugs, see support tests
5201function fixInput( src, dest ) {
5202	var nodeName = dest.nodeName.toLowerCase();
5203
5204	// Fails to persist the checked state of a cloned checkbox or radio button.
5205	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5206		dest.checked = src.checked;
5207
5208	// Fails to return the selected option to the default selected state when cloning options
5209	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5210		dest.defaultValue = src.defaultValue;
5211	}
5212}
5213
5214function domManip( collection, args, callback, ignored ) {
5215
5216	// Flatten any nested arrays
5217	args = concat.apply( [], args );
5218
5219	var fragment, first, scripts, hasScripts, node, doc,
5220		i = 0,
5221		l = collection.length,
5222		iNoClone = l - 1,
5223		value = args[ 0 ],
5224		isFunction = jQuery.isFunction( value );
5225
5226	// We can't cloneNode fragments that contain checked, in WebKit
5227	if ( isFunction ||
5228			( l > 1 && typeof value === "string" &&
5229				!support.checkClone && rchecked.test( value ) ) ) {
5230		return collection.each( function( index ) {
5231			var self = collection.eq( index );
5232			if ( isFunction ) {
5233				args[ 0 ] = value.call( this, index, self.html() );
5234			}
5235			domManip( self, args, callback, ignored );
5236		} );
5237	}
5238
5239	if ( l ) {
5240		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5241		first = fragment.firstChild;
5242
5243		if ( fragment.childNodes.length === 1 ) {
5244			fragment = first;
5245		}
5246
5247		// Require either new content or an interest in ignored elements to invoke the callback
5248		if ( first || ignored ) {
5249			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5250			hasScripts = scripts.length;
5251
5252			// Use the original fragment for the last item
5253			// instead of the first because it can end up
5254			// being emptied incorrectly in certain situations (#8070).
5255			for ( ; i < l; i++ ) {
5256				node = fragment;
5257
5258				if ( i !== iNoClone ) {
5259					node = jQuery.clone( node, true, true );
5260
5261					// Keep references to cloned scripts for later restoration
5262					if ( hasScripts ) {
5263
5264						// Support: Android<4.1, PhantomJS<2
5265						// push.apply(_, arraylike) throws on ancient WebKit
5266						jQuery.merge( scripts, getAll( node, "script" ) );
5267					}
5268				}
5269
5270				callback.call( collection[ i ], node, i );
5271			}
5272
5273			if ( hasScripts ) {
5274				doc = scripts[ scripts.length - 1 ].ownerDocument;
5275
5276				// Reenable scripts
5277				jQuery.map( scripts, restoreScript );
5278
5279				// Evaluate executable scripts on first document insertion
5280				for ( i = 0; i < hasScripts; i++ ) {
5281					node = scripts[ i ];
5282					if ( rscriptType.test( node.type || "" ) &&
5283						!dataPriv.access( node, "globalEval" ) &&
5284						jQuery.contains( doc, node ) ) {
5285
5286						if ( node.src ) {
5287
5288							// Optional AJAX dependency, but won't run scripts if not present
5289							if ( jQuery._evalUrl ) {
5290								jQuery._evalUrl( node.src );
5291							}
5292						} else {
5293							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5294						}
5295					}
5296				}
5297			}
5298		}
5299	}
5300
5301	return collection;
5302}
5303
5304function remove( elem, selector, keepData ) {
5305	var node,
5306		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5307		i = 0;
5308
5309	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5310		if ( !keepData && node.nodeType === 1 ) {
5311			jQuery.cleanData( getAll( node ) );
5312		}
5313
5314		if ( node.parentNode ) {
5315			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5316				setGlobalEval( getAll( node, "script" ) );
5317			}
5318			node.parentNode.removeChild( node );
5319		}
5320	}
5321
5322	return elem;
5323}
5324
5325jQuery.extend( {
5326	htmlPrefilter: function( html ) {
5327		return html.replace( rxhtmlTag, "<$1></$2>" );
5328	},
5329
5330	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5331		var i, l, srcElements, destElements,
5332			clone = elem.cloneNode( true ),
5333			inPage = jQuery.contains( elem.ownerDocument, elem );
5334
5335		// Fix IE cloning issues
5336		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5337				!jQuery.isXMLDoc( elem ) ) {
5338
5339			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5340			destElements = getAll( clone );
5341			srcElements = getAll( elem );
5342
5343			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5344				fixInput( srcElements[ i ], destElements[ i ] );
5345			}
5346		}
5347
5348		// Copy the events from the original to the clone
5349		if ( dataAndEvents ) {
5350			if ( deepDataAndEvents ) {
5351				srcElements = srcElements || getAll( elem );
5352				destElements = destElements || getAll( clone );
5353
5354				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5355					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5356				}
5357			} else {
5358				cloneCopyEvent( elem, clone );
5359			}
5360		}
5361
5362		// Preserve script evaluation history
5363		destElements = getAll( clone, "script" );
5364		if ( destElements.length > 0 ) {
5365			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5366		}
5367
5368		// Return the cloned set
5369		return clone;
5370	},
5371
5372	cleanData: function( elems ) {
5373		var data, elem, type,
5374			special = jQuery.event.special,
5375			i = 0;
5376
5377		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5378			if ( acceptData( elem ) ) {
5379				if ( ( data = elem[ dataPriv.expando ] ) ) {
5380					if ( data.events ) {
5381						for ( type in data.events ) {
5382							if ( special[ type ] ) {
5383								jQuery.event.remove( elem, type );
5384
5385							// This is a shortcut to avoid jQuery.event.remove's overhead
5386							} else {
5387								jQuery.removeEvent( elem, type, data.handle );
5388							}
5389						}
5390					}
5391
5392					// Support: Chrome <= 35-45+
5393					// Assign undefined instead of using delete, see Data#remove
5394					elem[ dataPriv.expando ] = undefined;
5395				}
5396				if ( elem[ dataUser.expando ] ) {
5397
5398					// Support: Chrome <= 35-45+
5399					// Assign undefined instead of using delete, see Data#remove
5400					elem[ dataUser.expando ] = undefined;
5401				}
5402			}
5403		}
5404	}
5405} );
5406
5407jQuery.fn.extend( {
5408
5409	// Keep domManip exposed until 3.0 (gh-2225)
5410	domManip: domManip,
5411
5412	detach: function( selector ) {
5413		return remove( this, selector, true );
5414	},
5415
5416	remove: function( selector ) {
5417		return remove( this, selector );
5418	},
5419
5420	text: function( value ) {
5421		return access( this, function( value ) {
5422			return value === undefined ?
5423				jQuery.text( this ) :
5424				this.empty().each( function() {
5425					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5426						this.textContent = value;
5427					}
5428				} );
5429		}, null, value, arguments.length );
5430	},
5431
5432	append: function() {
5433		return domManip( this, arguments, function( elem ) {
5434			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5435				var target = manipulationTarget( this, elem );
5436				target.appendChild( elem );
5437			}
5438		} );
5439	},
5440
5441	prepend: function() {
5442		return domManip( this, arguments, function( elem ) {
5443			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5444				var target = manipulationTarget( this, elem );
5445				target.insertBefore( elem, target.firstChild );
5446			}
5447		} );
5448	},
5449
5450	before: function() {
5451		return domManip( this, arguments, function( elem ) {
5452			if ( this.parentNode ) {
5453				this.parentNode.insertBefore( elem, this );
5454			}
5455		} );
5456	},
5457
5458	after: function() {
5459		return domManip( this, arguments, function( elem ) {
5460			if ( this.parentNode ) {
5461				this.parentNode.insertBefore( elem, this.nextSibling );
5462			}
5463		} );
5464	},
5465
5466	empty: function() {
5467		var elem,
5468			i = 0;
5469
5470		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5471			if ( elem.nodeType === 1 ) {
5472
5473				// Prevent memory leaks
5474				jQuery.cleanData( getAll( elem, false ) );
5475
5476				// Remove any remaining nodes
5477				elem.textContent = "";
5478			}
5479		}
5480
5481		return this;
5482	},
5483
5484	clone: function( dataAndEvents, deepDataAndEvents ) {
5485		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5486		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5487
5488		return this.map( function() {
5489			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5490		} );
5491	},
5492
5493	html: function( value ) {
5494		return access( this, function( value ) {
5495			var elem = this[ 0 ] || {},
5496				i = 0,
5497				l = this.length;
5498
5499			if ( value === undefined && elem.nodeType === 1 ) {
5500				return elem.innerHTML;
5501			}
5502
5503			// See if we can take a shortcut and just use innerHTML
5504			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5505				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5506
5507				value = jQuery.htmlPrefilter( value );
5508
5509				try {
5510					for ( ; i < l; i++ ) {
5511						elem = this[ i ] || {};
5512
5513						// Remove element nodes and prevent memory leaks
5514						if ( elem.nodeType === 1 ) {
5515							jQuery.cleanData( getAll( elem, false ) );
5516							elem.innerHTML = value;
5517						}
5518					}
5519
5520					elem = 0;
5521
5522				// If using innerHTML throws an exception, use the fallback method
5523				} catch ( e ) {}
5524			}
5525
5526			if ( elem ) {
5527				this.empty().append( value );
5528			}
5529		}, null, value, arguments.length );
5530	},
5531
5532	replaceWith: function() {
5533		var ignored = [];
5534
5535		// Make the changes, replacing each non-ignored context element with the new content
5536		return domManip( this, arguments, function( elem ) {
5537			var parent = this.parentNode;
5538
5539			if ( jQuery.inArray( this, ignored ) < 0 ) {
5540				jQuery.cleanData( getAll( this ) );
5541				if ( parent ) {
5542					parent.replaceChild( elem, this );
5543				}
5544			}
5545
5546		// Force callback invocation
5547		}, ignored );
5548	}
5549} );
5550
5551jQuery.each( {
5552	appendTo: "append",
5553	prependTo: "prepend",
5554	insertBefore: "before",
5555	insertAfter: "after",
5556	replaceAll: "replaceWith"
5557}, function( name, original ) {
5558	jQuery.fn[ name ] = function( selector ) {
5559		var elems,
5560			ret = [],
5561			insert = jQuery( selector ),
5562			last = insert.length - 1,
5563			i = 0;
5564
5565		for ( ; i <= last; i++ ) {
5566			elems = i === last ? this : this.clone( true );
5567			jQuery( insert[ i ] )[ original ]( elems );
5568
5569			// Support: QtWebKit
5570			// .get() because push.apply(_, arraylike) throws
5571			push.apply( ret, elems.get() );
5572		}
5573
5574		return this.pushStack( ret );
5575	};
5576} );
5577
5578
5579var iframe,
5580	elemdisplay = {
5581
5582		// Support: Firefox
5583		// We have to pre-define these values for FF (#10227)
5584		HTML: "block",
5585		BODY: "block"
5586	};
5587
5588/**
5589 * Retrieve the actual display of a element
5590 * @param {String} name nodeName of the element
5591 * @param {Object} doc Document object
5592 */
5593
5594// Called only from within defaultDisplay
5595function actualDisplay( name, doc ) {
5596	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5597
5598		display = jQuery.css( elem[ 0 ], "display" );
5599
5600	// We don't have any data stored on the element,
5601	// so use "detach" method as fast way to get rid of the element
5602	elem.detach();
5603
5604	return display;
5605}
5606
5607/**
5608 * Try to determine the default display value of an element
5609 * @param {String} nodeName
5610 */
5611function defaultDisplay( nodeName ) {
5612	var doc = document,
5613		display = elemdisplay[ nodeName ];
5614
5615	if ( !display ) {
5616		display = actualDisplay( nodeName, doc );
5617
5618		// If the simple way fails, read from inside an iframe
5619		if ( display === "none" || !display ) {
5620
5621			// Use the already-created iframe if possible
5622			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
5623				.appendTo( doc.documentElement );
5624
5625			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5626			doc = iframe[ 0 ].contentDocument;
5627
5628			// Support: IE
5629			doc.write();
5630			doc.close();
5631
5632			display = actualDisplay( nodeName, doc );
5633			iframe.detach();
5634		}
5635
5636		// Store the correct default display
5637		elemdisplay[ nodeName ] = display;
5638	}
5639
5640	return display;
5641}
5642var rmargin = ( /^margin/ );
5643
5644var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5645
5646var getStyles = function( elem ) {
5647
5648		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5649		// IE throws on elements created in popups
5650		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5651		var view = elem.ownerDocument.defaultView;
5652
5653		if ( !view || !view.opener ) {
5654			view = window;
5655		}
5656
5657		return view.getComputedStyle( elem );
5658	};
5659
5660var swap = function( elem, options, callback, args ) {
5661	var ret, name,
5662		old = {};
5663
5664	// Remember the old values, and insert the new ones
5665	for ( name in options ) {
5666		old[ name ] = elem.style[ name ];
5667		elem.style[ name ] = options[ name ];
5668	}
5669
5670	ret = callback.apply( elem, args || [] );
5671
5672	// Revert the old values
5673	for ( name in options ) {
5674		elem.style[ name ] = old[ name ];
5675	}
5676
5677	return ret;
5678};
5679
5680
5681var documentElement = document.documentElement;
5682
5683
5684
5685( function() {
5686	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
5687		container = document.createElement( "div" ),
5688		div = document.createElement( "div" );
5689
5690	// Finish early in limited (non-browser) environments
5691	if ( !div.style ) {
5692		return;
5693	}
5694
5695	// Support: IE9-11+
5696	// Style of cloned element affects source element cloned (#8908)
5697	div.style.backgroundClip = "content-box";
5698	div.cloneNode( true ).style.backgroundClip = "";
5699	support.clearCloneStyle = div.style.backgroundClip === "content-box";
5700
5701	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
5702		"padding:0;margin-top:1px;position:absolute";
5703	container.appendChild( div );
5704
5705	// Executing both pixelPosition & boxSizingReliable tests require only one layout
5706	// so they're executed at the same time to save the second computation.
5707	function computeStyleTests() {
5708		div.style.cssText =
5709
5710			// Support: Firefox<29, Android 2.3
5711			// Vendor-prefix box-sizing
5712			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
5713			"position:relative;display:block;" +
5714			"margin:auto;border:1px;padding:1px;" +
5715			"top:1%;width:50%";
5716		div.innerHTML = "";
5717		documentElement.appendChild( container );
5718
5719		var divStyle = window.getComputedStyle( div );
5720		pixelPositionVal = divStyle.top !== "1%";
5721		reliableMarginLeftVal = divStyle.marginLeft === "2px";
5722		boxSizingReliableVal = divStyle.width === "4px";
5723
5724		// Support: Android 4.0 - 4.3 only
5725		// Some styles come back with percentage values, even though they shouldn't
5726		div.style.marginRight = "50%";
5727		pixelMarginRightVal = divStyle.marginRight === "4px";
5728
5729		documentElement.removeChild( container );
5730	}
5731
5732	jQuery.extend( support, {
5733		pixelPosition: function() {
5734
5735			// This test is executed only once but we still do memoizing
5736			// since we can use the boxSizingReliable pre-computing.
5737			// No need to check if the test was already performed, though.
5738			computeStyleTests();
5739			return pixelPositionVal;
5740		},
5741		boxSizingReliable: function() {
5742			if ( boxSizingReliableVal == null ) {
5743				computeStyleTests();
5744			}
5745			return boxSizingReliableVal;
5746		},
5747		pixelMarginRight: function() {
5748
5749			// Support: Android 4.0-4.3
5750			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
5751			// since that compresses better and they're computed together anyway.
5752			if ( boxSizingReliableVal == null ) {
5753				computeStyleTests();
5754			}
5755			return pixelMarginRightVal;
5756		},
5757		reliableMarginLeft: function() {
5758
5759			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
5760			if ( boxSizingReliableVal == null ) {
5761				computeStyleTests();
5762			}
5763			return reliableMarginLeftVal;
5764		},
5765		reliableMarginRight: function() {
5766
5767			// Support: Android 2.3
5768			// Check if div with explicit width and no margin-right incorrectly
5769			// gets computed margin-right based on width of container. (#3333)
5770			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5771			// This support function is only executed once so no memoizing is needed.
5772			var ret,
5773				marginDiv = div.appendChild( document.createElement( "div" ) );
5774
5775			// Reset CSS: box-sizing; display; margin; border; padding
5776			marginDiv.style.cssText = div.style.cssText =
5777
5778				// Support: Android 2.3
5779				// Vendor-prefix box-sizing
5780				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
5781				"display:block;margin:0;border:0;padding:0";
5782			marginDiv.style.marginRight = marginDiv.style.width = "0";
5783			div.style.width = "1px";
5784			documentElement.appendChild( container );
5785
5786			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
5787
5788			documentElement.removeChild( container );
5789			div.removeChild( marginDiv );
5790
5791			return ret;
5792		}
5793	} );
5794} )();
5795
5796
5797function curCSS( elem, name, computed ) {
5798	var width, minWidth, maxWidth, ret,
5799		style = elem.style;
5800
5801	computed = computed || getStyles( elem );
5802	ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
5803
5804	// Support: Opera 12.1x only
5805	// Fall back to style even without computed
5806	// computed is undefined for elems on document fragments
5807	if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
5808		ret = jQuery.style( elem, name );
5809	}
5810
5811	// Support: IE9
5812	// getPropertyValue is only needed for .css('filter') (#12537)
5813	if ( computed ) {
5814
5815		// A tribute to the "awesome hack by Dean Edwards"
5816		// Android Browser returns percentage for some values,
5817		// but width seems to be reliably pixels.
5818		// This is against the CSSOM draft spec:
5819		// http://dev.w3.org/csswg/cssom/#resolved-values
5820		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5821
5822			// Remember the original values
5823			width = style.width;
5824			minWidth = style.minWidth;
5825			maxWidth = style.maxWidth;
5826
5827			// Put in the new values to get a computed value out
5828			style.minWidth = style.maxWidth = style.width = ret;
5829			ret = computed.width;
5830
5831			// Revert the changed values
5832			style.width = width;
5833			style.minWidth = minWidth;
5834			style.maxWidth = maxWidth;
5835		}
5836	}
5837
5838	return ret !== undefined ?
5839
5840		// Support: IE9-11+
5841		// IE returns zIndex value as an integer.
5842		ret + "" :
5843		ret;
5844}
5845
5846
5847function addGetHookIf( conditionFn, hookFn ) {
5848
5849	// Define the hook, we'll check on the first run if it's really needed.
5850	return {
5851		get: function() {
5852			if ( conditionFn() ) {
5853
5854				// Hook not needed (or it's not possible to use it due
5855				// to missing dependency), remove it.
5856				delete this.get;
5857				return;
5858			}
5859
5860			// Hook needed; redefine it so that the support test is not executed again.
5861			return ( this.get = hookFn ).apply( this, arguments );
5862		}
5863	};
5864}
5865
5866
5867var
5868
5869	// Swappable if display is none or starts with table
5870	// except "table", "table-cell", or "table-caption"
5871	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5872	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5873
5874	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5875	cssNormalTransform = {
5876		letterSpacing: "0",
5877		fontWeight: "400"
5878	},
5879
5880	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
5881	emptyStyle = document.createElement( "div" ).style;
5882
5883// Return a css property mapped to a potentially vendor prefixed property
5884function vendorPropName( name ) {
5885
5886	// Shortcut for names that are not vendor prefixed
5887	if ( name in emptyStyle ) {
5888		return name;
5889	}
5890
5891	// Check for vendor prefixed names
5892	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
5893		i = cssPrefixes.length;
5894
5895	while ( i-- ) {
5896		name = cssPrefixes[ i ] + capName;
5897		if ( name in emptyStyle ) {
5898			return name;
5899		}
5900	}
5901}
5902
5903function setPositiveNumber( elem, value, subtract ) {
5904
5905	// Any relative (+/-) values have already been
5906	// normalized at this point
5907	var matches = rcssNum.exec( value );
5908	return matches ?
5909
5910		// Guard against undefined "subtract", e.g., when used as in cssHooks
5911		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
5912		value;
5913}
5914
5915function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5916	var i = extra === ( isBorderBox ? "border" : "content" ) ?
5917
5918		// If we already have the right measurement, avoid augmentation
5919		4 :
5920
5921		// Otherwise initialize for horizontal or vertical properties
5922		name === "width" ? 1 : 0,
5923
5924		val = 0;
5925
5926	for ( ; i < 4; i += 2 ) {
5927
5928		// Both box models exclude margin, so add it if we want it
5929		if ( extra === "margin" ) {
5930			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5931		}
5932
5933		if ( isBorderBox ) {
5934
5935			// border-box includes padding, so remove it if we want content
5936			if ( extra === "content" ) {
5937				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5938			}
5939
5940			// At this point, extra isn't border nor margin, so remove border
5941			if ( extra !== "margin" ) {
5942				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5943			}
5944		} else {
5945
5946			// At this point, extra isn't content, so add padding
5947			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5948
5949			// At this point, extra isn't content nor padding, so add border
5950			if ( extra !== "padding" ) {
5951				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5952			}
5953		}
5954	}
5955
5956	return val;
5957}
5958
5959function getWidthOrHeight( elem, name, extra ) {
5960
5961	// Start with offset property, which is equivalent to the border-box value
5962	var valueIsBorderBox = true,
5963		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5964		styles = getStyles( elem ),
5965		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5966
5967	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
5968	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5969	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5970	if ( val <= 0 || val == null ) {
5971
5972		// Fall back to computed then uncomputed css if necessary
5973		val = curCSS( elem, name, styles );
5974		if ( val < 0 || val == null ) {
5975			val = elem.style[ name ];
5976		}
5977
5978		// Computed unit is not pixels. Stop here and return.
5979		if ( rnumnonpx.test( val ) ) {
5980			return val;
5981		}
5982
5983		// Check for style in case a browser which returns unreliable values
5984		// for getComputedStyle silently falls back to the reliable elem.style
5985		valueIsBorderBox = isBorderBox &&
5986			( support.boxSizingReliable() || val === elem.style[ name ] );
5987
5988		// Normalize "", auto, and prepare for extra
5989		val = parseFloat( val ) || 0;
5990	}
5991
5992	// Use the active box-sizing model to add/subtract irrelevant styles
5993	return ( val +
5994		augmentWidthOrHeight(
5995			elem,
5996			name,
5997			extra || ( isBorderBox ? "border" : "content" ),
5998			valueIsBorderBox,
5999			styles
6000		)
6001	) + "px";
6002}
6003
6004function showHide( elements, show ) {
6005	var display, elem, hidden,
6006		values = [],
6007		index = 0,
6008		length = elements.length;
6009
6010	for ( ; index < length; index++ ) {
6011		elem = elements[ index ];
6012		if ( !elem.style ) {
6013			continue;
6014		}
6015
6016		values[ index ] = dataPriv.get( elem, "olddisplay" );
6017		display = elem.style.display;
6018		if ( show ) {
6019
6020			// Reset the inline display of this element to learn if it is
6021			// being hidden by cascaded rules or not
6022			if ( !values[ index ] && display === "none" ) {
6023				elem.style.display = "";
6024			}
6025
6026			// Set elements which have been overridden with display: none
6027			// in a stylesheet to whatever the default browser style is
6028			// for such an element
6029			if ( elem.style.display === "" && isHidden( elem ) ) {
6030				values[ index ] = dataPriv.access(
6031					elem,
6032					"olddisplay",
6033					defaultDisplay( elem.nodeName )
6034				);
6035			}
6036		} else {
6037			hidden = isHidden( elem );
6038
6039			if ( display !== "none" || !hidden ) {
6040				dataPriv.set(
6041					elem,
6042					"olddisplay",
6043					hidden ? display : jQuery.css( elem, "display" )
6044				);
6045			}
6046		}
6047	}
6048
6049	// Set the display of most of the elements in a second loop
6050	// to avoid the constant reflow
6051	for ( index = 0; index < length; index++ ) {
6052		elem = elements[ index ];
6053		if ( !elem.style ) {
6054			continue;
6055		}
6056		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6057			elem.style.display = show ? values[ index ] || "" : "none";
6058		}
6059	}
6060
6061	return elements;
6062}
6063
6064jQuery.extend( {
6065
6066	// Add in style property hooks for overriding the default
6067	// behavior of getting and setting a style property
6068	cssHooks: {
6069		opacity: {
6070			get: function( elem, computed ) {
6071				if ( computed ) {
6072
6073					// We should always get a number back from opacity
6074					var ret = curCSS( elem, "opacity" );
6075					return ret === "" ? "1" : ret;
6076				}
6077			}
6078		}
6079	},
6080
6081	// Don't automatically add "px" to these possibly-unitless properties
6082	cssNumber: {
6083		"animationIterationCount": true,
6084		"columnCount": true,
6085		"fillOpacity": true,
6086		"flexGrow": true,
6087		"flexShrink": true,
6088		"fontWeight": true,
6089		"lineHeight": true,
6090		"opacity": true,
6091		"order": true,
6092		"orphans": true,
6093		"widows": true,
6094		"zIndex": true,
6095		"zoom": true
6096	},
6097
6098	// Add in properties whose names you wish to fix before
6099	// setting or getting the value
6100	cssProps: {
6101		"float": "cssFloat"
6102	},
6103
6104	// Get and set the style property on a DOM Node
6105	style: function( elem, name, value, extra ) {
6106
6107		// Don't set styles on text and comment nodes
6108		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6109			return;
6110		}
6111
6112		// Make sure that we're working with the right name
6113		var ret, type, hooks,
6114			origName = jQuery.camelCase( name ),
6115			style = elem.style;
6116
6117		name = jQuery.cssProps[ origName ] ||
6118			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6119
6120		// Gets hook for the prefixed version, then unprefixed version
6121		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6122
6123		// Check if we're setting a value
6124		if ( value !== undefined ) {
6125			type = typeof value;
6126
6127			// Convert "+=" or "-=" to relative numbers (#7345)
6128			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6129				value = adjustCSS( elem, name, ret );
6130
6131				// Fixes bug #9237
6132				type = "number";
6133			}
6134
6135			// Make sure that null and NaN values aren't set (#7116)
6136			if ( value == null || value !== value ) {
6137				return;
6138			}
6139
6140			// If a number was passed in, add the unit (except for certain CSS properties)
6141			if ( type === "number" ) {
6142				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6143			}
6144
6145			// Support: IE9-11+
6146			// background-* props affect original clone's values
6147			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6148				style[ name ] = "inherit";
6149			}
6150
6151			// If a hook was provided, use that value, otherwise just set the specified value
6152			if ( !hooks || !( "set" in hooks ) ||
6153				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6154
6155				style[ name ] = value;
6156			}
6157
6158		} else {
6159
6160			// If a hook was provided get the non-computed value from there
6161			if ( hooks && "get" in hooks &&
6162				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6163
6164				return ret;
6165			}
6166
6167			// Otherwise just get the value from the style object
6168			return style[ name ];
6169		}
6170	},
6171
6172	css: function( elem, name, extra, styles ) {
6173		var val, num, hooks,
6174			origName = jQuery.camelCase( name );
6175
6176		// Make sure that we're working with the right name
6177		name = jQuery.cssProps[ origName ] ||
6178			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6179
6180		// Try prefixed name followed by the unprefixed name
6181		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6182
6183		// If a hook was provided get the computed value from there
6184		if ( hooks && "get" in hooks ) {
6185			val = hooks.get( elem, true, extra );
6186		}
6187
6188		// Otherwise, if a way to get the computed value exists, use that
6189		if ( val === undefined ) {
6190			val = curCSS( elem, name, styles );
6191		}
6192
6193		// Convert "normal" to computed value
6194		if ( val === "normal" && name in cssNormalTransform ) {
6195			val = cssNormalTransform[ name ];
6196		}
6197
6198		// Make numeric if forced or a qualifier was provided and val looks numeric
6199		if ( extra === "" || extra ) {
6200			num = parseFloat( val );
6201			return extra === true || isFinite( num ) ? num || 0 : val;
6202		}
6203		return val;
6204	}
6205} );
6206
6207jQuery.each( [ "height", "width" ], function( i, name ) {
6208	jQuery.cssHooks[ name ] = {
6209		get: function( elem, computed, extra ) {
6210			if ( computed ) {
6211
6212				// Certain elements can have dimension info if we invisibly show them
6213				// but it must have a current display style that would benefit
6214				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6215					elem.offsetWidth === 0 ?
6216						swap( elem, cssShow, function() {
6217							return getWidthOrHeight( elem, name, extra );
6218						} ) :
6219						getWidthOrHeight( elem, name, extra );
6220			}
6221		},
6222
6223		set: function( elem, value, extra ) {
6224			var matches,
6225				styles = extra && getStyles( elem ),
6226				subtract = extra && augmentWidthOrHeight(
6227					elem,
6228					name,
6229					extra,
6230					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6231					styles
6232				);
6233
6234			// Convert to pixels if value adjustment is needed
6235			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6236				( matches[ 3 ] || "px" ) !== "px" ) {
6237
6238				elem.style[ name ] = value;
6239				value = jQuery.css( elem, name );
6240			}
6241
6242			return setPositiveNumber( elem, value, subtract );
6243		}
6244	};
6245} );
6246
6247jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6248	function( elem, computed ) {
6249		if ( computed ) {
6250			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6251				elem.getBoundingClientRect().left -
6252					swap( elem, { marginLeft: 0 }, function() {
6253						return elem.getBoundingClientRect().left;
6254					} )
6255				) + "px";
6256		}
6257	}
6258);
6259
6260// Support: Android 2.3
6261jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6262	function( elem, computed ) {
6263		if ( computed ) {
6264			return swap( elem, { "display": "inline-block" },
6265				curCSS, [ elem, "marginRight" ] );
6266		}
6267	}
6268);
6269
6270// These hooks are used by animate to expand properties
6271jQuery.each( {
6272	margin: "",
6273	padding: "",
6274	border: "Width"
6275}, function( prefix, suffix ) {
6276	jQuery.cssHooks[ prefix + suffix ] = {
6277		expand: function( value ) {
6278			var i = 0,
6279				expanded = {},
6280
6281				// Assumes a single number if not a string
6282				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6283
6284			for ( ; i < 4; i++ ) {
6285				expanded[ prefix + cssExpand[ i ] + suffix ] =
6286					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6287			}
6288
6289			return expanded;
6290		}
6291	};
6292
6293	if ( !rmargin.test( prefix ) ) {
6294		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6295	}
6296} );
6297
6298jQuery.fn.extend( {
6299	css: function( name, value ) {
6300		return access( this, function( elem, name, value ) {
6301			var styles, len,
6302				map = {},
6303				i = 0;
6304
6305			if ( jQuery.isArray( name ) ) {
6306				styles = getStyles( elem );
6307				len = name.length;
6308
6309				for ( ; i < len; i++ ) {
6310					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6311				}
6312
6313				return map;
6314			}
6315
6316			return value !== undefined ?
6317				jQuery.style( elem, name, value ) :
6318				jQuery.css( elem, name );
6319		}, name, value, arguments.length > 1 );
6320	},
6321	show: function() {
6322		return showHide( this, true );
6323	},
6324	hide: function() {
6325		return showHide( this );
6326	},
6327	toggle: function( state ) {
6328		if ( typeof state === "boolean" ) {
6329			return state ? this.show() : this.hide();
6330		}
6331
6332		return this.each( function() {
6333			if ( isHidden( this ) ) {
6334				jQuery( this ).show();
6335			} else {
6336				jQuery( this ).hide();
6337			}
6338		} );
6339	}
6340} );
6341
6342
6343function Tween( elem, options, prop, end, easing ) {
6344	return new Tween.prototype.init( elem, options, prop, end, easing );
6345}
6346jQuery.Tween = Tween;
6347
6348Tween.prototype = {
6349	constructor: Tween,
6350	init: function( elem, options, prop, end, easing, unit ) {
6351		this.elem = elem;
6352		this.prop = prop;
6353		this.easing = easing || jQuery.easing._default;
6354		this.options = options;
6355		this.start = this.now = this.cur();
6356		this.end = end;
6357		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6358	},
6359	cur: function() {
6360		var hooks = Tween.propHooks[ this.prop ];
6361
6362		return hooks && hooks.get ?
6363			hooks.get( this ) :
6364			Tween.propHooks._default.get( this );
6365	},
6366	run: function( percent ) {
6367		var eased,
6368			hooks = Tween.propHooks[ this.prop ];
6369
6370		if ( this.options.duration ) {
6371			this.pos = eased = jQuery.easing[ this.easing ](
6372				percent, this.options.duration * percent, 0, 1, this.options.duration
6373			);
6374		} else {
6375			this.pos = eased = percent;
6376		}
6377		this.now = ( this.end - this.start ) * eased + this.start;
6378
6379		if ( this.options.step ) {
6380			this.options.step.call( this.elem, this.now, this );
6381		}
6382
6383		if ( hooks && hooks.set ) {
6384			hooks.set( this );
6385		} else {
6386			Tween.propHooks._default.set( this );
6387		}
6388		return this;
6389	}
6390};
6391
6392Tween.prototype.init.prototype = Tween.prototype;
6393
6394Tween.propHooks = {
6395	_default: {
6396		get: function( tween ) {
6397			var result;
6398
6399			// Use a property on the element directly when it is not a DOM element,
6400			// or when there is no matching style property that exists.
6401			if ( tween.elem.nodeType !== 1 ||
6402				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6403				return tween.elem[ tween.prop ];
6404			}
6405
6406			// Passing an empty string as a 3rd parameter to .css will automatically
6407			// attempt a parseFloat and fallback to a string if the parse fails.
6408			// Simple values such as "10px" are parsed to Float;
6409			// complex values such as "rotate(1rad)" are returned as-is.
6410			result = jQuery.css( tween.elem, tween.prop, "" );
6411
6412			// Empty strings, null, undefined and "auto" are converted to 0.
6413			return !result || result === "auto" ? 0 : result;
6414		},
6415		set: function( tween ) {
6416
6417			// Use step hook for back compat.
6418			// Use cssHook if its there.
6419			// Use .style if available and use plain properties where available.
6420			if ( jQuery.fx.step[ tween.prop ] ) {
6421				jQuery.fx.step[ tween.prop ]( tween );
6422			} else if ( tween.elem.nodeType === 1 &&
6423				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6424					jQuery.cssHooks[ tween.prop ] ) ) {
6425				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6426			} else {
6427				tween.elem[ tween.prop ] = tween.now;
6428			}
6429		}
6430	}
6431};
6432
6433// Support: IE9
6434// Panic based approach to setting things on disconnected nodes
6435Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6436	set: function( tween ) {
6437		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6438			tween.elem[ tween.prop ] = tween.now;
6439		}
6440	}
6441};
6442
6443jQuery.easing = {
6444	linear: function( p ) {
6445		return p;
6446	},
6447	swing: function( p ) {
6448		return 0.5 - Math.cos( p * Math.PI ) / 2;
6449	},
6450	_default: "swing"
6451};
6452
6453jQuery.fx = Tween.prototype.init;
6454
6455// Back Compat <1.8 extension point
6456jQuery.fx.step = {};
6457
6458
6459
6460
6461var
6462	fxNow, timerId,
6463	rfxtypes = /^(?:toggle|show|hide)$/,
6464	rrun = /queueHooks$/;
6465
6466// Animations created synchronously will run synchronously
6467function createFxNow() {
6468	window.setTimeout( function() {
6469		fxNow = undefined;
6470	} );
6471	return ( fxNow = jQuery.now() );
6472}
6473
6474// Generate parameters to create a standard animation
6475function genFx( type, includeWidth ) {
6476	var which,
6477		i = 0,
6478		attrs = { height: type };
6479
6480	// If we include width, step value is 1 to do all cssExpand values,
6481	// otherwise step value is 2 to skip over Left and Right
6482	includeWidth = includeWidth ? 1 : 0;
6483	for ( ; i < 4 ; i += 2 - includeWidth ) {
6484		which = cssExpand[ i ];
6485		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6486	}
6487
6488	if ( includeWidth ) {
6489		attrs.opacity = attrs.width = type;
6490	}
6491
6492	return attrs;
6493}
6494
6495function createTween( value, prop, animation ) {
6496	var tween,
6497		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6498		index = 0,
6499		length = collection.length;
6500	for ( ; index < length; index++ ) {
6501		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6502
6503			// We're done with this property
6504			return tween;
6505		}
6506	}
6507}
6508
6509function defaultPrefilter( elem, props, opts ) {
6510	/* jshint validthis: true */
6511	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6512		anim = this,
6513		orig = {},
6514		style = elem.style,
6515		hidden = elem.nodeType && isHidden( elem ),
6516		dataShow = dataPriv.get( elem, "fxshow" );
6517
6518	// Handle queue: false promises
6519	if ( !opts.queue ) {
6520		hooks = jQuery._queueHooks( elem, "fx" );
6521		if ( hooks.unqueued == null ) {
6522			hooks.unqueued = 0;
6523			oldfire = hooks.empty.fire;
6524			hooks.empty.fire = function() {
6525				if ( !hooks.unqueued ) {
6526					oldfire();
6527				}
6528			};
6529		}
6530		hooks.unqueued++;
6531
6532		anim.always( function() {
6533
6534			// Ensure the complete handler is called before this completes
6535			anim.always( function() {
6536				hooks.unqueued--;
6537				if ( !jQuery.queue( elem, "fx" ).length ) {
6538					hooks.empty.fire();
6539				}
6540			} );
6541		} );
6542	}
6543
6544	// Height/width overflow pass
6545	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6546
6547		// Make sure that nothing sneaks out
6548		// Record all 3 overflow attributes because IE9-10 do not
6549		// change the overflow attribute when overflowX and
6550		// overflowY are set to the same value
6551		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6552
6553		// Set display property to inline-block for height/width
6554		// animations on inline elements that are having width/height animated
6555		display = jQuery.css( elem, "display" );
6556
6557		// Test default display if display is currently "none"
6558		checkDisplay = display === "none" ?
6559			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6560
6561		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6562			style.display = "inline-block";
6563		}
6564	}
6565
6566	if ( opts.overflow ) {
6567		style.overflow = "hidden";
6568		anim.always( function() {
6569			style.overflow = opts.overflow[ 0 ];
6570			style.overflowX = opts.overflow[ 1 ];
6571			style.overflowY = opts.overflow[ 2 ];
6572		} );
6573	}
6574
6575	// show/hide pass
6576	for ( prop in props ) {
6577		value = props[ prop ];
6578		if ( rfxtypes.exec( value ) ) {
6579			delete props[ prop ];
6580			toggle = toggle || value === "toggle";
6581			if ( value === ( hidden ? "hide" : "show" ) ) {
6582
6583				// If there is dataShow left over from a stopped hide or show
6584				// and we are going to proceed with show, we should pretend to be hidden
6585				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6586					hidden = true;
6587				} else {
6588					continue;
6589				}
6590			}
6591			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6592
6593		// Any non-fx value stops us from restoring the original display value
6594		} else {
6595			display = undefined;
6596		}
6597	}
6598
6599	if ( !jQuery.isEmptyObject( orig ) ) {
6600		if ( dataShow ) {
6601			if ( "hidden" in dataShow ) {
6602				hidden = dataShow.hidden;
6603			}
6604		} else {
6605			dataShow = dataPriv.access( elem, "fxshow", {} );
6606		}
6607
6608		// Store state if its toggle - enables .stop().toggle() to "reverse"
6609		if ( toggle ) {
6610			dataShow.hidden = !hidden;
6611		}
6612		if ( hidden ) {
6613			jQuery( elem ).show();
6614		} else {
6615			anim.done( function() {
6616				jQuery( elem ).hide();
6617			} );
6618		}
6619		anim.done( function() {
6620			var prop;
6621
6622			dataPriv.remove( elem, "fxshow" );
6623			for ( prop in orig ) {
6624				jQuery.style( elem, prop, orig[ prop ] );
6625			}
6626		} );
6627		for ( prop in orig ) {
6628			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6629
6630			if ( !( prop in dataShow ) ) {
6631				dataShow[ prop ] = tween.start;
6632				if ( hidden ) {
6633					tween.end = tween.start;
6634					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6635				}
6636			}
6637		}
6638
6639	// If this is a noop like .hide().hide(), restore an overwritten display value
6640	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
6641		style.display = display;
6642	}
6643}
6644
6645function propFilter( props, specialEasing ) {
6646	var index, name, easing, value, hooks;
6647
6648	// camelCase, specialEasing and expand cssHook pass
6649	for ( index in props ) {
6650		name = jQuery.camelCase( index );
6651		easing = specialEasing[ name ];
6652		value = props[ index ];
6653		if ( jQuery.isArray( value ) ) {
6654			easing = value[ 1 ];
6655			value = props[ index ] = value[ 0 ];
6656		}
6657
6658		if ( index !== name ) {
6659			props[ name ] = value;
6660			delete props[ index ];
6661		}
6662
6663		hooks = jQuery.cssHooks[ name ];
6664		if ( hooks && "expand" in hooks ) {
6665			value = hooks.expand( value );
6666			delete props[ name ];
6667
6668			// Not quite $.extend, this won't overwrite existing keys.
6669			// Reusing 'index' because we have the correct "name"
6670			for ( index in value ) {
6671				if ( !( index in props ) ) {
6672					props[ index ] = value[ index ];
6673					specialEasing[ index ] = easing;
6674				}
6675			}
6676		} else {
6677			specialEasing[ name ] = easing;
6678		}
6679	}
6680}
6681
6682function Animation( elem, properties, options ) {
6683	var result,
6684		stopped,
6685		index = 0,
6686		length = Animation.prefilters.length,
6687		deferred = jQuery.Deferred().always( function() {
6688
6689			// Don't match elem in the :animated selector
6690			delete tick.elem;
6691		} ),
6692		tick = function() {
6693			if ( stopped ) {
6694				return false;
6695			}
6696			var currentTime = fxNow || createFxNow(),
6697				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6698
6699				// Support: Android 2.3
6700				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6701				temp = remaining / animation.duration || 0,
6702				percent = 1 - temp,
6703				index = 0,
6704				length = animation.tweens.length;
6705
6706			for ( ; index < length ; index++ ) {
6707				animation.tweens[ index ].run( percent );
6708			}
6709
6710			deferred.notifyWith( elem, [ animation, percent, remaining ] );
6711
6712			if ( percent < 1 && length ) {
6713				return remaining;
6714			} else {
6715				deferred.resolveWith( elem, [ animation ] );
6716				return false;
6717			}
6718		},
6719		animation = deferred.promise( {
6720			elem: elem,
6721			props: jQuery.extend( {}, properties ),
6722			opts: jQuery.extend( true, {
6723				specialEasing: {},
6724				easing: jQuery.easing._default
6725			}, options ),
6726			originalProperties: properties,
6727			originalOptions: options,
6728			startTime: fxNow || createFxNow(),
6729			duration: options.duration,
6730			tweens: [],
6731			createTween: function( prop, end ) {
6732				var tween = jQuery.Tween( elem, animation.opts, prop, end,
6733						animation.opts.specialEasing[ prop ] || animation.opts.easing );
6734				animation.tweens.push( tween );
6735				return tween;
6736			},
6737			stop: function( gotoEnd ) {
6738				var index = 0,
6739
6740					// If we are going to the end, we want to run all the tweens
6741					// otherwise we skip this part
6742					length = gotoEnd ? animation.tweens.length : 0;
6743				if ( stopped ) {
6744					return this;
6745				}
6746				stopped = true;
6747				for ( ; index < length ; index++ ) {
6748					animation.tweens[ index ].run( 1 );
6749				}
6750
6751				// Resolve when we played the last frame; otherwise, reject
6752				if ( gotoEnd ) {
6753					deferred.notifyWith( elem, [ animation, 1, 0 ] );
6754					deferred.resolveWith( elem, [ animation, gotoEnd ] );
6755				} else {
6756					deferred.rejectWith( elem, [ animation, gotoEnd ] );
6757				}
6758				return this;
6759			}
6760		} ),
6761		props = animation.props;
6762
6763	propFilter( props, animation.opts.specialEasing );
6764
6765	for ( ; index < length ; index++ ) {
6766		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
6767		if ( result ) {
6768			if ( jQuery.isFunction( result.stop ) ) {
6769				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
6770					jQuery.proxy( result.stop, result );
6771			}
6772			return result;
6773		}
6774	}
6775
6776	jQuery.map( props, createTween, animation );
6777
6778	if ( jQuery.isFunction( animation.opts.start ) ) {
6779		animation.opts.start.call( elem, animation );
6780	}
6781
6782	jQuery.fx.timer(
6783		jQuery.extend( tick, {
6784			elem: elem,
6785			anim: animation,
6786			queue: animation.opts.queue
6787		} )
6788	);
6789
6790	// attach callbacks from options
6791	return animation.progress( animation.opts.progress )
6792		.done( animation.opts.done, animation.opts.complete )
6793		.fail( animation.opts.fail )
6794		.always( animation.opts.always );
6795}
6796
6797jQuery.Animation = jQuery.extend( Animation, {
6798	tweeners: {
6799		"*": [ function( prop, value ) {
6800			var tween = this.createTween( prop, value );
6801			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
6802			return tween;
6803		} ]
6804	},
6805
6806	tweener: function( props, callback ) {
6807		if ( jQuery.isFunction( props ) ) {
6808			callback = props;
6809			props = [ "*" ];
6810		} else {
6811			props = props.match( rnotwhite );
6812		}
6813
6814		var prop,
6815			index = 0,
6816			length = props.length;
6817
6818		for ( ; index < length ; index++ ) {
6819			prop = props[ index ];
6820			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
6821			Animation.tweeners[ prop ].unshift( callback );
6822		}
6823	},
6824
6825	prefilters: [ defaultPrefilter ],
6826
6827	prefilter: function( callback, prepend ) {
6828		if ( prepend ) {
6829			Animation.prefilters.unshift( callback );
6830		} else {
6831			Animation.prefilters.push( callback );
6832		}
6833	}
6834} );
6835
6836jQuery.speed = function( speed, easing, fn ) {
6837	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6838		complete: fn || !fn && easing ||
6839			jQuery.isFunction( speed ) && speed,
6840		duration: speed,
6841		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6842	};
6843
6844	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
6845		opt.duration : opt.duration in jQuery.fx.speeds ?
6846			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6847
6848	// Normalize opt.queue - true/undefined/null -> "fx"
6849	if ( opt.queue == null || opt.queue === true ) {
6850		opt.queue = "fx";
6851	}
6852
6853	// Queueing
6854	opt.old = opt.complete;
6855
6856	opt.complete = function() {
6857		if ( jQuery.isFunction( opt.old ) ) {
6858			opt.old.call( this );
6859		}
6860
6861		if ( opt.queue ) {
6862			jQuery.dequeue( this, opt.queue );
6863		}
6864	};
6865
6866	return opt;
6867};
6868
6869jQuery.fn.extend( {
6870	fadeTo: function( speed, to, easing, callback ) {
6871
6872		// Show any hidden elements after setting opacity to 0
6873		return this.filter( isHidden ).css( "opacity", 0 ).show()
6874
6875			// Animate to the value specified
6876			.end().animate( { opacity: to }, speed, easing, callback );
6877	},
6878	animate: function( prop, speed, easing, callback ) {
6879		var empty = jQuery.isEmptyObject( prop ),
6880			optall = jQuery.speed( speed, easing, callback ),
6881			doAnimation = function() {
6882
6883				// Operate on a copy of prop so per-property easing won't be lost
6884				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6885
6886				// Empty animations, or finishing resolves immediately
6887				if ( empty || dataPriv.get( this, "finish" ) ) {
6888					anim.stop( true );
6889				}
6890			};
6891			doAnimation.finish = doAnimation;
6892
6893		return empty || optall.queue === false ?
6894			this.each( doAnimation ) :
6895			this.queue( optall.queue, doAnimation );
6896	},
6897	stop: function( type, clearQueue, gotoEnd ) {
6898		var stopQueue = function( hooks ) {
6899			var stop = hooks.stop;
6900			delete hooks.stop;
6901			stop( gotoEnd );
6902		};
6903
6904		if ( typeof type !== "string" ) {
6905			gotoEnd = clearQueue;
6906			clearQueue = type;
6907			type = undefined;
6908		}
6909		if ( clearQueue && type !== false ) {
6910			this.queue( type || "fx", [] );
6911		}
6912
6913		return this.each( function() {
6914			var dequeue = true,
6915				index = type != null && type + "queueHooks",
6916				timers = jQuery.timers,
6917				data = dataPriv.get( this );
6918
6919			if ( index ) {
6920				if ( data[ index ] && data[ index ].stop ) {
6921					stopQueue( data[ index ] );
6922				}
6923			} else {
6924				for ( index in data ) {
6925					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6926						stopQueue( data[ index ] );
6927					}
6928				}
6929			}
6930
6931			for ( index = timers.length; index--; ) {
6932				if ( timers[ index ].elem === this &&
6933					( type == null || timers[ index ].queue === type ) ) {
6934
6935					timers[ index ].anim.stop( gotoEnd );
6936					dequeue = false;
6937					timers.splice( index, 1 );
6938				}
6939			}
6940
6941			// Start the next in the queue if the last step wasn't forced.
6942			// Timers currently will call their complete callbacks, which
6943			// will dequeue but only if they were gotoEnd.
6944			if ( dequeue || !gotoEnd ) {
6945				jQuery.dequeue( this, type );
6946			}
6947		} );
6948	},
6949	finish: function( type ) {
6950		if ( type !== false ) {
6951			type = type || "fx";
6952		}
6953		return this.each( function() {
6954			var index,
6955				data = dataPriv.get( this ),
6956				queue = data[ type + "queue" ],
6957				hooks = data[ type + "queueHooks" ],
6958				timers = jQuery.timers,
6959				length = queue ? queue.length : 0;
6960
6961			// Enable finishing flag on private data
6962			data.finish = true;
6963
6964			// Empty the queue first
6965			jQuery.queue( this, type, [] );
6966
6967			if ( hooks && hooks.stop ) {
6968				hooks.stop.call( this, true );
6969			}
6970
6971			// Look for any active animations, and finish them
6972			for ( index = timers.length; index--; ) {
6973				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6974					timers[ index ].anim.stop( true );
6975					timers.splice( index, 1 );
6976				}
6977			}
6978
6979			// Look for any animations in the old queue and finish them
6980			for ( index = 0; index < length; index++ ) {
6981				if ( queue[ index ] && queue[ index ].finish ) {
6982					queue[ index ].finish.call( this );
6983				}
6984			}
6985
6986			// Turn off finishing flag
6987			delete data.finish;
6988		} );
6989	}
6990} );
6991
6992jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
6993	var cssFn = jQuery.fn[ name ];
6994	jQuery.fn[ name ] = function( speed, easing, callback ) {
6995		return speed == null || typeof speed === "boolean" ?
6996			cssFn.apply( this, arguments ) :
6997			this.animate( genFx( name, true ), speed, easing, callback );
6998	};
6999} );
7000
7001// Generate shortcuts for custom animations
7002jQuery.each( {
7003	slideDown: genFx( "show" ),
7004	slideUp: genFx( "hide" ),
7005	slideToggle: genFx( "toggle" ),
7006	fadeIn: { opacity: "show" },
7007	fadeOut: { opacity: "hide" },
7008	fadeToggle: { opacity: "toggle" }
7009}, function( name, props ) {
7010	jQuery.fn[ name ] = function( speed, easing, callback ) {
7011		return this.animate( props, speed, easing, callback );
7012	};
7013} );
7014
7015jQuery.timers = [];
7016jQuery.fx.tick = function() {
7017	var timer,
7018		i = 0,
7019		timers = jQuery.timers;
7020
7021	fxNow = jQuery.now();
7022
7023	for ( ; i < timers.length; i++ ) {
7024		timer = timers[ i ];
7025
7026		// Checks the timer has not already been removed
7027		if ( !timer() && timers[ i ] === timer ) {
7028			timers.splice( i--, 1 );
7029		}
7030	}
7031
7032	if ( !timers.length ) {
7033		jQuery.fx.stop();
7034	}
7035	fxNow = undefined;
7036};
7037
7038jQuery.fx.timer = function( timer ) {
7039	jQuery.timers.push( timer );
7040	if ( timer() ) {
7041		jQuery.fx.start();
7042	} else {
7043		jQuery.timers.pop();
7044	}
7045};
7046
7047jQuery.fx.interval = 13;
7048jQuery.fx.start = function() {
7049	if ( !timerId ) {
7050		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7051	}
7052};
7053
7054jQuery.fx.stop = function() {
7055	window.clearInterval( timerId );
7056
7057	timerId = null;
7058};
7059
7060jQuery.fx.speeds = {
7061	slow: 600,
7062	fast: 200,
7063
7064	// Default speed
7065	_default: 400
7066};
7067
7068
7069// Based off of the plugin by Clint Helfers, with permission.
7070// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7071jQuery.fn.delay = function( time, type ) {
7072	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7073	type = type || "fx";
7074
7075	return this.queue( type, function( next, hooks ) {
7076		var timeout = window.setTimeout( next, time );
7077		hooks.stop = function() {
7078			window.clearTimeout( timeout );
7079		};
7080	} );
7081};
7082
7083
7084( function() {
7085	var input = document.createElement( "input" ),
7086		select = document.createElement( "select" ),
7087		opt = select.appendChild( document.createElement( "option" ) );
7088
7089	input.type = "checkbox";
7090
7091	// Support: iOS<=5.1, Android<=4.2+
7092	// Default value for a checkbox should be "on"
7093	support.checkOn = input.value !== "";
7094
7095	// Support: IE<=11+
7096	// Must access selectedIndex to make default options select
7097	support.optSelected = opt.selected;
7098
7099	// Support: Android<=2.3
7100	// Options inside disabled selects are incorrectly marked as disabled
7101	select.disabled = true;
7102	support.optDisabled = !opt.disabled;
7103
7104	// Support: IE<=11+
7105	// An input loses its value after becoming a radio
7106	input = document.createElement( "input" );
7107	input.value = "t";
7108	input.type = "radio";
7109	support.radioValue = input.value === "t";
7110} )();
7111
7112
7113var boolHook,
7114	attrHandle = jQuery.expr.attrHandle;
7115
7116jQuery.fn.extend( {
7117	attr: function( name, value ) {
7118		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7119	},
7120
7121	removeAttr: function( name ) {
7122		return this.each( function() {
7123			jQuery.removeAttr( this, name );
7124		} );
7125	}
7126} );
7127
7128jQuery.extend( {
7129	attr: function( elem, name, value ) {
7130		var ret, hooks,
7131			nType = elem.nodeType;
7132
7133		// Don't get/set attributes on text, comment and attribute nodes
7134		if ( nType === 3 || nType === 8 || nType === 2 ) {
7135			return;
7136		}
7137
7138		// Fallback to prop when attributes are not supported
7139		if ( typeof elem.getAttribute === "undefined" ) {
7140			return jQuery.prop( elem, name, value );
7141		}
7142
7143		// All attributes are lowercase
7144		// Grab necessary hook if one is defined
7145		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7146			name = name.toLowerCase();
7147			hooks = jQuery.attrHooks[ name ] ||
7148				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7149		}
7150
7151		if ( value !== undefined ) {
7152			if ( value === null ) {
7153				jQuery.removeAttr( elem, name );
7154				return;
7155			}
7156
7157			if ( hooks && "set" in hooks &&
7158				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7159				return ret;
7160			}
7161
7162			elem.setAttribute( name, value + "" );
7163			return value;
7164		}
7165
7166		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7167			return ret;
7168		}
7169
7170		ret = jQuery.find.attr( elem, name );
7171
7172		// Non-existent attributes return null, we normalize to undefined
7173		return ret == null ? undefined : ret;
7174	},
7175
7176	attrHooks: {
7177		type: {
7178			set: function( elem, value ) {
7179				if ( !support.radioValue && value === "radio" &&
7180					jQuery.nodeName( elem, "input" ) ) {
7181					var val = elem.value;
7182					elem.setAttribute( "type", value );
7183					if ( val ) {
7184						elem.value = val;
7185					}
7186					return value;
7187				}
7188			}
7189		}
7190	},
7191
7192	removeAttr: function( elem, value ) {
7193		var name, propName,
7194			i = 0,
7195			attrNames = value && value.match( rnotwhite );
7196
7197		if ( attrNames && elem.nodeType === 1 ) {
7198			while ( ( name = attrNames[ i++ ] ) ) {
7199				propName = jQuery.propFix[ name ] || name;
7200
7201				// Boolean attributes get special treatment (#10870)
7202				if ( jQuery.expr.match.bool.test( name ) ) {
7203
7204					// Set corresponding property to false
7205					elem[ propName ] = false;
7206				}
7207
7208				elem.removeAttribute( name );
7209			}
7210		}
7211	}
7212} );
7213
7214// Hooks for boolean attributes
7215boolHook = {
7216	set: function( elem, value, name ) {
7217		if ( value === false ) {
7218
7219			// Remove boolean attributes when set to false
7220			jQuery.removeAttr( elem, name );
7221		} else {
7222			elem.setAttribute( name, name );
7223		}
7224		return name;
7225	}
7226};
7227jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7228	var getter = attrHandle[ name ] || jQuery.find.attr;
7229
7230	attrHandle[ name ] = function( elem, name, isXML ) {
7231		var ret, handle;
7232		if ( !isXML ) {
7233
7234			// Avoid an infinite loop by temporarily removing this function from the getter
7235			handle = attrHandle[ name ];
7236			attrHandle[ name ] = ret;
7237			ret = getter( elem, name, isXML ) != null ?
7238				name.toLowerCase() :
7239				null;
7240			attrHandle[ name ] = handle;
7241		}
7242		return ret;
7243	};
7244} );
7245
7246
7247
7248
7249var rfocusable = /^(?:input|select|textarea|button)$/i,
7250	rclickable = /^(?:a|area)$/i;
7251
7252jQuery.fn.extend( {
7253	prop: function( name, value ) {
7254		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7255	},
7256
7257	removeProp: function( name ) {
7258		return this.each( function() {
7259			delete this[ jQuery.propFix[ name ] || name ];
7260		} );
7261	}
7262} );
7263
7264jQuery.extend( {
7265	prop: function( elem, name, value ) {
7266		var ret, hooks,
7267			nType = elem.nodeType;
7268
7269		// Don't get/set properties on text, comment and attribute nodes
7270		if ( nType === 3 || nType === 8 || nType === 2 ) {
7271			return;
7272		}
7273
7274		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7275
7276			// Fix name and attach hooks
7277			name = jQuery.propFix[ name ] || name;
7278			hooks = jQuery.propHooks[ name ];
7279		}
7280
7281		if ( value !== undefined ) {
7282			if ( hooks && "set" in hooks &&
7283				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7284				return ret;
7285			}
7286
7287			return ( elem[ name ] = value );
7288		}
7289
7290		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7291			return ret;
7292		}
7293
7294		return elem[ name ];
7295	},
7296
7297	propHooks: {
7298		tabIndex: {
7299			get: function( elem ) {
7300
7301				// elem.tabIndex doesn't always return the
7302				// correct value when it hasn't been explicitly set
7303				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7304				// Use proper attribute retrieval(#12072)
7305				var tabindex = jQuery.find.attr( elem, "tabindex" );
7306
7307				return tabindex ?
7308					parseInt( tabindex, 10 ) :
7309					rfocusable.test( elem.nodeName ) ||
7310						rclickable.test( elem.nodeName ) && elem.href ?
7311							0 :
7312							-1;
7313			}
7314		}
7315	},
7316
7317	propFix: {
7318		"for": "htmlFor",
7319		"class": "className"
7320	}
7321} );
7322
7323// Support: IE <=11 only
7324// Accessing the selectedIndex property
7325// forces the browser to respect setting selected
7326// on the option
7327// The getter ensures a default option is selected
7328// when in an optgroup
7329if ( !support.optSelected ) {
7330	jQuery.propHooks.selected = {
7331		get: function( elem ) {
7332			var parent = elem.parentNode;
7333			if ( parent && parent.parentNode ) {
7334				parent.parentNode.selectedIndex;
7335			}
7336			return null;
7337		},
7338		set: function( elem ) {
7339			var parent = elem.parentNode;
7340			if ( parent ) {
7341				parent.selectedIndex;
7342
7343				if ( parent.parentNode ) {
7344					parent.parentNode.selectedIndex;
7345				}
7346			}
7347		}
7348	};
7349}
7350
7351jQuery.each( [
7352	"tabIndex",
7353	"readOnly",
7354	"maxLength",
7355	"cellSpacing",
7356	"cellPadding",
7357	"rowSpan",
7358	"colSpan",
7359	"useMap",
7360	"frameBorder",
7361	"contentEditable"
7362], function() {
7363	jQuery.propFix[ this.toLowerCase() ] = this;
7364} );
7365
7366
7367
7368
7369var rclass = /[\t\r\n\f]/g;
7370
7371function getClass( elem ) {
7372	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7373}
7374
7375jQuery.fn.extend( {
7376	addClass: function( value ) {
7377		var classes, elem, cur, curValue, clazz, j, finalValue,
7378			i = 0;
7379
7380		if ( jQuery.isFunction( value ) ) {
7381			return this.each( function( j ) {
7382				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7383			} );
7384		}
7385
7386		if ( typeof value === "string" && value ) {
7387			classes = value.match( rnotwhite ) || [];
7388
7389			while ( ( elem = this[ i++ ] ) ) {
7390				curValue = getClass( elem );
7391				cur = elem.nodeType === 1 &&
7392					( " " + curValue + " " ).replace( rclass, " " );
7393
7394				if ( cur ) {
7395					j = 0;
7396					while ( ( clazz = classes[ j++ ] ) ) {
7397						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7398							cur += clazz + " ";
7399						}
7400					}
7401
7402					// Only assign if different to avoid unneeded rendering.
7403					finalValue = jQuery.trim( cur );
7404					if ( curValue !== finalValue ) {
7405						elem.setAttribute( "class", finalValue );
7406					}
7407				}
7408			}
7409		}
7410
7411		return this;
7412	},
7413
7414	removeClass: function( value ) {
7415		var classes, elem, cur, curValue, clazz, j, finalValue,
7416			i = 0;
7417
7418		if ( jQuery.isFunction( value ) ) {
7419			return this.each( function( j ) {
7420				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7421			} );
7422		}
7423
7424		if ( !arguments.length ) {
7425			return this.attr( "class", "" );
7426		}
7427
7428		if ( typeof value === "string" && value ) {
7429			classes = value.match( rnotwhite ) || [];
7430
7431			while ( ( elem = this[ i++ ] ) ) {
7432				curValue = getClass( elem );
7433
7434				// This expression is here for better compressibility (see addClass)
7435				cur = elem.nodeType === 1 &&
7436					( " " + curValue + " " ).replace( rclass, " " );
7437
7438				if ( cur ) {
7439					j = 0;
7440					while ( ( clazz = classes[ j++ ] ) ) {
7441
7442						// Remove *all* instances
7443						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7444							cur = cur.replace( " " + clazz + " ", " " );
7445						}
7446					}
7447
7448					// Only assign if different to avoid unneeded rendering.
7449					finalValue = jQuery.trim( cur );
7450					if ( curValue !== finalValue ) {
7451						elem.setAttribute( "class", finalValue );
7452					}
7453				}
7454			}
7455		}
7456
7457		return this;
7458	},
7459
7460	toggleClass: function( value, stateVal ) {
7461		var type = typeof value;
7462
7463		if ( typeof stateVal === "boolean" && type === "string" ) {
7464			return stateVal ? this.addClass( value ) : this.removeClass( value );
7465		}
7466
7467		if ( jQuery.isFunction( value ) ) {
7468			return this.each( function( i ) {
7469				jQuery( this ).toggleClass(
7470					value.call( this, i, getClass( this ), stateVal ),
7471					stateVal
7472				);
7473			} );
7474		}
7475
7476		return this.each( function() {
7477			var className, i, self, classNames;
7478
7479			if ( type === "string" ) {
7480
7481				// Toggle individual class names
7482				i = 0;
7483				self = jQuery( this );
7484				classNames = value.match( rnotwhite ) || [];
7485
7486				while ( ( className = classNames[ i++ ] ) ) {
7487
7488					// Check each className given, space separated list
7489					if ( self.hasClass( className ) ) {
7490						self.removeClass( className );
7491					} else {
7492						self.addClass( className );
7493					}
7494				}
7495
7496			// Toggle whole class name
7497			} else if ( value === undefined || type === "boolean" ) {
7498				className = getClass( this );
7499				if ( className ) {
7500
7501					// Store className if set
7502					dataPriv.set( this, "__className__", className );
7503				}
7504
7505				// If the element has a class name or if we're passed `false`,
7506				// then remove the whole classname (if there was one, the above saved it).
7507				// Otherwise bring back whatever was previously saved (if anything),
7508				// falling back to the empty string if nothing was stored.
7509				if ( this.setAttribute ) {
7510					this.setAttribute( "class",
7511						className || value === false ?
7512						"" :
7513						dataPriv.get( this, "__className__" ) || ""
7514					);
7515				}
7516			}
7517		} );
7518	},
7519
7520	hasClass: function( selector ) {
7521		var className, elem,
7522			i = 0;
7523
7524		className = " " + selector + " ";
7525		while ( ( elem = this[ i++ ] ) ) {
7526			if ( elem.nodeType === 1 &&
7527				( " " + getClass( elem ) + " " ).replace( rclass, " " )
7528					.indexOf( className ) > -1
7529			) {
7530				return true;
7531			}
7532		}
7533
7534		return false;
7535	}
7536} );
7537
7538
7539
7540
7541var rreturn = /\r/g,
7542	rspaces = /[\x20\t\r\n\f]+/g;
7543
7544jQuery.fn.extend( {
7545	val: function( value ) {
7546		var hooks, ret, isFunction,
7547			elem = this[ 0 ];
7548
7549		if ( !arguments.length ) {
7550			if ( elem ) {
7551				hooks = jQuery.valHooks[ elem.type ] ||
7552					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7553
7554				if ( hooks &&
7555					"get" in hooks &&
7556					( ret = hooks.get( elem, "value" ) ) !== undefined
7557				) {
7558					return ret;
7559				}
7560
7561				ret = elem.value;
7562
7563				return typeof ret === "string" ?
7564
7565					// Handle most common string cases
7566					ret.replace( rreturn, "" ) :
7567
7568					// Handle cases where value is null/undef or number
7569					ret == null ? "" : ret;
7570			}
7571
7572			return;
7573		}
7574
7575		isFunction = jQuery.isFunction( value );
7576
7577		return this.each( function( i ) {
7578			var val;
7579
7580			if ( this.nodeType !== 1 ) {
7581				return;
7582			}
7583
7584			if ( isFunction ) {
7585				val = value.call( this, i, jQuery( this ).val() );
7586			} else {
7587				val = value;
7588			}
7589
7590			// Treat null/undefined as ""; convert numbers to string
7591			if ( val == null ) {
7592				val = "";
7593
7594			} else if ( typeof val === "number" ) {
7595				val += "";
7596
7597			} else if ( jQuery.isArray( val ) ) {
7598				val = jQuery.map( val, function( value ) {
7599					return value == null ? "" : value + "";
7600				} );
7601			}
7602
7603			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7604
7605			// If set returns undefined, fall back to normal setting
7606			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7607				this.value = val;
7608			}
7609		} );
7610	}
7611} );
7612
7613jQuery.extend( {
7614	valHooks: {
7615		option: {
7616			get: function( elem ) {
7617
7618				var val = jQuery.find.attr( elem, "value" );
7619				return val != null ?
7620					val :
7621
7622					// Support: IE10-11+
7623					// option.text throws exceptions (#14686, #14858)
7624					// Strip and collapse whitespace
7625					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
7626					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
7627			}
7628		},
7629		select: {
7630			get: function( elem ) {
7631				var value, option,
7632					options = elem.options,
7633					index = elem.selectedIndex,
7634					one = elem.type === "select-one" || index < 0,
7635					values = one ? null : [],
7636					max = one ? index + 1 : options.length,
7637					i = index < 0 ?
7638						max :
7639						one ? index : 0;
7640
7641				// Loop through all the selected options
7642				for ( ; i < max; i++ ) {
7643					option = options[ i ];
7644
7645					// IE8-9 doesn't update selected after form reset (#2551)
7646					if ( ( option.selected || i === index ) &&
7647
7648							// Don't return options that are disabled or in a disabled optgroup
7649							( support.optDisabled ?
7650								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
7651							( !option.parentNode.disabled ||
7652								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7653
7654						// Get the specific value for the option
7655						value = jQuery( option ).val();
7656
7657						// We don't need an array for one selects
7658						if ( one ) {
7659							return value;
7660						}
7661
7662						// Multi-Selects return an array
7663						values.push( value );
7664					}
7665				}
7666
7667				return values;
7668			},
7669
7670			set: function( elem, value ) {
7671				var optionSet, option,
7672					options = elem.options,
7673					values = jQuery.makeArray( value ),
7674					i = options.length;
7675
7676				while ( i-- ) {
7677					option = options[ i ];
7678					if ( option.selected =
7679						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
7680					) {
7681						optionSet = true;
7682					}
7683				}
7684
7685				// Force browsers to behave consistently when non-matching value is set
7686				if ( !optionSet ) {
7687					elem.selectedIndex = -1;
7688				}
7689				return values;
7690			}
7691		}
7692	}
7693} );
7694
7695// Radios and checkboxes getter/setter
7696jQuery.each( [ "radio", "checkbox" ], function() {
7697	jQuery.valHooks[ this ] = {
7698		set: function( elem, value ) {
7699			if ( jQuery.isArray( value ) ) {
7700				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
7701			}
7702		}
7703	};
7704	if ( !support.checkOn ) {
7705		jQuery.valHooks[ this ].get = function( elem ) {
7706			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
7707		};
7708	}
7709} );
7710
7711
7712
7713
7714// Return jQuery for attributes-only inclusion
7715
7716
7717var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
7718
7719jQuery.extend( jQuery.event, {
7720
7721	trigger: function( event, data, elem, onlyHandlers ) {
7722
7723		var i, cur, tmp, bubbleType, ontype, handle, special,
7724			eventPath = [ elem || document ],
7725			type = hasOwn.call( event, "type" ) ? event.type : event,
7726			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
7727
7728		cur = tmp = elem = elem || document;
7729
7730		// Don't do events on text and comment nodes
7731		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
7732			return;
7733		}
7734
7735		// focus/blur morphs to focusin/out; ensure we're not firing them right now
7736		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
7737			return;
7738		}
7739
7740		if ( type.indexOf( "." ) > -1 ) {
7741
7742			// Namespaced trigger; create a regexp to match event type in handle()
7743			namespaces = type.split( "." );
7744			type = namespaces.shift();
7745			namespaces.sort();
7746		}
7747		ontype = type.indexOf( ":" ) < 0 && "on" + type;
7748
7749		// Caller can pass in a jQuery.Event object, Object, or just an event type string
7750		event = event[ jQuery.expando ] ?
7751			event :
7752			new jQuery.Event( type, typeof event === "object" && event );
7753
7754		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
7755		event.isTrigger = onlyHandlers ? 2 : 3;
7756		event.namespace = namespaces.join( "." );
7757		event.rnamespace = event.namespace ?
7758			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
7759			null;
7760
7761		// Clean up the event in case it is being reused
7762		event.result = undefined;
7763		if ( !event.target ) {
7764			event.target = elem;
7765		}
7766
7767		// Clone any incoming data and prepend the event, creating the handler arg list
7768		data = data == null ?
7769			[ event ] :
7770			jQuery.makeArray( data, [ event ] );
7771
7772		// Allow special events to draw outside the lines
7773		special = jQuery.event.special[ type ] || {};
7774		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
7775			return;
7776		}
7777
7778		// Determine event propagation path in advance, per W3C events spec (#9951)
7779		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
7780		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
7781
7782			bubbleType = special.delegateType || type;
7783			if ( !rfocusMorph.test( bubbleType + type ) ) {
7784				cur = cur.parentNode;
7785			}
7786			for ( ; cur; cur = cur.parentNode ) {
7787				eventPath.push( cur );
7788				tmp = cur;
7789			}
7790
7791			// Only add window if we got to document (e.g., not plain obj or detached DOM)
7792			if ( tmp === ( elem.ownerDocument || document ) ) {
7793				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
7794			}
7795		}
7796
7797		// Fire handlers on the event path
7798		i = 0;
7799		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
7800
7801			event.type = i > 1 ?
7802				bubbleType :
7803				special.bindType || type;
7804
7805			// jQuery handler
7806			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
7807				dataPriv.get( cur, "handle" );
7808			if ( handle ) {
7809				handle.apply( cur, data );
7810			}
7811
7812			// Native handler
7813			handle = ontype && cur[ ontype ];
7814			if ( handle && handle.apply && acceptData( cur ) ) {
7815				event.result = handle.apply( cur, data );
7816				if ( event.result === false ) {
7817					event.preventDefault();
7818				}
7819			}
7820		}
7821		event.type = type;
7822
7823		// If nobody prevented the default action, do it now
7824		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
7825
7826			if ( ( !special._default ||
7827				special._default.apply( eventPath.pop(), data ) === false ) &&
7828				acceptData( elem ) ) {
7829
7830				// Call a native DOM method on the target with the same name name as the event.
7831				// Don't do default actions on window, that's where global variables be (#6170)
7832				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
7833
7834					// Don't re-trigger an onFOO event when we call its FOO() method
7835					tmp = elem[ ontype ];
7836
7837					if ( tmp ) {
7838						elem[ ontype ] = null;
7839					}
7840
7841					// Prevent re-triggering of the same event, since we already bubbled it above
7842					jQuery.event.triggered = type;
7843					elem[ type ]();
7844					jQuery.event.triggered = undefined;
7845
7846					if ( tmp ) {
7847						elem[ ontype ] = tmp;
7848					}
7849				}
7850			}
7851		}
7852
7853		return event.result;
7854	},
7855
7856	// Piggyback on a donor event to simulate a different one
7857	// Used only for `focus(in | out)` events
7858	simulate: function( type, elem, event ) {
7859		var e = jQuery.extend(
7860			new jQuery.Event(),
7861			event,
7862			{
7863				type: type,
7864				isSimulated: true
7865			}
7866		);
7867
7868		jQuery.event.trigger( e, null, elem );
7869	}
7870
7871} );
7872
7873jQuery.fn.extend( {
7874
7875	trigger: function( type, data ) {
7876		return this.each( function() {
7877			jQuery.event.trigger( type, data, this );
7878		} );
7879	},
7880	triggerHandler: function( type, data ) {
7881		var elem = this[ 0 ];
7882		if ( elem ) {
7883			return jQuery.event.trigger( type, data, elem, true );
7884		}
7885	}
7886} );
7887
7888
7889jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
7890	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7891	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
7892	function( i, name ) {
7893
7894	// Handle event binding
7895	jQuery.fn[ name ] = function( data, fn ) {
7896		return arguments.length > 0 ?
7897			this.on( name, null, data, fn ) :
7898			this.trigger( name );
7899	};
7900} );
7901
7902jQuery.fn.extend( {
7903	hover: function( fnOver, fnOut ) {
7904		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7905	}
7906} );
7907
7908
7909
7910
7911support.focusin = "onfocusin" in window;
7912
7913
7914// Support: Firefox
7915// Firefox doesn't have focus(in | out) events
7916// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
7917//
7918// Support: Chrome, Safari
7919// focus(in | out) events fire after focus & blur events,
7920// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
7921// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
7922if ( !support.focusin ) {
7923	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
7924
7925		// Attach a single capturing handler on the document while someone wants focusin/focusout
7926		var handler = function( event ) {
7927			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
7928		};
7929
7930		jQuery.event.special[ fix ] = {
7931			setup: function() {
7932				var doc = this.ownerDocument || this,
7933					attaches = dataPriv.access( doc, fix );
7934
7935				if ( !attaches ) {
7936					doc.addEventListener( orig, handler, true );
7937				}
7938				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
7939			},
7940			teardown: function() {
7941				var doc = this.ownerDocument || this,
7942					attaches = dataPriv.access( doc, fix ) - 1;
7943
7944				if ( !attaches ) {
7945					doc.removeEventListener( orig, handler, true );
7946					dataPriv.remove( doc, fix );
7947
7948				} else {
7949					dataPriv.access( doc, fix, attaches );
7950				}
7951			}
7952		};
7953	} );
7954}
7955var location = window.location;
7956
7957var nonce = jQuery.now();
7958
7959var rquery = ( /\?/ );
7960
7961
7962
7963// Support: Android 2.3
7964// Workaround failure to string-cast null input
7965jQuery.parseJSON = function( data ) {
7966	return JSON.parse( data + "" );
7967};
7968
7969
7970// Cross-browser xml parsing
7971jQuery.parseXML = function( data ) {
7972	var xml;
7973	if ( !data || typeof data !== "string" ) {
7974		return null;
7975	}
7976
7977	// Support: IE9
7978	try {
7979		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
7980	} catch ( e ) {
7981		xml = undefined;
7982	}
7983
7984	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7985		jQuery.error( "Invalid XML: " + data );
7986	}
7987	return xml;
7988};
7989
7990
7991var
7992	rhash = /#.*$/,
7993	rts = /([?&])_=[^&]*/,
7994	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7995
7996	// #7653, #8125, #8152: local protocol detection
7997	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7998	rnoContent = /^(?:GET|HEAD)$/,
7999	rprotocol = /^\/\//,
8000
8001	/* Prefilters
8002	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8003	 * 2) These are called:
8004	 *    - BEFORE asking for a transport
8005	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8006	 * 3) key is the dataType
8007	 * 4) the catchall symbol "*" can be used
8008	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8009	 */
8010	prefilters = {},
8011
8012	/* Transports bindings
8013	 * 1) key is the dataType
8014	 * 2) the catchall symbol "*" can be used
8015	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8016	 */
8017	transports = {},
8018
8019	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8020	allTypes = "*/".concat( "*" ),
8021
8022	// Anchor tag for parsing the document origin
8023	originAnchor = document.createElement( "a" );
8024	originAnchor.href = location.href;
8025
8026// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8027function addToPrefiltersOrTransports( structure ) {
8028
8029	// dataTypeExpression is optional and defaults to "*"
8030	return function( dataTypeExpression, func ) {
8031
8032		if ( typeof dataTypeExpression !== "string" ) {
8033			func = dataTypeExpression;
8034			dataTypeExpression = "*";
8035		}
8036
8037		var dataType,
8038			i = 0,
8039			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8040
8041		if ( jQuery.isFunction( func ) ) {
8042
8043			// For each dataType in the dataTypeExpression
8044			while ( ( dataType = dataTypes[ i++ ] ) ) {
8045
8046				// Prepend if requested
8047				if ( dataType[ 0 ] === "+" ) {
8048					dataType = dataType.slice( 1 ) || "*";
8049					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8050
8051				// Otherwise append
8052				} else {
8053					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8054				}
8055			}
8056		}
8057	};
8058}
8059
8060// Base inspection function for prefilters and transports
8061function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8062
8063	var inspected = {},
8064		seekingTransport = ( structure === transports );
8065
8066	function inspect( dataType ) {
8067		var selected;
8068		inspected[ dataType ] = true;
8069		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8070			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8071			if ( typeof dataTypeOrTransport === "string" &&
8072				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8073
8074				options.dataTypes.unshift( dataTypeOrTransport );
8075				inspect( dataTypeOrTransport );
8076				return false;
8077			} else if ( seekingTransport ) {
8078				return !( selected = dataTypeOrTransport );
8079			}
8080		} );
8081		return selected;
8082	}
8083
8084	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8085}
8086
8087// A special extend for ajax options
8088// that takes "flat" options (not to be deep extended)
8089// Fixes #9887
8090function ajaxExtend( target, src ) {
8091	var key, deep,
8092		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8093
8094	for ( key in src ) {
8095		if ( src[ key ] !== undefined ) {
8096			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8097		}
8098	}
8099	if ( deep ) {
8100		jQuery.extend( true, target, deep );
8101	}
8102
8103	return target;
8104}
8105
8106/* Handles responses to an ajax request:
8107 * - finds the right dataType (mediates between content-type and expected dataType)
8108 * - returns the corresponding response
8109 */
8110function ajaxHandleResponses( s, jqXHR, responses ) {
8111
8112	var ct, type, finalDataType, firstDataType,
8113		contents = s.contents,
8114		dataTypes = s.dataTypes;
8115
8116	// Remove auto dataType and get content-type in the process
8117	while ( dataTypes[ 0 ] === "*" ) {
8118		dataTypes.shift();
8119		if ( ct === undefined ) {
8120			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8121		}
8122	}
8123
8124	// Check if we're dealing with a known content-type
8125	if ( ct ) {
8126		for ( type in contents ) {
8127			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8128				dataTypes.unshift( type );
8129				break;
8130			}
8131		}
8132	}
8133
8134	// Check to see if we have a response for the expected dataType
8135	if ( dataTypes[ 0 ] in responses ) {
8136		finalDataType = dataTypes[ 0 ];
8137	} else {
8138
8139		// Try convertible dataTypes
8140		for ( type in responses ) {
8141			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8142				finalDataType = type;
8143				break;
8144			}
8145			if ( !firstDataType ) {
8146				firstDataType = type;
8147			}
8148		}
8149
8150		// Or just use first one
8151		finalDataType = finalDataType || firstDataType;
8152	}
8153
8154	// If we found a dataType
8155	// We add the dataType to the list if needed
8156	// and return the corresponding response
8157	if ( finalDataType ) {
8158		if ( finalDataType !== dataTypes[ 0 ] ) {
8159			dataTypes.unshift( finalDataType );
8160		}
8161		return responses[ finalDataType ];
8162	}
8163}
8164
8165/* Chain conversions given the request and the original response
8166 * Also sets the responseXXX fields on the jqXHR instance
8167 */
8168function ajaxConvert( s, response, jqXHR, isSuccess ) {
8169	var conv2, current, conv, tmp, prev,
8170		converters = {},
8171
8172		// Work with a copy of dataTypes in case we need to modify it for conversion
8173		dataTypes = s.dataTypes.slice();
8174
8175	// Create converters map with lowercased keys
8176	if ( dataTypes[ 1 ] ) {
8177		for ( conv in s.converters ) {
8178			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8179		}
8180	}
8181
8182	current = dataTypes.shift();
8183
8184	// Convert to each sequential dataType
8185	while ( current ) {
8186
8187		if ( s.responseFields[ current ] ) {
8188			jqXHR[ s.responseFields[ current ] ] = response;
8189		}
8190
8191		// Apply the dataFilter if provided
8192		if ( !prev && isSuccess && s.dataFilter ) {
8193			response = s.dataFilter( response, s.dataType );
8194		}
8195
8196		prev = current;
8197		current = dataTypes.shift();
8198
8199		if ( current ) {
8200
8201		// There's only work to do if current dataType is non-auto
8202			if ( current === "*" ) {
8203
8204				current = prev;
8205
8206			// Convert response if prev dataType is non-auto and differs from current
8207			} else if ( prev !== "*" && prev !== current ) {
8208
8209				// Seek a direct converter
8210				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8211
8212				// If none found, seek a pair
8213				if ( !conv ) {
8214					for ( conv2 in converters ) {
8215
8216						// If conv2 outputs current
8217						tmp = conv2.split( " " );
8218						if ( tmp[ 1 ] === current ) {
8219
8220							// If prev can be converted to accepted input
8221							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8222								converters[ "* " + tmp[ 0 ] ];
8223							if ( conv ) {
8224
8225								// Condense equivalence converters
8226								if ( conv === true ) {
8227									conv = converters[ conv2 ];
8228
8229								// Otherwise, insert the intermediate dataType
8230								} else if ( converters[ conv2 ] !== true ) {
8231									current = tmp[ 0 ];
8232									dataTypes.unshift( tmp[ 1 ] );
8233								}
8234								break;
8235							}
8236						}
8237					}
8238				}
8239
8240				// Apply converter (if not an equivalence)
8241				if ( conv !== true ) {
8242
8243					// Unless errors are allowed to bubble, catch and return them
8244					if ( conv && s.throws ) {
8245						response = conv( response );
8246					} else {
8247						try {
8248							response = conv( response );
8249						} catch ( e ) {
8250							return {
8251								state: "parsererror",
8252								error: conv ? e : "No conversion from " + prev + " to " + current
8253							};
8254						}
8255					}
8256				}
8257			}
8258		}
8259	}
8260
8261	return { state: "success", data: response };
8262}
8263
8264jQuery.extend( {
8265
8266	// Counter for holding the number of active queries
8267	active: 0,
8268
8269	// Last-Modified header cache for next request
8270	lastModified: {},
8271	etag: {},
8272
8273	ajaxSettings: {
8274		url: location.href,
8275		type: "GET",
8276		isLocal: rlocalProtocol.test( location.protocol ),
8277		global: true,
8278		processData: true,
8279		async: true,
8280		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8281		/*
8282		timeout: 0,
8283		data: null,
8284		dataType: null,
8285		username: null,
8286		password: null,
8287		cache: null,
8288		throws: false,
8289		traditional: false,
8290		headers: {},
8291		*/
8292
8293		accepts: {
8294			"*": allTypes,
8295			text: "text/plain",
8296			html: "text/html",
8297			xml: "application/xml, text/xml",
8298			json: "application/json, text/javascript"
8299		},
8300
8301		contents: {
8302			xml: /\bxml\b/,
8303			html: /\bhtml/,
8304			json: /\bjson\b/
8305		},
8306
8307		responseFields: {
8308			xml: "responseXML",
8309			text: "responseText",
8310			json: "responseJSON"
8311		},
8312
8313		// Data converters
8314		// Keys separate source (or catchall "*") and destination types with a single space
8315		converters: {
8316
8317			// Convert anything to text
8318			"* text": String,
8319
8320			// Text to html (true = no transformation)
8321			"text html": true,
8322
8323			// Evaluate text as a json expression
8324			"text json": jQuery.parseJSON,
8325
8326			// Parse text as xml
8327			"text xml": jQuery.parseXML
8328		},
8329
8330		// For options that shouldn't be deep extended:
8331		// you can add your own custom options here if
8332		// and when you create one that shouldn't be
8333		// deep extended (see ajaxExtend)
8334		flatOptions: {
8335			url: true,
8336			context: true
8337		}
8338	},
8339
8340	// Creates a full fledged settings object into target
8341	// with both ajaxSettings and settings fields.
8342	// If target is omitted, writes into ajaxSettings.
8343	ajaxSetup: function( target, settings ) {
8344		return settings ?
8345
8346			// Building a settings object
8347			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8348
8349			// Extending ajaxSettings
8350			ajaxExtend( jQuery.ajaxSettings, target );
8351	},
8352
8353	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8354	ajaxTransport: addToPrefiltersOrTransports( transports ),
8355
8356	// Main method
8357	ajax: function( url, options ) {
8358
8359		// If url is an object, simulate pre-1.5 signature
8360		if ( typeof url === "object" ) {
8361			options = url;
8362			url = undefined;
8363		}
8364
8365		// Force options to be an object
8366		options = options || {};
8367
8368		var transport,
8369
8370			// URL without anti-cache param
8371			cacheURL,
8372
8373			// Response headers
8374			responseHeadersString,
8375			responseHeaders,
8376
8377			// timeout handle
8378			timeoutTimer,
8379
8380			// Url cleanup var
8381			urlAnchor,
8382
8383			// To know if global events are to be dispatched
8384			fireGlobals,
8385
8386			// Loop variable
8387			i,
8388
8389			// Create the final options object
8390			s = jQuery.ajaxSetup( {}, options ),
8391
8392			// Callbacks context
8393			callbackContext = s.context || s,
8394
8395			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8396			globalEventContext = s.context &&
8397				( callbackContext.nodeType || callbackContext.jquery ) ?
8398					jQuery( callbackContext ) :
8399					jQuery.event,
8400
8401			// Deferreds
8402			deferred = jQuery.Deferred(),
8403			completeDeferred = jQuery.Callbacks( "once memory" ),
8404
8405			// Status-dependent callbacks
8406			statusCode = s.statusCode || {},
8407
8408			// Headers (they are sent all at once)
8409			requestHeaders = {},
8410			requestHeadersNames = {},
8411
8412			// The jqXHR state
8413			state = 0,
8414
8415			// Default abort message
8416			strAbort = "canceled",
8417
8418			// Fake xhr
8419			jqXHR = {
8420				readyState: 0,
8421
8422				// Builds headers hashtable if needed
8423				getResponseHeader: function( key ) {
8424					var match;
8425					if ( state === 2 ) {
8426						if ( !responseHeaders ) {
8427							responseHeaders = {};
8428							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8429								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8430							}
8431						}
8432						match = responseHeaders[ key.toLowerCase() ];
8433					}
8434					return match == null ? null : match;
8435				},
8436
8437				// Raw string
8438				getAllResponseHeaders: function() {
8439					return state === 2 ? responseHeadersString : null;
8440				},
8441
8442				// Caches the header
8443				setRequestHeader: function( name, value ) {
8444					var lname = name.toLowerCase();
8445					if ( !state ) {
8446						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
8447						requestHeaders[ name ] = value;
8448					}
8449					return this;
8450				},
8451
8452				// Overrides response content-type header
8453				overrideMimeType: function( type ) {
8454					if ( !state ) {
8455						s.mimeType = type;
8456					}
8457					return this;
8458				},
8459
8460				// Status-dependent callbacks
8461				statusCode: function( map ) {
8462					var code;
8463					if ( map ) {
8464						if ( state < 2 ) {
8465							for ( code in map ) {
8466
8467								// Lazy-add the new callback in a way that preserves old ones
8468								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8469							}
8470						} else {
8471
8472							// Execute the appropriate callbacks
8473							jqXHR.always( map[ jqXHR.status ] );
8474						}
8475					}
8476					return this;
8477				},
8478
8479				// Cancel the request
8480				abort: function( statusText ) {
8481					var finalText = statusText || strAbort;
8482					if ( transport ) {
8483						transport.abort( finalText );
8484					}
8485					done( 0, finalText );
8486					return this;
8487				}
8488			};
8489
8490		// Attach deferreds
8491		deferred.promise( jqXHR ).complete = completeDeferred.add;
8492		jqXHR.success = jqXHR.done;
8493		jqXHR.error = jqXHR.fail;
8494
8495		// Remove hash character (#7531: and string promotion)
8496		// Add protocol if not provided (prefilters might expect it)
8497		// Handle falsy url in the settings object (#10093: consistency with old signature)
8498		// We also use the url parameter if available
8499		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
8500			.replace( rprotocol, location.protocol + "//" );
8501
8502		// Alias method option to type as per ticket #12004
8503		s.type = options.method || options.type || s.method || s.type;
8504
8505		// Extract dataTypes list
8506		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8507
8508		// A cross-domain request is in order when the origin doesn't match the current origin.
8509		if ( s.crossDomain == null ) {
8510			urlAnchor = document.createElement( "a" );
8511
8512			// Support: IE8-11+
8513			// IE throws exception if url is malformed, e.g. http://example.com:80x/
8514			try {
8515				urlAnchor.href = s.url;
8516
8517				// Support: IE8-11+
8518				// Anchor's host property isn't correctly set when s.url is relative
8519				urlAnchor.href = urlAnchor.href;
8520				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8521					urlAnchor.protocol + "//" + urlAnchor.host;
8522			} catch ( e ) {
8523
8524				// If there is an error parsing the URL, assume it is crossDomain,
8525				// it can be rejected by the transport if it is invalid
8526				s.crossDomain = true;
8527			}
8528		}
8529
8530		// Convert data if not already a string
8531		if ( s.data && s.processData && typeof s.data !== "string" ) {
8532			s.data = jQuery.param( s.data, s.traditional );
8533		}
8534
8535		// Apply prefilters
8536		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8537
8538		// If request was aborted inside a prefilter, stop there
8539		if ( state === 2 ) {
8540			return jqXHR;
8541		}
8542
8543		// We can fire global events as of now if asked to
8544		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8545		fireGlobals = jQuery.event && s.global;
8546
8547		// Watch for a new set of requests
8548		if ( fireGlobals && jQuery.active++ === 0 ) {
8549			jQuery.event.trigger( "ajaxStart" );
8550		}
8551
8552		// Uppercase the type
8553		s.type = s.type.toUpperCase();
8554
8555		// Determine if request has content
8556		s.hasContent = !rnoContent.test( s.type );
8557
8558		// Save the URL in case we're toying with the If-Modified-Since
8559		// and/or If-None-Match header later on
8560		cacheURL = s.url;
8561
8562		// More options handling for requests with no content
8563		if ( !s.hasContent ) {
8564
8565			// If data is available, append data to url
8566			if ( s.data ) {
8567				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8568
8569				// #9682: remove data so that it's not used in an eventual retry
8570				delete s.data;
8571			}
8572
8573			// Add anti-cache in url if needed
8574			if ( s.cache === false ) {
8575				s.url = rts.test( cacheURL ) ?
8576
8577					// If there is already a '_' parameter, set its value
8578					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8579
8580					// Otherwise add one to the end
8581					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8582			}
8583		}
8584
8585		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8586		if ( s.ifModified ) {
8587			if ( jQuery.lastModified[ cacheURL ] ) {
8588				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8589			}
8590			if ( jQuery.etag[ cacheURL ] ) {
8591				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8592			}
8593		}
8594
8595		// Set the correct header, if data is being sent
8596		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8597			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8598		}
8599
8600		// Set the Accepts header for the server, depending on the dataType
8601		jqXHR.setRequestHeader(
8602			"Accept",
8603			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
8604				s.accepts[ s.dataTypes[ 0 ] ] +
8605					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8606				s.accepts[ "*" ]
8607		);
8608
8609		// Check for headers option
8610		for ( i in s.headers ) {
8611			jqXHR.setRequestHeader( i, s.headers[ i ] );
8612		}
8613
8614		// Allow custom headers/mimetypes and early abort
8615		if ( s.beforeSend &&
8616			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8617
8618			// Abort if not done already and return
8619			return jqXHR.abort();
8620		}
8621
8622		// Aborting is no longer a cancellation
8623		strAbort = "abort";
8624
8625		// Install callbacks on deferreds
8626		for ( i in { success: 1, error: 1, complete: 1 } ) {
8627			jqXHR[ i ]( s[ i ] );
8628		}
8629
8630		// Get transport
8631		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8632
8633		// If no transport, we auto-abort
8634		if ( !transport ) {
8635			done( -1, "No Transport" );
8636		} else {
8637			jqXHR.readyState = 1;
8638
8639			// Send global event
8640			if ( fireGlobals ) {
8641				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8642			}
8643
8644			// If request was aborted inside ajaxSend, stop there
8645			if ( state === 2 ) {
8646				return jqXHR;
8647			}
8648
8649			// Timeout
8650			if ( s.async && s.timeout > 0 ) {
8651				timeoutTimer = window.setTimeout( function() {
8652					jqXHR.abort( "timeout" );
8653				}, s.timeout );
8654			}
8655
8656			try {
8657				state = 1;
8658				transport.send( requestHeaders, done );
8659			} catch ( e ) {
8660
8661				// Propagate exception as error if not done
8662				if ( state < 2 ) {
8663					done( -1, e );
8664
8665				// Simply rethrow otherwise
8666				} else {
8667					throw e;
8668				}
8669			}
8670		}
8671
8672		// Callback for when everything is done
8673		function done( status, nativeStatusText, responses, headers ) {
8674			var isSuccess, success, error, response, modified,
8675				statusText = nativeStatusText;
8676
8677			// Called once
8678			if ( state === 2 ) {
8679				return;
8680			}
8681
8682			// State is "done" now
8683			state = 2;
8684
8685			// Clear timeout if it exists
8686			if ( timeoutTimer ) {
8687				window.clearTimeout( timeoutTimer );
8688			}
8689
8690			// Dereference transport for early garbage collection
8691			// (no matter how long the jqXHR object will be used)
8692			transport = undefined;
8693
8694			// Cache response headers
8695			responseHeadersString = headers || "";
8696
8697			// Set readyState
8698			jqXHR.readyState = status > 0 ? 4 : 0;
8699
8700			// Determine if successful
8701			isSuccess = status >= 200 && status < 300 || status === 304;
8702
8703			// Get response data
8704			if ( responses ) {
8705				response = ajaxHandleResponses( s, jqXHR, responses );
8706			}
8707
8708			// Convert no matter what (that way responseXXX fields are always set)
8709			response = ajaxConvert( s, response, jqXHR, isSuccess );
8710
8711			// If successful, handle type chaining
8712			if ( isSuccess ) {
8713
8714				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8715				if ( s.ifModified ) {
8716					modified = jqXHR.getResponseHeader( "Last-Modified" );
8717					if ( modified ) {
8718						jQuery.lastModified[ cacheURL ] = modified;
8719					}
8720					modified = jqXHR.getResponseHeader( "etag" );
8721					if ( modified ) {
8722						jQuery.etag[ cacheURL ] = modified;
8723					}
8724				}
8725
8726				// if no content
8727				if ( status === 204 || s.type === "HEAD" ) {
8728					statusText = "nocontent";
8729
8730				// if not modified
8731				} else if ( status === 304 ) {
8732					statusText = "notmodified";
8733
8734				// If we have data, let's convert it
8735				} else {
8736					statusText = response.state;
8737					success = response.data;
8738					error = response.error;
8739					isSuccess = !error;
8740				}
8741			} else {
8742
8743				// Extract error from statusText and normalize for non-aborts
8744				error = statusText;
8745				if ( status || !statusText ) {
8746					statusText = "error";
8747					if ( status < 0 ) {
8748						status = 0;
8749					}
8750				}
8751			}
8752
8753			// Set data for the fake xhr object
8754			jqXHR.status = status;
8755			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8756
8757			// Success/Error
8758			if ( isSuccess ) {
8759				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8760			} else {
8761				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8762			}
8763
8764			// Status-dependent callbacks
8765			jqXHR.statusCode( statusCode );
8766			statusCode = undefined;
8767
8768			if ( fireGlobals ) {
8769				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8770					[ jqXHR, s, isSuccess ? success : error ] );
8771			}
8772
8773			// Complete
8774			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8775
8776			if ( fireGlobals ) {
8777				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8778
8779				// Handle the global AJAX counter
8780				if ( !( --jQuery.active ) ) {
8781					jQuery.event.trigger( "ajaxStop" );
8782				}
8783			}
8784		}
8785
8786		return jqXHR;
8787	},
8788
8789	getJSON: function( url, data, callback ) {
8790		return jQuery.get( url, data, callback, "json" );
8791	},
8792
8793	getScript: function( url, callback ) {
8794		return jQuery.get( url, undefined, callback, "script" );
8795	}
8796} );
8797
8798jQuery.each( [ "get", "post" ], function( i, method ) {
8799	jQuery[ method ] = function( url, data, callback, type ) {
8800
8801		// Shift arguments if data argument was omitted
8802		if ( jQuery.isFunction( data ) ) {
8803			type = type || callback;
8804			callback = data;
8805			data = undefined;
8806		}
8807
8808		// The url can be an options object (which then must have .url)
8809		return jQuery.ajax( jQuery.extend( {
8810			url: url,
8811			type: method,
8812			dataType: type,
8813			data: data,
8814			success: callback
8815		}, jQuery.isPlainObject( url ) && url ) );
8816	};
8817} );
8818
8819
8820jQuery._evalUrl = function( url ) {
8821	return jQuery.ajax( {
8822		url: url,
8823
8824		// Make this explicit, since user can override this through ajaxSetup (#11264)
8825		type: "GET",
8826		dataType: "script",
8827		async: false,
8828		global: false,
8829		"throws": true
8830	} );
8831};
8832
8833
8834jQuery.fn.extend( {
8835	wrapAll: function( html ) {
8836		var wrap;
8837
8838		if ( jQuery.isFunction( html ) ) {
8839			return this.each( function( i ) {
8840				jQuery( this ).wrapAll( html.call( this, i ) );
8841			} );
8842		}
8843
8844		if ( this[ 0 ] ) {
8845
8846			// The elements to wrap the target around
8847			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8848
8849			if ( this[ 0 ].parentNode ) {
8850				wrap.insertBefore( this[ 0 ] );
8851			}
8852
8853			wrap.map( function() {
8854				var elem = this;
8855
8856				while ( elem.firstElementChild ) {
8857					elem = elem.firstElementChild;
8858				}
8859
8860				return elem;
8861			} ).append( this );
8862		}
8863
8864		return this;
8865	},
8866
8867	wrapInner: function( html ) {
8868		if ( jQuery.isFunction( html ) ) {
8869			return this.each( function( i ) {
8870				jQuery( this ).wrapInner( html.call( this, i ) );
8871			} );
8872		}
8873
8874		return this.each( function() {
8875			var self = jQuery( this ),
8876				contents = self.contents();
8877
8878			if ( contents.length ) {
8879				contents.wrapAll( html );
8880
8881			} else {
8882				self.append( html );
8883			}
8884		} );
8885	},
8886
8887	wrap: function( html ) {
8888		var isFunction = jQuery.isFunction( html );
8889
8890		return this.each( function( i ) {
8891			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
8892		} );
8893	},
8894
8895	unwrap: function() {
8896		return this.parent().each( function() {
8897			if ( !jQuery.nodeName( this, "body" ) ) {
8898				jQuery( this ).replaceWith( this.childNodes );
8899			}
8900		} ).end();
8901	}
8902} );
8903
8904
8905jQuery.expr.filters.hidden = function( elem ) {
8906	return !jQuery.expr.filters.visible( elem );
8907};
8908jQuery.expr.filters.visible = function( elem ) {
8909
8910	// Support: Opera <= 12.12
8911	// Opera reports offsetWidths and offsetHeights less than zero on some elements
8912	// Use OR instead of AND as the element is not visible if either is true
8913	// See tickets #10406 and #13132
8914	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
8915};
8916
8917
8918
8919
8920var r20 = /%20/g,
8921	rbracket = /\[\]$/,
8922	rCRLF = /\r?\n/g,
8923	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8924	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8925
8926function buildParams( prefix, obj, traditional, add ) {
8927	var name;
8928
8929	if ( jQuery.isArray( obj ) ) {
8930
8931		// Serialize array item.
8932		jQuery.each( obj, function( i, v ) {
8933			if ( traditional || rbracket.test( prefix ) ) {
8934
8935				// Treat each array item as a scalar.
8936				add( prefix, v );
8937
8938			} else {
8939
8940				// Item is non-scalar (array or object), encode its numeric index.
8941				buildParams(
8942					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8943					v,
8944					traditional,
8945					add
8946				);
8947			}
8948		} );
8949
8950	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8951
8952		// Serialize object item.
8953		for ( name in obj ) {
8954			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8955		}
8956
8957	} else {
8958
8959		// Serialize scalar item.
8960		add( prefix, obj );
8961	}
8962}
8963
8964// Serialize an array of form elements or a set of
8965// key/values into a query string
8966jQuery.param = function( a, traditional ) {
8967	var prefix,
8968		s = [],
8969		add = function( key, value ) {
8970
8971			// If value is a function, invoke it and return its value
8972			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8973			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8974		};
8975
8976	// Set traditional to true for jQuery <= 1.3.2 behavior.
8977	if ( traditional === undefined ) {
8978		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8979	}
8980
8981	// If an array was passed in, assume that it is an array of form elements.
8982	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8983
8984		// Serialize the form elements
8985		jQuery.each( a, function() {
8986			add( this.name, this.value );
8987		} );
8988
8989	} else {
8990
8991		// If traditional, encode the "old" way (the way 1.3.2 or older
8992		// did it), otherwise encode params recursively.
8993		for ( prefix in a ) {
8994			buildParams( prefix, a[ prefix ], traditional, add );
8995		}
8996	}
8997
8998	// Return the resulting serialization
8999	return s.join( "&" ).replace( r20, "+" );
9000};
9001
9002jQuery.fn.extend( {
9003	serialize: function() {
9004		return jQuery.param( this.serializeArray() );
9005	},
9006	serializeArray: function() {
9007		return this.map( function() {
9008
9009			// Can add propHook for "elements" to filter or add form elements
9010			var elements = jQuery.prop( this, "elements" );
9011			return elements ? jQuery.makeArray( elements ) : this;
9012		} )
9013		.filter( function() {
9014			var type = this.type;
9015
9016			// Use .is( ":disabled" ) so that fieldset[disabled] works
9017			return this.name && !jQuery( this ).is( ":disabled" ) &&
9018				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9019				( this.checked || !rcheckableType.test( type ) );
9020		} )
9021		.map( function( i, elem ) {
9022			var val = jQuery( this ).val();
9023
9024			return val == null ?
9025				null :
9026				jQuery.isArray( val ) ?
9027					jQuery.map( val, function( val ) {
9028						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9029					} ) :
9030					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9031		} ).get();
9032	}
9033} );
9034
9035
9036jQuery.ajaxSettings.xhr = function() {
9037	try {
9038		return new window.XMLHttpRequest();
9039	} catch ( e ) {}
9040};
9041
9042var xhrSuccessStatus = {
9043
9044		// File protocol always yields status code 0, assume 200
9045		0: 200,
9046
9047		// Support: IE9
9048		// #1450: sometimes IE returns 1223 when it should be 204
9049		1223: 204
9050	},
9051	xhrSupported = jQuery.ajaxSettings.xhr();
9052
9053support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9054support.ajax = xhrSupported = !!xhrSupported;
9055
9056jQuery.ajaxTransport( function( options ) {
9057	var callback, errorCallback;
9058
9059	// Cross domain only allowed if supported through XMLHttpRequest
9060	if ( support.cors || xhrSupported && !options.crossDomain ) {
9061		return {
9062			send: function( headers, complete ) {
9063				var i,
9064					xhr = options.xhr();
9065
9066				xhr.open(
9067					options.type,
9068					options.url,
9069					options.async,
9070					options.username,
9071					options.password
9072				);
9073
9074				// Apply custom fields if provided
9075				if ( options.xhrFields ) {
9076					for ( i in options.xhrFields ) {
9077						xhr[ i ] = options.xhrFields[ i ];
9078					}
9079				}
9080
9081				// Override mime type if needed
9082				if ( options.mimeType && xhr.overrideMimeType ) {
9083					xhr.overrideMimeType( options.mimeType );
9084				}
9085
9086				// X-Requested-With header
9087				// For cross-domain requests, seeing as conditions for a preflight are
9088				// akin to a jigsaw puzzle, we simply never set it to be sure.
9089				// (it can always be set on a per-request basis or even using ajaxSetup)
9090				// For same-domain requests, won't change header if already provided.
9091				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9092					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9093				}
9094
9095				// Set headers
9096				for ( i in headers ) {
9097					xhr.setRequestHeader( i, headers[ i ] );
9098				}
9099
9100				// Callback
9101				callback = function( type ) {
9102					return function() {
9103						if ( callback ) {
9104							callback = errorCallback = xhr.onload =
9105								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9106
9107							if ( type === "abort" ) {
9108								xhr.abort();
9109							} else if ( type === "error" ) {
9110
9111								// Support: IE9
9112								// On a manual native abort, IE9 throws
9113								// errors on any property access that is not readyState
9114								if ( typeof xhr.status !== "number" ) {
9115									complete( 0, "error" );
9116								} else {
9117									complete(
9118
9119										// File: protocol always yields status 0; see #8605, #14207
9120										xhr.status,
9121										xhr.statusText
9122									);
9123								}
9124							} else {
9125								complete(
9126									xhrSuccessStatus[ xhr.status ] || xhr.status,
9127									xhr.statusText,
9128
9129									// Support: IE9 only
9130									// IE9 has no XHR2 but throws on binary (trac-11426)
9131									// For XHR2 non-text, let the caller handle it (gh-2498)
9132									( xhr.responseType || "text" ) !== "text"  ||
9133									typeof xhr.responseText !== "string" ?
9134										{ binary: xhr.response } :
9135										{ text: xhr.responseText },
9136									xhr.getAllResponseHeaders()
9137								);
9138							}
9139						}
9140					};
9141				};
9142
9143				// Listen to events
9144				xhr.onload = callback();
9145				errorCallback = xhr.onerror = callback( "error" );
9146
9147				// Support: IE9
9148				// Use onreadystatechange to replace onabort
9149				// to handle uncaught aborts
9150				if ( xhr.onabort !== undefined ) {
9151					xhr.onabort = errorCallback;
9152				} else {
9153					xhr.onreadystatechange = function() {
9154
9155						// Check readyState before timeout as it changes
9156						if ( xhr.readyState === 4 ) {
9157
9158							// Allow onerror to be called first,
9159							// but that will not handle a native abort
9160							// Also, save errorCallback to a variable
9161							// as xhr.onerror cannot be accessed
9162							window.setTimeout( function() {
9163								if ( callback ) {
9164									errorCallback();
9165								}
9166							} );
9167						}
9168					};
9169				}
9170
9171				// Create the abort callback
9172				callback = callback( "abort" );
9173
9174				try {
9175
9176					// Do send the request (this may raise an exception)
9177					xhr.send( options.hasContent && options.data || null );
9178				} catch ( e ) {
9179
9180					// #14683: Only rethrow if this hasn't been notified as an error yet
9181					if ( callback ) {
9182						throw e;
9183					}
9184				}
9185			},
9186
9187			abort: function() {
9188				if ( callback ) {
9189					callback();
9190				}
9191			}
9192		};
9193	}
9194} );
9195
9196
9197
9198
9199// Install script dataType
9200jQuery.ajaxSetup( {
9201	accepts: {
9202		script: "text/javascript, application/javascript, " +
9203			"application/ecmascript, application/x-ecmascript"
9204	},
9205	contents: {
9206		script: /\b(?:java|ecma)script\b/
9207	},
9208	converters: {
9209		"text script": function( text ) {
9210			jQuery.globalEval( text );
9211			return text;
9212		}
9213	}
9214} );
9215
9216// Handle cache's special case and crossDomain
9217jQuery.ajaxPrefilter( "script", function( s ) {
9218	if ( s.cache === undefined ) {
9219		s.cache = false;
9220	}
9221	if ( s.crossDomain ) {
9222		s.type = "GET";
9223	}
9224} );
9225
9226// Bind script tag hack transport
9227jQuery.ajaxTransport( "script", function( s ) {
9228
9229	// This transport only deals with cross domain requests
9230	if ( s.crossDomain ) {
9231		var script, callback;
9232		return {
9233			send: function( _, complete ) {
9234				script = jQuery( "<script>" ).prop( {
9235					charset: s.scriptCharset,
9236					src: s.url
9237				} ).on(
9238					"load error",
9239					callback = function( evt ) {
9240						script.remove();
9241						callback = null;
9242						if ( evt ) {
9243							complete( evt.type === "error" ? 404 : 200, evt.type );
9244						}
9245					}
9246				);
9247
9248				// Use native DOM manipulation to avoid our domManip AJAX trickery
9249				document.head.appendChild( script[ 0 ] );
9250			},
9251			abort: function() {
9252				if ( callback ) {
9253					callback();
9254				}
9255			}
9256		};
9257	}
9258} );
9259
9260
9261
9262
9263var oldCallbacks = [],
9264	rjsonp = /(=)\?(?=&|$)|\?\?/;
9265
9266// Default jsonp settings
9267jQuery.ajaxSetup( {
9268	jsonp: "callback",
9269	jsonpCallback: function() {
9270		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9271		this[ callback ] = true;
9272		return callback;
9273	}
9274} );
9275
9276// Detect, normalize options and install callbacks for jsonp requests
9277jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9278
9279	var callbackName, overwritten, responseContainer,
9280		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9281			"url" :
9282			typeof s.data === "string" &&
9283				( s.contentType || "" )
9284					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9285				rjsonp.test( s.data ) && "data"
9286		);
9287
9288	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9289	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9290
9291		// Get callback name, remembering preexisting value associated with it
9292		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9293			s.jsonpCallback() :
9294			s.jsonpCallback;
9295
9296		// Insert callback into url or form data
9297		if ( jsonProp ) {
9298			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9299		} else if ( s.jsonp !== false ) {
9300			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9301		}
9302
9303		// Use data converter to retrieve json after script execution
9304		s.converters[ "script json" ] = function() {
9305			if ( !responseContainer ) {
9306				jQuery.error( callbackName + " was not called" );
9307			}
9308			return responseContainer[ 0 ];
9309		};
9310
9311		// Force json dataType
9312		s.dataTypes[ 0 ] = "json";
9313
9314		// Install callback
9315		overwritten = window[ callbackName ];
9316		window[ callbackName ] = function() {
9317			responseContainer = arguments;
9318		};
9319
9320		// Clean-up function (fires after converters)
9321		jqXHR.always( function() {
9322
9323			// If previous value didn't exist - remove it
9324			if ( overwritten === undefined ) {
9325				jQuery( window ).removeProp( callbackName );
9326
9327			// Otherwise restore preexisting value
9328			} else {
9329				window[ callbackName ] = overwritten;
9330			}
9331
9332			// Save back as free
9333			if ( s[ callbackName ] ) {
9334
9335				// Make sure that re-using the options doesn't screw things around
9336				s.jsonpCallback = originalSettings.jsonpCallback;
9337
9338				// Save the callback name for future use
9339				oldCallbacks.push( callbackName );
9340			}
9341
9342			// Call if it was a function and we have a response
9343			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9344				overwritten( responseContainer[ 0 ] );
9345			}
9346
9347			responseContainer = overwritten = undefined;
9348		} );
9349
9350		// Delegate to script
9351		return "script";
9352	}
9353} );
9354
9355
9356
9357
9358// Argument "data" should be string of html
9359// context (optional): If specified, the fragment will be created in this context,
9360// defaults to document
9361// keepScripts (optional): If true, will include scripts passed in the html string
9362jQuery.parseHTML = function( data, context, keepScripts ) {
9363	if ( !data || typeof data !== "string" ) {
9364		return null;
9365	}
9366	if ( typeof context === "boolean" ) {
9367		keepScripts = context;
9368		context = false;
9369	}
9370	context = context || document;
9371
9372	var parsed = rsingleTag.exec( data ),
9373		scripts = !keepScripts && [];
9374
9375	// Single tag
9376	if ( parsed ) {
9377		return [ context.createElement( parsed[ 1 ] ) ];
9378	}
9379
9380	parsed = buildFragment( [ data ], context, scripts );
9381
9382	if ( scripts && scripts.length ) {
9383		jQuery( scripts ).remove();
9384	}
9385
9386	return jQuery.merge( [], parsed.childNodes );
9387};
9388
9389
9390// Keep a copy of the old load method
9391var _load = jQuery.fn.load;
9392
9393/**
9394 * Load a url into a page
9395 */
9396jQuery.fn.load = function( url, params, callback ) {
9397	if ( typeof url !== "string" && _load ) {
9398		return _load.apply( this, arguments );
9399	}
9400
9401	var selector, type, response,
9402		self = this,
9403		off = url.indexOf( " " );
9404
9405	if ( off > -1 ) {
9406		selector = jQuery.trim( url.slice( off ) );
9407		url = url.slice( 0, off );
9408	}
9409
9410	// If it's a function
9411	if ( jQuery.isFunction( params ) ) {
9412
9413		// We assume that it's the callback
9414		callback = params;
9415		params = undefined;
9416
9417	// Otherwise, build a param string
9418	} else if ( params && typeof params === "object" ) {
9419		type = "POST";
9420	}
9421
9422	// If we have elements to modify, make the request
9423	if ( self.length > 0 ) {
9424		jQuery.ajax( {
9425			url: url,
9426
9427			// If "type" variable is undefined, then "GET" method will be used.
9428			// Make value of this field explicit since
9429			// user can override it through ajaxSetup method
9430			type: type || "GET",
9431			dataType: "html",
9432			data: params
9433		} ).done( function( responseText ) {
9434
9435			// Save response for use in complete callback
9436			response = arguments;
9437
9438			self.html( selector ?
9439
9440				// If a selector was specified, locate the right elements in a dummy div
9441				// Exclude scripts to avoid IE 'Permission Denied' errors
9442				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9443
9444				// Otherwise use the full result
9445				responseText );
9446
9447		// If the request succeeds, this function gets "data", "status", "jqXHR"
9448		// but they are ignored because response was set above.
9449		// If it fails, this function gets "jqXHR", "status", "error"
9450		} ).always( callback && function( jqXHR, status ) {
9451			self.each( function() {
9452				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9453			} );
9454		} );
9455	}
9456
9457	return this;
9458};
9459
9460
9461
9462
9463// Attach a bunch of functions for handling common AJAX events
9464jQuery.each( [
9465	"ajaxStart",
9466	"ajaxStop",
9467	"ajaxComplete",
9468	"ajaxError",
9469	"ajaxSuccess",
9470	"ajaxSend"
9471], function( i, type ) {
9472	jQuery.fn[ type ] = function( fn ) {
9473		return this.on( type, fn );
9474	};
9475} );
9476
9477
9478
9479
9480jQuery.expr.filters.animated = function( elem ) {
9481	return jQuery.grep( jQuery.timers, function( fn ) {
9482		return elem === fn.elem;
9483	} ).length;
9484};
9485
9486
9487
9488
9489/**
9490 * Gets a window from an element
9491 */
9492function getWindow( elem ) {
9493	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9494}
9495
9496jQuery.offset = {
9497	setOffset: function( elem, options, i ) {
9498		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9499			position = jQuery.css( elem, "position" ),
9500			curElem = jQuery( elem ),
9501			props = {};
9502
9503		// Set position first, in-case top/left are set even on static elem
9504		if ( position === "static" ) {
9505			elem.style.position = "relative";
9506		}
9507
9508		curOffset = curElem.offset();
9509		curCSSTop = jQuery.css( elem, "top" );
9510		curCSSLeft = jQuery.css( elem, "left" );
9511		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9512			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9513
9514		// Need to be able to calculate position if either
9515		// top or left is auto and position is either absolute or fixed
9516		if ( calculatePosition ) {
9517			curPosition = curElem.position();
9518			curTop = curPosition.top;
9519			curLeft = curPosition.left;
9520
9521		} else {
9522			curTop = parseFloat( curCSSTop ) || 0;
9523			curLeft = parseFloat( curCSSLeft ) || 0;
9524		}
9525
9526		if ( jQuery.isFunction( options ) ) {
9527
9528			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9529			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9530		}
9531
9532		if ( options.top != null ) {
9533			props.top = ( options.top - curOffset.top ) + curTop;
9534		}
9535		if ( options.left != null ) {
9536			props.left = ( options.left - curOffset.left ) + curLeft;
9537		}
9538
9539		if ( "using" in options ) {
9540			options.using.call( elem, props );
9541
9542		} else {
9543			curElem.css( props );
9544		}
9545	}
9546};
9547
9548jQuery.fn.extend( {
9549	offset: function( options ) {
9550		if ( arguments.length ) {
9551			return options === undefined ?
9552				this :
9553				this.each( function( i ) {
9554					jQuery.offset.setOffset( this, options, i );
9555				} );
9556		}
9557
9558		var docElem, win,
9559			elem = this[ 0 ],
9560			box = { top: 0, left: 0 },
9561			doc = elem && elem.ownerDocument;
9562
9563		if ( !doc ) {
9564			return;
9565		}
9566
9567		docElem = doc.documentElement;
9568
9569		// Make sure it's not a disconnected DOM node
9570		if ( !jQuery.contains( docElem, elem ) ) {
9571			return box;
9572		}
9573
9574		box = elem.getBoundingClientRect();
9575		win = getWindow( doc );
9576		return {
9577			top: box.top + win.pageYOffset - docElem.clientTop,
9578			left: box.left + win.pageXOffset - docElem.clientLeft
9579		};
9580	},
9581
9582	position: function() {
9583		if ( !this[ 0 ] ) {
9584			return;
9585		}
9586
9587		var offsetParent, offset,
9588			elem = this[ 0 ],
9589			parentOffset = { top: 0, left: 0 };
9590
9591		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9592		// because it is its only offset parent
9593		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9594
9595			// Assume getBoundingClientRect is there when computed position is fixed
9596			offset = elem.getBoundingClientRect();
9597
9598		} else {
9599
9600			// Get *real* offsetParent
9601			offsetParent = this.offsetParent();
9602
9603			// Get correct offsets
9604			offset = this.offset();
9605			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9606				parentOffset = offsetParent.offset();
9607			}
9608
9609			// Add offsetParent borders
9610			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
9611			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
9612		}
9613
9614		// Subtract parent offsets and element margins
9615		return {
9616			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9617			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9618		};
9619	},
9620
9621	// This method will return documentElement in the following cases:
9622	// 1) For the element inside the iframe without offsetParent, this method will return
9623	//    documentElement of the parent window
9624	// 2) For the hidden or detached element
9625	// 3) For body or html element, i.e. in case of the html node - it will return itself
9626	//
9627	// but those exceptions were never presented as a real life use-cases
9628	// and might be considered as more preferable results.
9629	//
9630	// This logic, however, is not guaranteed and can change at any point in the future
9631	offsetParent: function() {
9632		return this.map( function() {
9633			var offsetParent = this.offsetParent;
9634
9635			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
9636				offsetParent = offsetParent.offsetParent;
9637			}
9638
9639			return offsetParent || documentElement;
9640		} );
9641	}
9642} );
9643
9644// Create scrollLeft and scrollTop methods
9645jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9646	var top = "pageYOffset" === prop;
9647
9648	jQuery.fn[ method ] = function( val ) {
9649		return access( this, function( elem, method, val ) {
9650			var win = getWindow( elem );
9651
9652			if ( val === undefined ) {
9653				return win ? win[ prop ] : elem[ method ];
9654			}
9655
9656			if ( win ) {
9657				win.scrollTo(
9658					!top ? val : win.pageXOffset,
9659					top ? val : win.pageYOffset
9660				);
9661
9662			} else {
9663				elem[ method ] = val;
9664			}
9665		}, method, val, arguments.length );
9666	};
9667} );
9668
9669// Support: Safari<7-8+, Chrome<37-44+
9670// Add the top/left cssHooks using jQuery.fn.position
9671// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9672// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9673// getComputedStyle returns percent when specified for top/left/bottom/right;
9674// rather than make the css module depend on the offset module, just check for it here
9675jQuery.each( [ "top", "left" ], function( i, prop ) {
9676	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9677		function( elem, computed ) {
9678			if ( computed ) {
9679				computed = curCSS( elem, prop );
9680
9681				// If curCSS returns percentage, fallback to offset
9682				return rnumnonpx.test( computed ) ?
9683					jQuery( elem ).position()[ prop ] + "px" :
9684					computed;
9685			}
9686		}
9687	);
9688} );
9689
9690
9691// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9692jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9693	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
9694		function( defaultExtra, funcName ) {
9695
9696		// Margin is only for outerHeight, outerWidth
9697		jQuery.fn[ funcName ] = function( margin, value ) {
9698			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9699				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9700
9701			return access( this, function( elem, type, value ) {
9702				var doc;
9703
9704				if ( jQuery.isWindow( elem ) ) {
9705
9706					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9707					// isn't a whole lot we can do. See pull request at this URL for discussion:
9708					// https://github.com/jquery/jquery/pull/764
9709					return elem.document.documentElement[ "client" + name ];
9710				}
9711
9712				// Get document width or height
9713				if ( elem.nodeType === 9 ) {
9714					doc = elem.documentElement;
9715
9716					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9717					// whichever is greatest
9718					return Math.max(
9719						elem.body
9719 ? elem.body[ "scroll" + name ] : 0, doc[ "scroll" + name ],
9720                        elem.body ? elem.body[ "offset" + name ] : 0, doc[ "offset" + name ],
9721						doc[ "client" + name ]
9722					);
9723				}
9724
9725				return value === undefined ?
9726
9727					// Get width or height on the element, requesting but not forcing parseFloat
9728					jQuery.css( elem, type, extra ) :
9729
9730					// Set width or height on the element
9731					jQuery.style( elem, type, value, extra );
9732			}, type, chainable ? margin : undefined, chainable, null );
9733		};
9734	} );
9735} );
9736
9737
9738jQuery.fn.extend( {
9739
9740	bind: function( types, data, fn ) {
9741		return this.on( types, null, data, fn );
9742	},
9743	unbind: function( types, fn ) {
9744		return this.off( types, null, fn );
9745	},
9746
9747	delegate: function( selector, types, data, fn ) {
9748		return this.on( types, selector, data, fn );
9749	},
9750	undelegate: function( selector, types, fn ) {
9751
9752		// ( namespace ) or ( selector, types [, fn] )
9753		return arguments.length === 1 ?
9754			this.off( selector, "**" ) :
9755			this.off( types, selector || "**", fn );
9756	},
9757	size: function() {
9758		return this.length;
9759	}
9760} );
9761
9762jQuery.fn.andSelf = jQuery.fn.addBack;
9763
9764
9765
9766
9767// Register as a named AMD module, since jQuery can be concatenated with other
9768// files that may use define, but not via a proper concatenation script that
9769// understands anonymous AMD modules. A named AMD is safest and most robust
9770// way to register. Lowercase jquery is used because AMD module names are
9771// derived from file names, and jQuery is normally delivered in a lowercase
9772// file name. Do this after creating the global so that if an AMD module wants
9773// to call noConflict to hide this version of jQuery, it will work.
9774
9775// Note that for maximum portability, libraries that are not jQuery should
9776// declare themselves as anonymous modules, and avoid setting a global if an
9777// AMD loader is present. jQuery is a special case. For more information, see
9778// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9779
9780if ( typeof define === "function" && define.amd ) {
9781	define( "jquery", [], function() {
9782		return jQuery;
9783	} );
9784}
9785
9786
9787
9788var
9789
9790	// Map over jQuery in case of overwrite
9791	_jQuery = window.jQuery,
9792
9793	// Map over the $ in case of overwrite
9794	_$ = window.$;
9795
9796jQuery.noConflict = function( deep ) {
9797	if ( window.$ === jQuery ) {
9798		window.$ = _$;
9799	}
9800
9801	if ( deep && window.jQuery === jQuery ) {
9802		window.jQuery = _jQuery;
9803	}
9804
9805	return jQuery;
9806};
9807
9808// Expose jQuery and $ identifiers, even in AMD
9809// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9810// and CommonJS for browser emulators (#13566)
9811if ( !noGlobal ) {
9812	window.jQuery = window.$ = jQuery;
9813}
9814
9815return jQuery;
9816}));
9817
9818/* End */
9819;
9820; /* Start:"a:4:{s:4:"full";s:55:"/bitrix/resources/intec.core/js/core.js?177790467632505";s:6:"source";s:39:"/bitrix/resources/intec.core/js/core.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
9821(function ($) {
9822
9823    // Convert form values to object
9824    $.fn.serializeObject = function() {
9825        var object = {};
9826
9827        $.each(this.serializeArray(), function() {
9828            if (object[this.name]) {
9829                if (!object[this.name].push) {
9830                    object[this.name] = [object[this.name]];
9831                }
9832                object[this.name].push(this.value || '');
9833            } else {
9834                object[this.name] = this.value || '';
9835            }
9836        });
9837
9838        return object;
9839    };
9840
9841    // Running event when element sizes change
9842    $.fn.checkSizes = function (timeout) {
9843        var $target = $(this),
9844            width = $target.width(),
9845            height = $target.height();
9846
9847        if ($target.data('isChecksizes'))
9848            return;
9849
9850        if (!api.isNumber(timeout))
9851            timeout = 500;
9852
9853        function checkSizes () {
9854            var newWidth = $target.width(),
9855                newHeight = $target.height(),
9856                changed = false;
9857
9858            if (height !== newHeight) {
9859                height = newHeight;
9860                changed = true;
9861            }
9862
9863            if (width !== newWidth) {
9864                width = newWidth;
9865                changed = true;
9866            }
9867
9868            if (changed) {
9869                $target.trigger('resize');
9870            }
9871        }
9872
9873        $target.data('isChecksizes', true);
9874        setInterval(checkSizes, timeout);
9875    };
9876
9877    var wrapper = function (object) {
9878        this.get = function () {
9879            return object;
9880        };
9881    };
9882
9883    var api = function (object) {
9884        if (object instanceof wrapper)
9885            return object;
9886
9887        return new wrapper(object);
9888    };
9889
9890    api.type = {
9891        'string': 'string',
9892        'number': 'number',
9893        'integer': 'integer',
9894        'float': 'float',
9895        'nan': 'nan',
9896        'object': 'object',
9897        'array': 'array',
9898        'function': 'function',
9899        'null': 'null',
9900        'undefined': 'undefined',
9901        'boolean': 'boolean'
9902    };
9903
9904    api.isWrapper = function (object) {
9905        return object instanceof wrapper;
9906    };
9907    api.isString = function (object) {
9908        return typeof object == api.type.string;
9909    };
9910    api.toString = function (object) {
9911        return String(object);
9912    };
9913    api.isNumber = function (object) {
9914        return typeof object == api.type.number;
9915    };
9916    api.toNumber = function (object) {
9917        return Number(object);
9918    };
9919    api.isInteger = function (object) {
9920        if (api.isNumber(object))
9921            return object % 1 === 0;
9922
9923        return false;
9924    };
9925    api.toInteger = function (object) {
9926        return parseInt(object);
9927    };
9928    api.isFloat = function (object) {
9929        if (api.isNumber(object))
9930            return object % 1 !== 0;
9931
9932        return false;
9933    };
9934    api.toFloat = function (object) {
9935        return parseFloat(object);
9936    };
9937    api.isNaN = function (object) {
9938        return isNaN(object);
9939    };
9940    api.isObject = function (object) {
9941        return typeof object == api.type.object && object !== null && !(object instanceof Array);
9942    };
9943    api.isArray = function (object) {
9944        return (object instanceof Array);
9945    };
9946    api.isFunction = function (object) {
9947        return typeof object == api.type.function;
9948    };
9949    api.isNull = function (object) {
9950        return object === null;
9951    };
9952    api.isUndefined = function (object) {
9953        return typeof object == api.type.undefined;
9954    };
9955    api.isBoolean = function (object) {
9956        return typeof object == api.type.boolean;
9957    };
9958    api.toBoolean = function (object) {
9959        return Boolean(object);
9960    };
9961    api.isDeclared = function (object) {
9962        return !api.isNull(object) && !api.isUndefined(object);
9963    };
9964    api.isEmpty = function (object) {
9965        if (!api.isDeclared(object))
9966            return true;
9967
9968        if (api.isNumber(object))
9969            return api.isNaN(object);
9970
9971        if (api.isBoolean(object))
9972            return object === false;
9973
9974        if (api.isArray(object) || api.isString(object))
9975            return object.length === 0;
9976
9977        if (api.isObject(object))
9978            return api.isEmpty(Object.getOwnPropertyNames(object));
9979
9980        return false;
9981    };
9982    api.is = function () {
9983        if (arguments.length == 0)
9984            return false;
9985
9986        var object = arguments[0];
9987        var types = Array.prototype.slice.call(arguments, 1);
9988        var result = false;
9989
9990        if (types.length == 0)
9991            return false;
9992
9993        if (api.isArray(types[0]))
9994            types = types[0];
9995
9996        api.each(types, function (index, type) {
9997            switch (type) {
9998                case api.type.string:   result = api.isString(object);      break;
9999                case api.type.number:   result = api.isNumber(object);      break;
10000                case api.type.integer:  result = api.isInteger(object);     break;
10001                case api.type.float:    result = api.isFloat(object);       break;
10002                case api.type.nan:      result = api.isNaN(object);         break;
10003                case api.type.object:   result = api.isObject(object);      break;
10004                case api.type.array:    result = api.isArray(object);       break;
10005                case api.type.function: result = api.isFunction(object);    break;
10006                case api.type.null:     result = api.isNull(object);        break;
10007                case api.type.undefined:result = api.isUndefined(object);   break;
10008                case api.type.boolean:  result = api.isBoolean(object);     break;
10009            }
10010
10011            if (result)
10012                return false;
10013        });
10014
10015        return result;
10016    };
10017    api.to = function (object, type) {
10018        var result = object;
10019
10020        switch (type) {
10021            case api.type.string: result = api.toString(object); break;
10022            case api.type.number: result = api.toNumber(object); break;
10023            case api.type.integer: result = api.toInteger(object); break;
10024            case api.type.float: result = api.toFloat(object); break;
10025            case api.type.boolean: result = api.toBoolean(object); break;
10026        }
10027
10028        return result;
10029    };
10030    api.each = function (object, callback) {
10031        var key;
10032
10033        if (api.isFunction(callback)) {
10034            if (api.isObject(object)) {
10035                for (key in object) {
10036                    if (object.hasOwnProperty(key)) {
10037                        if (callback(key, object[key]) == false) {
10038                            break;
10039                        }
10040                    }
10041                }
10042            } else if (api.isArray(object)) {
10043                var length = object.length;
10044
10045                for (key = 0; key < length; key++) {
10046                    if (callback(key, object[key]) == false) {
10047                        break;
10048                    }
10049                }
10050            }
10051        }
10052    };
10053    api.some = function (object, callback) {
10054        var result = false;
10055
10056        if (api.isFunction(callback)) {
10057            api.each(object, function (key, element) {
10058                if (callback(key, element) == true) {
10059                    result = true;
10060                    return false;
10061                }
10062            });
10063        }
10064
10065        return result;
10066    };
10067    api.every = function (object, callback) {
10068        var result = true;
10069
10070        if (api.isFunction(callback)) {
10071            api.each(object, function (key, element) {
10072                if (callback(key, element) == false) {
10073                    result = false;
10074                    return false;
10075                }
10076            });
10077        }
10078
10079        return result;
10080    };
10081    api.extend = function (object) {
10082        var objects = Array.prototype.slice.call(arguments, 1);
10083
10084        if (!api.isObject(object) && !api.isArray(object) && !api.isFunction(object))
10085            object = {};
10086
10087        api.each(objects, function (key, extender) {
10088            if (!api.isObject(extender) && !api.isArray(extender) && !api.isFunction(extender))
10089                return;
10090
10091            api.each(extender, function (key, value) {
10092                if (api.isObject(value) || api.isArray(value)) {
10093                    if (!api.isObject(object[key]) && !api.isArray(object[key]))
10094                        object[key] = api.isArray(value) ? [] : {};
10095
10096                    api.extend(object[key], value);
10097                } else {
10098                    object[key] = value;
10099                }
10100            });
10101        });
10102
10103        return object;
10104    };
10105    api.inherit = function (children, parent) {
10106        if (!api.isObject(children) && !api.isObject(parent))
10107            return;
10108
10109        var object = function () {};
10110
10111        object.prototype = parent.prototype;
10112        children.prototype = new object();
10113        children.prototype.constructor = children;
10114        children.superclass = parent;
10115    };
10116    api.bind = function (method, context) {
10117        if (!api.isFunction(method))
10118            return null;
10119
10120        return function () {
10121            return method.apply(context, arguments);
10122        }
10123    };
10124
10125    api.objectToArray = function (obj) {
10126        return Object.keys(obj).map(function (key) { return obj[key]; });
10127    };
10128
10129    api.isEqual = function (a, b) {
10130        if (api.isObject(a) && api.isObject(b)) {
10131            var aKeys = Object.keys(a),
10132                bKeys = Object.keys(b);
10133
10134            if (aKeys.length != bKeys.length )
10135                return false;
10136
10137            return !aKeys.filter(function(key){
10138                if (api.is(a[key], [api.type.object, api.type.array])) {
10139                    return !api.isEqual(a[key], b[key]);
10140                }
10141                return a[key] !== b[key];
10142            }).length;
10143        }
10144
10145        return false;
10146    };
10147
10148    api.inArray = function (needle, haystack, isStrict) {
10149        var result = false;
10150        isStrict = !!isStrict;
10151
10152        api.each(haystack, function(key, value) {
10153            if (api.is(needle, [api.type.object, api.type.array])) {
10154                if (api.isEqual(needle, value)) {
10155                    result = true;
10156                    return false;
10157                }
10158            } else if (isStrict && value === needle || !isStrict && value == needle) {
10159                result = true;
10160                return false;
10161            }
10162
10163        });
10164
10165        return result;
10166    };
10167
10168    api.proxy = function (callback, context) {
10169        if (!api.isFunction(callback))
10170            return undefined;
10171
10172        return function () {
10173            return callback.apply(context, arguments);
10174        }
10175    };
10176
10177    api.throttle = function (callback, timeout, late) {
10178        var wait = false;
10179
10180        return function () {
10181            if (!wait) {
10182                if (!late)
10183                    callback.call();
10184
10185                wait = true;
10186
10187                setTimeout(function () {
10188                    wait = false;
10189
10190                    if (late)
10191                        callback.call();
10192                }, timeout);
10193            }
10194        };
10195    };
10196
10197    api.array = {};
10198
10199    /**
10200     * api.array.clone
10201     * @param array
10202     * @returns {Array}
10203     */
10204    api.array.clone = function (array) {
10205        var result = [];
10206
10207        if (!api.isArray(array))
10208            return result;
10209
10210        api.each(array, function (index, value) {
10211            result.push(value);
10212        });
10213
10214        return result;
10215    };
10216
10217    /**
10218     * api.array.find
10219     * @param object
10220     * @param array
10221     * @param comparator
10222     * @returns {Object}
10223     */
10224    api.array.find = function (object, array, comparator) {
10225        var result = null;
10226
10227        if (!api.isArray(array))
10228            return result;
10229
10230        if (array.indexOf(object) !== -1) {
10231            result = object;
10232        } else if (api.isFunction(comparator)) {
10233            api.each(array, function (index, item) {
10234                if (comparator(index, item, object) === true) {
10235                    result = item;
10236                    return false;
10237                }
10238            });
10239        }
10240
10241        return result;
10242    };
10243
10244    /**
10245     * api.array.rebuild
10246     * @param array
10247     * @param builder
10248     */
10249    api.array.rebuild = function (array, builder) {
10250        var result = [];
10251
10252        if (api.isArray(array))
10253            if (api.isFunction(builder)) {
10254                api.each(array, function (index, item) {
10255                    result.push(builder(index, item));
10256                });
10257            } else {
10258                api.each(array, function (index, item) {
10259                    result.push(item);
10260                });
10261            }
10262
10263        return result;
10264    };
10265
10266    api.object = {};
10267
10268    /**
10269     * api.object.scan
10270     * Рекурсивный сканер объекта.
10271     * Сканирует весь объект рекурсивно и предоставляет доступ к каждому свойству, не являющемуся объектом.
10272     */
10273    api.object.scan = (function () {
10274        var Event;
10275        var handler;
10276
10277        Event = function (path, getter, setter) {
10278            var self = this;
10279
10280            Object.defineProperty(self, 'path', {
10281                'configurable': true,
10282                'enumerable': true,
10283                'get': function () {
10284                    return api.array.clone(path);
10285                }
10286            });
10287
10288            Object.defineProperty(self, 'pathString', {
10289                'configurable': true,
10290                'enumerable': true,
10291                'get': function () {
10292                    return self.path.join('.');
10293                }
10294            });
10295
10296            Object.defineProperty(self, 'value', {
10297                'configurable': true,
10298                'enumerable': true,
10299                'get': getter,
10300                'set': setter
10301            });
10302        };
10303
10304        handler = function (object, basePath, callback) {
10305            api.each(object, function (key, value) {
10306                var path;
10307
10308                path = api.array.clone(basePath);
10309                path.push(key);
10310
10311                if (api.isObject(value)) {
10312                    handler(value, path, callback);
10313                } else {
10314                    callback(new Event(path, function () {
10315                        return object[key];
10316                    }, function (value) {
10317                        object[key] = value;
10318                    }));
10319                }
10320            });
10321        };
10322
10323        return function (object, callback) {
10324            if (!api.isObject(object) || !api.isFunction(callback))
10325                return;
10326
10327            handler(object, [], callback);
10328        };
10329    })();
10330
10331    /**
10332     * api.object.configure
10333     * Рекурсивно обходит свойства объекта, которые присутствуют в объекте с данными
10334     * и устанавливает в них значения в соответствии с объектом данных.
10335     */
10336    api.object.configure = (function () {
10337        var Event;
10338        var handler;
10339
10340        Event = function (path, oldValue, value) {
10341            var self = this;
10342            var isCancelled = false;
10343
10344            Object.defineProperty(self, 'path', {
10345                'configurable': true,
10346                'enumerable': true,
10347                'get': function () {
10348                    return api.array.clone(path);
10349                }
10350            });
10351
10352            Object.defineProperty(self, 'pathString', {
10353                'configurable': true,
10354                'enumerable': true,
10355                'get': function () {
10356                    return self.path.join('.');
10357                }
10358            });
10359
10360            Object.defineProperty(self, 'value', {
10361                'configurable': true,
10362                'enumerable': true,
10363                'get': function () {
10364                    return value;
10365                },
10366                'set': function (data) {
10367                    value = data;
10368                }
10369            });
10370
10371            Object.defineProperty(self, 'oldValue', {
10372                'configurable': true,
10373                'enumerable': true,
10374                'get': function () {
10375                    return oldValue;
10376                },
10377                'set': function (data) {
10378                    oldValue = data;
10379                }
10380            });
10381
10382            Object.defineProperty(self, 'isCancelled', {
10383                'configurable': true,
10384                'enumerable': true,
10385                'get': function () {
10386                    return isCancelled;
10387                }
10388            });
10389
10390            self.cancel = function () {
10391                isCancelled = true;
10392            };
10393        };
10394
10395        handler = function (object, data, basePath, callback) {
10396            api.each(object, function (key, value) {
10397                var path;
10398                var event;
10399
10400                path = api.array.clone(basePath);
10401                path.push(key);
10402
10403                if (api.isFunction(value))
10404                    return;
10405
10406                if (api.isObject(value)) {
10407                    if (api.isObject(data[key]))
10408                        handler(value, data[key], path, callback);
10409                } else if (!api.isUndefined(data[key])) {
10410                    if (callback !== null) {
10411                        event = new Event(path, value, api.isArray(data[key]) ? api.extend([], data[key]) : data[key]);
10412                        callback(event);
10413
10414                        if (event.isCancelled)
10415                            return;
10416
10417                        value = event.value;
10418                    } else {
10419                        value = api.isArray(data[key]) ? api.extend([], data[key]) : data[key];
10420                    }
10421
10422                    if (api.isArray(object[key])) {
10423                        if (object[key].length > 0)
10424                            object[key].splice(0, object[key].length);
10425
10426                        api.each(value, function (index, part) {
10427                            object[key].push(part);
10428                        });
10429                        object[key] = value;
10430                    } else {
10431                        object[key] = value;
10432                    }
10433                }
10434            });
10435        };
10436
10437        return function (object, data, callback) {
10438            if (!api.isFunction(callback))
10439                callback = null;
10440
10441            if (!api.isObject(object) || !api.isObject(data))
10442                return;
10443
10444            handler(object, data, [], callback);
10445        };
10446    })();
10447
10448    /**
10449     * api.object.getValue
10450     * Рекурсивно получает значение свойства из объекта.
10451     */
10452    api.object.getValue = function (object, path) {
10453        if (!api.isObject(object))
10454            return undefined;
10455
10456        if (api.isArray(path)) {
10457            path = api.array.rebuild(path);
10458        } else {
10459            return object[path];
10460        }
10461
10462        while (true) {
10463            if (path.length === 0)
10464                return object;
10465
10466            if (!api.isObject(object))
10467                return undefined;
10468
10469            var part = path.shift();
10470
10471            object = object[part];
10472        }
10473    };
10474
10475    /**
10476     * api.object.getValue
10477     * Рекурсивно устанавливает значение свойства в объект.
10478     */
10479    api.object.setValue = function (object, path, value) {
10480        if (!api.isObject(object))
10481            return;
10482
10483        if (api.isArray(path)) {
10484            path = api.array.rebuild(path);
10485        } else {
10486            object[path] = value;
10487            return;
10488        }
10489
10490        if (path.length === 0)
10491            return;
10492
10493        while (true) {
10494            var part = path.shift();
10495            var candidate;
10496
10497            if (path.length === 0) {
10498                object[part] = value;
10499                return;
10500            } else {
10501                candidate = object[part];
10502
10503                if (!api.isDeclared(candidate)) {
10504                    object[part] = {};
10505                    object = object[part];
10506                } else if (api.isObject(candidate) || !api.isArray(candidate) || !api.isFunction(candidate)) {
10507                    object = candidate;
10508                }
10509            }
10510        }
10511    };
10512
10513    api.string = {};
10514    api.string.replace = function (string, rules) {
10515        string = api.toString(string);
10516
10517        if (!api.isObject(rules))
10518            return string;
10519
10520        api.each(rules, function (from, to) {
10521            string = string.replace(new RegExp(RegExp.escape(from), 'g'), to);
10522        });
10523
10524        return string;
10525    };
10526
10527    api.ext = {};
10528
10529    /** Класс событий **/
10530    (function () {
10531        var getName = function (name) {
10532            name = api.toString(name);
10533            return name.split('.').shift();
10534        };
10535        var getNamespace = function (name) {
10536            var namespace;
10537            namespace = api.toString(name);
10538            namespace = namespace.split('.');
10539            namespace.shift();
10540            namespace = namespace.join('.');
10541            return namespace.length ? namespace : null;
10542        };
10543
10544        var event = function () {
10545            var self = this;
10546
10547            self.once = false;
10548            self.name = null;
10549            self.context = null;
10550            self.function = null;
10551        };
10552        event.prototype.getName = function () {
10553            return getName(this.name);
10554        };
10555        event.prototype.getNamespace = function () {
10556            return getNamespace(this.name);
10557        };
10558        event.prototype.fire = function (context, parameters) {
10559            var self = this;
10560            parameters.unshift(self);
10561            if (this.context) context = this.context;
10562            return self.function.apply(context, parameters);
10563        };
10564
10565        var events = function (context, available) {
10566            var self = this;
10567            var list = [];
10568
10569            list.add = function (events, callback, context, once) {
10570                var self = this;
10571
10572                if (api.isFunction(callback) && (
10573                        api.isString(events) ||
10574                        api.isArray(events) ||
10575                        api.isObject(events)
10576                    ) && !api.isEmpty(events)) {
10577                    if (api.isString(events)) { events = events.split(' '); }
10578
10579                    api.each(events, function (index, eventName) {
10580                        var name = event.prototype.getName.call({ name: eventName });
10581
10582                        if (api.isEmpty(available) || api.some(available, function (key, value) {
10583                                return name == value;
10584                            })) {
10585                            var instance = new event();
10586
10587                            instance.name = eventName;
10588                            instance.once = once;
10589                            instance.function = callback;
10590                            instance.context = context;
10591
10592                            self.push(instance);
10593                        }
10594                    });
10595                }
10596            };
10597
10598            list.removeAt = function (id) {
10599                var self = this;
10600                if (api.isUndefined(id) || api.isNull(id)) return;
10601                if (!api.isArray(id)) id = [id];
10602                var shift = 0;
10603
10604                api.each(id, function (index, id) {
10605                    self.splice(id - shift, 1);
10606                    shift++;
10607                });
10608            };
10609
10610            list.remove = function (events, callback) {
10611                var self = this;
10612                var indexes = [];
10613
10614                if (!api.isString(events) && !api.isArray(events) && !api.isObject(events)) { return; }
10615                if (api.isString(events)) { events = events.split(' '); }
10616
10617                api.each(self, function (index, instance) {
10618                    api.each(events, function (index, eventName) {
10619                        var name = getName(eventName);
10620                        var namespace = getNamespace(eventName);
10621
10622                        if (name != instance.getName())
10623                            return true;
10624
10625                        if (namespace !== null)
10626                            if (namespace !== instance.getNamespace())
10627                                return true;
10628
10629                        if (api.isFunction(callback))
10630                            if (instance.function != callback)
10631                                return true;
10632
10633                        indexes.push(index);
10634                        return true;
10635                    });
10636                });
10637
10638                self.removeAt(indexes);
10639            };
10640
10641            self.setContext = function (object) { context = object; };
10642            self.getContext = function () { return context; };
10643
10644            self.on = function (events, callback, context) {
10645                list.add(events, callback, context, false);
10646            };
10647
10648            self.once = function (events, callback, context) {
10649                list.add(events, callback, context, true);
10650            };
10651
10652            self.off = function (events, callback) {
10653                list.remove(events, callback);
10654            };
10655
10656            //event, argument1, ..., argumentN
10657            self.trigger = function () {
10658                if (arguments.length == 0) return false;
10659
10660                var eventName = arguments[0];
10661                var name = event.prototype.getName.call({ name: eventName });
10662                var namespace = event.prototype.getNamespace.call({ name: eventName });
10663                var indexes = [];
10664                var result = true;
10665                var tempParameters = arguments;
10666
10667                api.each(list, function (index, instance) {
10668                    var parameters = Array.prototype.slice.call(tempParameters, 1);
10669
10670                    if (name != instance.getName())
10671                        return true;
10672
10673                    if (namespace !== null)
10674                        if (namespace !== instance.getNamespace())
10675                            return true;
10676
10677                    if (instance.fire(context, parameters) === false)
10678                        result = false;
10679
10680                    if (instance.once) indexes.push(index);
10681                });
10682
10683                list.removeAt(indexes);
10684                return result;
10685            };
10686        };
10687
10688        api.ext.events = function (context, available) {
10689            return new events(context, available)
10690        };
10691    })();
10692
10693    api.fn = wrapper.prototype;
10694    api.fn.isString = function () { return api.isString(this.get()) };
10695    api.fn.toString = function () { return api.toString(this.get()) };
10696    api.fn.isNumber = function () { return api.isNumber(this.get()) };
10697    api.fn.toNumber = function () { return api.toNumber(this.get()) };
10698    api.fn.isInteger = function () { return api.isInteger(this.get()) };
10699    api.fn.toInteger = function () { return api.toInteger(this.get()) };
10700    api.fn.isFloat = function () { return api.isFloat(this.get()) };
10701    api.fn.toFloat = function () { return api.toFloat(this.get()) };
10702    api.fn.isNaN = function () { return api.isNaN(this.get()) };
10703    api.fn.isObject = function () { return api.isObject(this.get()) };
10704    api.fn.isArray = function () { return api.isArray(this.get()) };
10705    api.fn.isFunction = function () { return api.isFunction(this.get()) };
10706    api.fn.isNull = function () { return api.isNull(this.get()) };
10707    api.fn.isUndefined = function () { return api.isUndefined(this.get()) };
10708    api.fn.isBoolean = function () { return api.isBoolean(this.get()) };
10709    api.fn.isDeclared = function () { return api.isDeclared(this.get()) };
10710    api.fn.isEmpty = function () { return api.isEmpty(this.get()) };
10711    api.fn.is = function () {
10712        Array.prototype.unshift.call(arguments, this.get());
10713        return api.is.apply(api, arguments);
10714    };
10715    api.fn.to = function (type) { return api.to(this.get(), type); };
10716    api.fn.each = function (callback) { api.each(this.get(), callback); return this; };
10717    api.fn.some = function (callback) { api.some(this.get(), callback); return this; };
10718    api.fn.every = function (callback) { api.every(this.get(), callback); return this; };
10719
10720    api.ui = {};
10721    api.ui.update = function () {
10722        api.each(api.ui.controls, function (key, constructor) {
10723            $('[data-ui-' + key + ']').each(function () {
10724                var element = $(this);
10725                if (element.parent().is('label.api-ui-switch')) {
10726                    return;
10727                }
10728                var attribute = 'ui' + key.charAt(0).toUpperCase() + key.slice(1);
10729                var object = element.data(attribute);
10730
10731                if (!(object instanceof constructor)) {
10732                    try {
10733                        object = eval('(' + object + ')');
10734                    } catch (error) {}
10735
10736                    element.data(attribute, new constructor(element, api.isObject(object) ? object : {}));
10737                }
10738            })
10739        });
10740    };
10741    api.ui.controls = {};
10742    api.ui.controls.switch = function (element, settings) {
10743        var wrap, control, flag;
10744        var self = this;
10745
10746        element = $(element);
10747        settings = api.extend({}, api.ui.controls.switch.settings, settings);
10748
10749        self.getElement = function () {
10750            return element;
10751        };
10752        self.getWrap = function () {
10753            return wrap;
10754        };
10755        self.getControl = function () {
10756            return control;
10757        };
10758        self.getFlag = function () {
10759            return flag;
10760        };
10761
10762        self.isBuilt = function () {
10763            return api.isDeclared(wrap) && api.isDeclared(control) && api.isDeclared(flag);
10764        };
10765
10766        self.build = function () {
10767            if (self.isBuilt())
10768                return;
10769
10770            wrap = $('<label />', {
10771                'class': settings.classes.wrap
10772            }).insertBefore(element);
10773            element.appendTo(wrap);
10774            control = $('<div />', {
10775                'class': settings.classes.control
10776            }).appendTo(wrap);
10777            flag = $('<div />', {
10778                'class': settings.classes.flag
10779            }).appendTo(control);
10780
10781            element.on('change.api.ui.checkbox', function () {
10782                wrap.removeClass(settings.classes.active);
10783
10784                if (element.prop('checked')) {
10785                    wrap.addClass(settings.classes.active);
10786                }
10787            });
10788
10789            wrap.on('mouseover.api.ui.switch', function () {
10790                wrap.addClass(settings.classes.hover);
10791            }).on('mouseout.api.ui.switch', function () {
10792                wrap.removeClass(settings.classes.hover);
10793            });
10794
10795            if (element.prop('checked')) {
10796                wrap.addClass(settings.classes.active);
10797            }
10798        };
10799
10800        self.destroy = function () {
10801            if (!self.isBuilt())
10802                return;
10803
10804            element.off('change.api.ui.switch');
10805            wrap.off('mouseover.api.ui.switch')
10806                .off('mouseout.api.ui.switch')
10807                .off('click.api.ui.switch');
10808
10809            element.insertBefore(wrap);
10810            flag.remove();
10811            control.remove();
10812            wrap.remove();
10813        };
10814
10815        self.build();
10816    };
10817    api.ui.controls.switch.settings = {
10818        'classes': {
10819            'wrap': 'api-ui-switch',
10820            'control': 'api-ui-switch-control',
10821            'flag': 'api-ui-switch-control-flag',
10822            'hover': 'api-ui-switch-hover',
10823            'active': 'api-ui-switch-active'
10824        }
10825    };
10826
10827    if (!api.isFunction(RegExp.escape)) {
10828        RegExp.escape = function (value) {
10829            if (api.isString(value))
10830                return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
10831
10832            return value;
10833        };
10834    }
10835
10836    if (!api.isFunction(Math.count)) {
10837        Math.count = {};
10838        Math.count.decimals = function (value) {
10839            var count = 0;
10840
10841            value = api.toFloat(value);
10842
10843            while (value % 1 !== 0) {
10844                value = value * 10;
10845                count++;
10846            }
10847
10848            return count;
10849        };
10850        Math.count.integers = function (value) {
10851            var count = 0;
10852
10853            value = api.toFloat(value);
10854
10855            while (value !== 0) {
10856                value = Math.floor(value / 10);
10857                count++;
10858            }
10859
10860            return count;
10861        }
10862    }
10863
10864    if (!api.isFunction(Math.extend)) {
10865        Math.extend = function (value, rank) {
10866            value = api.toFloat(value);
10867
10868            for (i = 0; i < rank; i++)
10869                value = value * 10;
10870
10871            return value;
10872        }
10873    }
10874
10875    api.$ = $;
10876
10877    window.intec = api;
10878})(jQuery);
10879/* End */
10880;
10881; /* Start:"a:4:{s:4:"full";s:59:"/bitrix/resources/intec.core/js/controls.js?177790467610327";s:6:"source";s:43:"/bitrix/resources/intec.core/js/controls.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
10882(function ($, api) {
10883    var control;
10884    var controls;
10885    var signature;
10886
10887    signature = function () {};
10888    signature.instance = new signature();
10889    control = function (definitions) {
10890        var control;
10891        var wrapper;
10892
10893        if (!api.isObject(definitions))
10894            definitions = {};
10895
10896        control = function (settings, node) {
10897            var self;
10898            var base;
10899
10900            self = this;
10901            base = {};
10902            base.initialized = false;
10903            base.events = api.ext.events(self);
10904            node = $(node);
10905
10906            if (node.size() !== 1)
10907                node = null;
10908
10909            settings = api.extend({}, definitions.settings, settings);
10910
10911            if (api.isFunction(definitions.configure))
10912                definitions.configure.call(self, base, settings);
10913
10914            if (api.isFunction(definitions.construct))
10915                definitions.construct.call(self, base, settings, node);
10916
10917            self.on = function (event, callback) {
10918                base.events.on(event, callback);
10919                return self;
10920            };
10921            self.once = function (event, callback) {
10922                base.events.off(event, callback);
10923                return self;
10924            };
10925            self.off = function (event, callback) {
10926                base.events.off(events, callback);
10927                return self;
10928            };
10929            self.destruct = function () {
10930                if (api.isFunction(definitions.destruct))
10931                    definitions.destruct.call(self, base, node);
10932            };
10933            self.configure = function (configuration) {
10934                settings = api.extend(settings, configuration);
10935
10936                if (api.isFunction(definitions.configure))
10937                    definitions.configure.call(self, base, settings);
10938            };
10939
10940            base.initialized = true;
10941
10942            if (api.isFunction(definitions.configure))
10943                definitions.configure.call(self, base, settings);
10944        };
10945        control.prototype = signature.instance;
10946
10947        wrapper = function (settings, nodes) {
10948            return new control(settings, nodes);
10949        };
10950        wrapper.is = function (object) {
10951              return object instanceof control;
10952        };
10953
10954        return wrapper;
10955    };
10956    controls = {};
10957    controls.is = function (object) {
10958        return object instanceof signature;
10959    };
10960
10961    /**
10962     * Numeric control
10963     * Parameters:
10964     *  settings: {
10965     *      bounds: {
10966     *          maximum: false|float|integer,
10967     *          minimum: false|float|integer
10968     *      },
10969     *      step: float|integer,
10970     *      value: float|integer,
10971     *      selectors: {
10972     *          increment: string|Element|jQuery,
10973     *          decrement: string|Element|jQuery,
10974     *          input: string|Element|jQuery
10975     *      }
10976     *  },
10977     *  node: string|Element|jQuery
10978     **/
10979    controls.numeric = control({
10980        'construct': function (base, settings, node) {
10981            var self = this;
10982            var lock = false;
10983
10984            self.set = function (value, callback) {
10985                var locker = !lock;
10986                var decimals;
10987                var old = settings.value;
10988
10989                if (locker)
10990                    lock = true;
10991
10992                value = api.toFloat(value);
10993                decimals = Math.count.decimals(settings.step);
10994
10995                if (api.isNaN(value))
10996                    if (settings.bounds.minimum !== false) {
10997                        value = settings.bounds.minimum;
10998                    } else {
10999                        value = 0;
11000                    }
11001
11002                value = api.toFloat(value.toFixed(decimals));
11003
11004                if (settings.bounds.maximum !== false)
11005                    if (value > settings.bounds.maximum)
11006                        value = settings.bounds.maximum;
11007
11008                if (settings.bounds.minimum !== false)
11009                    if (value < settings.bounds.minimum)
11010                        value = settings.bounds.minimum;
11011
11012                if (value % settings.step !== 0)
11013                    value = settings.step * Math.round(value / settings.step);
11014
11015                value = api.toFloat(value.toFixed(decimals));
11016                settings.value = value;
11017
11018                if (locker || old !== value)
11019                    base.events.trigger('change', value);
11020
11021                if (locker)
11022                    lock = false;
11023
11024                if (api.isFunction(callback))
11025                    callback.call(self, value);
11026
11027                return self;
11028            };
11029            self.get = function () {
11030                return settings.value;
11031            };
11032            self.reset = function () {
11033                self.set(settings.value);
11034                return self;
11035            };
11036            self.increment = function (callback) {
11037                var value;
11038
11039                self.set(self.get() + settings.step);
11040                value = self.get();
11041                base.events.trigger('increment', value);
11042
11043                if (api.isFunction(callback))
11044                    callback.call(self, value);
11045
11046                return self;
11047            };
11048            self.decrement = function (callback) {
11049                var value;
11050
11051                self.set(self.get() - settings.step);
11052                value = self.get();
11053                base.events.trigger('decrement', value);
11054
11055                if (api.isFunction(callback))
11056                    callback.call(self, value);
11057
11058                return self;
11059            };
11060
11061            if (node !== null) {
11062                var nodes;
11063
11064                nodes = {};
11065                nodes.increment = node.find(settings.selectors.increment);
11066                nodes.decrement = node.find(settings.selectors.decrement);
11067                nodes.input = node.find(settings.selectors.input);
11068
11069                nodes.input.handler = function () {
11070                    self.set(nodes.input.val());
11071                };
11072                nodes.input.on('change', nodes.input.handler);
11073                nodes.decrement.handler = function () {
11074                    self.increment();
11075                };
11076                nodes.increment.on('click', nodes.decrement.handler);
11077                nodes.decrement.handler = function () {
11078                    self.decrement();
11079                };
11080                nodes.decrement.on('click', nodes.decrement.handler);
11081
11082                base.events.on('change', function (event, value) {
11083                    nodes.input.val(value);
11084                });
11085
11086                base.nodes = nodes;
11087            }
11088        },
11089        'configure': function (base, settings) {
11090            var self = this;
11091
11092            settings.bounds.maximum = settings.bounds.maximum !== false ? api.toFloat(settings.bounds.maximum) : false;
11093            settings.bounds.minimum = settings.bounds.minimum !== false ? api.toFloat(settings.bounds.minimum) : false;
11094            settings.step = api.toFloat(settings.step);
11095            settings.value = api.toFloat(settings.value);
11096
11097            if (api.isNaN(settings.bounds.maximum)) settings.bounds.maximum = 0;
11098            if (api.isNaN(settings.bounds.minimum)) settings.bounds.minimum = 0;
11099            if (api.isNaN(settings.step)) settings.step = 1;
11100            if (api.isNaN(settings.value)) settings.value = 1;
11101
11102            if (settings.step <= 0)
11103                settings.step = 1;
11104
11105            if (base.initialized)
11106                self.reset();
11107        },
11108        'settings': {
11109            'bounds': {
11110                'maximum': false,
11111                'minimum': false
11112            },
11113            'step': 1,
11114            'value': 0,
11115            'selectors': {
11116                'increment': '[data-type="button"][data-action="increment"]',
11117                'decrement': '[data-type="button"][data-action="decrement"]',
11118                'input': '[data-type="input"]'
11119            }
11120        },
11121        'destroy': function (base, node) {
11122            var nodes;
11123
11124            if (node !== null) {
11125                nodes = base.nodes;
11126                nodes.input.off('change', nodes.input.handler);
11127                nodes.increment.off('click', nodes.increment.handler);
11128                nodes.decrement.off('click', nodes.decrement.handler);
11129            }
11130        }
11131    });
11132
11133    api.controls = controls;
11134
11135    $(document).ready(function () {
11136        (function ($) {
11137            $.fn.extend({
11138                'control': function (control, settings, callback) {
11139                    if (control === true) {
11140                        this.each(function () {
11141                            node = $(this);
11142                            instance = node.data('control');
11143
11144                            if (control.is(instance)) {
11145                                instance.destroy();
11146                                node.removeData('control');
11147                            }
11148                        });
11149
11150                        return;
11151                    }
11152
11153                    if (!api.isString(control)) {
11154                        control = this.data('control');
11155
11156                        if (controls.is(control))
11157                            return control;
11158
11159                        return null;
11160                    }
11161
11162                    if (control === 'is')
11163                        return null;
11164
11165                    control = controls[control];
11166
11167                    if (!api.isFunction(control))
11168                        return null;
11169
11170                    this.each(function () {
11171                        var node;
11172                        var instance;
11173                        var configuration;
11174
11175                        node = $(this);
11176                        instance = node.data('control');
11177
11178                        if (control.is(instance))
11179                            return;
11180
11181                        configuration = api.extend({}, settings, node.data('settings'));
11182
11183                        if (api.isFunction(callback))
11184                            callback.call(node, configuration, null);
11185
11186                        instance = control(configuration, node);
11187
11188                        if (api.isFunction(callback))
11189                            callback.call(node, configuration, instance);
11190
11191                        node.data('control', instance);
11192                    });
11193
11194                    return this;
11195                }
11196            })
11197        })(jQuery);
11198    });
11199})(jQuery, intec);
11200/* End */
11201;
11202; /* Start:"a:4:{s:4:"full";s:79:"/bitrix/templates/universe_s5/plugins/bootstrap/js/bootstrap.js?167687089469707";s:6:"source";s:63:"/bitrix/templates/universe_s5/plugins/bootstrap/js/bootstrap.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
vendor: 40,181 bytes, lines 11203-12577
11203/*!
11204 * Bootstrap v3.3.7 (http://getbootstrap.com)
11205 * Copyright 2011-2016 Twitter, Inc.
11206 * Licensed under the MIT license
11207 */
11208
11209if (typeof jQuery === 'undefined') {
11210  throw new Error('Bootstrap\'s JavaScript requires jQuery')
11211}
11212
11213+function ($) {
11214  'use strict';
11215  var version = $.fn.jquery.split(' ')[0].split('.')
11216  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {
11217    throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')
11218  }
11219}(jQuery);
11220
11221/* ========================================================================
11222 * Bootstrap: transition.js v3.3.7
11223 * http://getbootstrap.com/javascript/#transitions
11224 * ========================================================================
11225 * Copyright 2011-2016 Twitter, Inc.
11226 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11227 * ======================================================================== */
11228
11229
11230+function ($) {
11231  'use strict';
11232
11233  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
11234  // ============================================================
11235
11236  function transitionEnd() {
11237    var el = document.createElement('bootstrap')
11238
11239    var transEndEventNames = {
11240      WebkitTransition : 'webkitTransitionEnd',
11241      MozTransition    : 'transitionend',
11242      OTransition      : 'oTransitionEnd otransitionend',
11243      transition       : 'transitionend'
11244    }
11245
11246    for (var name in transEndEventNames) {
11247      if (el.style[name] !== undefined) {
11248        return { end: transEndEventNames[name] }
11249      }
11250    }
11251
11252    return false // explicit for ie8 (  ._.)
11253  }
11254
11255  // http://blog.alexmaccaw.com/css-transitions
11256  $.fn.emulateTransitionEnd = function (duration) {
11257    var called = false
11258    var $el = this
11259    $(this).one('bsTransitionEnd', function () { called = true })
11260    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
11261    setTimeout(callback, duration)
11262    return this
11263  }
11264
11265  $(function () {
11266    $.support.transition = transitionEnd()
11267
11268    if (!$.support.transition) return
11269
11270    $.event.special.bsTransitionEnd = {
11271      bindType: $.support.transition.end,
11272      delegateType: $.support.transition.end,
11273      handle: function (e) {
11274        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
11275      }
11276    }
11277  })
11278
11279}(jQuery);
11280
11281/* ========================================================================
11282 * Bootstrap: alert.js v3.3.7
11283 * http://getbootstrap.com/javascript/#alerts
11284 * ========================================================================
11285 * Copyright 2011-2016 Twitter, Inc.
11286 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11287 * ======================================================================== */
11288
11289
11290+function ($) {
11291  'use strict';
11292
11293  // ALERT CLASS DEFINITION
11294  // ======================
11295
11296  var dismiss = '[data-dismiss="alert"]'
11297  var Alert   = function (el) {
11298    $(el).on('click', dismiss, this.close)
11299  }
11300
11301  Alert.VERSION = '3.3.7'
11302
11303  Alert.TRANSITION_DURATION = 150
11304
11305  Alert.prototype.close = function (e) {
11306    var $this    = $(this)
11307    var selector = $this.attr('data-target')
11308
11309    if (!selector) {
11310      selector = $this.attr('href')
11311      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
11312    }
11313
11314    var $parent = $(selector === '#' ? [] : selector)
11315
11316    if (e) e.preventDefault()
11317
11318    if (!$parent.length) {
11319      $parent = $this.closest('.alert')
11320    }
11321
11322    $parent.trigger(e = $.Event('close.bs.alert'))
11323
11324    if (e.isDefaultPrevented()) return
11325
11326    $parent.removeClass('in')
11327
11328    function removeElement() {
11329      // detach from parent, fire event then clean up data
11330      $parent.detach().trigger('closed.bs.alert').remove()
11331    }
11332
11333    $.support.transition && $parent.hasClass('fade') ?
11334      $parent
11335        .one('bsTransitionEnd', removeElement)
11336        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
11337      removeElement()
11338  }
11339
11340
11341  // ALERT PLUGIN DEFINITION
11342  // =======================
11343
11344  function Plugin(option) {
11345    return this.each(function () {
11346      var $this = $(this)
11347      var data  = $this.data('bs.alert')
11348
11349      if (!data) $this.data('bs.alert', (data = new Alert(this)))
11350      if (typeof option == 'string') data[option].call($this)
11351    })
11352  }
11353
11354  var old = $.fn.alert
11355
11356  $.fn.alert             = Plugin
11357  $.fn.alert.Constructor = Alert
11358
11359
11360  // ALERT NO CONFLICT
11361  // =================
11362
11363  $.fn.alert.noConflict = function () {
11364    $.fn.alert = old
11365    return this
11366  }
11367
11368
11369  // ALERT DATA-API
11370  // ==============
11371
11372  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
11373
11374}(jQuery);
11375
11376/* ========================================================================
11377 * Bootstrap: button.js v3.3.7
11378 * http://getbootstrap.com/javascript/#buttons
11379 * ========================================================================
11380 * Copyright 2011-2016 Twitter, Inc.
11381 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11382 * ======================================================================== */
11383
11384
11385+function ($) {
11386  'use strict';
11387
11388  // BUTTON PUBLIC CLASS DEFINITION
11389  // ==============================
11390
11391  var Button = function (element, options) {
11392    this.$element  = $(element)
11393    this.options   = $.extend({}, Button.DEFAULTS, options)
11394    this.isLoading = false
11395  }
11396
11397  Button.VERSION  = '3.3.7'
11398
11399  Button.DEFAULTS = {
11400    loadingText: 'loading...'
11401  }
11402
11403  Button.prototype.setState = function (state) {
11404    var d    = 'disabled'
11405    var $el  = this.$element
11406    var val  = $el.is('input') ? 'val' : 'html'
11407    var data = $el.data()
11408
11409    state += 'Text'
11410
11411    if (data.resetText == null) $el.data('resetText', $el[val]())
11412
11413    // push to event loop to allow forms to submit
11414    setTimeout($.proxy(function () {
11415      $el[val](data[state] == null ? this.options[state] : data[state])
11416
11417      if (state == 'loadingText') {
11418        this.isLoading = true
11419        $el.addClass(d).attr(d, d).prop(d, true)
11420      } else if (this.isLoading) {
11421        this.isLoading = false
11422        $el.removeClass(d).removeAttr(d).prop(d, false)
11423      }
11424    }, this), 0)
11425  }
11426
11427  Button.prototype.toggle = function () {
11428    var changed = true
11429    var $parent = this.$element.closest('[data-toggle="buttons"]')
11430
11431    if ($parent.length) {
11432      var $input = this.$element.find('input')
11433      if ($input.prop('type') == 'radio') {
11434        if ($input.prop('checked')) changed = false
11435        $parent.find('.active').removeClass('active')
11436        this.$element.addClass('active')
11437      } else if ($input.prop('type') == 'checkbox') {
11438        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
11439        this.$element.toggleClass('active')
11440      }
11441      $input.prop('checked', this.$element.hasClass('active'))
11442      if (changed) $input.trigger('change')
11443    } else {
11444      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
11445      this.$element.toggleClass('active')
11446    }
11447  }
11448
11449
11450  // BUTTON PLUGIN DEFINITION
11451  // ========================
11452
11453  function Plugin(option) {
11454    return this.each(function () {
11455      var $this   = $(this)
11456      var data    = $this.data('bs.button')
11457      var options = typeof option == 'object' && option
11458
11459      if (!data) $this.data('bs.button', (data = new Button(this, options)))
11460
11461      if (option == 'toggle') data.toggle()
11462      else if (option) data.setState(option)
11463    })
11464  }
11465
11466  var old = $.fn.button
11467
11468  $.fn.button             = Plugin
11469  $.fn.button.Constructor = Button
11470
11471
11472  // BUTTON NO CONFLICT
11473  // ==================
11474
11475  $.fn.button.noConflict = function () {
11476    $.fn.button = old
11477    return this
11478  }
11479
11480
11481  // BUTTON DATA-API
11482  // ===============
11483
11484  $(document)
11485    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
11486      var $btn = $(e.target).closest('.btn')
11487      Plugin.call($btn, 'toggle')
11488      if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
11489        // Prevent double click on radios, and the double selections (so cancellation) on checkboxes
11490        e.preventDefault()
11491        // The target component still receive the focus
11492        if ($btn.is('input,button')) $btn.trigger('focus')
11493        else $btn.find('input:visible,button:visible').first().trigger('focus')
11494      }
11495    })
11496    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
11497      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
11498    })
11499
11500}(jQuery);
11501
11502/* ========================================================================
11503 * Bootstrap: carousel.js v3.3.7
11504 * http://getbootstrap.com/javascript/#carousel
11505 * ========================================================================
11506 * Copyright 2011-2016 Twitter, Inc.
11507 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11508 * ======================================================================== */
11509
11510
11511+function ($) {
11512  'use strict';
11513
11514  // CAROUSEL CLASS DEFINITION
11515  // =========================
11516
11517  var Carousel = function (element, options) {
11518    this.$element    = $(element)
11519    this.$indicators = this.$element.find('.carousel-indicators')
11520    this.options     = options
11521    this.paused      = null
11522    this.sliding     = null
11523    this.interval    = null
11524    this.$active     = null
11525    this.$items      = null
11526
11527    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
11528
11529    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
11530      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
11531      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
11532  }
11533
11534  Carousel.VERSION  = '3.3.7'
11535
11536  Carousel.TRANSITION_DURATION = 600
11537
11538  Carousel.DEFAULTS = {
11539    interval: 5000,
11540    pause: 'hover',
11541    wrap: true,
11542    keyboard: true
11543  }
11544
11545  Carousel.prototype.keydown = function (e) {
11546    if (/input|textarea/i.test(e.target.tagName)) return
11547    switch (e.which) {
11548      case 37: this.prev(); break
11549      case 39: this.next(); break
11550      default: return
11551    }
11552
11553    e.preventDefault()
11554  }
11555
11556  Carousel.prototype.cycle = function (e) {
11557    e || (this.paused = false)
11558
11559    this.interval && clearInterval(this.interval)
11560
11561    this.options.interval
11562      && !this.paused
11563      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
11564
11565    return this
11566  }
11567
11568  Carousel.prototype.getItemIndex = function (item) {
11569    this.$items = item.parent().children('.item')
11570    return this.$items.index(item || this.$active)
11571  }
11572
11573  Carousel.prototype.getItemForDirection = function (direction, active) {
11574    var activeIndex = this.getItemIndex(active)
11575    var willWrap = (direction == 'prev' && activeIndex === 0)
11576                || (direction == 'next' && activeIndex == (this.$items.length - 1))
11577    if (willWrap && !this.options.wrap) return active
11578    var delta = direction == 'prev' ? -1 : 1
11579    var itemIndex = (activeIndex + delta) % this.$items.length
11580    return this.$items.eq(itemIndex)
11581  }
11582
11583  Carousel.prototype.to = function (pos) {
11584    var that        = this
11585    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
11586
11587    if (pos > (this.$items.length - 1) || pos < 0) return
11588
11589    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
11590    if (activeIndex == pos) return this.pause().cycle()
11591
11592    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
11593  }
11594
11595  Carousel.prototype.pause = function (e) {
11596    e || (this.paused = true)
11597
11598    if (this.$element.find('.next, .prev').length && $.support.transition) {
11599      this.$element.trigger($.support.transition.end)
11600      this.cycle(true)
11601    }
11602
11603    this.interval = clearInterval(this.interval)
11604
11605    return this
11606  }
11607
11608  Carousel.prototype.next = function () {
11609    if (this.sliding) return
11610    return this.slide('next')
11611  }
11612
11613  Carousel.prototype.prev = function () {
11614    if (this.sliding) return
11615    return this.slide('prev')
11616  }
11617
11618  Carousel.prototype.slide = function (type, next) {
11619    var $active   = this.$element.find('.item.active')
11620    var $next     = next || this.getItemForDirection(type, $active)
11621    var isCycling = this.interval
11622    var direction = type == 'next' ? 'left' : 'right'
11623    var that      = this
11624
11625    if ($next.hasClass('active')) return (this.sliding = false)
11626
11627    var relatedTarget = $next[0]
11628    var slideEvent = $.Event('slide.bs.carousel', {
11629      relatedTarget: relatedTarget,
11630      direction: direction
11631    })
11632    this.$element.trigger(slideEvent)
11633    if (slideEvent.isDefaultPrevented()) return
11634
11635    this.sliding = true
11636
11637    isCycling && this.pause()
11638
11639    if (this.$indicators.length) {
11640      this.$indicators.find('.active').removeClass('active')
11641      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
11642      $nextIndicator && $nextIndicator.addClass('active')
11643    }
11644
11645    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
11646    if ($.support.transition && this.$element.hasClass('slide')) {
11647      $next.addClass(type)
11648      $next[0].offsetWidth // force reflow
11649      $active.addClass(direction)
11650      $next.addClass(direction)
11651      $active
11652        .one('bsTransitionEnd', function () {
11653          $next.removeClass([type, direction].join(' ')).addClass('active')
11654          $active.removeClass(['active', direction].join(' '))
11655          that.sliding = false
11656          setTimeout(function () {
11657            that.$element.trigger(slidEvent)
11658          }, 0)
11659        })
11660        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
11661    } else {
11662      $active.removeClass('active')
11663      $next.addClass('active')
11664      this.sliding = false
11665      this.$element.trigger(slidEvent)
11666    }
11667
11668    isCycling && this.cycle()
11669
11670    return this
11671  }
11672
11673
11674  // CAROUSEL PLUGIN DEFINITION
11675  // ==========================
11676
11677  function Plugin(option) {
11678    return this.each(function () {
11679      var $this   = $(this)
11680      var data    = $this.data('bs.carousel')
11681      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
11682      var action  = typeof option == 'string' ? option : options.slide
11683
11684      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
11685      if (typeof option == 'number') data.to(option)
11686      else if (action) data[action]()
11687      else if (options.interval) data.pause().cycle()
11688    })
11689  }
11690
11691  var old = $.fn.carousel
11692
11693  $.fn.carousel             = Plugin
11694  $.fn.carousel.Constructor = Carousel
11695
11696
11697  // CAROUSEL NO CONFLICT
11698  // ====================
11699
11700  $.fn.carousel.noConflict = function () {
11701    $.fn.carousel = old
11702    return this
11703  }
11704
11705
11706  // CAROUSEL DATA-API
11707  // =================
11708
11709  var clickHandler = function (e) {
11710    var href
11711    var $this   = $(this)
11712    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
11713    if (!$target.hasClass('carousel')) return
11714    var options = $.extend({}, $target.data(), $this.data())
11715    var slideIndex = $this.attr('data-slide-to')
11716    if (slideIndex) options.interval = false
11717
11718    Plugin.call($target, options)
11719
11720    if (slideIndex) {
11721      $target.data('bs.carousel').to(slideIndex)
11722    }
11723
11724    e.preventDefault()
11725  }
11726
11727  $(document)
11728    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
11729    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
11730
11731  $(window).on('load', function () {
11732    $('[data-ride="carousel"]').each(function () {
11733      var $carousel = $(this)
11734      Plugin.call($carousel, $carousel.data())
11735    })
11736  })
11737
11738}(jQuery);
11739
11740/* ========================================================================
11741 * Bootstrap: collapse.js v3.3.7
11742 * http://getbootstrap.com/javascript/#collapse
11743 * ========================================================================
11744 * Copyright 2011-2016 Twitter, Inc.
11745 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11746 * ======================================================================== */
11747
11748/* jshint latedef: false */
11749
11750+function ($) {
11751  'use strict';
11752
11753  // COLLAPSE PUBLIC CLASS DEFINITION
11754  // ================================
11755
11756  var Collapse = function (element, options) {
11757    this.$element      = $(element)
11758    this.options       = $.extend({}, Collapse.DEFAULTS, options)
11759    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
11760                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
11761    this.transitioning = null
11762
11763    if (this.options.parent) {
11764      this.$parent = this.getParent()
11765    } else {
11766      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
11767    }
11768
11769    if (this.options.toggle) this.toggle()
11770  }
11771
11772  Collapse.VERSION  = '3.3.7'
11773
11774  Collapse.TRANSITION_DURATION = 350
11775
11776  Collapse.DEFAULTS = {
11777    toggle: true
11778  }
11779
11780  Collapse.prototype.dimension = function () {
11781    var hasWidth = this.$element.hasClass('width')
11782    return hasWidth ? 'width' : 'height'
11783  }
11784
11785  Collapse.prototype.show = function () {
11786    if (this.transitioning || this.$element.hasClass('in')) return
11787
11788    var activesData
11789    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
11790
11791    if (actives && actives.length) {
11792      activesData = actives.data('bs.collapse')
11793      if (activesData && activesData.transitioning) return
11794    }
11795
11796    var startEvent = $.Event('show.bs.collapse')
11797    this.$element.trigger(startEvent)
11798    if (startEvent.isDefaultPrevented()) return
11799
11800    if (actives && actives.length) {
11801      Plugin.call(actives, 'hide')
11802      activesData || actives.data('bs.collapse', null)
11803    }
11804
11805    var dimension = this.dimension()
11806
11807    this.$element
11808      .removeClass('collapse')
11809      .addClass('collapsing')[dimension](0)
11810      .attr('aria-expanded', true)
11811
11812    this.$trigger
11813      .removeClass('collapsed')
11814      .attr('aria-expanded', true)
11815
11816    this.transitioning = 1
11817
11818    var complete = function () {
11819      this.$element
11820        .removeClass('collapsing')
11821        .addClass('collapse in')[dimension]('')
11822      this.transitioning = 0
11823      this.$element
11824        .trigger('shown.bs.collapse')
11825    }
11826
11827    if (!$.support.transition) return complete.call(this)
11828
11829    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
11830
11831    this.$element
11832      .one('bsTransitionEnd', $.proxy(complete, this))
11833      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
11834  }
11835
11836  Collapse.prototype.hide = function () {
11837    if (this.transitioning || !this.$element.hasClass('in')) return
11838
11839    var startEvent = $.Event('hide.bs.collapse')
11840    this.$element.trigger(startEvent)
11841    if (startEvent.isDefaultPrevented()) return
11842
11843    var dimension = this.dimension()
11844
11845    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
11846
11847    this.$element
11848      .addClass('collapsing')
11849      .removeClass('collapse in')
11850      .attr('aria-expanded', false)
11851
11852    this.$trigger
11853      .addClass('collapsed')
11854      .attr('aria-expanded', false)
11855
11856    this.transitioning = 1
11857
11858    var complete = function () {
11859      this.transitioning = 0
11860      this.$element
11861        .removeClass('collapsing')
11862        .addClass('collapse')
11863        .trigger('hidden.bs.collapse')
11864    }
11865
11866    if (!$.support.transition) return complete.call(this)
11867
11868    this.$element
11869      [dimension](0)
11870      .one('bsTransitionEnd', $.proxy(complete, this))
11871      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
11872  }
11873
11874  Collapse.prototype.toggle = function () {
11875    this[this.$element.hasClass('in') ? 'hide' : 'show']()
11876  }
11877
11878  Collapse.prototype.getParent = function () {
11879    return $(this.options.parent)
11880      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
11881      .each($.proxy(function (i, element) {
11882        var $element = $(element)
11883        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
11884      }, this))
11885      .end()
11886  }
11887
11888  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
11889    var isOpen = $element.hasClass('in')
11890
11891    $element.attr('aria-expanded', isOpen)
11892    $trigger
11893      .toggleClass('collapsed', !isOpen)
11894      .attr('aria-expanded', isOpen)
11895  }
11896
11897  function getTargetFromTrigger($trigger) {
11898    var href
11899    var target = $trigger.attr('data-target')
11900      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
11901
11902    return $(target)
11903  }
11904
11905
11906  // COLLAPSE PLUGIN DEFINITION
11907  // ==========================
11908
11909  function Plugin(option) {
11910    return this.each(function () {
11911      var $this   = $(this)
11912      var data    = $this.data('bs.collapse')
11913      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
11914
11915      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
11916      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
11917      if (typeof option == 'string') data[option]()
11918    })
11919  }
11920
11921  var old = $.fn.collapse
11922
11923  $.fn.collapse             = Plugin
11924  $.fn.collapse.Constructor = Collapse
11925
11926
11927  // COLLAPSE NO CONFLICT
11928  // ====================
11929
11930  $.fn.collapse.noConflict = function () {
11931    $.fn.collapse = old
11932    return this
11933  }
11934
11935
11936  // COLLAPSE DATA-API
11937  // =================
11938
11939  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
11940    var $this   = $(this)
11941
11942    if (!$this.attr('data-target')) e.preventDefault()
11943
11944    var $target = getTargetFromTrigger($this)
11945    var data    = $target.data('bs.collapse')
11946    var option  = data ? 'toggle' : $this.data()
11947
11948    Plugin.call($target, option)
11949  })
11950
11951}(jQuery);
11952
11953/* ========================================================================
11954 * Bootstrap: dropdown.js v3.3.7
11955 * http://getbootstrap.com/javascript/#dropdowns
11956 * ========================================================================
11957 * Copyright 2011-2016 Twitter, Inc.
11958 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
11959 * ======================================================================== */
11960
11961
11962+function ($) {
11963  'use strict';
11964
11965  // DROPDOWN CLASS DEFINITION
11966  // =========================
11967
11968  var backdrop = '.dropdown-backdrop'
11969  var toggle   = '[data-toggle="dropdown"]'
11970  var Dropdown = function (element) {
11971    $(element).on('click.bs.dropdown', this.toggle)
11972  }
11973
11974  Dropdown.VERSION = '3.3.7'
11975
11976  function getParent($this) {
11977    var selector = $this.attr('data-target')
11978
11979    if (!selector) {
11980      selector = $this.attr('href')
11981      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
11982    }
11983
11984    var $parent = selector && $(selector)
11985
11986    return $parent && $parent.length ? $parent : $this.parent()
11987  }
11988
11989  function clearMenus(e) {
11990    if (e && e.which === 3) return
11991    $(backdrop).remove()
11992    $(toggle).each(function () {
11993      var $this         = $(this)
11994      var $parent       = getParent($this)
11995      var relatedTarget = { relatedTarget: this }
11996
11997      if (!$parent.hasClass('open')) return
11998
11999      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
12000
12001      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
12002
12003      if (e.isDefaultPrevented()) return
12004
12005      $this.attr('aria-expanded', 'false')
12006      $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
12007    })
12008  }
12009
12010  Dropdown.prototype.toggle = function (e) {
12011    var $this = $(this)
12012
12013    if ($this.is('.disabled, :disabled')) return
12014
12015    var $parent  = getParent($this)
12016    var isActive = $parent.hasClass('open')
12017
12018    clearMenus()
12019
12020    if (!isActive) {
12021      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
12022        // if mobile we use a backdrop because click events don't delegate
12023        $(document.createElement('div'))
12024          .addClass('dropdown-backdrop')
12025          .insertAfter($(this))
12026          .on('click', clearMenus)
12027      }
12028
12029      var relatedTarget = { relatedTarget: this }
12030      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
12031
12032      if (e.isDefaultPrevented()) return
12033
12034      $this
12035        .trigger('focus')
12036        .attr('aria-expanded', 'true')
12037
12038      $parent
12039        .toggleClass('open')
12040        .trigger($.Event('shown.bs.dropdown', relatedTarget))
12041    }
12042
12043    return false
12044  }
12045
12046  Dropdown.prototype.keydown = function (e) {
12047    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
12048
12049    var $this = $(this)
12050
12051    e.preventDefault()
12052    e.stopPropagation()
12053
12054    if ($this.is('.disabled, :disabled')) return
12055
12056    var $parent  = getParent($this)
12057    var isActive = $parent.hasClass('open')
12058
12059    if (!isActive && e.which != 27 || isActive && e.which == 27) {
12060      if (e.which == 27) $parent.find(toggle).trigger('focus')
12061      return $this.trigger('click')
12062    }
12063
12064    var desc = ' li:not(.disabled):visible a'
12065    var $items = $parent.find('.dropdown-menu' + desc)
12066
12067    if (!$items.length) return
12068
12069    var index = $items.index(e.target)
12070
12071    if (e.which == 38 && index > 0)                 index--         // up
12072    if (e.which == 40 && index < $items.length - 1) index++         // down
12073    if (!~index)                                    index = 0
12074
12075    $items.eq(index).trigger('focus')
12076  }
12077
12078
12079  // DROPDOWN PLUGIN DEFINITION
12080  // ==========================
12081
12082  function Plugin(option) {
12083    return this.each(function () {
12084      var $this = $(this)
12085      var data  = $this.data('bs.dropdown')
12086
12087      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
12088      if (typeof option == 'string') data[option].call($this)
12089    })
12090  }
12091
12092  var old = $.fn.dropdown
12093
12094  $.fn.dropdown             = Plugin
12095  $.fn.dropdown.Constructor = Dropdown
12096
12097
12098  // DROPDOWN NO CONFLICT
12099  // ====================
12100
12101  $.fn.dropdown.noConflict = function () {
12102    $.fn.dropdown = old
12103    return this
12104  }
12105
12106
12107  // APPLY TO STANDARD DROPDOWN ELEMENTS
12108  // ===================================
12109
12110  $(document)
12111    .on('click.bs.dropdown.data-api', clearMenus)
12112    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
12113    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
12114    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
12115    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
12116
12117}(jQuery);
12118
12119/* ========================================================================
12120 * Bootstrap: modal.js v3.3.7
12121 * http://getbootstrap.com/javascript/#modals
12122 * ========================================================================
12123 * Copyright 2011-2016 Twitter, Inc.
12124 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12125 * ======================================================================== */
12126
12127
12128+function ($) {
12129  'use strict';
12130
12131  // MODAL CLASS DEFINITION
12132  // ======================
12133
12134  var Modal = function (element, options) {
12135    this.options             = options
12136    this.$body               = $(document.body)
12137    this.$element            = $(element)
12138    this.$dialog             = this.$element.find('.modal-dialog')
12139    this.$backdrop           = null
12140    this.isShown             = null
12141    this.originalBodyPad     = null
12142    this.scrollbarWidth      = 0
12143    this.ignoreBackdropClick = false
12144
12145    if (this.options.remote) {
12146      this.$element
12147        .find('.modal-content')
12148        .load(this.options.remote, $.proxy(function () {
12149          this.$element.trigger('loaded.bs.modal')
12150        }, this))
12151    }
12152  }
12153
12154  Modal.VERSION  = '3.3.7'
12155
12156  Modal.TRANSITION_DURATION = 300
12157  Modal.BACKDROP_TRANSITION_DURATION = 150
12158
12159  Modal.DEFAULTS = {
12160    backdrop: true,
12161    keyboard: true,
12162    show: true
12163  }
12164
12165  Modal.prototype.toggle = function (_relatedTarget) {
12166    return this.isShown ? this.hide() : this.show(_relatedTarget)
12167  }
12168
12169  Modal.prototype.show = function (_relatedTarget) {
12170    var that = this
12171    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
12172
12173    this.$element.trigger(e)
12174
12175    if (this.isShown || e.isDefaultPrevented()) return
12176
12177    this.isShown = true
12178
12179    this.checkScrollbar()
12180    this.setScrollbar()
12181    this.$body.addClass('modal-open')
12182
12183    this.escape()
12184    this.resize()
12185
12186    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
12187
12188    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
12189      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
12190        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
12191      })
12192    })
12193
12194    this.backdrop(function () {
12195      var transition = $.support.transition && that.$element.hasClass('fade')
12196
12197      if (!that.$element.parent().length) {
12198        that.$element.appendTo(that.$body) // don't move modals dom position
12199      }
12200
12201      that.$element
12202        .show()
12203        .scrollTop(0)
12204
12205      that.adjustDialog()
12206
12207      if (transition) {
12208        that.$element[0].offsetWidth // force reflow
12209      }
12210
12211      that.$element.addClass('in')
12212
12213      that.enforceFocus()
12214
12215      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
12216
12217      transition ?
12218        that.$dialog // wait for modal to slide in
12219          .one('bsTransitionEnd', function () {
12220            that.$element.trigger('focus').trigger(e)
12221          })
12222          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
12223        that.$element.trigger('focus').trigger(e)
12224    })
12225  }
12226
12227  Modal.prototype.hide = function (e) {
12228    if (e) e.preventDefault()
12229
12230    e = $.Event('hide.bs.modal')
12231
12232    this.$element.trigger(e)
12233
12234    if (!this.isShown || e.isDefaultPrevented()) return
12235
12236    this.isShown = false
12237
12238    this.escape()
12239    this.resize()
12240
12241    $(document).off('focusin.bs.modal')
12242
12243    this.$element
12244      .removeClass('in')
12245      .off('click.dismiss.bs.modal')
12246      .off('mouseup.dismiss.bs.modal')
12247
12248    this.$dialog.off('mousedown.dismiss.bs.modal')
12249
12250    $.support.transition && this.$element.hasClass('fade') ?
12251      this.$element
12252        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
12253        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
12254      this.hideModal()
12255  }
12256
12257  Modal.prototype.enforceFocus = function () {
12258    $(document)
12259      .off('focusin.bs.modal') // guard against infinite focus loop
12260      .on('focusin.bs.modal', $.proxy(function (e) {
12261        if (document !== e.target &&
12262            this.$element[0] !== e.target &&
12263            !this.$element.has(e.target).length) {
12264          this.$element.trigger('focus')
12265        }
12266      }, this))
12267  }
12268
12269  Modal.prototype.escape = function () {
12270    if (this.isShown && this.options.keyboard) {
12271      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
12272        e.which == 27 && this.hide()
12273      }, this))
12274    } else if (!this.isShown) {
12275      this.$element.off('keydown.dismiss.bs.modal')
12276    }
12277  }
12278
12279  Modal.prototype.resize = function () {
12280    if (this.isShown) {
12281      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
12282    } else {
12283      $(window).off('resize.bs.modal')
12284    }
12285  }
12286
12287  Modal.prototype.hideModal = function () {
12288    var that = this
12289    this.$element.hide()
12290    this.backdrop(function () {
12291      that.$body.removeClass('modal-open')
12292      that.resetAdjustments()
12293      that.resetScrollbar()
12294      that.$element.trigger('hidden.bs.modal')
12295    })
12296  }
12297
12298  Modal.prototype.removeBackdrop = function () {
12299    this.$backdrop && this.$backdrop.remove()
12300    this.$backdrop = null
12301  }
12302
12303  Modal.prototype.backdrop = function (callback) {
12304    var that = this
12305    var animate = this.$element.hasClass('fade') ? 'fade' : ''
12306
12307    if (this.isShown && this.options.backdrop) {
12308      var doAnimate = $.support.transition && animate
12309
12310      this.$backdrop = $(document.createElement('div'))
12311        .addClass('modal-backdrop ' + animate)
12312        .appendTo(this.$body)
12313
12314      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
12315        if (this.ignoreBackdropClick) {
12316          this.ignoreBackdropClick = false
12317          return
12318        }
12319        if (e.target !== e.currentTarget) return
12320        this.options.backdrop == 'static'
12321          ? this.$element[0].focus()
12322          : this.hide()
12323      }, this))
12324
12325      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
12326
12327      this.$backdrop.addClass('in')
12328
12329      if (!callback) return
12330
12331      doAnimate ?
12332        this.$backdrop
12333          .one('bsTransitionEnd', callback)
12334          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
12335        callback()
12336
12337    } else if (!this.isShown && this.$backdrop) {
12338      this.$backdrop.removeClass('in')
12339
12340      var callbackRemove = function () {
12341        that.removeBackdrop()
12342        callback && callback()
12343      }
12344      $.support.transition && this.$element.hasClass('fade') ?
12345        this.$backdrop
12346          .one('bsTransitionEnd', callbackRemove)
12347          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
12348        callbackRemove()
12349
12350    } else if (callback) {
12351      callback()
12352    }
12353  }
12354
12355  // these following methods are used to handle overflowing modals
12356
12357  Modal.prototype.handleUpdate = function () {
12358    this.adjustDialog()
12359  }
12360
12361  Modal.prototype.adjustDialog = function () {
12362    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
12363
12364    this.$element.css({
12365      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
12366      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
12367    })
12368  }
12369
12370  Modal.prototype.resetAdjustments = function () {
12371    this.$element.css({
12372      paddingLeft: '',
12373      paddingRight: ''
12374    })
12375  }
12376
12377  Modal.prototype.checkScrollbar = function () {
12378    var fullWindowWidth = window.innerWidth
12379    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
12380      var documentElementRect = document.documentElement.getBoundingClientRect()
12381      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
12382    }
12383    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
12384    this.scrollbarWidth = this.measureScrollbar()
12385  }
12386
12387  Modal.prototype.setScrollbar = function () {
12388    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
12389    this.originalBodyPad = document.body.style.paddingRight || ''
12390    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
12391  }
12392
12393  Modal.prototype.resetScrollbar = function () {
12394    this.$body.css('padding-right', this.originalBodyPad)
12395  }
12396
12397  Modal.prototype.measureScrollbar = function () { // thx walsh
12398    var scrollDiv = document.createElement('div')
12399    scrollDiv.className = 'modal-scrollbar-measure'
12400    this.$body.append(scrollDiv)
12401    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
12402    this.$body[0].removeChild(scrollDiv)
12403    return scrollbarWidth
12404  }
12405
12406
12407  // MODAL PLUGIN DEFINITION
12408  // =======================
12409
12410  function Plugin(option, _relatedTarget) {
12411    return this.each(function () {
12412      var $this   = $(this)
12413      var data    = $this.data('bs.modal')
12414      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
12415
12416      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
12417      if (typeof option == 'string') data[option](_relatedTarget)
12418      else if (options.show) data.show(_relatedTarget)
12419    })
12420  }
12421
12422  var old = $.fn.modal
12423
12424  $.fn.modal             = Plugin
12425  $.fn.modal.Constructor = Modal
12426
12427
12428  // MODAL NO CONFLICT
12429  // =================
12430
12431  $.fn.modal.noConflict = function () {
12432    $.fn.modal = old
12433    return this
12434  }
12435
12436
12437  // MODAL DATA-API
12438  // ==============
12439
12440  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
12441    var $this   = $(this)
12442    var href    = $this.attr('href')
12443    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
12444    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
12445
12446    if ($this.is('a')) e.preventDefault()
12447
12448    $target.one('show.bs.modal', function (showEvent) {
12449      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
12450      $target.one('hidden.bs.modal', function () {
12451        $this.is(':visible') && $this.trigger('focus')
12452      })
12453    })
12454    Plugin.call($target, option, this)
12455  })
12456
12457}(jQuery);
12458
12459/* ========================================================================
12460 * Bootstrap: tooltip.js v3.3.7
12461 * http://getbootstrap.com/javascript/#tooltip
12462 * Inspired by the original jQuery.tipsy by Jason Frame
12463 * ========================================================================
12464 * Copyright 2011-2016 Twitter, Inc.
12465 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12466 * ======================================================================== */
12467
12468
12469+function ($) {
12470  'use strict';
12471
12472  // TOOLTIP PUBLIC CLASS DEFINITION
12473  // ===============================
12474
12475  var Tooltip = function (element, options) {
12476    this.type       = null
12477    this.options    = null
12478    this.enabled    = null
12479    this.timeout    = null
12480    this.hoverState = null
12481    this.$element   = null
12482    this.inState    = null
12483
12484    this.init('tooltip', element, options)
12485  }
12486
12487  Tooltip.VERSION  = '3.3.7'
12488
12489  Tooltip.TRANSITION_DURATION = 150
12490
12491  Tooltip.DEFAULTS = {
12492    animation: true,
12493    placement: 'top',
12494    selector: false,
12495    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
12496    trigger: 'hover focus',
12497    title: '',
12498    delay: 0,
12499    html: false,
12500    container: false,
12501    viewport: {
12502      selector: 'body',
12503      padding: 0
12504    }
12505  }
12506
12507  Tooltip.prototype.init = function (type, element, options) {
12508    this.enabled   = true
12509    this.type      = type
12510    this.$element  = $(element)
12511    this.options   = this.getOptions(options)
12512    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
12513    this.inState   = { click: false, hover: false, focus: false }
12514
12515    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
12516      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
12517    }
12518
12519    var triggers = this.options.trigger.split(' ')
12520
12521    for (var i = triggers.length; i--;) {
12522      var trigger = triggers[i]
12523
12524      if (trigger == 'click') {
12525        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
12526      } else if (trigger != 'manual') {
12527        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
12528        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
12529
12530        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
12531        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
12532      }
12533    }
12534
12535    this.options.selector ?
12536      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
12537      this.fixTitle()
12538  }
12539
12540  Tooltip.prototype.getDefaults = function () {
12541    return Tooltip.DEFAULTS
12542  }
12543
12544  Tooltip.prototype.getOptions = function (options) {
12545    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
12546
12547    if (options.delay && typeof options.delay == 'number') {
12548      options.delay = {
12549        show: options.delay,
12550        hide: options.delay
12551      }
12552    }
12553
12554    return options
12555  }
12556
12557  Tooltip.prototype.getDelegateOptions = function () {
12558    var options  = {}
12559    var defaults = this.getDefaults()
12560
12561    this._options && $.each(this._options, function (key, value) {
12562      if (defaults[key] != value) options[key] = value
12563    })
12564
12565    return options
12566  }
12567
12568  Tooltip.prototype.enter = function (obj) {
12569    var self = obj instanceof this.constructor ?
12570      obj : $(obj.currentTarget).data('bs.' + this.type)
12571
12572    if (!self) {
12573      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
12574      $(obj.currentTarget).data('bs.' + this.type, self)
12575    }
12576
12577    if (obj instanceof $.Event) {
vendor: 9,753 bytes, lines 12578-12856
12578      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
12579    }
12580
12581    if (self.tip().hasClass('in') || self.hoverState == 'in') {
12582      self.hoverState = 'in'
12583      return
12584    }
12585
12586    clearTimeout(self.timeout)
12587
12588    self.hoverState = 'in'
12589
12590    if (!self.options.delay || !self.options.delay.show) return self.show()
12591
12592    self.timeout = setTimeout(function () {
12593      if (self.hoverState == 'in') self.show()
12594    }, self.options.delay.show)
12595  }
12596
12597  Tooltip.prototype.isInStateTrue = function () {
12598    for (var key in this.inState) {
12599      if (this.inState[key]) return true
12600    }
12601
12602    return false
12603  }
12604
12605  Tooltip.prototype.leave = function (obj) {
12606    var self = obj instanceof this.constructor ?
12607      obj : $(obj.currentTarget).data('bs.' + this.type)
12608
12609    if (!self) {
12610      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
12611      $(obj.currentTarget).data('bs.' + this.type, self)
12612    }
12613
12614    if (obj instanceof $.Event) {
12615      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
12616    }
12617
12618    if (self.isInStateTrue()) return
12619
12620    clearTimeout(self.timeout)
12621
12622    self.hoverState = 'out'
12623
12624    if (!self.options.delay || !self.options.delay.hide) return self.hide()
12625
12626    self.timeout = setTimeout(function () {
12627      if (self.hoverState == 'out') self.hide()
12628    }, self.options.delay.hide)
12629  }
12630
12631  Tooltip.prototype.show = function () {
12632    var e = $.Event('show.bs.' + this.type)
12633
12634    if (this.hasContent() && this.enabled) {
12635      this.$element.trigger(e)
12636
12637      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
12638      if (e.isDefaultPrevented() || !inDom) return
12639      var that = this
12640
12641      var $tip = this.tip()
12642
12643      var tipId = this.getUID(this.type)
12644
12645      this.setContent()
12646      $tip.attr('id', tipId)
12647      this.$element.attr('aria-describedby', tipId)
12648
12649      if (this.options.animation) $tip.addClass('fade')
12650
12651      var placement = typeof this.options.placement == 'function' ?
12652        this.options.placement.call(this, $tip[0], this.$element[0]) :
12653        this.options.placement
12654
12655      var autoToken = /\s?auto?\s?/i
12656      var autoPlace = autoToken.test(placement)
12657      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
12658
12659      $tip
12660        .detach()
12661        .css({ top: 0, left: 0, display: 'block' })
12662        .addClass(placement)
12663        .data('bs.' + this.type, this)
12664
12665      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
12666      this.$element.trigger('inserted.bs.' + this.type)
12667
12668      var pos          = this.getPosition()
12669      var actualWidth  = $tip[0].offsetWidth
12670      var actualHeight = $tip[0].offsetHeight
12671
12672      if (autoPlace) {
12673        var orgPlacement = placement
12674        var viewportDim = this.getPosition(this.$viewport)
12675
12676        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
12677                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
12678                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
12679                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
12680                    placement
12681
12682        $tip
12683          .removeClass(orgPlacement)
12684          .addClass(placement)
12685      }
12686
12687      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
12688
12689      this.applyPlacement(calculatedOffset, placement)
12690
12691      var complete = function () {
12692        var prevHoverState = that.hoverState
12693        that.$element.trigger('shown.bs.' + that.type)
12694        that.hoverState = null
12695
12696        if (prevHoverState == 'out') that.leave(that)
12697      }
12698
12699      $.support.transition && this.$tip.hasClass('fade') ?
12700        $tip
12701          .one('bsTransitionEnd', complete)
12702          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
12703        complete()
12704    }
12705  }
12706
12707  Tooltip.prototype.applyPlacement = function (offset, placement) {
12708    var $tip   = this.tip()
12709    var width  = $tip[0].offsetWidth
12710    var height = $tip[0].offsetHeight
12711
12712    // manually read margins because getBoundingClientRect includes difference
12713    var marginTop = parseInt($tip.css('margin-top'), 10)
12714    var marginLeft = parseInt($tip.css('margin-left'), 10)
12715
12716    // we must check for NaN for ie 8/9
12717    if (isNaN(marginTop))  marginTop  = 0
12718    if (isNaN(marginLeft)) marginLeft = 0
12719
12720    offset.top  += marginTop
12721    offset.left += marginLeft
12722
12723    // $.fn.offset doesn't round pixel values
12724    // so we use setOffset directly with our own function B-0
12725    $.offset.setOffset($tip[0], $.extend({
12726      using: function (props) {
12727        $tip.css({
12728          top: Math.round(props.top),
12729          left: Math.round(props.left)
12730        })
12731      }
12732    }, offset), 0)
12733
12734    $tip.addClass('in')
12735
12736    // check to see if placing tip in new offset caused the tip to resize itself
12737    var actualWidth  = $tip[0].offsetWidth
12738    var actualHeight = $tip[0].offsetHeight
12739
12740    if (placement == 'top' && actualHeight != height) {
12741      offset.top = offset.top + height - actualHeight
12742    }
12743
12744    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
12745
12746    if (delta.left) offset.left += delta.left
12747    else offset.top += delta.top
12748
12749    var isVertical          = /top|bottom/.test(placement)
12750    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
12751    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
12752
12753    $tip.offset(offset)
12754    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
12755  }
12756
12757  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
12758    this.arrow()
12759      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
12760      .css(isVertical ? 'top' : 'left', '')
12761  }
12762
12763  Tooltip.prototype.setContent = function () {
12764    var $tip  = this.tip()
12765    var title = this.getTitle()
12766
12767    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
12768    $tip.removeClass('fade in top bottom left right')
12769  }
12770
12771  Tooltip.prototype.hide = function (callback) {
12772    var that = this
12773    var $tip = $(this.$tip)
12774    var e    = $.Event('hide.bs.' + this.type)
12775
12776    function complete() {
12777      if (that.hoverState != 'in') $tip.detach()
12778      if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary.
12779        that.$element
12780          .removeAttr('aria-describedby')
12781          .trigger('hidden.bs.' + that.type)
12782      }
12783      callback && callback()
12784    }
12785
12786    this.$element.trigger(e)
12787
12788    if (e.isDefaultPrevented()) return
12789
12790    $tip.removeClass('in')
12791
12792    $.support.transition && $tip.hasClass('fade') ?
12793      $tip
12794        .one('bsTransitionEnd', complete)
12795        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
12796      complete()
12797
12798    this.hoverState = null
12799
12800    return this
12801  }
12802
12803  Tooltip.prototype.fixTitle = function () {
12804    var $e = this.$element
12805    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
12806      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
12807    }
12808  }
12809
12810  Tooltip.prototype.hasContent = function () {
12811    return this.getTitle()
12812  }
12813
12814  Tooltip.prototype.getPosition = function ($element) {
12815    $element   = $element || this.$element
12816
12817    var el     = $element[0]
12818    var isBody = el.tagName == 'BODY'
12819
12820    var elRect    = el.getBoundingClientRect()
12821    if (elRect.width == null) {
12822      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
12823      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
12824    }
12825    var isSvg = window.SVGElement && el instanceof window.SVGElement
12826    // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3.
12827    // See https://github.com/twbs/bootstrap/issues/20280
12828    var elOffset  = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset())
12829    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
12830    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
12831
12832    return $.extend({}, elRect, scroll, outerDims, elOffset)
12833  }
12834
12835  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
12836    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
12837           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
12838           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
12839        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
12840
12841  }
12842
12843  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
12844    var delta = { top: 0, left: 0 }
12845    if (!this.$viewport) return delta
12846
12847    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
12848    var viewportDimensions = this.getPosition(this.$viewport)
12849
12850    if (/right|left/.test(placement)) {
12851      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
12852      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
12853      if (topEdgeOffset < viewportDimensions.top) { // top overflow
12854        delta.top = viewportDimensions.top - topEdgeOffset
12855      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
12856        delta.top = viewportDimensions.top + viewportDimensions.height - bottom
vendor: 19,773 bytes, lines 12856-13579
12856EdgeOffset
12857      }
12858    } else {
12859      var leftEdgeOffset  = pos.left - viewportPadding
12860      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
12861      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
12862        delta.left = viewportDimensions.left - leftEdgeOffset
12863      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
12864        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
12865      }
12866    }
12867
12868    return delta
12869  }
12870
12871  Tooltip.prototype.getTitle = function () {
12872    var title
12873    var $e = this.$element
12874    var o  = this.options
12875
12876    title = $e.attr('data-original-title')
12877      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
12878
12879    return title
12880  }
12881
12882  Tooltip.prototype.getUID = function (prefix) {
12883    do prefix += ~~(Math.random() * 1000000)
12884    while (document.getElementById(prefix))
12885    return prefix
12886  }
12887
12888  Tooltip.prototype.tip = function () {
12889    if (!this.$tip) {
12890      this.$tip = $(this.options.template)
12891      if (this.$tip.length != 1) {
12892        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
12893      }
12894    }
12895    return this.$tip
12896  }
12897
12898  Tooltip.prototype.arrow = function () {
12899    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
12900  }
12901
12902  Tooltip.prototype.enable = function () {
12903    this.enabled = true
12904  }
12905
12906  Tooltip.prototype.disable = function () {
12907    this.enabled = false
12908  }
12909
12910  Tooltip.prototype.toggleEnabled = function () {
12911    this.enabled = !this.enabled
12912  }
12913
12914  Tooltip.prototype.toggle = function (e) {
12915    var self = this
12916    if (e) {
12917      self = $(e.currentTarget).data('bs.' + this.type)
12918      if (!self) {
12919        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
12920        $(e.currentTarget).data('bs.' + this.type, self)
12921      }
12922    }
12923
12924    if (e) {
12925      self.inState.click = !self.inState.click
12926      if (self.isInStateTrue()) self.enter(self)
12927      else self.leave(self)
12928    } else {
12929      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
12930    }
12931  }
12932
12933  Tooltip.prototype.destroy = function () {
12934    var that = this
12935    clearTimeout(this.timeout)
12936    this.hide(function () {
12937      that.$element.off('.' + that.type).removeData('bs.' + that.type)
12938      if (that.$tip) {
12939        that.$tip.detach()
12940      }
12941      that.$tip = null
12942      that.$arrow = null
12943      that.$viewport = null
12944      that.$element = null
12945    })
12946  }
12947
12948
12949  // TOOLTIP PLUGIN DEFINITION
12950  // =========================
12951
12952  function Plugin(option) {
12953    return this.each(function () {
12954      var $this   = $(this)
12955      var data    = $this.data('bs.tooltip')
12956      var options = typeof option == 'object' && option
12957
12958      if (!data && /destroy|hide/.test(option)) return
12959      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
12960      if (typeof option == 'string') data[option]()
12961    })
12962  }
12963
12964  var old = $.fn.tooltip
12965
12966  $.fn.tooltip             = Plugin
12967  $.fn.tooltip.Constructor = Tooltip
12968
12969
12970  // TOOLTIP NO CONFLICT
12971  // ===================
12972
12973  $.fn.tooltip.noConflict = function () {
12974    $.fn.tooltip = old
12975    return this
12976  }
12977
12978}(jQuery);
12979
12980/* ========================================================================
12981 * Bootstrap: popover.js v3.3.7
12982 * http://getbootstrap.com/javascript/#popovers
12983 * ========================================================================
12984 * Copyright 2011-2016 Twitter, Inc.
12985 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
12986 * ======================================================================== */
12987
12988
12989+function ($) {
12990  'use strict';
12991
12992  // POPOVER PUBLIC CLASS DEFINITION
12993  // ===============================
12994
12995  var Popover = function (element, options) {
12996    this.init('popover', element, options)
12997  }
12998
12999  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
13000
13001  Popover.VERSION  = '3.3.7'
13002
13003  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
13004    placement: 'right',
13005    trigger: 'click',
13006    content: '',
13007    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
13008  })
13009
13010
13011  // NOTE: POPOVER EXTENDS tooltip.js
13012  // ================================
13013
13014  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
13015
13016  Popover.prototype.constructor = Popover
13017
13018  Popover.prototype.getDefaults = function () {
13019    return Popover.DEFAULTS
13020  }
13021
13022  Popover.prototype.setContent = function () {
13023    var $tip    = this.tip()
13024    var title   = this.getTitle()
13025    var content = this.getContent()
13026
13027    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
13028    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
13029      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
13030    ](content)
13031
13032    $tip.removeClass('fade top bottom left right in')
13033
13034    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
13035    // this manually by checking the contents.
13036    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
13037  }
13038
13039  Popover.prototype.hasContent = function () {
13040    return this.getTitle() || this.getContent()
13041  }
13042
13043  Popover.prototype.getContent = function () {
13044    var $e = this.$element
13045    var o  = this.options
13046
13047    return $e.attr('data-content')
13048      || (typeof o.content == 'function' ?
13049            o.content.call($e[0]) :
13050            o.content)
13051  }
13052
13053  Popover.prototype.arrow = function () {
13054    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
13055  }
13056
13057
13058  // POPOVER PLUGIN DEFINITION
13059  // =========================
13060
13061  function Plugin(option) {
13062    return this.each(function () {
13063      var $this   = $(this)
13064      var data    = $this.data('bs.popover')
13065      var options = typeof option == 'object' && option
13066
13067      if (!data && /destroy|hide/.test(option)) return
13068      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
13069      if (typeof option == 'string') data[option]()
13070    })
13071  }
13072
13073  var old = $.fn.popover
13074
13075  $.fn.popover             = Plugin
13076  $.fn.popover.Constructor = Popover
13077
13078
13079  // POPOVER NO CONFLICT
13080  // ===================
13081
13082  $.fn.popover.noConflict = function () {
13083    $.fn.popover = old
13084    return this
13085  }
13086
13087}(jQuery);
13088
13089/* ========================================================================
13090 * Bootstrap: scrollspy.js v3.3.7
13091 * http://getbootstrap.com/javascript/#scrollspy
13092 * ========================================================================
13093 * Copyright 2011-2016 Twitter, Inc.
13094 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13095 * ======================================================================== */
13096
13097
13098+function ($) {
13099  'use strict';
13100
13101  // SCROLLSPY CLASS DEFINITION
13102  // ==========================
13103
13104  function ScrollSpy(element, options) {
13105    this.$body          = $(document.body)
13106    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
13107    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
13108    this.selector       = (this.options.target || '') + ' .nav li > a'
13109    this.offsets        = []
13110    this.targets        = []
13111    this.activeTarget   = null
13112    this.scrollHeight   = 0
13113
13114    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
13115    this.refresh()
13116    this.process()
13117  }
13118
13119  ScrollSpy.VERSION  = '3.3.7'
13120
13121  ScrollSpy.DEFAULTS = {
13122    offset: 10
13123  }
13124
13125  ScrollSpy.prototype.getScrollHeight = function () {
13126    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
13127  }
13128
13129  ScrollSpy.prototype.refresh = function () {
13130    var that          = this
13131    var offsetMethod  = 'offset'
13132    var offsetBase    = 0
13133
13134    this.offsets      = []
13135    this.targets      = []
13136    this.scrollHeight = this.getScrollHeight()
13137
13138    if (!$.isWindow(this.$scrollElement[0])) {
13139      offsetMethod = 'position'
13140      offsetBase   = this.$scrollElement.scrollTop()
13141    }
13142
13143    this.$body
13144      .find(this.selector)
13145      .map(function () {
13146        var $el   = $(this)
13147        var href  = $el.data('target') || $el.attr('href')
13148        var $href = /^#./.test(href) && $(href)
13149
13150        return ($href
13151          && $href.length
13152          && $href.is(':visible')
13153          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
13154      })
13155      .sort(function (a, b) { return a[0] - b[0] })
13156      .each(function () {
13157        that.offsets.push(this[0])
13158        that.targets.push(this[1])
13159      })
13160  }
13161
13162  ScrollSpy.prototype.process = function () {
13163    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
13164    var scrollHeight = this.getScrollHeight()
13165    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
13166    var offsets      = this.offsets
13167    var targets      = this.targets
13168    var activeTarget = this.activeTarget
13169    var i
13170
13171    if (this.scrollHeight != scrollHeight) {
13172      this.refresh()
13173    }
13174
13175    if (scrollTop >= maxScroll) {
13176      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
13177    }
13178
13179    if (activeTarget && scrollTop < offsets[0]) {
13180      this.activeTarget = null
13181      return this.clear()
13182    }
13183
13184    for (i = offsets.length; i--;) {
13185      activeTarget != targets[i]
13186        && scrollTop >= offsets[i]
13187        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
13188        && this.activate(targets[i])
13189    }
13190  }
13191
13192  ScrollSpy.prototype.activate = function (target) {
13193    this.activeTarget = target
13194
13195    this.clear()
13196
13197    var selector = this.selector +
13198      '[data-target="' + target + '"],' +
13199      this.selector + '[href="' + target + '"]'
13200
13201    var active = $(selector)
13202      .parents('li')
13203      .addClass('active')
13204
13205    if (active.parent('.dropdown-menu').length) {
13206      active = active
13207        .closest('li.dropdown')
13208        .addClass('active')
13209    }
13210
13211    active.trigger('activate.bs.scrollspy')
13212  }
13213
13214  ScrollSpy.prototype.clear = function () {
13215    $(this.selector)
13216      .parentsUntil(this.options.target, '.active')
13217      .removeClass('active')
13218  }
13219
13220
13221  // SCROLLSPY PLUGIN DEFINITION
13222  // ===========================
13223
13224  function Plugin(option) {
13225    return this.each(function () {
13226      var $this   = $(this)
13227      var data    = $this.data('bs.scrollspy')
13228      var options = typeof option == 'object' && option
13229
13230      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
13231      if (typeof option == 'string') data[option]()
13232    })
13233  }
13234
13235  var old = $.fn.scrollspy
13236
13237  $.fn.scrollspy             = Plugin
13238  $.fn.scrollspy.Constructor = ScrollSpy
13239
13240
13241  // SCROLLSPY NO CONFLICT
13242  // =====================
13243
13244  $.fn.scrollspy.noConflict = function () {
13245    $.fn.scrollspy = old
13246    return this
13247  }
13248
13249
13250  // SCROLLSPY DATA-API
13251  // ==================
13252
13253  $(window).on('load.bs.scrollspy.data-api', function () {
13254    $('[data-spy="scroll"]').each(function () {
13255      var $spy = $(this)
13256      Plugin.call($spy, $spy.data())
13257    })
13258  })
13259
13260}(jQuery);
13261
13262/* ========================================================================
13263 * Bootstrap: tab.js v3.3.7
13264 * http://getbootstrap.com/javascript/#tabs
13265 * ========================================================================
13266 * Copyright 2011-2016 Twitter, Inc.
13267 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13268 * ======================================================================== */
13269
13270
13271+function ($) {
13272  'use strict';
13273
13274  // TAB CLASS DEFINITION
13275  // ====================
13276
13277  var Tab = function (element) {
13278    // jscs:disable requireDollarBeforejQueryAssignment
13279    this.element = $(element)
13280    // jscs:enable requireDollarBeforejQueryAssignment
13281  }
13282
13283  Tab.VERSION = '3.3.7'
13284
13285  Tab.TRANSITION_DURATION = 150
13286
13287  Tab.prototype.show = function () {
13288    var $this    = this.element
13289    var $ul      = $this.closest('ul:not(.dropdown-menu)')
13290    var selector = $this.data('target')
13291
13292    if (!selector) {
13293      selector = $this.attr('href')
13294      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
13295    }
13296
13297    if ($this.parent('li').hasClass('active')) return
13298
13299    var $previous = $ul.find('.active:last a')
13300    var hideEvent = $.Event('hide.bs.tab', {
13301      relatedTarget: $this[0]
13302    })
13303    var showEvent = $.Event('show.bs.tab', {
13304      relatedTarget: $previous[0]
13305    })
13306
13307    $previous.trigger(hideEvent)
13308    $this.trigger(showEvent)
13309
13310    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
13311
13312    var $target = $(selector)
13313
13314    this.activate($this.closest('li'), $ul)
13315    this.activate($target, $target.parent(), function () {
13316      $previous.trigger({
13317        type: 'hidden.bs.tab',
13318        relatedTarget: $this[0]
13319      })
13320      $this.trigger({
13321        type: 'shown.bs.tab',
13322        relatedTarget: $previous[0]
13323      })
13324    })
13325  }
13326
13327  Tab.prototype.activate = function (element, container, callback) {
13328    var $active    = container.find('> .active')
13329    var transition = callback
13330      && $.support.transition
13331      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
13332
13333    function next() {
13334      $active
13335        .removeClass('active')
13336        .find('> .dropdown-menu > .active')
13337          .removeClass('active')
13338        .end()
13339        .find('[data-toggle="tab"]')
13340          .attr('aria-expanded', false)
13341
13342      element
13343        .addClass('active')
13344        .find('[data-toggle="tab"]')
13345          .attr('aria-expanded', true)
13346
13347      if (transition) {
13348        element[0].offsetWidth // reflow for transition
13349        element.addClass('in')
13350      } else {
13351        element.removeClass('fade')
13352      }
13353
13354      if (element.parent('.dropdown-menu').length) {
13355        element
13356          .closest('li.dropdown')
13357            .addClass('active')
13358          .end()
13359          .find('[data-toggle="tab"]')
13360            .attr('aria-expanded', true)
13361      }
13362
13363      callback && callback()
13364    }
13365
13366    $active.length && transition ?
13367      $active
13368        .one('bsTransitionEnd', next)
13369        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
13370      next()
13371
13372    $active.removeClass('in')
13373  }
13374
13375
13376  // TAB PLUGIN DEFINITION
13377  // =====================
13378
13379  function Plugin(option) {
13380    return this.each(function () {
13381      var $this = $(this)
13382      var data  = $this.data('bs.tab')
13383
13384      if (!data) $this.data('bs.tab', (data = new Tab(this)))
13385      if (typeof option == 'string') data[option]()
13386    })
13387  }
13388
13389  var old = $.fn.tab
13390
13391  $.fn.tab             = Plugin
13392  $.fn.tab.Constructor = Tab
13393
13394
13395  // TAB NO CONFLICT
13396  // ===============
13397
13398  $.fn.tab.noConflict = function () {
13399    $.fn.tab = old
13400    return this
13401  }
13402
13403
13404  // TAB DATA-API
13405  // ============
13406
13407  var clickHandler = function (e) {
13408    e.preventDefault()
13409    Plugin.call($(this), 'show')
13410  }
13411
13412  $(document)
13413    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
13414    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
13415
13416}(jQuery);
13417
13418/* ========================================================================
13419 * Bootstrap: affix.js v3.3.7
13420 * http://getbootstrap.com/javascript/#affix
13421 * ========================================================================
13422 * Copyright 2011-2016 Twitter, Inc.
13423 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
13424 * ======================================================================== */
13425
13426
13427+function ($) {
13428  'use strict';
13429
13430  // AFFIX CLASS DEFINITION
13431  // ======================
13432
13433  var Affix = function (element, options) {
13434    this.options = $.extend({}, Affix.DEFAULTS, options)
13435
13436    this.$target = $(this.options.target)
13437      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
13438      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
13439
13440    this.$element     = $(element)
13441    this.affixed      = null
13442    this.unpin        = null
13443    this.pinnedOffset = null
13444
13445    this.checkPosition()
13446  }
13447
13448  Affix.VERSION  = '3.3.7'
13449
13450  Affix.RESET    = 'affix affix-top affix-bottom'
13451
13452  Affix.DEFAULTS = {
13453    offset: 0,
13454    target: window
13455  }
13456
13457  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
13458    var scrollTop    = this.$target.scrollTop()
13459    var position     = this.$element.offset()
13460    var targetHeight = this.$target.height()
13461
13462    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
13463
13464    if (this.affixed == 'bottom') {
13465      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
13466      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
13467    }
13468
13469    var initializing   = this.affixed == null
13470    var colliderTop    = initializing ? scrollTop : position.top
13471    var colliderHeight = initializing ? targetHeight : height
13472
13473    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
13474    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
13475
13476    return false
13477  }
13478
13479  Affix.prototype.getPinnedOffset = function () {
13480    if (this.pinnedOffset) return this.pinnedOffset
13481    this.$element.removeClass(Affix.RESET).addClass('affix')
13482    var scrollTop = this.$target.scrollTop()
13483    var position  = this.$element.offset()
13484    return (this.pinnedOffset = position.top - scrollTop)
13485  }
13486
13487  Affix.prototype.checkPositionWithEventLoop = function () {
13488    setTimeout($.proxy(this.checkPosition, this), 1)
13489  }
13490
13491  Affix.prototype.checkPosition = function () {
13492    if (!this.$element.is(':visible')) return
13493
13494    var height       = this.$element.height()
13495    var offset       = this.options.offset
13496    var offsetTop    = offset.top
13497    var offsetBottom = offset.bottom
13498    var scrollHeight = Math.max($(document).height(), $(document.body).height())
13499
13500    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
13501    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
13502    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
13503
13504    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
13505
13506    if (this.affixed != affix) {
13507      if (this.unpin != null) this.$element.css('top', '')
13508
13509      var affixType = 'affix' + (affix ? '-' + affix : '')
13510      var e         = $.Event(affixType + '.bs.affix')
13511
13512      this.$element.trigger(e)
13513
13514      if (e.isDefaultPrevented()) return
13515
13516      this.affixed = affix
13517      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
13518
13519      this.$element
13520        .removeClass(Affix.RESET)
13521        .addClass(affixType)
13522        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
13523    }
13524
13525    if (affix == 'bottom') {
13526      this.$element.offset({
13527        top: scrollHeight - height - offsetBottom
13528      })
13529    }
13530  }
13531
13532
13533  // AFFIX PLUGIN DEFINITION
13534  // =======================
13535
13536  function Plugin(option) {
13537    return this.each(function () {
13538      var $this   = $(this)
13539      var data    = $this.data('bs.affix')
13540      var options = typeof option == 'object' && option
13541
13542      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
13543      if (typeof option == 'string') data[option]()
13544    })
13545  }
13546
13547  var old = $.fn.affix
13548
13549  $.fn.affix             = Plugin
13550  $.fn.affix.Constructor = Affix
13551
13552
13553  // AFFIX NO CONFLICT
13554  // =================
13555
13556  $.fn.affix.noConflict = function () {
13557    $.fn.affix = old
13558    return this
13559  }
13560
13561
13562  // AFFIX DATA-API
13563  // ==============
13564
13565  $(window).on('load', function () {
13566    $('[data-spy="affix"]').each(function () {
13567      var $spy = $(this)
13568      var data = $spy.data()
13569
13570      data.offset = data.offset || {}
13571
13572      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
13573      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
13574
13575      Plugin.call($spy, data)
13576    })
13577  })
13578
13579}(jQuery);
13580
13581/* End */
13582;
13583; /* Start:"a:4:{s:4:"full";s:94:"/bitrix/templates/universe_s5/plugins/jquery.colorpicker/jquery.colorpicker.js?167687089416692";s:6:"source";s:78:"/bitrix/templates/universe_s5/plugins/jquery.colorpicker/jquery.colorpicker.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
13584/**
13585 *
13586 * Color picker
13587 * Author: Stefan Petre www.eyecon.ro
13588 * 
13589 * Dual licensed under the MIT and GPL licenses
13590 * 
13591 */
13592(function ($) {
13593	var ColorPicker = function () {
13594		var
13595			ids = {},
13596			inAction,
13597			charMin = 65,
13598			visible,
13599			tpl = '<div class="colorpicker"><div class="colorpicker_color"><div><div></div></div></div><div class="colorpicker_hue"><div></div></div><div class="colorpicker_new_color"></div><div class="colorpicker_current_color"></div><div class="colorpicker_hex"><input type="text" maxlength="6" size="6" /></div><div class="colorpicker_rgb_r colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_g colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_rgb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_h colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_s colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_hsb_b colorpicker_field"><input type="text" maxlength="3" size="3" /><span></span></div><div class="colorpicker_submit"></div></div>',
13600			defaults = {
13601				eventName: 'click',
13602				onShow: function () {},
13603				onBeforeShow: function(){},
13604				onHide: function () {},
13605				onChange: function () {},
13606				onSubmit: function () {},
13607				color: 'ff0000',
13608				livePreview: true,
13609				flat: false
13610			},
13611			fillRGBFields = function  (hsb, cal) {
13612				var rgb = HSBToRGB(hsb);
13613				$(cal).data('colorpicker').fields
13614					.eq(1).val(rgb.r).end()
13615					.eq(2).val(rgb.g).end()
13616					.eq(3).val(rgb.b).end();
13617			},
13618			fillHSBFields = function  (hsb, cal) {
13619				$(cal).data('colorpicker').fields
13620					.eq(4).val(hsb.h).end()
13621					.eq(5).val(hsb.s).end()
13622					.eq(6).val(hsb.b).end();
13623			},
13624			fillHexFields = function (hsb, cal) {
13625				$(cal).data('colorpicker').fields
13626					.eq(0).val(HSBToHex(hsb)).end();
13627			},
13628			setSelector = function (hsb, cal) {
13629				$(cal).data('colorpicker').selector.css('backgroundColor', '#' + HSBToHex({h: hsb.h, s: 100, b: 100}));
13630				$(cal).data('colorpicker').selectorIndic.css({
13631					left: parseInt(150 * hsb.s/100, 10),
13632					top: parseInt(150 * (100-hsb.b)/100, 10)
13633				});
13634			},
13635			setHue = function (hsb, cal) {
13636				$(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h/360, 10));
13637			},
13638			setCurrentColor = function (hsb, cal) {
13639				$(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + HSBToHex(hsb));
13640			},
13641			setNewColor = function (hsb, cal) {
13642				$(cal).data('colorpicker').newColor.css('backgroundColor', '#' + HSBToHex(hsb));
13643			},
13644			keyDown = function (ev) {
13645				var pressedKey = ev.charCode || ev.keyCode || -1;
13646				if ((pressedKey > charMin && pressedKey <= 90) || pressedKey == 32) {
13647					return false;
13648				}
13649				var cal = $(this).parent().parent();
13650				if (cal.data('colorpicker').livePreview === true) {
13651					change.apply(this);
13652				}
13653			},
13654			change = function (ev) {
13655				var cal = $(this).parent().parent(), col;
13656				if (this.parentNode.className.indexOf('_hex') > 0) {
13657					cal.data('colorpicker').color = col = HexToHSB(fixHex(this.value));
13658				} else if (this.parentNode.className.indexOf('_hsb') > 0) {
13659					cal.data('colorpicker').color = col = fixHSB({
13660						h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10),
13661						s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10),
13662						b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10)
13663					});
13664				} else {
13665					cal.data('colorpicker').color = col = RGBToHSB(fixRGB({
13666						r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10),
13667						g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10),
13668						b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10)
13669					}));
13670				}
13671				if (ev) {
13672					fillRGBFields(col, cal.get(0));
13673					fillHexFields(col, cal.get(0));
13674					fillHSBFields(col, cal.get(0));
13675				}
13676				setSelector(col, cal.get(0));
13677				setHue(col, cal.get(0));
13678				setNewColor(col, cal.get(0));
13679				cal.data('colorpicker').onChange.apply(cal, [col, HSBToHex(col), HSBToRGB(col)]);
13680			},
13681			blur = function (ev) {
13682				var cal = $(this).parent().parent();
13683				cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus');
13684			},
13685			focus = function () {
13686				charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65;
13687				$(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus');
13688				$(this).parent().addClass('colorpicker_focus');
13689			},
13690			downIncrement = function (ev) {
13691				var field = $(this).parent().find('input').focus();
13692				var current = {
13693					el: $(this).parent().addClass('colorpicker_slider'),
13694					max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255),
13695					y: ev.pageY,
13696					field: field,
13697					val: parseInt(field.val(), 10),
13698					preview: $(this).parent().parent().data('colorpicker').livePreview					
13699				};
13700				$(document).bind('mouseup', current, upIncrement);
13701				$(document).bind('mousemove', current, moveIncrement);
13702			},
13703			moveIncrement = function (ev) {
13704				ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10))));
13705				if (ev.data.preview) {
13706					change.apply(ev.data.field.get(0), [true]);
13707				}
13708				return false;
13709			},
13710			upIncrement = function (ev) {
13711				change.apply(ev.data.field.get(0), [true]);
13712				ev.data.el.removeClass('colorpicker_slider').find('input').focus();
13713				$(document).unbind('mouseup', upIncrement);
13714				$(document).unbind('mousemove', moveIncrement);
13715				return false;
13716			},
13717			downHue = function (ev) {
13718				var current = {
13719					cal: $(this).parent(),
13720					y: $(this).offset().top
13721				};
13722				current.preview = current.cal.data('colorpicker').livePreview;
13723				$(document).bind('mouseup', current, upHue);
13724				$(document).bind('mousemove', current, moveHue);
13725			},
13726			moveHue = function (ev) {
13727				change.apply(
13728					ev.data.cal.data('colorpicker')
13729						.fields
13730						.eq(4)
13731						.val(parseInt(360*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.y))))/150, 10))
13732						.get(0),
13733					[ev.data.preview]
13734				);
13735				return false;
13736			},
13737			upHue = function (ev) {
13738				fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
13739				fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
13740				$(document).unbind('mouseup', upHue);
13741				$(document).unbind('mousemove', moveHue);
13742				return false;
13743			},
13744			downSelector = function (ev) {
13745				var current = {
13746					cal: $(this).parent(),
13747					pos: $(this).offset()
13748				};
13749				current.preview = current.cal.data('colorpicker').livePreview;
13750				$(document).bind('mouseup', current, upSelector);
13751				$(document).bind('mousemove', current, moveSelector);
13752			},
13753			moveSelector = function (ev) {
13754				change.apply(
13755					ev.data.cal.data('colorpicker')
13756						.fields
13757						.eq(6)
13758						.val(parseInt(100*(150 - Math.max(0,Math.min(150,(ev.pageY - ev.data.pos.top))))/150, 10))
13759						.end()
13760						.eq(5)
13761						.val(parseInt(100*(Math.max(0,Math.min(150,(ev.pageX - ev.data.pos.left))))/150, 10))
13762						.get(0),
13763					[ev.data.preview]
13764				);
13765				return false;
13766			},
13767			upSelector = function (ev) {
13768				fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
13769				fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
13770				$(document).unbind('mouseup', upSelector);
13771				$(document).unbind('mousemove', moveSelector);
13772				return false;
13773			},
13774			enterSubmit = function (ev) {
13775				$(this).addClass('colorpicker_focus');
13776			},
13777			leaveSubmit = function (ev) {
13778				$(this).removeClass('colorpicker_focus');
13779			},
13780			clickSubmit = function (ev) {
13781				var cal = $(this).parent();
13782				var col = cal.data('colorpicker').color;
13783				cal.data('colorpicker').origColor = col;
13784				setCurrentColor(col, cal.get(0));
13785				cal.data('colorpicker').onSubmit(col, HSBToHex(col), HSBToRGB(col), cal.data('colorpicker').el);
13786			},
13787			show = function (ev) {
13788				var cal = $('#' + $(this).data('colorpickerId'));
13789				cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]);
13790				var pos = $(this).offset();
13791				var viewPort = getViewport();
13792				var top = pos.top + this.offsetHeight;
13793				var left = pos.left;
13794				if (top + 176 > viewPort.t + viewPort.h) {
13795					top -= this.offsetHeight + 176;
13796				}
13797				if (left + 356 > viewPort.l + viewPort.w) {
13798					left -= 356;
13799				}
13800				cal.css({left: left + 'px', top: top + 'px'});
13801				if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) != false) {
13802					cal.show();
13803				}
13804				$(document).bind('mousedown', {cal: cal}, hide);
13805				return false;
13806			},
13807			hide = function (ev) {
13808				if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
13809					if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
13810						ev.data.cal.hide();
13811					}
13812					$(document).unbind('mousedown', hide);
13813				}
13814			},
13815			isChildOf = function(parentEl, el, container) {
13816				if (parentEl == el) {
13817					return true;
13818				}
13819				if (parentEl.contains) {
13820					return parentEl.contains(el);
13821				}
13822				if ( parentEl.compareDocumentPosition ) {
13823					return !!(parentEl.compareDocumentPosition(el) & 16);
13824				}
13825				var prEl = el.parentNode;
13826				while(prEl && prEl != container) {
13827					if (prEl == parentEl)
13828						return true;
13829					prEl = prEl.parentNode;
13830				}
13831				return false;
13832			},
13833			getViewport = function () {
13834				var m = document.compatMode == 'CSS1Compat';
13835				return {
13836					l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
13837					t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
13838					w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
13839					h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
13840				};
13841			},
13842			fixHSB = function (hsb) {
13843				return {
13844					h: Math.min(360, Math.max(0, hsb.h)),
13845					s: Math.min(100, Math.max(0, hsb.s)),
13846					b: Math.min(100, Math.max(0, hsb.b))
13847				};
13848			}, 
13849			fixRGB = function (rgb) {
13850				return {
13851					r: Math.min(255, Math.max(0, rgb.r)),
13852					g: Math.min(255, Math.max(0, rgb.g)),
13853					b: Math.min(255, Math.max(0, rgb.b))
13854				};
13855			},
13856			fixHex = function (hex) {
13857				var len = 6 - hex.length;
13858				if (len > 0) {
13859					var o = [];
13860					for (var i=0; i<len; i++) {
13861						o.push('0');
13862					}
13863					o.push(hex);
13864					hex = o.join('');
13865				}
13866				return hex;
13867			}, 
13868			HexToRGB = function (hex) {
13869				var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
13870				return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
13871			},
13872			HexToHSB = function (hex) {
13873				return RGBToHSB(HexToRGB(hex));
13874			},
13875			RGBToHSB = function (rgb) {
13876				var hsb = {
13877					h: 0,
13878					s: 0,
13879					b: 0
13880				};
13881				var min = Math.min(rgb.r, rgb.g, rgb.b);
13882				var max = Math.max(rgb.r, rgb.g, rgb.b);
13883				var delta = max - min;
13884				hsb.b = max;
13885				if (max != 0) {
13886					
13887				}
13888				hsb.s = max != 0 ? 255 * delta / max : 0;
13889				if (hsb.s != 0) {
13890					if (rgb.r == max) {
13891						hsb.h = (rgb.g - rgb.b) / delta;
13892					} else if (rgb.g == max) {
13893						hsb.h = 2 + (rgb.b - rgb.r) / delta;
13894					} else {
13895						hsb.h = 4 + (rgb.r - rgb.g) / delta;
13896					}
13897				} else {
13898					hsb.h = -1;
13899				}
13900				hsb.h *= 60;
13901				if (hsb.h < 0) {
13902					hsb.h += 360;
13903				}
13904				hsb.s *= 100/255;
13905				hsb.b *= 100/255;
13906				return hsb;
13907			},
13908			HSBToRGB = function (hsb) {
13909				var rgb = {};
13910				var h = Math.round(hsb.h);
13911				var s = Math.round(hsb.s*255/100);
13912				var v = Math.round(hsb.b*255/100);
13913				if(s == 0) {
13914					rgb.r = rgb.g = rgb.b = v;
13915				} else {
13916					var t1 = v;
13917					var t2 = (255-s)*v/255;
13918					var t3 = (t1-t2)*(h%60)/60;
13919					if(h==360) h = 0;
13920					if(h<60) {rgb.r=t1;	rgb.b=t2; rgb.g=t2+t3}
13921					else if(h<120) {rgb.g=t1; rgb.b=t2;	rgb.r=t1-t3}
13922					else if(h<180) {rgb.g=t1; rgb.r=t2;	rgb.b=t2+t3}
13923					else if(h<240) {rgb.b=t1; rgb.r=t2;	rgb.g=t1-t3}
13924					else if(h<300) {rgb.b=t1; rgb.g=t2;	rgb.r=t2+t3}
13925					else if(h<360) {rgb.r=t1; rgb.g=t2;	rgb.b=t1-t3}
13926					else {rgb.r=0; rgb.g=0;	rgb.b=0}
13927				}
13928				return {r:Math.round(rgb.r), g:Math.round(rgb.g), b:Math.round(rgb.b)};
13929			},
13930			RGBToHex = function (rgb) {
13931				var hex = [
13932					rgb.r.toString(16),
13933					rgb.g.toString(16),
13934					rgb.b.toString(16)
13935				];
13936				$.each(hex, function (nr, val) {
13937					if (val.length == 1) {
13938						hex[nr] = '0' + val;
13939					}
13940				});
13941				return hex.join('');
13942			},
13943			HSBToHex = function (hsb) {
13944				return RGBToHex(HSBToRGB(hsb));
13945			},
13946			restoreOriginal = function () {
13947				var cal = $(this).parent();
13948				var col = cal.data('colorpicker').origColor;
13949				cal.data('colorpicker').color = col;
13950				fillRGBFields(col, cal.get(0));
13951				fillHexFields(col, cal.get(0));
13952				fillHSBFields(col, cal.get(0));
13953				setSelector(col, cal.get(0));
13954				setHue(col, cal.get(0));
13955				setNewColor(col, cal.get(0));
13956			};
13957		return {
13958			init: function (opt) {
13959				opt = $.extend({}, defaults, opt||{});
13960				if (typeof opt.color == 'string') {
13961					opt.color = HexToHSB(opt.color);
13962				} else if (opt.color.r != undefined && opt.color.g != undefined && opt.color.b != undefined) {
13963					opt.color = RGBToHSB(opt.color);
13964				} else if (opt.color.h != undefined && opt.color.s != undefined && opt.color.b != undefined) {
13965					opt.color = fixHSB(opt.color);
13966				} else {
13967					return this;
13968				}
13969				return this.each(function () {
13970					if (!$(this).data('colorpickerId')) {
13971						var options = $.extend({}, opt);
13972						options.origColor = opt.color;
13973						var id = 'collorpicker_' + parseInt(Math.random() * 1000);
13974						$(this).data('colorpickerId', id);
13975						var cal = $(tpl).attr('id', id);
13976						if (options.flat) {
13977							cal.appendTo(this).show();
13978						} else {
13979							cal.appendTo(document.body);
13980						}
13981						options.fields = cal
13982											.find('input')
13983												.bind('keyup', keyDown)
13984												.bind('change', change)
13985												.bind('blur', blur)
13986												.bind('focus', focus);
13987						cal
13988							.find('span').bind('mousedown', downIncrement).end()
13989							.find('>div.colorpicker_current_color').bind('click', restoreOriginal);
13990						options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector);
13991						options.selectorIndic = options.selector.find('div div');
13992						options.el = this;
13993						options.hue = cal.find('div.colorpicker_hue div');
13994						cal.find('div.colorpicker_hue').bind('mousedown', downHue);
13995						options.newColor = cal.find('div.colorpicker_new_color');
13996						options.currentColor = cal.find('div.colorpicker_current_color');
13997						cal.data('colorpicker', options);
13998						cal.find('div.colorpicker_submit')
13999							.bind('mouseenter', enterSubmit)
14000							.bind('mouseleave', leaveSubmit)
14001							.bind('click', clickSubmit);
14002						fillRGBFields(options.color, cal.get(0));
14003						fillHSBFields(options.color, cal.get(0));
14004						fillHexFields(options.color, cal.get(0));
14005						setHue(options.color, cal.get(0));
14006						setSelector(options.color, cal.get(0));
14007						setCurrentColor(options.color, cal.get(0));
14008						setNewColor(options.color, cal.get(0));
14009						if (options.flat) {
14010							cal.css({
14011								position: 'relative',
14012								display: 'block'
14013							});
14014						} else {
14015							$(this).bind(options.eventName, show);
14016						}
14017					}
14018				});
14019			},
14020			showPicker: function() {
14021				return this.each( function () {
14022					if ($(this).data('colorpickerId')) {
14023						show.apply(this);
14024					}
14025				});
14026			},
14027			hidePicker: function() {
14028				return this.each( function () {
14029					if ($(this).data('colorpickerId')) {
14030						$('#' + $(this).data('colorpickerId')).hide();
14031					}
14032				});
14033			},
14034			setColor: function(col) {
14035				if (typeof col == 'string') {
14036					col = HexToHSB(col);
14037				} else if (col.r != undefined && col.g != undefined && col.b != undefined) {
14038					col = RGBToHSB(col);
14039				} else if (col.h != undefined && col.s != undefined && col.b != undefined) {
14040					col = fixHSB(col);
14041				} else {
14042					return this;
14043				}
14044				return this.each(function(){
14045					if ($(this).data('colorpickerId')) {
14046						var cal = $('#' + $(this).data('colorpickerId'));
14047						cal.data('colorpicker').color = col;
14048						cal.data('colorpicker').origColor = col;
14049						fillRGBFields(col, cal.get(0));
14050						fillHSBFields(col, cal.get(0));
14051						fillHexFields(col, cal.get(0));
14052						setHue(col, cal.get(0));
14053						setSelector(col, cal.get(0));
14054						setCurrentColor(col, cal.get(0));
14055						setNewColor(col, cal.get(0));
14056					}
14057				});
14058			}
14059		};
14060	}();
14061	$.fn.extend({
14062		ColorPicker: ColorPicker.init,
14063		ColorPickerHide: ColorPicker.hidePicker,
14064		ColorPickerShow: ColorPicker.showPicker,
14065		ColorPickerSetColor: ColorPicker.setColor
14066	});
14067})(jQuery)
14068/* End */
14069;
14070; /* Start:"a:4:{s:4:"full";s:91:"/bitrix/templates/universe_s5/plugins/jquery.mousewheel/jquery.mousewheel.js?16768708948267";s:6:"source";
vendor: 7,397 bytes, lines 14070-14269
14070s:76:"/bitrix/templates/universe_s5/plugins/jquery.mousewheel/jquery.mousewheel.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
14071/*!
14072 * jQuery Mousewheel 3.1.13
14073 *
14074 * Copyright jQuery Foundation and other contributors
14075 * Released under the MIT license
14076 * http://jquery.org/license
14077 */
14078
14079(function (factory) {
14080    if ( typeof define === 'function' && define.amd ) {
14081        // AMD. Register as an anonymous module.
14082        define(['jquery'], factory);
14083    } else if (typeof exports === 'object') {
14084        // Node/CommonJS style for Browserify
14085        module.exports = factory;
14086    } else {
14087        // Browser globals
14088        factory(jQuery);
14089    }
14090}(function ($) {
14091
14092    var toFix  = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
14093        toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
14094                    ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
14095        slice  = Array.prototype.slice,
14096        nullLowestDeltaTimeout, lowestDelta;
14097
14098    if ( $.event.fixHooks ) {
14099        for ( var i = toFix.length; i; ) {
14100            $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
14101        }
14102    }
14103
14104    var special = $.event.special.mousewheel = {
14105        version: '3.1.12',
14106
14107        setup: function() {
14108            if ( this.addEventListener ) {
14109                for ( var i = toBind.length; i; ) {
14110                    this.addEventListener( toBind[--i], handler, false );
14111                }
14112            } else {
14113                this.onmousewheel = handler;
14114            }
14115            // Store the line height and page height for this particular element
14116            $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
14117            $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
14118        },
14119
14120        teardown: function() {
14121            if ( this.removeEventListener ) {
14122                for ( var i = toBind.length; i; ) {
14123                    this.removeEventListener( toBind[--i], handler, false );
14124                }
14125            } else {
14126                this.onmousewheel = null;
14127            }
14128            // Clean up the data we added to the element
14129            $.removeData(this, 'mousewheel-line-height');
14130            $.removeData(this, 'mousewheel-page-height');
14131        },
14132
14133        getLineHeight: function(elem) {
14134            var $elem = $(elem),
14135                $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
14136            if (!$parent.length) {
14137                $parent = $('body');
14138            }
14139            return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
14140        },
14141
14142        getPageHeight: function(elem) {
14143            return $(elem).height();
14144        },
14145
14146        settings: {
14147            adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
14148            normalizeOffset: true  // calls getBoundingClientRect for each event
14149        }
14150    };
14151
14152    $.fn.extend({
14153        mousewheel: function(fn) {
14154            return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');
14155        },
14156
14157        unmousewheel: function(fn) {
14158            return this.unbind('mousewheel', fn);
14159        }
14160    });
14161
14162
14163    function handler(event) {
14164        var orgEvent   = event || window.event,
14165            args       = slice.call(arguments, 1),
14166            delta      = 0,
14167            deltaX     = 0,
14168            deltaY     = 0,
14169            absDelta   = 0,
14170            offsetX    = 0,
14171            offsetY    = 0;
14172        event = $.event.fix(orgEvent);
14173        event.type = 'mousewheel';
14174
14175        // Old school scrollwheel delta
14176        if ( 'detail'      in orgEvent ) { deltaY = orgEvent.detail * -1;      }
14177        if ( 'wheelDelta'  in orgEvent ) { deltaY = orgEvent.wheelDelta;       }
14178        if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY;      }
14179        if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
14180
14181        // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
14182        if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
14183            deltaX = deltaY * -1;
14184            deltaY = 0;
14185        }
14186
14187        // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
14188        delta = deltaY === 0 ? deltaX : deltaY;
14189
14190        // New school wheel delta (wheel event)
14191        if ( 'deltaY' in orgEvent ) {
14192            deltaY = orgEvent.deltaY * -1;
14193            delta  = deltaY;
14194        }
14195        if ( 'deltaX' in orgEvent ) {
14196            deltaX = orgEvent.deltaX;
14197            if ( deltaY === 0 ) { delta  = deltaX * -1; }
14198        }
14199
14200        // No change actually happened, no reason to go any further
14201        if ( deltaY === 0 && deltaX === 0 ) { return; }
14202
14203        // Need to convert lines and pages to pixels if we aren't already in pixels
14204        // There are three delta modes:
14205        //   * deltaMode 0 is by pixels, nothing to do
14206        //   * deltaMode 1 is by lines
14207        //   * deltaMode 2 is by pages
14208        if ( orgEvent.deltaMode === 1 ) {
14209            var lineHeight = $.data(this, 'mousewheel-line-height');
14210            delta  *= lineHeight;
14211            deltaY *= lineHeight;
14212            deltaX *= lineHeight;
14213        } else if ( orgEvent.deltaMode === 2 ) {
14214            var pageHeight = $.data(this, 'mousewheel-page-height');
14215            delta  *= pageHeight;
14216            deltaY *= pageHeight;
14217            deltaX *= pageHeight;
14218        }
14219
14220        // Store lowest absolute delta to normalize the delta values
14221        absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
14222
14223        if ( !lowestDelta || absDelta < lowestDelta ) {
14224            lowestDelta = absDelta;
14225
14226            // Adjust older deltas if necessary
14227            if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
14228                lowestDelta /= 40;
14229            }
14230        }
14231
14232        // Adjust older deltas if necessary
14233        if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
14234            // Divide all the things by 40!
14235            delta  /= 40;
14236            deltaX /= 40;
14237            deltaY /= 40;
14238        }
14239
14240        // Get a whole, normalized value for the deltas
14241        delta  = Math[ delta  >= 1 ? 'floor' : 'ceil' ](delta  / lowestDelta);
14242        deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
14243        deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
14244
14245        // Normalise offsetX and offsetY properties
14246        if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
14247            var boundingRect = this.getBoundingClientRect();
14248            offsetX = event.clientX - boundingRect.left;
14249            offsetY = event.clientY - boundingRect.top;
14250        }
14251
14252        // Add information to the event object
14253        event.deltaX = deltaX;
14254        event.deltaY = deltaY;
14255        event.deltaFactor = lowestDelta;
14256        event.offsetX = offsetX;
14257        event.offsetY = offsetY;
14258        // Go ahead and set deltaMode to 0 since we converted to pixels
14259        // Although this is a little odd since we overwrite the deltaX/Y
14260        // properties with normalized deltas.
14261        event.deltaMode = 0;
14262
14263        // Add event and delta to the front of the arguments
14264        args.unshift(event, delta, deltaX, deltaY);
14265
14266        // Clearout lowestDelta after sometime to better
14267        // handle multiple device types that give different
14268        // a different lowestDelta
14269        // Ex: trackpad = 3 and mouse wheel = 120
vendor: 5,670 bytes, lines 14270-14465
14270        if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
14271        nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
14272
14273        return ($.event.dispatch || $.event.handle).apply(this, args);
14274    }
14275
14276    function nullLowestDelta() {
14277        lowestDelta = null;
14278    }
14279
14280    function shouldAdjustOldDeltas(orgEvent, absDelta) {
14281        // If this is an older event and the delta is divisable by 120,
14282        // then we are assuming that the browser is treating this as an
14283        // older mouse wheel event and that we should divide the deltas
14284        // by 40 to try and get a more usable deltaFactor.
14285        // Side note, this actually impacts the reported scroll distance
14286        // in older browsers and can cause scrolling to be slower than native.
14287        // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
14288        return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
14289    }
14290
14291}));
14292
14293/* End */
14294;
14295; /* Start:"a:4:{s:4:"full";s:79:"/bitrix/templates/universe_s5/plugins/jquery.zoom/jquery.zoom.js?16768708945948";s:6:"source";s:64:"/bitrix/templates/universe_s5/plugins/jquery.zoom/jquery.zoom.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
14296/*!
14297	Zoom 1.7.21
14298	license: MIT
14299	http://www.jacklmoore.com/zoom
14300*/
14301(function ($) {
14302	var defaults = {
14303		url: false,
14304		callback: false,
14305		target: false,
14306		duration: 120,
14307		on: 'mouseover', // other options: grab, click, toggle
14308		touch: true, // enables a touch fallback
14309		onZoomIn: false,
14310		onZoomOut: false,
14311		magnify: 1
14312	};
14313
14314	// Core Zoom Logic, independent of event listeners.
14315	$.zoom = function(target, source, img, magnify) {
14316		var targetHeight,
14317			targetWidth,
14318			sourceHeight,
14319			sourceWidth,
14320			xRatio,
14321			yRatio,
14322			offset,
14323			$target = $(target),
14324			position = $target.css('position'),
14325			$source = $(source);
14326
14327		// The parent element needs positioning so that the zoomed element can be correctly positioned within.
14328		target.style.position = /(absolute|fixed)/.test(position) ? position : 'relative';
14329		target.style.overflow = 'hidden';
14330		img.style.width = img.style.height = '';
14331
14332		$(img)
14333			.addClass('zoomImg')
14334			.css({
14335				position: 'absolute',
14336				top: 0,
14337				left: 0,
14338				opacity: 0,
14339				width: img.width * magnify,
14340				height: img.height * magnify,
14341				border: 'none',
14342				maxWidth: 'none',
14343				maxHeight: 'none'
14344			})
14345			.appendTo(target);
14346
14347		return {
14348			init: function() {
14349				targetWidth = $target.outerWidth();
14350				targetHeight = $target.outerHeight();
14351
14352				if (source === target) {
14353					sourceWidth = targetWidth;
14354					sourceHeight = targetHeight;
14355				} else {
14356					sourceWidth = $source.outerWidth();
14357					sourceHeight = $source.outerHeight();
14358				}
14359
14360				xRatio = (img.width - targetWidth) / sourceWidth;
14361				yRatio = (img.height - targetHeight) / sourceHeight;
14362
14363				offset = $source.offset();
14364			},
14365			move: function (e) {
14366				var left = (e.pageX - offset.left),
14367					top = (e.pageY - offset.top);
14368
14369				top = Math.max(Math.min(top, sourceHeight), 0);
14370				left = Math.max(Math.min(left, sourceWidth), 0);
14371
14372				img.style.left = (left * -xRatio) + 'px';
14373				img.style.top = (top * -yRatio) + 'px';
14374			}
14375		};
14376	};
14377
14378	$.fn.zoom = function (options) {
14379		return this.each(function () {
14380			var
14381			settings = $.extend({}, defaults, options || {}),
14382			//target will display the zoomed image
14383			target = settings.target && $(settings.target)[0] || this,
14384			//source will provide zoom location info (thumbnail)
14385			source = this,
14386			$source = $(source),
14387			img = document.createElement('img'),
14388			$img = $(img),
14389			mousemove = 'mousemove.zoom',
14390			clicked = false,
14391			touched = false;
14392
14393			// If a url wasn't specified, look for an image element.
14394			if (!settings.url) {
14395				var srcElement = source.querySelector('img');
14396				if (srcElement) {
14397					settings.url = srcElement.getAttribute('data-src') || srcElement.currentSrc || srcElement.src;
14398				}
14399				if (!settings.url) {
14400					return;
14401				}
14402			}
14403
14404			$source.one('zoom.destroy', function(position, overflow){
14405				$source.off(".zoom");
14406				target.style.position = position;
14407				target.style.overflow = overflow;
14408				img.onload = null;
14409				$img.remove();
14410			}.bind(this, target.style.position, target.style.overflow));
14411
14412			img.onload = function () {
14413				var zoom = $.zoom(target, source, img, settings.magnify);
14414
14415				function start(e) {
14416					zoom.init();
14417					zoom.move(e);
14418
14419					// Skip the fade-in for IE8 and lower since it chokes on fading-in
14420					// and changing position based on mousemovement at the same time.
14421					$img.stop()
14422					.fadeTo($.support.opacity ? settings.duration : 0, 1, $.isFunction(settings.onZoomIn) ? settings.onZoomIn.call(img) : false);
14423				}
14424
14425				function stop() {
14426					$img.stop()
14427					.fadeTo(settings.duration, 0, $.isFunction(settings.onZoomOut) ? settings.onZoomOut.call(img) : false);
14428				}
14429
14430				// Mouse events
14431				if (settings.on === 'grab') {
14432					$source
14433						.on('mousedown.zoom',
14434							function (e) {
14435								if (e.which === 1) {
14436									$(document).one('mouseup.zoom',
14437										function () {
14438											stop();
14439
14440											$(document).off(mousemove, zoom.move);
14441										}
14442									);
14443
14444									start(e);
14445
14446									$(document).on(mousemove, zoom.move);
14447
14448									e.preventDefault();
14449								}
14450							}
14451						);
14452				} else if (settings.on === 'click') {
14453					$source.on('click.zoom',
14454						function (e) {
14455							if (clicked) {
14456								// bubble the event up to the document to trigger the unbind.
14457								return;
14458							} else {
14459								clicked = true;
14460								start(e);
14461								$(document).on(mousemove, zoom.move);
14462								$(document).one('click.zoom',
14463									function () {
14464										stop();
14465										clicked = false;
14466										$(document).off(mousemove, zoom.move);
14467									}
14468								);
14469								return false;
14470							}
14471						}
14472					);
14473				} else if (settings.on === 'toggle') {
14474					$source.on('click.zoom',
14475						function (e) {
14476							if (clicked) {
14477								stop();
14478							} else {
14479								start(e);
14480							}
14481							clicked = !clicked;
14482						}
14483					);
14484				} else if (settings.on === 'mouseover') {
14485					zoom.init(); // Preemptively call init because IE7 will fire the mousemove handler before the hover handler.
14486
14487					$source
14488						.on('mouseenter.zoom', start)
14489						.on('mouseleave.zoom', stop)
14490						.on(mousemove, zoom.move);
14491				}
14492
14493				// Touch fallback
14494				if (settings.touch) {
14495					$source
14496						.on('touchstart.zoom', function (e) {
14497							e.preventDefault();
14498							if (touched) {
14499								touched = false;
14500								stop();
14501							} else {
14502								touched = true;
14503								start( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
14504							}
14505						})
14506						.on('touchmove.zoom', function (e) {
14507							e.preventDefault();
14508							zoom.move( e.originalEvent.touches[0] || e.originalEvent.changedTouches[0] );
14509						})
14510						.on('touchend.zoom', function (e) {
14511							e.preventDefault();
14512							if (touched) {
14513								touched = false;
14514								stop();
14515							}
14516						});
14517				}
14518				
14519				if ($.isFunction(settings.callback)) {
14520					settings.callback.call(img);
14521				}
14522			};
14523
14524			img.setAttribute('role', 'presentation');
14525			img.alt = '';
14526			img.src = settings.url;
14527		});
14528	};
14529
14530	$.fn.zoom.defaults = defaults;
14531}(window.jQuery));
14532
14533/* End */
14534;
14535; /* Start:"a:4:{s:4:"full";s:87:"/bitrix/templates/universe_s5/plugins/jquery.scrollTo/jquery.scrollTo.js?16768708945707";s:6:"source";s:72:"/bitrix/templates/universe_s5/plugins/jquery.scrollTo/jquery.scrollTo.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
14536/*!
14537 * jQuery.scrollTo
14538 * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler
14539 * Licensed under MIT
14540 * https://github.com/flesler/jquery.scrollTo
14541 * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery
14542 * @author Ariel Flesler
14543 * @version 2.1.2
14544 */
14545;(function(factory) {
14546	'use strict';
14547	if (typeof define === 'function' && define.amd) {
14548		// AMD
14549		define(['jquery'], factory);
14550	} else if (typeof module !== 'undefined' && module.exports) {
14551		// CommonJS
14552		module.exports = factory(require('jquery'));
14553	} else {
14554		// Global
14555		factory(jQuery);
14556	}
14557})(function($) {
14558	'use strict';
14559
14560	var $scrollTo = $.scrollTo = function(target, duration, settings) {
14561		return $(window).scrollTo(target, duration, settings);
14562	};
14563
14564	$scrollTo.defaults = {
14565		axis:'xy',
14566		duration: 0,
14567		limit:true
14568	};
14569
14570	function isWin(elem) {
14571		return !elem.nodeName ||
14572			$.inArray(elem.nodeName.toLowerCase(), ['iframe','#document','html','body']) !== -1;
14573	}
14574
14575	$.fn.scrollTo = function(target, duration, settings) {
14576		if (typeof duration === 'object') {
14577			settings = duration;
14578			duration = 0;
14579		}
14580		if (typeof settings === 'function') {
14581			settings = { onAfter:settings };
14582		}
14583		if (target === 'max') {
14584			target = 9e9;
14585		}
14586
14587		settings = $.extend({}, $scrollTo.defaults, settings);
14588		// Speed is still recognized for backwards compatibility
14589		duration = duration || settings.duration;
14590		// Make sure the settings are given right
14591		var queue = settings.queue && settings.axis.length > 1;
14592		if (queue) {
14593			// Let's keep the overall duration
14594			duration /= 2;
14595		}
14596		settings.offset = both(settings.offset);
14597		settings.over = both(settings.over);
14598
14599		return this.each(function() {
14600			// Null target yields nothing, just like jQuery does
14601			if (target === null) return;
14602
14603			var win = isWin(this),
14604				elem = win ? this.contentWindow || window : this,
14605				$elem = $(elem),
14606				targ = target,
14607				attr = {},
14608				toff;
14609
14610			switch (typeof targ) {
14611				// A number will pass the regex
14612				case 'number':
14613				case 'string':
14614					if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
14615						targ = both(targ);
14616						// We are done
14617						break;
14618					}
14619					// Relative/Absolute selector
14620					targ = win ? $(targ) : $(targ, elem);
14621					/* falls through */
14622				case 'object':
14623					if (targ.length === 0) return;
14624					// DOMElement / jQuery
14625					if (targ.is || targ.style) {
14626						// Get the real position of the target
14627						toff = (targ = $(targ)).offset();
14628					}
14629			}
14630
14631			var offset = $.isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset;
14632
14633			$.each(settings.axis.split(''), function(i, axis) {
14634				var Pos	= axis === 'x' ? 'Left' : 'Top',
14635					pos = Pos.toLowerCase(),
14636					key = 'scroll' + Pos,
14637					prev = $elem[key](),
14638					max = $scrollTo.max(elem, axis);
14639
14640				if (toff) {// jQuery / DOMElement
14641					attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]);
14642
14643					// If it's a dom element, reduce the margin
14644					if (settings.margin) {
14645						attr[key] -= parseInt(targ.css('margin'+Pos), 10) || 0;
14646						attr[key] -= parseInt(targ.css('border'+Pos+'Width'), 10) || 0;
14647					}
14648
14649					attr[key] += offset[pos] || 0;
14650
14651					if (settings.over[pos]) {
14652						// Scroll to a fraction of its width/height
14653						attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos];
14654					}
14655				} else {
14656					var val = targ[pos];
14657					// Handle percentage values
14658					attr[key] = val.slice && val.slice(-1) === '%' ?
14659						parseFloat(val) / 100 * max
14660						: val;
14661				}
14662
14663				// Number or 'number'
14664				if (settings.limit && /^\d+$/.test(attr[key])) {
14665					// Check the limits
14666					attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
14667				}
14668
14669				// Don't waste time animating, if there's no need.
14670				if (!i && settings.axis.length > 1) {
14671					if (prev === attr[key]) {
14672						// No animation needed
14673						attr = {};
14674					} else if (queue) {
14675						// Intermediate animation
14676						animate(settings.onAfterFirst);
14677						// Don't animate this axis again in the next iteration.
14678						attr = {};
14679					}
14680				}
14681			});
14682
14683			animate(settings.onAfter);
14684
14685			function animate(callback) {
14686				var opts = $.extend({}, settings, {
14687					// The queue setting conflicts with animate()
14688					// Force it to always be true
14689					queue: true,
14690					duration: duration,
14691					complete: callback && function() {
14692						callback.call(elem, targ, settings);
14693					}
14694				});
14695				$elem.animate(attr, opts);
14696			}
14697		});
14698	};
14699
14700	// Max scrolling position, works on quirks mode
14701	// It only fails (not too badly) on IE, quirks mode.
14702	$scrollTo.max = function(elem, axis) {
14703		var Dim = axis === 'x' ? 'Width' : 'Height',
14704			scroll = 'scroll'+Dim;
14705
14706		if (!isWin(elem))
14707			return elem[scroll] - $(elem)[Dim.toLowerCase()]();
14708
14709		var size = 'client' + Dim,
14710			doc = elem.ownerDocument || elem.document,
14711			html = doc.documentElement,
14712			body = doc.body;
14713
14714		return Math.max(html[scroll], body[scroll]) - Math.min(html[size], body[size]);
14715	};
14716
14717	function both(val) {
14718		return $.isFunction(val) || $.isPlainObject(val) ? val : { top:val, left:val };
14719	}
14720
14721	// Add special hooks so that window scroll properties can be animated
14722	$.Tween.propHooks.scrollLeft =
14723	$.Tween.propHooks.scrollTop = {
14724		get: function(t) {
14725			return $(t.elem)[t.prop]();
14726		},
14727		set: function(t) {
14728			var curr = this.get(t);
14729			// If interrupt is true and user scrolled, stop animating
14730			if (t.options.interrupt && t._last && t._last !== curr) {
14731				return $(t.elem).stop();
14732			}
14733			var next = Math.round(t.now);
14734			// Don't waste CPU
14735			// Browsers don't render floating point scroll
14736			if (curr !== next) {
14737				$(t.elem)[t.prop](next);
14738				t._last = this.get(t);
14739			}
14740		}
14741	};
14742
14743	// AMD requirement
14744	return $scrollTo;
14745});
14746
14747/* End */
14748;
14749; /* Start:"a:4:{s:4:"full";s:64:"/bitrix/templates/universe_s5/plugins/sly/sly.js?167687089460427";s:6:"source";s:48:"/bitrix/templates/universe_s5/plugins/sly/sly.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
14750/*!
14751 * sly 1.6.1 - 8th Aug 2015
14752 * https://github.com/darsain/sly
14753 *
14754 * Licensed under the MIT license.
14755 * http://opensource.org/licenses/MIT
14756 */
14757
14758;(function ($, w, undefined) {
14759	'use strict';
14760
14761	var pluginName = 'sly';
14762	var className  = 'Sly';
14763	var namespace  = pluginName;
14764
14765	// Local WindowAnimationTiming interface
14766	var cAF = w.cancelAnimationFrame || w.cancelRequestAnimationFrame;
14767	var rAF = w.requestAnimationFrame;
14768
14769	// Support indicators
14770	var transform, gpuAcceleration;
14771
14772	// Other global values
14773	var $doc = $(document);
14774	var dragInitEvents = 'touchstart.' + namespace + ' mousedown.' + namespace;
14775	var dragMouseEvents = 'mousemove.' + namespace + ' mouseup.' + namespace;
14776	var dragTouchEvents = 'touchmove.' + namespace + ' touchend.' + namespace;
14777	var wheelEvent = (document.implementation.hasFeature('Event.wheel', '3.0') ? 'wheel.' : 'mousewheel.') + namespace;
14778	var clickEvent = 'click.' + namespace;
14779	var mouseDownEvent = 'mousedown.' + namespace;
14780	var interactiveElements = ['INPUT', 'SELECT', 'BUTTON', 'TEXTAREA'];
14781	var tmpArray = [];
14782	var time;
14783
14784	// Math shorthands
14785	var abs = Math.abs;
14786	var sqrt = Math.sqrt;
14787	var pow = Math.pow;
14788	var round = Math.round;
14789	var max = Math.max;
14790	var min = Math.min;
14791
14792	// Keep track of last fired global wheel event
14793	var lastGlobalWheel = 0;
14794	$doc.on(wheelEvent, function (event) {
14795		var sly = event.originalEvent[namespace];
14796		var time = +new Date();
14797		// Update last global wheel time, but only when event didn't originate
14798		// in Sly frame, or the origin was less than scrollHijack time ago
14799		if (!sly || sly.options.scrollHijack < time - lastGlobalWheel) lastGlobalWheel = time;
14800	});
14801
14802	/**
14803	 * Sly.
14804	 *
14805	 * @class
14806	 *
14807	 * @param {Element} frame       DOM element of sly container.
14808	 * @param {Object}  options     Object with options.
14809	 * @param {Object}  callbackMap Callbacks map.
14810	 */
14811	function Sly(frame, options, callbackMap) {
14812		if (!(this instanceof Sly)) return new Sly(frame, options, callbackMap);
14813
14814		// Extend options
14815		var o = $.extend({}, Sly.defaults, options);
14816
14817		// Private variables
14818		var self = this;
14819		var parallax = isNumber(frame);
14820
14821		// Frame
14822		var $frame = $(frame);
14823		var $slidee = o.slidee ? $(o.slidee).eq(0) : $frame.children().eq(0);
14824		var frameSize = 0;
14825		var slideeSize = 0;
14826		var pos = {
14827			start: 0,
14828			center: 0,
14829			end: 0,
14830			cur: 0,
14831			dest: 0
14832		};
14833
14834		// Scrollbar
14835		var $sb = $(o.scrollBar).eq(0);
14836		var $handle = $sb.children().eq(0);
14837		var sbSize = 0;
14838		var handleSize = 0;
14839		var hPos = {
14840			start: 0,
14841			end: 0,
14842			cur: 0
14843		};
14844
14845		// Pagesbar
14846		var $pb = $(o.pagesBar);
14847		var $pages = 0;
14848		var pages = [];
14849
14850		// Items
14851		var $items = 0;
14852		var items = [];
14853		var rel = {
14854			firstItem: 0,
14855			lastItem: 0,
14856			centerItem: 0,
14857			activeItem: null,
14858			activePage: 0
14859		};
14860
14861		// Styles
14862		var frameStyles = new StyleRestorer($frame[0]);
14863		var slideeStyles = new StyleRestorer($slidee[0]);
14864		var sbStyles = new StyleRestorer($sb[0]);
14865		var handleStyles = new StyleRestorer($handle[0]);
14866
14867		// Navigation type booleans
14868		var basicNav = o.itemNav === 'basic';
14869		var forceCenteredNav = o.itemNav === 'forceCentered';
14870		var centeredNav = o.itemNav === 'centered' || forceCenteredNav;
14871		var itemNav = !parallax && (basicNav || centeredNav || forceCenteredNav);
14872
14873		// Miscellaneous
14874		var $scrollSource = o.scrollSource ? $(o.scrollSource) : $frame;
14875		var $dragSource = o.dragSource ? $(o.dragSource) : $frame;
14876		var $forwardButton = $(o.forward);
14877		var $backwardButton = $(o.backward);
14878		var $prevButton = $(o.prev);
14879		var $nextButton = $(o.next);
14880		var $prevPageButton = $(o.prevPage);
14881		var $nextPageButton = $(o.nextPage);
14882		var callbacks = {};
14883		var last = {};
14884		var animation = {};
14885		var move = {};
14886		var dragging = {
14887			released: 1
14888		};
14889		var scrolling = {
14890			last: 0,
14891			delta: 0,
14892			resetTime: 200
14893		};
14894		var renderID = 0;
14895		var historyID = 0;
14896		var cycleID = 0;
14897		var continuousID = 0;
14898		var i, l;
14899
14900		// Normalizing frame
14901		if (!parallax) {
14902			frame = $frame[0];
14903		}
14904
14905		// Expose properties
14906		self.initialized = 0;
14907		self.frame = frame;
14908		self.slidee = $slidee[0];
14909		self.pos = pos;
14910		self.rel = rel;
14911		self.items = items;
14912		self.pages = pages;
14913		self.isPaused = 0;
14914		self.options = o;
14915		self.dragging = dragging;
14916
14917		/**
14918		 * Loading function.
14919		 *
14920		 * Populate arrays, set sizes, bind events, ...
14921		 *
14922		 * @param {Boolean} [isInit] Whether load is called from within self.init().
14923		 * @return {Void}
14924		 */
14925		function load(isInit) {
14926			// Local variables
14927			var lastItemsCount = 0;
14928			var lastPagesCount = pages.length;
14929
14930			// Save old position
14931			pos.old = $.extend({}, pos);
14932
14933			// Reset global variables
14934			frameSize = parallax ? 0 : $frame[o.horizontal ? 'width' : 'height']();
14935			sbSize = $sb[o.horizontal ? 'width' : 'height']();
14936			slideeSize = parallax ? frame : $slidee[o.horizontal ? 'outerWidth' : 'outerHeight']();
14937			pages.length = 0;
14938
14939			// Set position limits & relatives
14940			pos.start = 0;
14941			pos.end = max(slideeSize - frameSize, 0);
14942
14943			// Sizes & offsets for item based navigations
14944			if (itemNav) {
14945				// Save the number of current items
14946				lastItemsCount = items.length;
14947
14948				// Reset itemNav related variables
14949				$items = $slidee.children(o.itemSelector);
14950				items.length = 0;
14951
14952				// Needed variables
14953				var paddingStart = getPx($slidee, o.horizontal ? 'paddingLeft' : 'paddingTop');
14954				var paddingEnd = getPx($slidee, o.horizontal ? 'paddingRight' : 'paddingBottom');
14955				var borderBox = $($items).css('boxSizing') === 'border-box';
14956				var areFloated = $items.css('float') !== 'none';
14957				var ignoredMargin = 0;
14958				var lastItemIndex = $items.length - 1;
14959				var lastItem;
14960
14961				// Reset slideeSize
14962				slideeSize = 0;
14963
14964				// Iterate through items
14965				$items.each(function (i, element) {
14966					// Item
14967					var $item = $(element);
14968					var rect = element.getBoundingClientRect();
14969					var itemSize = round(o.horizontal ? rect.width || rect.right - rect.left : rect.height || rect.bottom - rect.top);
14970					var itemMarginStart = getPx($item, o.horizontal ? 'marginLeft' : 'marginTop');
14971					var itemMarginEnd = getPx($item, o.horizontal ? 'marginRight' : 'marginBottom');
14972					var itemSizeFull = itemSize + itemMarginStart + itemMarginEnd;
14973					var singleSpaced = !itemMarginStart || !itemMarginEnd;
14974					var item = {};
14975					item.el = element;
14976					item.size = singleSpaced ? itemSize : itemSizeFull;
14977					item.half = item.size / 2;
14978					item.start = slideeSize + (singleSpaced ? itemMarginStart : 0);
14979					item.center = item.start - round(frameSize / 2 - item.size / 2);
14980					item.end = item.start - frameSize + item.size;
14981
14982					// Account for slidee padding
14983					if (!i) {
14984						slideeSize += paddingStart;
14985					}
14986
14987					// Increment slidee size for size of the active element
14988					slideeSize += itemSizeFull;
14989
14990					// Try to account for vertical margin collapsing in vertical mode
14991					// It's not bulletproof, but should work in 99% of cases
14992					if (!o.horizontal && !areFloated) {
14993						// Subtract smaller margin, but only when top margin is not 0, and this is not the first element
14994						if (itemMarginEnd && itemMarginStart && i > 0) {
14995							slideeSize -= min(itemMarginStart, itemMarginEnd);
14996						}
14997					}
14998
14999					// Things to be done on last item
15000					if (i === lastItemIndex) {
15001						item.end += paddingEnd;
15002						slideeSize += paddingEnd;
15003						ignoredMargin = singleSpaced ? itemMarginEnd : 0;
15004					}
15005
15006					// Add item object to items array
15007					items.push(item);
15008					lastItem = item;
15009				});
15010
15011				// Resize SLIDEE to fit all items
15012				$slidee[0].style[o.horizontal ? 'width' : 'height'] = (borderBox ? slideeSize: slideeSize - paddingStart - paddingEnd) + 'px';
15013
15014				// Adjust internal SLIDEE size for last margin
15015				slideeSize -= ignoredMargin;
15016
15017				// Set limits
15018				if (items.length) {
15019					pos.start =  items[0][forceCenteredNav ? 'center' : 'start'];
15020					pos.end = forceCenteredNav ? lastItem.center : frameSize < slideeSize ? lastItem.end : pos.start;
15021				} else {
15022					pos.start = pos.end = 0;
15023				}
15024			}
15025
15026			// Calculate SLIDEE center position
15027			pos.center = round(pos.end / 2 + pos.start / 2);
15028
15029			// Update relative positions
15030			updateRelatives();
15031
15032			// Scrollbar
15033			if ($handle.length && sbSize > 0) {
15034				// Stretch scrollbar handle to represent the visible area
15035				if (o.dynamicHandle) {
15036					handleSize = pos.start === pos.end ? sbSize : round(sbSize * frameSize / slideeSize);
15037					handleSize = within(handleSize, o.minHandleSize, sbSize);
15038					$handle[0].style[o.horizontal ? 'width' : 'height'] = handleSize + 'px';
15039				} else {
15040					handleSize = $handle[o.horizontal ? 'outerWidth' : 'outerHeight']();
15041				}
15042
15043				hPos.end = sbSize - handleSize;
15044
15045				if (!renderID) {
15046					syncScrollbar();
15047				}
15048			}
15049
15050			// Pages
15051			if (!parallax && frameSize > 0) {
15052				var tempPagePos = pos.start;
15053				var pagesHtml = '';
15054
15055				// Populate pages array
15056				if (itemNav) {
15057					$.each(items, function (i, item) {
15058						if (forceCenteredNav) {
15059							pages.push(item.center);
15060						} else if (item.start + item.size > tempPagePos && tempPagePos <= pos.end) {
15061							tempPagePos = item.start;
15062							pages.push(tempPagePos);
15063							tempPagePos += frameSize;
15064							if (tempPagePos > pos.end && tempPagePos < pos.end + frameSize) {
15065								pages.push(pos.end);
15066							}
15067						}
15068					});
15069				} else {
15070					while (tempPagePos - frameSize < pos.end) {
15071						pages.push(tempPagePos);
15072						tempPagePos += frameSize;
15073					}
15074				}
15075
15076				// Pages bar
15077				if ($pb[0] && lastPagesCount !== pages.length) {
15078					for (var i = 0; i < pages.length; i++) {
15079						pagesHtml += o.pageBuilder.call(self, i);
15080					}
15081					$pages = $pb.html(pagesHtml).children();
15082					$pages.eq(rel.activePage).addClass(o.activeClass);
15083				}
15084			}
15085
15086			// Extend relative variables object with some useful info
15087			rel.slideeSize = slideeSize;
15088			rel.frameSize = frameSize;
15089			rel.sbSize = sbSize;
15090			rel.handleSize = handleSize;
15091
15092			// Activate requested position
15093			if (itemNav) {
15094				if (isInit && o.startAt != null) {
15095					activate(o.startAt);
15096					self[centeredNav ? 'toCenter' : 'toStart'](o.startAt);
15097				}
15098				// Fix possible overflowing
15099				var activeItem = items[rel.activeItem];
15100				slideTo(centeredNav && activeItem ? activeItem.center : within(pos.dest, pos.start, pos.end));
15101			} else {
15102				if (isInit) {
15103					if (o.startAt != null) slideTo(o.startAt, 1);
15104				} else {
15105					// Fix possible overflowing
15106					slideTo(within(pos.dest, pos.start, pos.end));
15107				}
15108			}
15109
15110			// Trigger load event
15111			trigger('load');
15112		}
15113		self.reload = function () { load(); };
15114
15115		/**
15116		 * Animate to a position.
15117		 *
15118		 * @param {Int}  newPos    New position.
15119		 * @param {Bool} immediate Reposition immediately without an animation.
15120		 * @param {Bool}
15120 dontAlign Do not align items, use the raw position passed in first argument.
15121		 *
15122		 * @return {Void}
15123		 */
15124		function slideTo(newPos, immediate, dontAlign) {
15125			// Align items
15126			if (itemNav && dragging.released && !dontAlign) {
15127				var tempRel = getRelatives(newPos);
15128				var isNotBordering = newPos > pos.start && newPos < pos.end;
15129
15130				if (centeredNav) {
15131					if (isNotBordering) {
15132						newPos = items[tempRel.centerItem].center;
15133					}
15134					if (forceCenteredNav && o.activateMiddle) {
15135						activate(tempRel.centerItem);
15136					}
15137				} else if (isNotBordering) {
15138					newPos = items[tempRel.firstItem].start;
15139				}
15140			}
15141
15142			// Handle overflowing position limits
15143			if (dragging.init && dragging.slidee && o.elasticBounds) {
15144				if (newPos > pos.end) {
15145					newPos = pos.end + (newPos - pos.end) / 6;
15146				} else if (newPos < pos.start) {
15147					newPos = pos.start + (newPos - pos.start) / 6;
15148				}
15149			} else {
15150				newPos = within(newPos, pos.start, pos.end);
15151			}
15152
15153			// Update the animation object
15154			animation.start = +new Date();
15155			animation.time = 0;
15156			animation.from = pos.cur;
15157			animation.to = newPos;
15158			animation.delta = newPos - pos.cur;
15159			animation.tweesing = dragging.tweese || dragging.init && !dragging.slidee;
15160			animation.immediate = !animation.tweesing && (immediate || dragging.init && dragging.slidee || !o.speed);
15161
15162			// Reset dragging tweesing request
15163			dragging.tweese = 0;
15164
15165			// Start animation rendering
15166			if (newPos !== pos.dest) {
15167				pos.dest = newPos;
15168				trigger('change');
15169				if (!renderID) {
15170					render();
15171				}
15172			}
15173
15174			// Reset next cycle timeout
15175			resetCycle();
15176
15177			// Synchronize states
15178			updateRelatives();
15179			updateButtonsState();
15180			syncPagesbar();
15181		}
15182
15183		/**
15184		 * Render animation frame.
15185		 *
15186		 * @return {Void}
15187		 */
15188		function render() {
15189			if (!self.initialized) {
15190				return;
15191			}
15192
15193			// If first render call, wait for next animationFrame
15194			if (!renderID) {
15195				renderID = rAF(render);
15196				if (dragging.released) {
15197					trigger('moveStart');
15198				}
15199				return;
15200			}
15201
15202			// If immediate repositioning is requested, don't animate.
15203			if (animation.immediate) {
15204				pos.cur = animation.to;
15205			}
15206			// Use tweesing for animations without known end point
15207			else if (animation.tweesing) {
15208				animation.tweeseDelta = animation.to - pos.cur;
15209				// Fuck Zeno's paradox
15210				if (abs(animation.tweeseDelta) < 0.1) {
15211					pos.cur = animation.to;
15212				} else {
15213					pos.cur += animation.tweeseDelta * (dragging.released ? o.swingSpeed : o.syncSpeed);
15214				}
15215			}
15216			// Use tweening for basic animations with known end point
15217			else {
15218				animation.time = min(+new Date() - animation.start, o.speed);
15219				pos.cur = animation.from + animation.delta * $.easing[o.easing](animation.time/o.speed, animation.time, 0, 1, o.speed);
15220			}
15221
15222			// If there is nothing more to render break the rendering loop, otherwise request new animation frame.
15223			if (animation.to === pos.cur) {
15224				pos.cur = animation.to;
15225				dragging.tweese = renderID = 0;
15226			} else {
15227				renderID = rAF(render);
15228			}
15229
15230			trigger('move');
15231
15232			// Update SLIDEE position
15233			if (!parallax) {
15234				if (transform) {
15235					$slidee[0].style[transform] = gpuAcceleration + (o.horizontal ? 'translateX' : 'translateY') + '(' + (-pos.cur) + 'px)';
15236				} else {
15237					$slidee[0].style[o.horizontal ? 'left' : 'top'] = -round(pos.cur) + 'px';
15238				}
15239			}
15240
15241			// When animation reached the end, and dragging is not active, trigger moveEnd
15242			if (!renderID && dragging.released) {
15243				trigger('moveEnd');
15244			}
15245
15246			syncScrollbar();
15247		}
15248
15249		/**
15250		 * Synchronizes scrollbar with the SLIDEE.
15251		 *
15252		 * @return {Void}
15253		 */
15254		function syncScrollbar() {
15255			if ($handle.length) {
15256				hPos.cur = pos.start === pos.end ? 0 : (((dragging.init && !dragging.slidee) ? pos.dest : pos.cur) - pos.start) / (pos.end - pos.start) * hPos.end;
15257				hPos.cur = within(round(hPos.cur), hPos.start, hPos.end);
15258				if (last.hPos !== hPos.cur) {
15259					last.hPos = hPos.cur;
15260					if (transform) {
15261						$handle[0].style[transform] = gpuAcceleration + (o.horizontal ? 'translateX' : 'translateY') + '(' + hPos.cur + 'px)';
15262					} else {
15263						$handle[0].style[o.horizontal ? 'left' : 'top'] = hPos.cur + 'px';
15264					}
15265				}
15266			}
15267		}
15268
15269		/**
15270		 * Synchronizes pagesbar with SLIDEE.
15271		 *
15272		 * @return {Void}
15273		 */
15274		function syncPagesbar() {
15275			if ($pages[0] && last.page !== rel.activePage) {
15276				last.page = rel.activePage;
15277				$pages.removeClass(o.activeClass).eq(rel.activePage).addClass(o.activeClass);
15278				trigger('activePage', last.page);
15279			}
15280		}
15281
15282		/**
15283		 * Returns the position object.
15284		 *
15285		 * @param {Mixed} item
15286		 *
15287		 * @return {Object}
15288		 */
15289		self.getPos = function (item) {
15290			if (itemNav) {
15291				var index = getIndex(item);
15292				return index !== -1 ? items[index] : false;
15293			} else {
15294				var $item = $slidee.find(item).eq(0);
15295
15296				if ($item[0]) {
15297					var offset = o.horizontal ? $item.offset().left - $slidee.offset().left : $item.offset().top - $slidee.offset().top;
15298					var size = $item[o.horizontal ? 'outerWidth' : 'outerHeight']();
15299
15300					return {
15301						start: offset,
15302						center: offset - frameSize / 2 + size / 2,
15303						end: offset - frameSize + size,
15304						size: size
15305					};
15306				} else {
15307					return false;
15308				}
15309			}
15310		};
15311
15312		/**
15313		 * Continuous move in a specified direction.
15314		 *
15315		 * @param  {Bool} forward True for forward movement, otherwise it'll go backwards.
15316		 * @param  {Int}  speed   Movement speed in pixels per frame. Overrides options.moveBy value.
15317		 *
15318		 * @return {Void}
15319		 */
15320		self.moveBy = function (speed) {
15321			move.speed = speed;
15322			// If already initiated, or there is nowhere to move, abort
15323			if (dragging.init || !move.speed || pos.cur === (move.speed > 0 ? pos.end : pos.start)) {
15324				return;
15325			}
15326			// Initiate move object
15327			move.lastTime = +new Date();
15328			move.startPos = pos.cur;
15329			// Set dragging as initiated
15330			continuousInit('button');
15331			dragging.init = 1;
15332			// Start movement
15333			trigger('moveStart');
15334			cAF(continuousID);
15335			moveLoop();
15336		};
15337
15338		/**
15339		 * Continuous movement loop.
15340		 *
15341		 * @return {Void}
15342		 */
15343		function moveLoop() {
15344			// If there is nowhere to move anymore, stop
15345			if (!move.speed || pos.cur === (move.speed > 0 ? pos.end : pos.start)) {
15346				self.stop();
15347			}
15348			// Request new move loop if it hasn't been stopped
15349			continuousID = dragging.init ? rAF(moveLoop) : 0;
15350			// Update move object
15351			move.now = +new Date();
15352			move.pos = pos.cur + (move.now - move.lastTime) / 1000 * move.speed;
15353			// Slide
15354			slideTo(dragging.init ? move.pos : round(move.pos));
15355			// Normally, this is triggered in render(), but if there
15356			// is nothing to render, we have to do it manually here.
15357			if (!dragging.init && pos.cur === pos.dest) {
15358				trigger('moveEnd');
15359			}
15360			// Update times for future iteration
15361			move.lastTime = move.now;
15362		}
15363
15364		/**
15365		 * Stops continuous movement.
15366		 *
15367		 * @return {Void}
15368		 */
15369		self.stop = function () {
15370			if (dragging.source === 'button') {
15371				dragging.init = 0;
15372				dragging.released = 1;
15373			}
15374		};
15375
15376		/**
15377		 * Activate previous item.
15378		 *
15379		 * @return {Void}
15380		 */
15381		self.prev = function () {
15382			self.activate(rel.activeItem == null ? 0 : rel.activeItem - 1);
15383		};
15384
15385		/**
15386		 * Activate next item.
15387		 *
15388		 * @return {Void}
15389		 */
15390		self.next = function () {
15391			self.activate(rel.activeItem == null ? 0 : rel.activeItem + 1);
15392		};
15393
15394		/**
15395		 * Activate previous page.
15396		 *
15397		 * @return {Void}
15398		 */
15399		self.prevPage = function () {
15400			self.activatePage(rel.activePage - 1);
15401		};
15402
15403		/**
15404		 * Activate next page.
15405		 *
15406		 * @return {Void}
15407		 */
15408		self.nextPage = function () {
15409			self.activatePage(rel.activePage + 1);
15410		};
15411
15412		/**
15413		 * Slide SLIDEE by amount of pixels.
15414		 *
15415		 * @param {Int}  delta     Pixels/Items. Positive means forward, negative means backward.
15416		 * @param {Bool} immediate Reposition immediately without an animation.
15417		 *
15418		 * @return {Void}
15419		 */
15420		self.slideBy = function (delta, immediate) {
15421			if (!delta) {
15422				return;
15423			}
15424			if (itemNav) {
15425				self[centeredNav ? 'toCenter' : 'toStart'](
15426					within((centeredNav ? rel.centerItem : rel.firstItem) + o.scrollBy * delta, 0, items.length)
15427				);
15428			} else {
15429				slideTo(pos.dest + delta, immediate);
15430			}
15431		};
15432
15433		/**
15434		 * Animate SLIDEE to a specific position.
15435		 *
15436		 * @param {Int}  pos       New position.
15437		 * @param {Bool} immediate Reposition immediately without an animation.
15438		 *
15439		 * @return {Void}
15440		 */
15441		self.slideTo = function (pos, immediate) {
15442			slideTo(pos, immediate);
15443		};
15444
15445		/**
15446		 * Core method for handling `toLocation` methods.
15447		 *
15448		 * @param  {String} location
15449		 * @param  {Mixed}  item
15450		 * @param  {Bool}   immediate
15451		 *
15452		 * @return {Void}
15453		 */
15454		function to(location, item, immediate) {
15455			// Optional arguments logic
15456			if (type(item) === 'boolean') {
15457				immediate = item;
15458				item = undefined;
15459			}
15460
15461			if (item === undefined) {
15462				slideTo(pos[location], immediate);
15463			} else {
15464				// You can't align items to sides of the frame
15465				// when centered navigation type is enabled
15466				if (centeredNav && location !== 'center') {
15467					return;
15468				}
15469
15470				var itemPos = self.getPos(item);
15471				if (itemPos) {
15472					slideTo(itemPos[location], immediate, !centeredNav);
15473				}
15474			}
15475		}
15476
15477		/**
15478		 * Animate element or the whole SLIDEE to the start of the frame.
15479		 *
15480		 * @param {Mixed} item      Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
15481		 * @param {Bool}  immediate Reposition immediately without an animation.
15482		 *
15483		 * @return {Void}
15484		 */
15485		self.toStart = function (item, immediate) {
15486			to('start', item, immediate);
15487		};
15488
15489		/**
15490		 * Animate element or the whole SLIDEE to the end of the frame.
15491		 *
15492		 * @param {Mixed} item      Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
15493		 * @param {Bool}  immediate Reposition immediately without an animation.
15494		 *
15495		 * @return {Void}
15496		 */
15497		self.toEnd = function (item, immediate) {
15498			to('end', item, immediate);
15499		};
15500
15501		/**
15502		 * Animate element or the whole SLIDEE to the center of the frame.
15503		 *
15504		 * @param {Mixed} item      Item DOM element, or index starting at 0. Omitting will animate SLIDEE.
15505		 * @param {Bool}  immediate Reposition immediately without an animation.
15506		 *
15507		 * @return {Void}
15508		 */
15509		self.toCenter = function (item, immediate) {
15510			to('center', item, immediate);
15511		};
15512
15513		/**
15514		 * Get the index of an item in SLIDEE.
15515		 *
15516		 * @param {Mixed} item     Item DOM element.
15517		 *
15518		 * @return {Int}  Item index, or -1 if not found.
15519		 */
15520		function getIndex(item) {
15521			return item != null ?
15522					isNumber(item) ?
15523						item >= 0 && item < items.length ? item : -1 :
15524						$items.index(item) :
15525					-1;
15526		}
15527		// Expose getIndex without lowering the compressibility of it,
15528		// as it is used quite often throughout Sly.
15529		self.getIndex = getIndex;
15530
15531		/**
15532		 * Get index of an item in SLIDEE based on a variety of input types.
15533		 *
15534		 * @param  {Mixed} item DOM element, positive or negative integer.
15535		 *
15536		 * @return {Int}   Item index, or -1 if not found.
15537		 */
15538		function getRelativeIndex(item) {
15539			return getIndex(isNumber(item) && item < 0 ? item + items.length : item);
15540		}
15541
15542		/**
15543		 * Activates an item.
15544		 *
15545		 * @param  {Mixed} item Item DOM element, or index starting at 0.
15546		 *
15547		 * @return {Mixed} Activated item index or false on fail.
15548		 */
15549		function activate(item, force) {
15550			var index = getIndex(item);
15551
15552			if (!itemNav || index < 0) {
15553				return false;
15554			}
15555
15556			// Update classes, last active index, and trigger active event only when there
15557			// has been a change. Otherwise just return the current active index.
15558			if (last.active !== index || force) {
15559				// Update classes
15560				$items.eq(rel.activeItem).removeClass(o.activeClass);
15561				$items.eq(index).addClass(o.activeClass);
15562
15563				last.active = rel.activeItem = index;
15564
15565				updateButtonsState();
15566				trigger('active', index);
15567			}
15568
15569			return index;
15570		}
15571
15572		/**
15573		 * Activates an item and helps with further navigation when o.smart is enabled.
15574		 *
15575		 * @param {Mixed} item      Item DOM element, or index starting at 0.
15576		 * @param {Bool}  immediate Whether to reposition immediately in smart navigation.
15577		 *
15578		 * @return {Void}
15579		 */
15580		self.activate = function (item, immediate) {
15581			var index = activate(item);
15582
15583			// Smart navigation
15584			if (o.smart && index !== false) {
15585				// When centeredNav is enabled, center the element.
15586				// Otherwise, determine where to position the element based on its current position.
15587				// If the element is currently on the far end side of the frame, assume that user is
15588				// moving forward and animate it to the start of the visible frame, and vice versa.
15589				if (centeredNav) {
15590					self.toCenter(index, immediate);
15591				} else if (index >= rel.lastItem) {
15592					self.toStart(index, immediate);
15593				} else if (index <= rel.firstItem) {
15594					self.toEnd(index, immediate);
15595				} else {
15596					resetCycle();
15597				}
15598			}
15599		};
15600
15601		/**
15602		 * Activates a page.
15603		 *
15604		 * @param {Int}  index     Page index, starting from 0.
15605		 * @param {Bool} immediate Whether to reposition immediately without animation.
15606		 *
15607		 * @return {Void}
15608		 */
15609		self.activatePage = function (index, immediate) {
15610			if (isNumber(index)) {
15611				slideTo(pages[within(index, 0, pages.length - 1)], immediate);
15612			}
15613		};
15614
15615		/**
15616		 * Return relative positions of items based on their visibility within FRAME.
15617		 *
15618		 * @param {Int} slideePos Position of SLIDEE.
15619		 *
15620		 * @return {Void}
15621		 */
15622		function getRelatives(slideePos) {
15623			slideePos = within(isNumber(slideePos) ? slideePos : pos.dest, pos.start, pos.end);
15624
15625			var relatives = {};
15626			var centerOffset = forceCenteredNav ? 0 : frameSize / 2;
15627
15628			// Determine active page
15629			if (!parallax) {
15630				for (var p = 0, pl = pages.length; p < pl; p++) {
15631					if (slideePos >= pos.end || p === pages.length - 1) {
15632						relatives.activePage = pages.length - 1;
15633						break;
15634					}
15635
15636					if (slideePos <= pages[p] + centerOffset) {
15637						relatives.activePage = p;
15638						break;
15639					}
15640				}
15641			}
15642
15643			// Relative item indexes
15644			if (itemNav) {
15645				var first = false;
15646				var last = false;
15647				var center = false;
15648
15649				// From start
15650				for (var i = 0, il = items.length; i < il; i++) {
15651					// First item
15652					if (first === false && slideePos <= items[i].start + items[i].half) {
15653						first = i;
15654					}
15655
15656					// Center item
15657					if (center === false && slideePos <= items[i].center + items[i].half) {
15658						center = i;
15659					}
15660
15661					// Last item
15662					if (i === il - 1 || slideePos <= items[i].end + items[i].half) {
15663						last = i;
15664						break;
15665					}
15666				}
15667
15668				// Safe assignment, just to be sure the false won't be returned
15669				relatives.firstItem = isNumber(first) ? first : 0;
15670				relatives.centerItem = isNumber(center) ? center : relatives.firstItem;
15671				relatives.lastItem = isNumber(last) ? last : relatives.centerItem;
15672			}
15673
15674			return relatives;
15675		}
15676
15677		/**
15678		 * Update object with relative positions.
15679		 *
15680		 * @param {Int} newPos
15681		 *
15682		 * @return {Void}
15683		 */
15684		function updateRelatives(newPos) {
15685			$.extend(rel, getRelatives(newPos));
15686		}
15687
15688		/**
15689		 * Disable navigation buttons when needed.
15690		 *
15691		 * Adds disabledClass, and when the button is <button> or <input>, activates :disabled state.
15692		 *
15693		 * @return {Void}
15694		 */
15695		function updateButtonsState() {
15696			var isStart = pos.dest <= pos.start;
15697			var isEnd = pos.dest >= pos.end;
15698			var slideePosState = (isStart ? 1 : 0) | (isEnd ? 2 : 0);
15699
15700			// Update paging buttons only if there has been a change in SLIDEE position
15701			if (last.slideePosState !== slideePosState) {
15702				last.slideePosState = slideePosState;
15703
15704				if ($prevPageButton.is('button,input')) {
15705					$prevPageButton.prop('disabled', isStart);
15706				}
15707
15708				if ($nextPageButton.is('button,input')) {
15709					$nextPageButton.prop('disabled', isEnd);
15710				}
15711
15712				$prevPageButton.add($backwardButton)[isStart ? 'addClass' : 'removeClass'](o.disabledClass);
15713				$nextPageButton.add($forwardButton)[isEnd ? 'addClass' : 'removeClass'](o.disabledClass);
15714			}
15715
15716			// Forward & Backward buttons need a separate state caching because we cannot "property disable"
15717			// them while they are being used, as disabled buttons stop emitting mouse events.
15718			if (last.fwdbwdState !== slideePosState && dragging.released) {
15719				last.fwdbwdState = slideePosState;
15720
15721				if ($backwardButton.is('button,input')) {
15722					$backwardButton.prop('disabled', isStart);
15723				}
15724
15725				if ($forwardButton.is('button,input')) {
15726					$forwardButton.prop('disabled', isEnd);
15727				}
15728			}
15729
15730			// Item navigation
15731			if (itemNav && rel.activeItem != null) {
15732				var isFirst = rel.activeItem === 0;
15733				var isLast = rel.activeItem >= items.length - 1;
15734				var itemsButtonState = (isFirst ? 1 : 0) | (isLast ? 2 : 0);
15735
15736				if (last.itemsButtonState !== itemsButtonState) {
15737					last.itemsButtonState = itemsButtonState;
15738
15739					if ($prevButton.is('button,input')) {
15740						$prevButton.prop('disabled', isFirst);
15741					}
15742
15743					if ($nextButton.is('button,input')) {
15744						$nextButton.prop('disabled', isLast);
15745					}
15746
15747					$prevButton[isFirst ? 'addClass' : 'removeClass'](o.disabledClass);
15748					$nextButton[isLast ? 'addClass' : 'removeClass'](o.disabledClass);
15749				}
15750			}
15751		}
15752
15753		/**
15754		 * Resume cycling.
15755		 *
15756		 * @param {Int} priority Resume pause with priority lower or equal than this. Used internally for pauseOnHover.
15757		 *
15758		 * @return {Void}
15759		 */
15760		self.resume = function (priority) {
15761			if (!o.cycleBy || !o.cycleInterval || o.cycleBy === 'items' && (!items[0] || rel.activeItem == null) || priority < self.isPaused) {
15762				return;
15763			}
15764
15765			self.isPaused = 0;
15766
15767			if (cycleID) {
15768				cycleID = clearTimeout(cycleID);
15769			} else {
15770				trigger('resume');
15771			}
15772
15773			cycleID = setTimeout(function () {
15774				trigger('cycle');
15775				switch (o.cycleBy) {
15776					case 'items':
15777						self.activate(rel.activeItem >= items.length - 1 ? 0 : rel.activeItem + 1);
15778						break;
15779
15780					case 'pages':
15781						self.activatePage(rel.activePage >
15781= pages.length - 1 ? 0 : rel.activePage + 1);
15782						break;
15783				}
15784			}, o.cycleInterval);
15785		};
15786
15787		/**
15788		 * Pause cycling.
15789		 *
15790		 * @param {Int} priority Pause priority. 100 is default. Used internally for pauseOnHover.
15791		 *
15792		 * @return {Void}
15793		 */
15794		self.pause = function (priority) {
15795			if (priority < self.isPaused) {
15796				return;
15797			}
15798
15799			self.isPaused = priority || 100;
15800
15801			if (cycleID) {
15802				cycleID = clearTimeout(cycleID);
15803				trigger('pause');
15804			}
15805		};
15806
15807		/**
15808		 * Toggle cycling.
15809		 *
15810		 * @return {Void}
15811		 */
15812		self.toggle = function () {
15813			self[cycleID ? 'pause' : 'resume']();
15814		};
15815
15816		/**
15817		 * Updates a signle or multiple option values.
15818		 *
15819		 * @param {Mixed} name  Name of the option that should be updated, or object that will extend the options.
15820		 * @param {Mixed} value New option value.
15821		 *
15822		 * @return {Void}
15823		 */
15824		self.set = function (name, value) {
15825			if ($.isPlainObject(name)) {
15826				$.extend(o, name);
15827			} else if (o.hasOwnProperty(name)) {
15828				o[name] = value;
15829			}
15830		};
15831
15832		/**
15833		 * Add one or multiple items to the SLIDEE end, or a specified position index.
15834		 *
15835		 * @param {Mixed} element Node element, or HTML string.
15836		 * @param {Int}   index   Index of a new item position. By default item is appended at the end.
15837		 *
15838		 * @return {Void}
15839		 */
15840		self.add = function (element, index) {
15841			var $element = $(element);
15842
15843			if (itemNav) {
15844				// Insert the element(s)
15845				if (index == null || !items[0] || index >= items.length) {
15846					$element.appendTo($slidee);
15847				} else if (items.length) {
15848					$element.insertBefore(items[index].el);
15849				}
15850
15851				// Adjust the activeItem index
15852				if (rel.activeItem != null && index <= rel.activeItem) {
15853					last.active = rel.activeItem += $element.length;
15854				}
15855			} else {
15856				$slidee.append($element);
15857			}
15858
15859			// Reload
15860			load();
15861		};
15862
15863		/**
15864		 * Remove an item from SLIDEE.
15865		 *
15866		 * @param {Mixed} element Item index, or DOM element.
15867		 * @param {Int}   index   Index of a new item position. By default item is appended at the end.
15868		 *
15869		 * @return {Void}
15870		 */
15871		self.remove = function (element) {
15872			if (itemNav) {
15873				var index = getRelativeIndex(element);
15874
15875				if (index > -1) {
15876					// Remove the element
15877					$items.eq(index).remove();
15878
15879					// If the current item is being removed, activate new one after reload
15880					var reactivate = index === rel.activeItem;
15881
15882					// Adjust the activeItem index
15883					if (rel.activeItem != null && index < rel.activeItem) {
15884						last.active = --rel.activeItem;
15885					}
15886
15887					// Reload
15888					load();
15889
15890					// Activate new item at the removed position
15891					if (reactivate) {
15892						last.active = null;
15893						self.activate(rel.activeItem);
15894					}
15895				}
15896			} else {
15897				$(element).remove();
15898				load();
15899			}
15900		};
15901
15902		/**
15903		 * Helps re-arranging items.
15904		 *
15905		 * @param  {Mixed} item     Item DOM element, or index starting at 0. Use negative numbers to select items from the end.
15906		 * @param  {Mixed} position Item insertion anchor. Accepts same input types as item argument.
15907		 * @param  {Bool}  after    Insert after instead of before the anchor.
15908		 *
15909		 * @return {Void}
15910		 */
15911		function moveItem(item, position, after) {
15912			item = getRelativeIndex(item);
15913			position = getRelativeIndex(position);
15914
15915			// Move only if there is an actual change requested
15916			if (item > -1 && position > -1 && item !== position && (!after || position !== item - 1) && (after || position !== item + 1)) {
15917				$items.eq(item)[after ? 'insertAfter' : 'insertBefore'](items[position].el);
15918
15919				var shiftStart = item < position ? item : (after ? position : position - 1);
15920				var shiftEnd = item > position ? item : (after ? position + 1 : position);
15921				var shiftsUp = item > position;
15922
15923				// Update activeItem index
15924				if (rel.activeItem != null) {
15925					if (item === rel.activeItem) {
15926						last.active = rel.activeItem = after ? (shiftsUp ? position + 1 : position) : (shiftsUp ? position : position - 1);
15927					} else if (rel.activeItem > shiftStart && rel.activeItem < shiftEnd) {
15928						last.active = rel.activeItem += shiftsUp ? 1 : -1;
15929					}
15930				}
15931
15932				// Reload
15933				load();
15934			}
15935		}
15936
15937		/**
15938		 * Move item after the target anchor.
15939		 *
15940		 * @param  {Mixed} item     Item to be moved. Can be DOM element or item index.
15941		 * @param  {Mixed} position Target position anchor. Can be DOM element or item index.
15942		 *
15943		 * @return {Void}
15944		 */
15945		self.moveAfter = function (item, position) {
15946			moveItem(item, position, 1);
15947		};
15948
15949		/**
15950		 * Move item before the target anchor.
15951		 *
15952		 * @param  {Mixed} item     Item to be moved. Can be DOM element or item index.
15953		 * @param  {Mixed} position Target position anchor. Can be DOM element or item index.
15954		 *
15955		 * @return {Void}
15956		 */
15957		self.moveBefore = function (item, position) {
15958			moveItem(item, position);
15959		};
15960
15961		/**
15962		 * Registers callbacks.
15963		 *
15964		 * @param  {Mixed}
15964 name  Event name, or callbacks map.
15965		 * @param  {Mixed} fn    Callback, or an array of callback functions.
15966		 *
15967		 * @return {Void}
15968		 */
15969		self.on = function (name, fn) {
15970			// Callbacks map
15971			if (type(name) === 'object') {
15972				for (var key in name) {
15973					if (name.hasOwnProperty(key)) {
15974						self.on(key, name[key]);
15975					}
15976				}
15977			// Callback
15978			} else if (type(fn) === 'function') {
15979				var names = name.split(' ');
15980				for (var n = 0, nl = names.length; n < nl; n++) {
15981					callbacks[names[n]] = callbacks[names[n]] || [];
15982					if (callbackIndex(names[n], fn) === -1) {
15983						callbacks[names[n]].push(fn);
15984					}
15985				}
15986			// Callbacks array
15987			} else if (type(fn) === 'array') {
15988				for (var f = 0, fl = fn.length; f < fl; f++) {
15989					self.on(name, fn[f]);
15990				}
15991			}
15992		};
15993
15994		/**
15995		 * Registers callbacks to be executed only once.
15996		 *
15997		 * @param  {Mixed} name  Event name, or callbacks map.
15998		 * @param  {Mixed} fn    Callback, or an array of callback functions.
15999		 *
16000		 * @return {Void}
16001		 */
16002		self.one = function (name, fn) {
16003			function proxy() {
16004				fn.apply(self, arguments);
16005				self.off(name, proxy);
16006			}
16007			self.on(name, proxy);
16008		};
16009
16010		/**
16011		 * Remove one or all callbacks.
16012		 *
16013		 * @param  {String} name Event name.
16014		 * @param  {Mixed}  fn   Callback, or an array of callback functions. Omit to remove all callbacks.
16015		 *
16016		 * @return {Void}
16017		 */
16018		self.off = function (name, fn) {
16019			if (fn instanceof Array) {
16020				for (var f = 0, fl = fn.length; f < fl; f++) {
16021					self.off(name, fn[f]);
16022				}
16023			} else {
16024				var names = name.split(' ');
16025				for (var n = 0, nl = names.length; n < nl; n++) {
16026					callbacks[names[n]] = callbacks[names[n]] || [];
16027					if (fn == null) {
16028						callbacks[names[n]].length = 0;
16029					} else {
16030						var index = callbackIndex(names[n], fn);
16031						if (index !== -1) {
16032							callbacks[names[n]].splice(index, 1);
16033						}
16034					}
16035				}
16036			}
16037		};
16038
16039		/**
16040		 * Returns callback array index.
16041		 *
16042		 * @param  {String}   name Event name.
16043		 * @param  {Function} fn   Function
16044		 *
16045		 * @return {Int} Callback array index, or -1 if isn't registered.
16046		 */
16047		function callbackIndex(name, fn) {
16048			for (var i = 0, l = callbacks[name].length; i < l; i++) {
16049				if (callbacks[name][i] === fn) {
16050					return i;
16051				}
16052			}
16053			return -1;
16054		}
16055
16056		/**
16057		 * Reset next cycle timeout.
16058		 *
16059		 * @return {Void}
16060		 */
16061		function resetCycle() {
16062			if (dragging.released && !self.isPaused) {
16063				self.resume();
16064			}
16065		}
16066
16067		/**
16068		 * Calculate SLIDEE representation of handle position.
16069		 *
16070		 * @param  {Int} handlePos
16071		 *
16072		 * @return {Int}
16073		 */
16074		function handleToSlidee(handlePos) {
16075			return round(within(handlePos, hPos.start, hPos.end) / hPos.end * (pos.end - pos.start)) + pos.start;
16076		}
16077
16078		/**
16079		 * Keeps track of a dragging delta history.
16080		 *
16081		 * @return {Void}
16082		 */
16083		function draggingHistoryTick() {
16084			// Looking at this, I know what you're thinking :) But as we need only 4 history states, doing it this way
16085			// as opposed to a proper loop is ~25 bytes smaller (when minified with GCC), a lot faster, and doesn't
16086			// generate garbage. The loop version would create 2 new variables on every tick. Unexaptable!
16087			dragging.history[0] = dragging.history[1];
16088			dragging.history[1] = dragging.history[2];
16089			dragging.history[2] = dragging.history[3];
16090			dragging.history[3] = dragging.delta;
16091		}
16092
16093		/**
16094		 * Initialize continuous movement.
16095		 *
16096		 * @return {Void}
16097		 */
16098		function continuousInit(source) {
16099			dragging.released = 0;
16100			dragging.source = source;
16101			dragging.slidee = source === 'slidee';
16102		}
16103
16104		/**
16105		 * Dragging initiator.
16106		 *
16107		 * @param  {Event} event
16108		 *
16109		 * @return {Void}
16110		 */
16111		function dragInit(event) {
16112			var isTouch = event.type === 'touchstart';
16113			var source = event.data.source;
16114			var isSlidee = source === 'slidee';
16115
16116			// Ignore when already in progress, or interactive element in non-touch navivagion
16117			if (dragging.init || !isTouch && isInteractive(event.target)) {
16118				return;
16119			}
16120
16121			// Handle dragging conditions
16122			if (source === 'handle' && (!o.dragHandle || hPos.start === hPos.end)) {
16123				return;
16124			}
16125
16126			// SLIDEE dragging conditions
16127			if (isSlidee && !(isTouch ? o.touchDragging : o.mouseDragging && event.which < 2)) {
16128				return;
16129			}
16130
16131			if (!isTouch) {
16132				// prevents native image dragging in Firefox
16133				stopDefault(event);
16134			}
16135
16136			// Reset dragging object
16137			continuousInit(source);
16138
16139			// Properties used in dragHandler
16140			dragging.init = 0;
16141			dragging.$source = $(event.target);
16142			dragging.touch = isTouch;
16143			dragging.pointer = isTouch ? event.originalEvent.touches[0] : event;
16144			dragging.initX = dragging.pointer.pageX;
16145			dragging.initY = dragging.pointer.pageY;
16146			dragging.initPos = isSlidee ? pos.cur : hPos.cur;
16147			dragging.start = +new Date();
16148			dragging.time = 0;
16149			dragging.path = 0;
16150			dragging.delta = 0;
16151			dragging.locked = 0;
16152			dragging.history = [0, 0, 0, 0];
16153			dragging.pathToLock = isSlidee ? isTouch ? 30 : 10 : 0;
16154
16155			// Bind dragging events
16156			$doc.on(isTouch ? dragTouchEvents : dragMouseEvents, dragHandler);
16157
16158			// Pause ongoing cycle
16159			self.pause(1);
16160
16161			// Add dragging class
16162			(isSlidee ? $slidee : $handle).addClass(o.draggedClass);
16163
16164			// Trigger moveStart event
16165			trigger('moveStart');
16166
16167			// Keep track of a dragging path history. This is later used in the
16168			// dragging release swing calculation when dragging SLIDEE.
16169			if (isSlidee) {
16170				historyID = setInterval(draggingHistoryTick, 10);
16171			}
16172		}
16173
16174		/**
16175		 * Handler for dragging scrollbar handle or SLIDEE.
16176		 *
16177		 * @param  {Event} event
16178		 *
16179		 * @return {Void}
16180		 */
16181		function dragHandler(event) {
16182			dragging.released = event.type === 'mouseup' || event.type === 'touchend';
16183			dragging.pointer = dragging.touch ? event.originalEvent[dragging.released ? 'changedTouches' : 'touches'][0] : event;
16184			dragging.pathX = dragging.pointer.pageX - dragging.initX;
16185			dragging.pathY = dragging.pointer.pageY - dragging.initY;
16186			dragging.path = sqrt(pow(dragging.pathX, 2) + pow(dragging.pathY, 2));
16187			dragging.delta = o.horizontal ? dragging.pathX : dragging.pathY;
16188
16189			if (!dragging.released && dragging.path < 1) return;
16190
16191			// We haven't decided whether this is a drag or not...
16192			if (!dragging.init) {
16193				// If the drag path was very short, maybe it's not a drag?
16194				if (dragging.path < o.dragThreshold) {
16195					// If the pointer was released, the path will not become longer and it's
16196					// definitely not a drag. If not released yet, decide on next iteration
16197					return dragging.released ? dragEnd() : undefined;
16198				}
16199				else {
16200					// If dragging path is sufficiently long we can confidently start a drag
16201					// if drag is in different direction than scroll, ignore it
16202					if (o.horizontal ? abs(dragging.pathX) > abs(dragging.pathY) : abs(dragging.pathX) < abs(dragging.pathY)) {
16203						dragging.init = 1;
16204					} else {
16205						return dragEnd();
16206					}
16207				}
16208			}
16209
16210			stopDefault(event);
16211
16212			// Disable click on a source element, as it is unwelcome when dragging
16213			if (!dragging.locked && dragging.path > dragging.pathToLock && dragging.slidee) {
16214				dragging.locked = 1;
16215				dragging.$source.on(clickEvent, disableOneEvent);
16216			}
16217
16218			// Cancel dragging on release
16219			if (dragging.released) {
16220				dragEnd();
16221
16222				// Adjust path with a swing on mouse release
16223				if (o.releaseSwing && dragging.slidee) {
16224					dragging.swing = (dragging.delta - dragging.history[0]) / 40 * 300;
16225					dragging.delta += dragging.swing;
16226					dragging.tweese = abs(dragging.swing) > 10;
16227				}
16228			}
16229
16230			slideTo(dragging.slidee ? round(dragging.initPos - dragging.delta) : handleToSlidee(dragging.initPos + dragging.delta));
16231		}
16232
16233		/**
16234		 * Stops dragging and cleans up after it.
16235		 *
16236		 * @return {Void}
16237		 */
16238		function dragEnd() {
16239			clearInterval(historyID);
16240			dragging.released = true;
16241			$doc.off(dragging.touch ? dragTouchEvents : dragMouseEvents, dragHandler);
16242			(dragging.slidee ? $slidee : $handle).removeClass(o.draggedClass);
16243
16244			// Make sure that disableOneEvent is not active in next tick.
16245			setTimeout(function () {
16246				dragging.$source.off(clickEvent, disableOneEvent);
16247			});
16248
16249			// Normally, this is triggered in render(), but if there
16250			// is nothing to render, we have to do it manually here.
16251			if (pos.cur === pos.dest && dragging.init) {
16252				trigger('moveEnd');
16253			}
16254
16255			// Resume ongoing cycle
16256			self.resume(1);
16257
16258			dragging.init = 0;
16259		}
16260
16261		/**
16262		 * Check whether element is interactive.
16263		 *
16264		 * @return {Boolean}
16265		 */
16266		function isInteractive(element) {
16267			return ~$.inArray(element.nodeName, interactiveElements) || $(element).is(o.interactive);
16268		}
16269
16270		/**
16271		 * Continuous movement cleanup on mouseup.
16272		 *
16273		 * @return {Void}
16274		 */
16275		function movementReleaseHandler() {
16276			self.stop();
16277			$doc.off('mouseup', movementReleaseHandler);
16278		}
16279
16280		/**
16281		 * Buttons navigation handler.
16282		 *
16283		 * @param  {Event} event
16284		 *
16285		 * @return {Void}
16286		 */
16287		function buttonsHandler(event) {
16288			/*jshint validthis:true */
16289			stopDefault(event);
16290			switch (this) {
16291				case $forwardButton[0]:
16292				case $backwardButton[0]:
16293					self.moveBy($forwardButton.is(this) ? o.moveBy : -o.moveBy);
16294					$doc.on('mouseup', movementReleaseHandler);
16295					break;
16296
16297				case $prevButton[0]:
16298					self.prev();
16299					break;
16300
16301				case $nextButton[0]:
16302					self.next();
16303					break;
16304
16305				case $prevPageButton[0]:
16306					self.prevPage();
16307					break;
16308
16309				case $nextPageButton[0]:
16310					self.nextPage();
16311					break;
16312			}
16313		}
16314
16315		/**
16316		 * Mouse wheel delta normalization.
16317		 *
16318		 * @param  {Event} event
16319		 *
16320		 * @return {Int}
16321		 */
16322		function normalizeWheelDelta(event) {
16323			// wheelDelta needed only for IE8-
16324			scrolling.curDelta = ((o.horizontal ? event.deltaY || event.deltaX : event.deltaY) || -event.wheelDelta);
16325			scrolling.curDelta /= event.deltaMode === 1 ? 3 : 100;
16326			if (!itemNav) {
16327				return scrolling.curDelta;
16328			}
16329			time = +new Date();
16330			if (scrolling.last < time - scrolling.resetTime) {
16331				scrolling.delta = 0;
16332			}
16333			scrolling.last = time;
16334			scrolling.delta += scrolling.curDelta;
16335			if (abs(scrolling.delta) < 1) {
16336				scrolling.finalDelta = 0;
16337			} else {
16338				scrolling.finalDelta = round(scrolling.delta / 1);
16339				scrolling.delta %= 1;
16340			}
16341			return scrolling.finalDelta;
16342		}
16343
16344		/**
16345		 * Mouse scrolling handler.
16346		 *
16347		 * @param  {Event} event
16348		 *
16349		 * @return {Void}
16350		 */
16351		function scrollHandler(event) {
16352			// Mark event as originating in a Sly instance
16353			event.originalEvent[namespace] = self;
16354			// Don't hijack global scrolling
16355			var time = +new Date();
16356			if (lastGlobalWheel + o.scrollHijack > time && $scrollSource[0] !== document && $scrollSource[0] !== window) {
16357				lastGlobalWheel = time;
16358				return;
16359			}
16360			// Ignore if there is no scrolling to be done
16361			if (!o.scrollBy || pos.start === pos.end) {
16362				return;
16363			}
16364			var delta = normalizeWheelDelta(event.originalEvent);
16365			// Trap scrolling only when necessary and/or requested
16366			if (o.scrollTrap || delta > 0 && pos.dest < pos.end || delta < 0 && pos.dest > pos.start) {
16367				stopDefault(event, 1);
16368			}
16369			self.slideBy(o.scrollBy * delta);
16370		}
16371
16372		/**
16373		 * Scrollbar click handler.
16374		 *
16375		 * @param  {Event} event
16376		 *
16377		 * @return {Void}
16378		 */
16379		function scrollbarHandler(event) {
16380			// Only clicks on scroll bar. Ignore the handle.
16381			if (o.clickBar && event.target === $sb[0]) {
16382				stopDefault(event);
16383				// Calculate new handle position and sync SLIDEE to it
16384				slideTo(handleToSlidee((o.horizontal ? event.pageX - $sb.offset().left : event.pageY - $sb.offset().top) - handleSize / 2));
16385			}
16386		}
16387
16388		/**
16389		 * Keyboard input handler.
16390		 *
16391		 * @param  {Event} event
16392		 *
16393		 * @return {Void}
16394		 */
16395		function keyboardHandler(event) {
16396			if (!o.keyboardNavBy) {
16397				return;
16398			}
16399
16400			switch (event.which) {
16401				// Left or Up
16402				case o.horizontal ? 37 : 38:
16403					stopDefault(event);
16404					self[o.keyboardNavBy === 'pages' ? 'prevPage' : 'prev']();
16405					break;
16406
16407				// Right or Down
16408				case o.horizontal ? 39 : 40:
16409					stopDefault(event);
16410					self[o.keyboardNavBy === 'pages' ? 'nextPage' : 'next']();
16411					break;
16412			}
16413		}
16414
16415		/**
16416		 * Click on item activation handler.
16417		 *
16418		 * @param  {Event} event
16419		 *
16420		 * @return {Void}
16421		 */
16422		function activateHandler(event) {
16423			/*jshint validthis:true */
16424
16425			// Ignore clicks on interactive elements.
16426			if (isInteractive(this)) {
16427				event.originalEvent[namespace + 'ignore'] = true;
16428				return;
16429			}
16430
16431			// Ignore events that:
16432			// - are not originating from direct SLIDEE children
16433			// - originated from interactive elements
16434			if (this.parentNode !== $slidee[0] || event.originalEvent[namespace + 'ignore']) return;
16435
16436			self.activate(this);
16437		}
16438
16439		/**
16440		 * Click on page button handler.
16441		 *
16442		 * @param {Event} event
16443		 *
16444		 * @return {Void}
16445		 */
16446		function activatePageHandler() {
16447			/*jshint validthis:true */
16448			// Accept only events from direct pages bar children.
16449			if (this.parentNode === $pb[0]) {
16450				self.activatePage($pages.index(this));
16451			}
16452		}
16453
16454		/**
16455		 * Pause on hover handler.
16456		 *
16457		 * @param  {Event} event
16458		 *
16459		 * @return {Void}
16460		 */
16461		function pauseOnHoverHandler(event) {
16462			if (o.pauseOnHover) {
16463				self[event.type === 'mouseenter' ? 'pause' : 'resume'](2);
16464			}
16465		}
16466
16467		/**
16468		 * Trigger callbacks for event.
16469		 *
16470		 * @param  {String} name Event name.
16471		 * @param  {Mixed}  argX Arguments passed to callbacks.
16472		 *
16473		 * @return {Void}
16474		 */
16475		function trigger(name, arg1) {
16476			if (callbacks[name]) {
16477				l = callbacks[name].length;
16478				// Callbacks will be stored and executed from a temporary array to not
16479				// break the execution queue when one of the callbacks unbinds itself.
16480				tmpArray.length = 0;
16481				for (i = 0; i < l; i++) {
16482					tmpArray.push(callbacks[name][i]);
16483				}
16484				// Execute the callbacks
16485				for (i = 0; i < l; i++) {
16486					tmpArray[i].call(self, name, arg1);
16487				}
16488			}
16489		}
16490
16491		/**
16492		 * Destroys instance and everything it created.
16493		 *
16494		 * @return {Void}
16495		 */
16496		self.destroy = function () {
16497			// Remove the reference to itself
16498			Sly.removeInstance(frame);
16499
16500			// Unbind all events
16501			$scrollSource
16502				.add($handle)
16503				.add($sb)
16504				.add($pb)
16505				.add($forwardButton)
16506				.add($backwardButton)
16507				.add($prevButton)
16508				.add($nextButton)
16509				.add($prevPageButton)
16510				.add($nextPageButton)
16511				.off('.' + namespace);
16512
16513			// Unbinding specifically as to not nuke out other instances
16514			$doc.off('keydown', keyboardHandler);
16515
16516			// Remove classes
16517			$prevButton
16518				.add($nextButton)
16519				.add($prevPageButton)
16520				.add($nextPageButton)
16521				.removeClass(o.disabledClass);
16522
16523			if ($items && rel.activeItem != null) {
16524				$items.eq(rel.activeItem).removeClass(o.activeClass);
16525			}
16526
16527			// Remove page items
16528			$pb.empty();
16529
16530			if (!parallax) {
16531				// Unbind events from frame
16532				$frame.off('.' + namespace);
16533				// Restore original styles
16534				frameStyles.restore();
16535				slideeStyles.restore();
16536				sbStyles.restore();
16537				handleStyles.restore();
16538				// Remove the instance from element data storage
16539				$.removeData(frame, namespace);
16540			}
16541
16542			// Clean up collections
16543			items.length = pages.length = 0;
16544			last = {};
16545
16546			// Reset initialized status and return the instance
16547			self.initialized = 0;
16548			return self;
16549		};
16550
16551		/**
16552		 * Initialize.
16553		 *
16554		 * @return {Object}
16555		 */
16556		self.init = function () {
16557			if (self.initialized) {
16558				return;
16559			}
16560
16561			// Disallow multiple instances on the same element
16562			if (Sly.getInstance(frame)) throw new Error('There is already a Sly instance on this element');
16563
16564			// Store the reference to itself
16565			Sly.storeInstance(frame, self);
16566
16567			// Register callbacks map
16568			self.on(callbackMap);
16569
16570			// Save styles
16571			var holderProps = ['overflow', 'position'];
16572			var movableProps = ['position', 'webkitTransform', 'msTransform', 'transform', 'left', 'top', 'width', 'height'];
16573			frameStyles.save.apply(frameStyles, holderProps);
16574			sbStyles.save.apply(sbStyles, holderProps);
16575			slideeStyles.save.apply(slideeStyles, movableProps);
16576			handleStyles.save.apply(handleStyles, movableProps);
16577
16578			// Set required styles
16579			var $movables = $handle;
16580			if (!parallax) {
16581				$movables = $movables.add($slidee);
16582				$frame.css('overflow', 'hidden');
16583				if (!transform && $frame.css('position') === 'static') {
16584					$frame.css('position', 'relative');
16585				}
16586			}
16587			if (transform) {
16588				if (gpuAcceleration) {
16589					$movables.css(transform, gpuAcceleration);
16590				}
16591			} else {
16592				if ($sb.css('position') === 'static') {
16593					$sb.css('position', 'relative');
16594				}
16595				$movables.css({ position: 'absolute' });
16596			}
16597
16598			// Navigation buttons
16599			if (o.forward) {
16600				$forwardButton.on(mouseDownEvent, buttonsHandler);
16601			}
16602			if (o.backward) {
16603				$backwardButton.on(mouseDownEvent, buttonsHandler);
16604			}
16605			if (o.prev) {
16606				$prevButton.on(clickEvent, buttonsHandler);
16607			}
16608			if (o.next) {
16609				$nextButton.on(clickEvent, buttonsHandler);
16610			}
16611			if (o.prevPage) {
16612				$prevPageButton.on(clickEvent, buttonsHandler);
16613			}
16614			if (o.nextPage) {
16615				$nextPageButton.on(clickEvent, buttonsHandler);
16616			}
16617
16618			// Scrolling navigation
16619			$scrollSource.on(wheelEvent, scrollHandler);
16620
16621			// Clicking on scrollbar navigation
16622			if ($sb[0]) {
16623				$sb.on(clickEvent, scrollbarHandler);
16624			}
16625
16626			// Click on items navigation
16627			if (itemNav && o.activateOn) {
16628				$frame.on(o.activateOn + '.' + namespace, '*', activateHandler);
16629			}
16630
16631			// Pages navigation
16632			if ($pb[0] && o.activatePageOn) {
16633				$pb.on(o.activatePageOn + '.' + namespace, '*', activatePageHandler);
16634			}
16635
16636			// Dragging navigation
16637			$dragSource.on(dragInitEvents, { source: 'slidee' }, dragInit);
16638
16639			// Scrollbar dragging navigation
16640			if ($handle) {
16641				$handle.on(dragInitEvents, { source: 'handle' }, dragInit);
16642			}
16643
16644			// Keyboard navigation
16645			$doc.on('keydown', keyboardHandler);
16646
16647			if (!parallax) {
16648				// Pause on hover
16649				$frame.on('mouseenter.' + namespace + ' mouseleave.' + namespace, pauseOnHoverHandler);
16650				// Reset native FRAME element scroll
16651				$frame.on('scroll.' + namespace, resetScroll);
16652			}
16653
16654			// Mark instance as initialized
16655			self.initialized = 1;
16656
16657			// Load
16658			load(true);
16659
16660			// Initiate automatic cycling
16661			if (o.cycleBy && !parallax) {
16662				self[o.startPaused ? 'pause' : 'resume']();
16663			}
16664
16665			// Return instance
16666			return self;
16667		};
16668	}
16669
16670	Sly.getInstance = function (element) {
16671		return $.data(element, namespace);
16672	};
16673
16674	Sly.storeInstance = function (element, sly) {
16675		return $.data(element, namespace, sly);
16676	};
16677
16678	Sly.removeInstance = function (element) {
16679		return $.removeData(element, namespace);
16680	};
16681
16682	/**
16683	 * Return type of the value.
16684	 *
16685	 * @param  {Mixed} value
16686	 *
16687	 * @return {String}
16688	 */
16689	function type(value) {
16690		if (value == null) {
16691			return String(value);
16692		}
16693
16694		if (typeof value === 'object' || typeof value === 'function') {
16695			return Object.prototype.toString.call(value).match(/\s([a-z]+)/i)[1].toLowerCase() || 'object';
16696		}
16697
16698		return typeof value;
16699	}
16700
16701	/**
16702	 * Event preventDefault & stopPropagation helper.
16703	 *
16704	 * @param {Event} event     Event object.
16705	 * @param {Bool}  noBubbles Cancel event bubbling.
16706	 *
16707	 * @return {Void}
16708	 */
16709	function stopDefault(event, noBubbles) {
16710		event.preventDefault();
16711		if (noBubbles) {
16712			event.stopPropagation();
16713		}
16714	}
16715
16716	/**
16717	 * Disables an event it was triggered on and unbinds itself.
16718	 *
16719	 * @param  {Event} event
16720	 *
16721	 * @return {Void}
16722	 */
16723	function disableOneEvent(event) {
16724		/*jshint validthis:true */
16725		stopDefault(event, 1);
16726		$(this).off(event.type, disableOneEvent);
16727	}
16728
16729	/**
16730	 * Resets native element scroll values to 0.
16731	 *
16732	 * @return {Void}
16733	 */
16734	function resetScroll() {
16735		/*jshint validthis:true */
16736		this.scrollLeft = 0;
16737		this.scrollTop = 0;
16738	}
16739
16740	/**
16741	 * Check if variable is a number.
16742	 *
16743	 * @param {Mixed} value
16744	 *
16745	 * @return {Boolean}
16746	 */
16747	function isNumber(value) {
16748		return !isNaN(parseFloat(value)) && isFinite(value);
16749	}
16750
16751	/**
16752	 * Parse style to pixels.
16753	 *
16754	 * @param {Object}   $item    jQuery object with element.
16755	 * @param {Property} property CSS property to get the pixels from.
16756	 *
16757	 * @return {Int}
16758	 */
16759	function getPx($item, property) {
16760		return 0 | round(String($item.css(property)).replace(/[^\-0-9.]/g, ''));
16761	}
16762
16763	/**
16764	 * Make sure that number is within the limits.
16765	 *
16766	 * @param {Number} number
16767	 * @param {Number} min
16768	 * @param {Number} max
16769	 *
16770	 * @return {Number}
16771	 */
16772	function within(number, min, max) {
16773		return number < min ? min : number > max ? max : number;
16774	}
16775
16776	/**
16777	 * Saves element styles for later restoration.
16778	 *
16779	 * Example:
16780	 *   var styles = new StyleRestorer(frame);
16781	 *   styles.save('position');
16782	 *   element.style.position = 'absolute';
16783	 *   styles.restore(); // restores to state before the assignment above
16784	 *
16785	 * @param {Element} element
16786	 */
16787	function StyleRestorer(element) {
16788		var self = {};
16789		self.style = {};
16790		self.save = function () {
16791			if (!element || !element.nodeType) return;
16792			for (var i = 0; i < arguments.length; i++) {
16793				self.style[arguments[i]] = element.style[arguments[i]];
16794			}
16795			return self;
16796		};
16797		self.restore = function () {
16798			if (!element || !element.nodeType) return;
16799			for (var prop in self.style) {
16800				if (self.style.hasOwnProperty(prop)) element.style[prop] = self.style[prop];
16801			}
16802			return self;
16803		};
16804		return self;
16805	}
16806
16807	// Local WindowAnimationTiming interface polyfill
16808	(function (w) {
16809		rAF = w.requestAnimationFrame
16810			|| w.webkitRequestAnimationFrame
16811			|| fallback;
16812
16813		/**
16814		* Fallback implementation.
16815		*/
16816		var prev = new Date().getTime();
16817		function fallback(fn) {
16818			var curr = new Date().getTime();
16819			var ms = Math.max(0, 16 - (curr - prev));
16820			var req = setTimeout(fn, ms);
16821			prev = curr;
16822			return req;
16823		}
16824
16825		/**
16826		* Cancel.
16827		*/
16828		var cancel = w.cancelAnimationFrame
16829			|| w.webkitCancelAnimationFrame
16830			|| w.clearTimeout;
16831
16832		cAF = function(id){
16833			cancel.call(w, id);
16834		};
16835	}(window));
16836
16837	// Feature detects
16838	(function () {
16839		var prefixes = ['', 'Webkit', 'Moz', 'ms', 'O'];
16840		var el = document.createElement('div');
16841
16842		function testProp(prop) {
16843			for (var p = 0, pl = prefixes.length; p < pl; p++) {
16844				var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop;
16845				if (el.style[prefixedProp] != null) {
16846					return prefixedProp;
16847				}
16848			}
16849		}
16850
16851		// Global support indicators
16852		transform = testProp('transform');
16853		gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : '';
16854	}());
16855
16856	// Expose class globally
16857	w[className] = Sly;
16858
16859	// jQuery proxy
16860	$.fn[pluginName] = function (options, callbackMap) {
16861		var method, methodArgs;
16862
16863		// Attributes logic
16864		if (!$.isPlainObject(options)) {
16865			if (type(options) === 'string' || options === false) {
16866				method = options === false ? 'destroy' : options;
16867				methodArgs = Array.prototype.slice.call(arguments, 1);
16868			}
16869			options = {};
16870		}
16871
16872		// Apply to all elements
16873		return this.each(function (i, element) {
16874			// Call with prevention against multiple instantiations
16875			var plugin = Sly.getInstance(element);
16876
16877			if (!plugin && !method) {
16878				// Create a new object if it doesn't exist yet
16879				plugin = new Sly(element, options, callbackMap).init();
16880			} else if (plugin && method) {
16881				// Call method
16882				if (plugin[method]) {
16883					plugin[method].apply(plugin, methodArgs);
16884				}
16885			}
16886		});
16887	};
16888
16889	// Default options
16890	Sly.defaults = {
16891		slidee:     null,  // Selector, DOM element, or jQuery object with DOM element representing SLIDEE.
16892		horizontal: false, // Switch to horizontal mode.
16893
16894		// Item based navigation
16895		itemNav:        null,  // Item navigation type. Can be: 'basic', 'centered', 'forceCentered'.
16896		itemSelector:   null,  // Select only items that match this selector.
16897		smart:          false, // Repositions the activated item to help with further navigation.
16898		activateOn:     null,  // Activate an item on this event. Can be: 'click', 'mouseenter', ...
16899		activateMiddle: false, // Always activate the item in the middle of the FRAME. forceCentered only.
16900
16901		// Scrolling
16902		scrollSource: null,  // Element for catching the mouse wheel scrolling. Default is FRAME.
16903		scrollBy:     0,     // Pixels or items to move per one mouse scroll. 0 to disable scrolling.
16904		scrollHijack: 300,   // Milliseconds since last wheel event after which it is acceptable to hijack global scroll.
16905		scrollTrap:   false, // Don't bubble scrolling when hitting scrolling limits.
16906
16907		// Dragging
16908		dragSource:    null,  // Selector or DOM element for catching dragging events. Default is FRAME.
16909		mouseDragging: false, // Enable navigation by dragging the SLIDEE with mouse cursor.
16910		touchDragging: false, // Enable navigation by dragging the SLIDEE with touch events.
16911		releaseSwing:  false, // Ease out on dragging swing release.
16912		swingSpeed:    0.2,   // Swing synchronization speed, where: 1 = instant, 0 = infinite.
16913		elasticBounds: false, // Stretch SLIDEE position limits when dragging past FRAME boundaries.
16914		dragThreshold: 3,     // Distance in pixels before Sly recognizes dragging.
16915		interactive:   null,  // Selector for special interactive elements.
16916
16917		// Scrollbar
16918		scrollBar:     null,  // Selector or DOM element for scrollbar container.
16919		dragHandle:    false, // Whether the scrollbar handle should be draggable.
16920		dynamicHandle: false, // Scrollbar handle represents the ratio between hidden and visible content.
16921		minHandleSize: 50,    // Minimal height or width (depends on sly direction) of a handle in pixels.
16922		clickBar:      false, // Enable navigation by clicking on scrollbar.
16923		syncSpeed:     0.5,   // Handle =>
16923 SLIDEE synchronization speed, where: 1 = instant, 0 = infinite.
16924
16925		// Pagesbar
16926		pagesBar:       null, // Selector or DOM element for pages bar container.
16927		activatePageOn: null, // Event used to activate page. Can be: click, mouseenter, ...
16928		pageBuilder:          // Page item generator.
16929			function (index) {
16930				return '<li>' + (index + 1) + '</li>';
16931			},
16932
16933		// Navigation buttons
16934		forward:  null, // Selector or DOM element for "forward movement" button.
16935		backward: null, // Selector or DOM element for "backward movement" button.
16936		prev:     null, // Selector or DOM element for "previous item" button.
16937		next:     null, // Selector or DOM element for "next item" button.
16938		prevPage: null, // Selector or DOM element for "previous page" button.
16939		nextPage: null, // Selector or DOM element for "next page" button.
16940
16941		// Automated cycling
16942		cycleBy:       null,  // Enable automatic cycling by 'items' or 'pages'.
16943		cycleInterval: 5000,  // Delay between cycles in milliseconds.
16944		pauseOnHover:  false, // Pause cycling when mouse hovers over the FRAME.
16945		startPaused:   false, // Whether to start in paused sate.
16946
16947		// Mixed options
16948		moveBy:        300,     // Speed in pixels per second used by forward and backward buttons.
16949		speed:         0,       // Animations speed in milliseconds. 0 to disable animations.
16950		easing:        'swing', // Easing for duration based (tweening) animations.
16951		startAt:       null,    // Starting offset in pixels or items.
16952		keyboardNavBy: null,    // Enable keyboard navigation by 'items' or 'pages'.
16953
16954		// Classes
16955		draggedClass:  'dragged', // Class for dragged elements (like SLIDEE or scrollbar handle).
16956		activeClass:   'active',  // Class for active items and pages.
16957		disabledClass: 'disabled' // Class for disabled navigation elements.
16958	};
16959}(jQuery, window));
16960
16961/* End */
16962;
16963; /* Start:"a:4:{s:4:"full";s:86:"/bitrix/templates/universe_s5/plugins/jquery.stellar/jquery.stellar.js?167687089423077";s:6:"source";s:70:"/bitrix/templates/universe_s5/plugins/jquery.stellar/jquery.stellar.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
vendor: 23,078 bytes, lines 16963-17614
16963
16964;(function($, window, document, undefined) {
16965
16966	var pluginName = 'stellar',
16967		defaults = {
16968			scrollProperty: 'scroll',
16969			positionProperty: 'position',
16970			horizontalScrolling: true,
16971			verticalScrolling: true,
16972			horizontalOffset: 0,
16973			verticalOffset: 0,
16974			responsive: false,
16975			parallaxBackgrounds: true,
16976			parallaxElements: true,
16977			hideDistantElements: true,
16978			hideElement: function($elem) { $elem.hide(); },
16979			showElement: function($elem) { $elem.show(); }
16980		},
16981
16982		scrollProperty = {
16983			scroll: {
16984				getLeft: function($elem) { return $elem.scrollLeft(); },
16985				setLeft: function($elem, val) { $elem.scrollLeft(val); },
16986
16987				getTop: function($elem) { return $elem.scrollTop();	},
16988				setTop: function($elem, val) { $elem.scrollTop(val); }
16989			},
16990			position: {
16991				getLeft: function($elem) { return parseInt($elem.css('left'), 10) * -1; },
16992				getTop: function($elem) { return parseInt($elem.css('top'), 10) * -1; }
16993			},
16994			margin: {
16995				getLeft: function($elem) { return parseInt($elem.css('margin-left'), 10) * -1; },
16996				getTop: function($elem) { return parseInt($elem.css('margin-top'), 10) * -1; }
16997			},
16998			transform: {
16999				getLeft: function($elem) {
17000					var computedTransform = getComputedStyle($elem[0])[prefixedTransform];
17001					return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[4], 10) * -1 : 0);
17002				},
17003				getTop: function($elem) {
17004					var computedTransform = getComputedStyle($elem[0])[prefixedTransform];
17005					return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[5], 10) * -1 : 0);
17006				}
17007			}
17008		},
17009
17010		positionProperty = {
17011			position: {
17012				setLeft: function($elem, left) { $elem.css('left', left); },
17013				setTop: function($elem, top) { $elem.css('top', top); }
17014			},
17015			transform: {
17016				setPosition: function($elem, left, startingLeft, top, startingTop) {
17017					$elem[0].style[prefixedTransform] = 'translate3d(' + (left - startingLeft) + 'px, ' + (top - startingTop) + 'px, 0)';
17018				}
17019			}
17020		},
17021
17022		// Returns a function which adds a vendor prefix to any CSS property name
17023		vendorPrefix = (function() {
17024			var prefixes = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/,
17025				style = $('script')[0].style,
17026				prefix = '',
17027				prop;
17028
17029			for (prop in style) {
17030				if (prefixes.test(prop)) {
17031					prefix = prop.match(prefixes)[0];
17032					break;
17033				}
17034			}
17035
17036			if ('WebkitOpacity' in style) { prefix = 'Webkit'; }
17037			if ('KhtmlOpacity' in style) { prefix = 'Khtml'; }
17038
17039			return function(property) {
17040				return prefix + (prefix.length > 0 ? property.charAt(0).toUpperCase() + property.slice(1) : property);
17041			};
17042		}()),
17043
17044		prefixedTransform = vendorPrefix('transform'),
17045
17046		supportsBackgroundPositionXY = $('<div />', { style: 'background:#fff' }).css('background-position-x') !== undefined,
17047
17048		setBackgroundPosition = (supportsBackgroundPositionXY ?
17049			function($elem, x, y) {
17050				$elem.css({
17051					'background-position-x': x,
17052					'background-position-y': y
17053				});
17054			} :
17055			function($elem, x, y) {
17056				$elem.css('background-position', x + ' ' + y);
17057			}
17058		),
17059
17060		getBackgroundPosition = (supportsBackgroundPositionXY ?
17061			function($elem) {
17062				return [
17063					$elem.css('background-position-x'),
17064					$elem.css('background-position-y')
17065				];
17066			} :
17067			function($elem) {
17068				return $elem.css('background-position').split(' ');
17069			}
17070		),
17071
17072		requestAnimFrame = (
17073			window.requestAnimationFrame       ||
17074			window.webkitRequestAnimationFrame ||
17075			window.mozRequestAnimationFrame    ||
17076			window.oRequestAnimationFrame      ||
17077			window.msRequestAnimationFrame     ||
17078			function(callback) {
17079				setTimeout(callback, 1000 / 60);
17080			}
17081		);
17082
17083	function Plugin(element, options) {
17084		this.element = element;
17085		this.options = $.extend({}, defaults, options);
17086
17087		this._defaults = defaults;
17088		this._name = pluginName;
17089
17090		this.init();
17091	}
17092
17093	Plugin.prototype = {
17094		init: function() {
17095			this.options.name = pluginName + '_' + Math.floor(Math.random() * 1e9);
17096
17097			this._defineElements();
17098			this._defineGetters();
17099			this._defineSetters();
17100			this._handleWindowLoadAndResize();
17101			this._detectViewport();
17102
17103			this.refresh({ firstLoad: true });
17104
17105			if (this.options.scrollProperty === 'scroll') {
17106				this._handleScrollEvent();
17107			} else {
17108				this._startAnimationLoop();
17109			}
17110		},
17111		_defineElements: function() {
17112			if (this.element === document.body) this.element = window;
17113			this.$scrollElement = $(this.element);
17114			this.$element = (this.element === window ? $('body') : this.$scrollElement);
17115			this.$viewportElement = (this.options.viewportElement !== undefined ? $(this.options.viewportElement) : (this.$scrollElement[0] === window || this.options.scrollProperty === 'scroll' ? this.$scrollElement : this.$scrollElement.parent()) );
17116		},
17117		_defineGetters: function() {
17118			var self = this,
17119				scrollPropertyAdapter = scrollProperty[self.options.scrollProperty];
17120
17121			this._getScrollLeft = function() {
17122				return scrollPropertyAdapter.getLeft(self.$scrollElement);
17123			};
17124
17125			this._getScrollTop = function() {
17126				return scrollPropertyAdapter.getTop(self.$scrollElement);
17127			};
17128		},
17129		_defineSetters: function() {
17130			var self = this,
17131				scrollPropertyAdapter = scrollProperty[self.options.scrollProperty],
17132				positionPropertyAdapter = positionProperty[self.options.positionProperty],
17133				setScrollLeft = scrollPropertyAdapter.setLeft,
17134				setScrollTop = scrollPropertyAdapter.setTop;
17135
17136			this._setScrollLeft = (typeof setScrollLeft === 'function' ? function(val) {
17137				setScrollLeft(self.$scrollElement, val);
17138			} : $.noop);
17139
17140			this._setScrollTop = (typeof setScrollTop === 'function' ? function(val) {
17141				setScrollTop(self.$scrollElement, val);
17142			} : $.noop);
17143
17144			this._setPosition = positionPropertyAdapter.setPosition ||
17145				function($elem, left, startingLeft, top, startingTop) {
17146					if (self.options.horizontalScrolling) {
17147						positionPropertyAdapter.setLeft($elem, left, startingLeft);
17148					}
17149
17150					if (self.options.verticalScrolling) {
17151						positionPropertyAdapter.setTop($elem, top, startingTop);
17152					}
17153				};
17154		},
17155		_handleWindowLoadAndResize: function() {
17156			var self = this,
17157				$window = $(window);
17158
17159			if (self.options.responsive) {
17160				$window.bind('load.' + this.name, function() {
17161					self.refresh();
17162				});
17163			}
17164
17165			$window.bind('resize.' + this.name, function() {
17166				self._detectViewport();
17167
17168				if (self.options.responsive) {
17169					self.refresh();
17170				}
17171			});
17172		},
17173		refresh: function(options) {
17174			var self = this,
17175				oldLeft = self._getScrollLeft(),
17176				oldTop = self._getScrollTop();
17177
17178			if (!options || !options.firstLoad) {
17179				this._reset();
17180			}
17181
17182			this._setScrollLeft(0);
17183			this._setScrollTop(0);
17184
17185			this._setOffsets();
17186			this._findParticles();
17187			this._findBackgrounds();
17188
17189			// Fix for WebKit background rendering bug
17190			if (options && options.firstLoad && /WebKit/.test(navigator.userAgent)) {
17191				$(window).load(function() {
17192					var oldLeft = self._getScrollLeft(),
17193						oldTop = self._getScrollTop();
17194
17195					self._setScrollLeft(oldLeft + 1);
17196					self._setScrollTop(oldTop + 1);
17197
17198					self._setScrollLeft(oldLeft);
17199					self._setScrollTop(oldTop);
17200				});
17201			}
17202
17203			this._setScrollLeft(oldLeft);
17204			this._setScrollTop(oldTop);
17205		},
17206		_detectViewport: function() {
17207			var viewportOffsets = this.$viewportElement.offset(),
17208				hasOffsets = viewportOffsets !== null && viewportOffsets !== undefined;
17209
17210			this.viewportWidth = this.$viewportElement.width();
17211			this.viewportHeight = this.$viewportElement.height();
17212
17213			this.viewportOffsetTop = (hasOffsets ? viewportOffsets.top : 0);
17214			this.viewportOffsetLeft = (hasOffsets ? viewportOffsets.left : 0);
17215		},
17216		_findParticles: function() {
17217			var self = this,
17218				scrollLeft = this._getScrollLeft(),
17219				scrollTop = this._getScrollTop();
17220
17221			if (this.particles !== undefined) {
17222				for (var i = this.particles.length - 1; i >= 0; i--) {
17223					this.particles[i].$element.data('stellar-elementIsActive', undefined);
17224				}
17225			}
17226
17227			this.particles = [];
17228
17229			if (!this.options.parallaxElements) return;
17230
17231			this.$element.find('[data-stellar-ratio]').each(function(i) {
17232				var $this = $(this),
17233					horizontalOffset,
17234					verticalOffset,
17235					positionLeft,
17236					positionTop,
17237					marginLeft,
17238					marginTop,
17239					$offsetParent,
17240					offsetLeft,
17241					offsetTop,
17242					parentOffsetLeft = 0,
17243					parentOffsetTop = 0,
17244					tempParentOffsetLeft = 0,
17245					tempParentOffsetTop = 0;
17246
17247				// Ensure this element isn't already part of another scrolling element
17248				if (!$this.data('stellar-elementIsActive')) {
17249					$this.data('stellar-elementIsActive', this);
17250				} else if ($this.data('stellar-elementIsActive') !== this) {
17251					return;
17252				}
17253
17254				self.options.showElement($this);
17255
17256				// Save/restore the original top and left CSS values in case we refresh the particles or destroy the instance
17257				if (!$this.data('stellar-startingLeft')) {
17258					$this.data('stellar-startingLeft', $this.css('left'));
17259					$this.data('stellar-startingTop', $this.css('top'));
17260				} else {
17261					$this.css('left', $this.data('stellar-startingLeft'));
17262					$this.css('top', $this.data('stellar-startingTop'));
17263				}
17264
17265				positionLeft = $this.position().left;
17266				positionTop = $this.position().top;
17267
17268				// Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8)
17269				marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10);
17270				marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10);
17271
17272				offsetLeft = $this.offset().left - marginLeft;
17273				offsetTop = $this.offset().top - marginTop;
17274
17275				// Calculate the offset parent
17276				$this.parents().each(function() {
17277					var $this = $(this);
17278
17279					if ($this.data('stellar-offset-parent') === true) {
17280						parentOffsetLeft = tempParentOffsetLeft;
17281						parentOffsetTop = tempParentOffsetTop;
17282						$offsetParent = $this;
17283
17284						return false;
17285					} else {
17286						tempParentOffsetLeft += $this.position().left;
17287						tempParentOffsetTop += $this.position().top;
17288					}
17289				});
17290
17291				// Detect the offsets
17292				horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset));
17293				verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset));
17294
17295				// Add our object to the particles collection
17296				self.particles.push({
17297					$element: $this,
17298					$offsetParent: $offsetParent,
17299					isFixed: $this.css('position') === 'fixed',
17300					horizontalOffset: horizontalOffset,
17301					verticalOffset: verticalOffset,
17302					startingPositionLeft: positionLeft,
17303					startingPositionTop: positionTop,
17304					startingOffsetLeft: offsetLeft,
17305					startingOffsetTop: offsetTop,
17306					parentOffsetLeft: parentOffsetLeft,
17307					parentOffsetTop: parentOffsetTop,
17308					stellarRatio: ($this.data('stellar-ratio') !== undefined ? $this.data('stellar-ratio') : 1),
17309					width: $this.outerWidth(true),
17310					height: $this.outerHeight(true),
17311					isHidden: false
17312				});
17313			});
17314		},
17315		_findBackgrounds: function() {
17316			var self = this,
17317				scrollLeft = this._getScrollLeft(),
17318				scrollTop = this._getScrollTop(),
17319				$backgroundElements;
17320
17321			this.backgrounds = [];
17322
17323			if (!this.options.parallaxBackgrounds) return;
17324
17325			$backgroundElements = this.$element.find('[data-stellar-background-ratio]');
17326
17327			if (this.$element.data('stellar-background-ratio')) {
17328                $backgroundElements = $backgroundElements.add(this.$element);
17329			}
17330
17331			$backgroundElements.each(function() {
17332				var $this = $(this),
17333					backgroundPosition = getBackgroundPosition($this),
17334					horizontalOffset,
17335					verticalOffset,
17336					positionLeft,
17337					positionTop,
17338					marginLeft,
17339					marginTop,
17340					offsetLeft,
17341					offsetTop,
17342					$offsetParent,
17343					parentOffsetLeft = 0,
17344					parentOffsetTop = 0,
17345					tempParentOffsetLeft = 0,
17346					tempParentOffsetTop = 0;
17347
17348				// Ensure this element isn't already part of another scrolling element
17349				if (!$this.data('stellar-backgroundIsActive')) {
17350					$this.data('stellar-backgroundIsActive', this);
17351				} else if ($this.data('stellar-backgroundIsActive') !== this) {
17352					return;
17353				}
17354
17355				// Save/restore the original top and left CSS values in case we destroy the instance
17356				if (!$this.data('stellar-backgroundStartingLeft')) {
17357					$this.data('stellar-backgroundStartingLeft', backgroundPosition[0]);
17358					$this.data('stellar-backgroundStartingTop', backgroundPosition[1]);
17359				} else {
17360					setBackgroundPosition($this, $this.data('stellar-backgroundStartingLeft'), $this.data('stellar-backgroundStartingTop'));
17361				}
17362
17363				// Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8)
17364				marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), 10);
17365				marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), 10);
17366
17367				offsetLeft = $this.offset().left - marginLeft - scrollLeft;
17368				offsetTop = $this.offset().top - marginTop - scrollTop;
17369				
17370				// Calculate the offset parent
17371				$this.parents().each(function() {
17372					var $this = $(this);
17373
17374					if ($this.data('stellar-offset-parent') === true) {
17375						parentOffsetLeft = tempParentOffsetLeft;
17376						parentOffsetTop = tempParentOffsetTop;
17377						$offsetParent = $this;
17378
17379						return false;
17380					} else {
17381						tempParentOffsetLeft += $this.position().left;
17382						tempParentOffsetTop += $this.position().top;
17383					}
17384				});
17385
17386				// Detect the offsets
17387				horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset));
17388				verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset));
17389
17390				self.backgrounds.push({
17391					$element: $this,
17392					$offsetParent: $offsetParent,
17393					isFixed: $this.css('background-attachment') === 'fixed',
17394					horizontalOffset: horizontalOffset,
17395					verticalOffset: verticalOffset,
17396					startingValueLeft: backgroundPosition[0],
17397					startingValueTop: backgroundPosition[1],
17398					startingBackgroundPositionLeft: (isNaN(parseInt(backgroundPosition[0], 10)) ? 0 : parseInt(backgroundPosition[0], 10)),
17399					startingBackgroundPositionTop: (isNaN(parseInt(backgroundPosition[1], 10)) ? 0 : parseInt(backgroundPosition[1], 10)),
17400					startingPositionLeft: $this.position().left,
17401					startingPositionTop: $this.position().top,
17402					startingOffsetLeft: offsetLeft,
17403					startingOffsetTop: offsetTop,
17404					parentOffsetLeft: parentOffsetLeft,
17405					parentOffsetTop: parentOffsetTop,
17406					stellarRatio: ($this.data('stellar-background-ratio') === undefined ? 1 : $this.data('stellar-background-ratio'))
17407				});
17408			});
17409		},
17410		_reset: function() {
17411			var particle,
17412				startingPositionLeft,
17413				startingPositionTop,
17414				background,
17415				i;
17416
17417			for (i = this.particles.length - 1; i >= 0; i--) {
17418				particle = this.particles[i];
17419				startingPositionLeft = particle.$element.data('stellar-startingLeft');
17420				startingPositionTop = particle.$element.data('stellar-startingTop');
17421
17422				this._setPosition(particle.$element, startingPositionLeft, startingPositionLeft, startingPositionTop, startingPositionTop);
17423
17424				this.options.showElement(particle.$element);
17425
17426				particle.$element.data('stellar-startingLeft', null).data('stellar-elementIsActive', null).data('stellar-backgroundIsActive', null);
17427			}
17428
17429			for (i = this.backgrounds.length - 1; i >= 0; i--) {
17430				background = this.backgrounds[i];
17431
17432				background.$element.data('stellar-backgroundStartingLeft', null).data('stellar-backgroundStartingTop', null);
17433
17434				setBackgroundPosition(background.$element, background.startingValueLeft, background.startingValueTop);
17435			}
17436		},
17437		destroy: function() {
17438			this._reset();
17439
17440			this.$scrollElement.unbind('resize.' + this.name).unbind('scroll.' + this.name);
17441			this._animationLoop = $.noop;
17442
17443			$(window).unbind('load.' + this.name).unbind('resize.' + this.name);
17444		},
17445		_setOffsets: function() {
17446			var self = this,
17447				$window = $(window);
17448
17449			$window.unbind('resize.horizontal-' + this.name).unbind('resize.vertical-' + this.name);
17450
17451			if (typeof this.options.horizontalOffset === 'function') {
17452				this.horizontalOffset = this.options.horizontalOffset();
17453				$window.bind('resize.horizontal-' + this.name, function() {
17454					self.horizontalOffset = self.options.horizontalOffset();
17455				});
17456			} else {
17457				this.horizontalOffset = this.options.horizontalOffset;
17458			}
17459
17460			if (typeof this.options.verticalOffset === 'function') {
17461				this.verticalOffset = this.options.verticalOffset();
17462				$window.bind('resize.vertical-' + this.name, function() {
17463					self.verticalOffset = self.options.verticalOffset();
17464				});
17465			} else {
17466				this.verticalOffset = this.options.verticalOffset;
17467			}
17468		},
17469		_repositionElements: function() {
17470			var scrollLeft = this._getScrollLeft(),
17471				scrollTop = this._getScrollTop(),
17472				horizontalOffset,
17473				verticalOffset,
17474				particle,
17475				fixedRatioOffset,
17476				background,
17477				bgLeft,
17478				bgTop,
17479				isVisibleVertical = true,
17480				isVisibleHorizontal = true,
17481				newPositionLeft,
17482				newPositionTop,
17483				newOffsetLeft,
17484				newOffsetTop,
17485				i;
17486
17487			// First check that the scroll position or container size has changed
17488			if (this.currentScrollLeft === scrollLeft && this.currentScrollTop === scrollTop && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight) {
17489				return;
17490			} else {
17491				this.currentScrollLeft = scrollLeft;
17492				this.currentScrollTop = scrollTop;
17493				this.currentWidth = this.viewportWidth;
17494				this.currentHeight = this.viewportHeight;
17495			}
17496
17497			// Reposition elements
17498			for (i = this.particles.length - 1; i >= 0; i--) {
17499				particle = this.particles[i];
17500
17501				fixedRatioOffset = (particle.isFixed ? 1 : 0);
17502
17503				// Calculate position, then calculate what the particle's new offset will be (for visibility check)
17504				if (this.options.horizontalScrolling) {
17505					newPositionLeft = (scrollLeft + particle.horizontalOffset + this.viewportOffsetLeft + particle.startingPositionLeft - particle.startingOffsetLeft + particle.parentOffsetLeft) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionLeft;
17506					newOffsetLeft = newPositionLeft - particle.startingPositionLeft + particle.startingOffsetLeft;
17507				} else {
17508					newPositionLeft = particle.startingPositionLeft;
17509					newOffsetLeft = particle.startingOffsetLeft;
17510				}
17511
17512				if (this.options.verticalScrolling) {
17513					newPositionTop = (scrollTop + particle.verticalOffset + this.viewportOffsetTop + particle.startingPositionTop - particle.startingOffsetTop + particle.parentOffsetTop) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionTop;
17514					newOffsetTop = newPositionTop - particle.startingPositionTop + particle.startingOffsetTop;
17515				} else {
17516					newPositionTop = particle.startingPositionTop;
17517					newOffsetTop = particle.startingOffsetTop;
17518				}
17519
17520				// Check visibility
17521				if (this.options.hideDistantElements) {
17522					isVisibleHorizontal = !this.options.horizontalScrolling || newOffsetLeft + particle.width > (particle.isFixed ? 0 : scrollLeft) && newOffsetLeft < (particle.isFixed ? 0 : scrollLeft) + this.viewportWidth + this.viewportOffsetLeft;
17523					isVisibleVertical = !this.options.verticalScrolling || newOffsetTop + particle.height > (particle.isFixed ? 0 : scrollTop) && newOffsetTop < (particle.isFixed ? 0 : scrollTop) + this.viewportHeight + this.viewportOffsetTop;
17524				}
17525
17526				if (isVisibleHorizontal && isVisibleVertical) {
17527					if (particle.isHidden) {
17528						this.options.showElement(particle.$element);
17529						particle.isHidden = false;
17530					}
17531
17532					this._setPosition(particle.$element, newPositionLeft, particle.startingPositionLeft, newPositionTop, particle.startingPositionTop);
17533				} else {
17534					if (!particle.isHidden) {
17535						this.options.hideElement(particle.$element);
17536						particle.isHidden = true;
17537					}
17538				}
17539			}
17540
17541			// Reposition backgrounds
17542			for (i = this.backgrounds.length - 1; i >= 0; i--) {
17543				background = this.backgrounds[i];
17544
17545				fixedRatioOffset = (background.isFixed ? 0 : 1);
17546				bgLeft = (this.options.horizontalScrolling ? (scrollLeft + background.horizontalOffset - this.viewportOffsetLeft - background.startingOffsetLeft + background.parentOffsetLeft - background.startingBackgroundPositionLeft) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueLeft);
17547				bgTop = (this.options.verticalScrolling ? (scrollTop + background.verticalOffset - this.viewportOffsetTop - background.startingOffsetTop + background.parentOffsetTop - background.startingBackgroundPositionTop) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueTop);
17548
17549				setBackgroundPosition(background.$element, bgLeft, bgTop);
17550			}
17551		},
17552		_handleScrollEvent: function() {
17553			var self = this,
17554				ticking = false;
17555
17556			var update = function() {
17557				self._repositionElements();
17558				ticking = false;
17559			};
17560
17561			var requestTick = function() {
17562				if (!ticking) {
17563					requestAnimFrame(update);
17564					ticking = true;
17565				}
17566			};
17567			
17568			this.$scrollElement.bind('scroll.' + this.name, requestTick);
17569			requestTick();
17570		},
17571		_startAnimationLoop: function() {
17572			var self = this;
17573
17574			this._animationLoop = function() {
17575				requestAnimFrame(self._animationLoop);
17576				self._repositionElements();
17577			};
17578			this._animationLoop();
17579		}
17580	};
17581
17582	$.fn[pluginName] = function (options) {
17583		var args = arguments;
17584		if (options === undefined || typeof options === 'object') {
17585			return this.each(function () {
17586				if (!$.data(this, 'plugin_' + pluginName)) {
17587					$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
17588				}
17589			});
17590		} else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
17591			return this.each(function () {
17592				var instance = $.data(this, 'plugin_' + pluginName);
17593				if (instance instanceof Plugin && typeof instance[options] === 'function') {
17594					instance[options].apply(instance, Array.prototype.slice.call(args, 1));
17595				}
17596				if (options === 'destroy') {
17597					$.data(this, 'plugin_' + pluginName, null);
17598				}
17599			});
17600		}
17601	};
17602
17603	$[pluginName] = function(options) {
17604		var $window = $(window);
17605		return $window.stellar.apply($window, Array.prototype.slice.call(arguments, 0));
17606	};
17607
17608	// Expose the scroll and position property function hashes so they can be extended
17609	$[pluginName].scrollProperty = scrollProperty;
17610	$[pluginName].positionProperty = positionProperty;
17611
17612	// Expose the plugin class so it can be modified
17613	window.Stellar = Plugin;
17614}(jQuery, this, document));
17614
17615/* End */
17616;
17617; /* Start:"a:4:{s:4:"full";s:87:"/bitrix/templates/universe_s5/plugins/jquery.lazyLoad/jquery.lazyLoad.js?16768708946571";s:6:"source";s:72:"/bitrix/templates/universe_s5/plugins/jquery.lazyLoad/jquery.lazyLoad.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
17618/**
17619 * @plugin Lazy Load
17620 * @description loads images on scroll
17621 * @author [email protected]
17622 */
17623(function ($) {
17624    var engine;
17625    var loader;
17626
17627    engine = {};
17628    engine.events = [
17629        'scroll',
17630        'resize',
17631        'orientationchange'
17632    ];
17633
17634    engine.initialize = function (node, options) {
17635        this.node = node;
17636        this.options = {};
17637        this.images = null;
17638        this.observer = null;
17639        this.handler = $.proxy(engine.run, this);
17640        this.interval = null;
17641        this.busy = {
17642            'used': false,
17643            'delayed': false
17644        };
17645
17646        engine.configure.call(this, $.extend({
17647            'autoRunUse': true,
17648            'autoRunInterval': 500,
17649            'busyUse': true,
17650            'busyTimeout': 500,
17651            'enableAttributeName': 'data-lazyload-use',
17652            'sourceAttributeName': 'data-lazyload-src',
17653            'sourceSetAttributeName': 'data-lazyload-srcset'
17654        }, options));
17655
17656        if ($.isFunction(MutationObserver)) {
17657            node = this.node;
17658
17659            if (!node)
17660                node = $('html').get(0);
17661
17662            if (node) {
17663                this.observer = new MutationObserver($.proxy(engine.bind, this));
17664                this.observer.observe(node, {
17665                    'childList': true,
17666                    'subtree': true
17667                });
17668            }
17669        }
17670    };
17671
17672    engine.bind = function () {
17673        if (this.node) {
17674            this.images = $('[' + this.options['enableAttributeName'] + '="true"]', this.node);
17675        } else {
17676            this.images = $('[' + this.options['enableAttributeName'] + '="true"]');
17677        }
17678
17679        if (this.images.length > 0) {
17680            $(window).off(engine.events.join(' '), this.handler);
17681            $(window).on(engine.events.join(' '), this.handler);
17682        }
17683    };
17684
17685    engine.reload = function () {
17686        engine.bind.call(this);
17687        engine.run.call(this);
17688    };
17689
17690    engine.configure = function (options) {
17691        this.options = $.extend(this.options, options);
17692
17693        if (this.interval) {
17694            clearInterval(this.interval);
17695            this.interval = null;
17696        }
17697
17698        if (this.options['autoRunUse'])
17699            this.interval = setInterval(this.handler, this.options['autoRunInterval']);
17700
17701        engine.reload.call(this);
17702    };
17703
17704    engine.run = function () {
17705        var context = this;
17706
17707        if (context.images.length === 0)
17708            return;
17709
17710        if (context.options['busyUse'] && context.busy.used) {
17711            context.busy.delayed = true;
17712            return;
17713        }
17714
17715        context.busy.used = true;
17716
17717        setTimeout(function () {
17718            context.images.each(function () {
17719                var image = this;
17720                var style = $.isFunction(getComputedStyle) ? getComputedStyle(image) : image.currentStyle;
17721                var visible = style && style.visibility === 'visible' && (
17722                    image.offsetWidth ||
17723                    image.offsetHeight ||
17724                    image.getClientRects().length
17725                );
17726
17727                if (!visible)
17728                    return;
17729
17730                var bounds = image.getBoundingClientRect();
17731                var available = bounds.top <= window.innerHeight && bounds.bottom >= 0;
17732
17733                if (!available)
17734                    return;
17735
17736                var source = image.getAttribute(context.options['sourceAttributeName']);
17737                var sourceSet = image.getAttribute(context.options['sourceSetAttributeName']);
17738
17739                if (image.tagName === 'IMG') {
17740                    if (source)
17741                        image.src = source;
17742
17743                    if (sourceSet)
17744                        image.srcset = sourceSet;
17745                } else {
17746                    if (source)
17747                        image.style.backgroundImage = 'url(\'' + source + '\')';
17748                }
17749
17750                image.removeAttribute(context.options['enableAttributeName']);
17751                image.removeAttribute(context.options['sourceAttributeName']);
17752                image.removeAttribute(context.options['sourceSetAttributeName']);
17753
17754                context.images = context.images.filter(function (index, item) {
17755                    return item !== image;
17756                });
17757            });
17758
17759            if (context.images.length === 0)
17760                $(window).off(engine.events.join(' '), context.handler);
17761
17762            context.busy.used = false;
17763
17764            if (context.busy.delayed) {
17765                context.busy.delayed = false;
17766                engine.run.call(context);
17767            }
17768        }, context.options['busyTimeout']);
17769    };
17770
17771    engine.destroy = function () {
17772        this.node = null;
17773        this.options = {};
17774        this.images = null;
17775
17776        $(window).off(engine.events.join(' '), this.handler);
17777
17778        if (this.interval)
17779            clearInterval(this.interval);
17780
17781        if (this.observer) {
17782            this.observer.disconnect();
17783            this.observer = null;
17784        }
17785    };
17786
17787    loader = function (node, options) {
17788        var self = this;
17789        var context = {};
17790
17791        engine.initialize.call(context, node, options);
17792
17793        self.run = $.proxy(engine.run, context);
17794        self.reload = $.proxy(engine.reload, context);
17795        self.destroy = $.proxy(engine.destroy, context);
17796    };
17797
17798    $.lazyLoad = function (options) {
17799        return new loader(null, options);
17800    };
17801
17802    $.fn.extend({
17803        'lazyLoad': function (options) {
17804            this.each(function () {
17805                if (!(this.lazyLoader instanceof loader)) {
17806                    if (options === undefined || $.isPlainObject(options)) {
17807                        this.lazyLoader = new loader(this, options);
17808                    }
17809                } else {
17810                    if ($.isPlainObject(options)) {
17811                        this.lazyLoader.configure(options);
17812                    } else if (options === 'run') {
17813                        this.lazyLoader.run();
17814                    } else if (options === 'reload') {
17815                        this.lazyLoader.reload();
17816                    } else if (options === 'destroy') {
17817                        this.lazyLoader.destroy();
17818                        this.lazyLoader = undefined;
17819                    }
17820                }
17821            });
17822
17823            return this;
17824        }
17825    });
17826})(jQuery);
17827/* End */
17828;
17829; /* Start:"a:4:{s:4:"full";s:94:"/bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.js?167687089489992";s:6:"source";s:78:"/bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
vendor: 23,216 bytes, lines 17830-18776
17830/**
17831 * Owl Carousel v2.3.4
17832 * Copyright 2013-2018 David Deutsch
17833 * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
17834 */
17835/**
17836 * Owl carousel
17837 * @version 2.3.4
17838 * @author Bartosz Wojciechowski
17839 * @author David Deutsch
17840 * @license The MIT License (MIT)
17841 * @todo Lazy Load Icon
17842 * @todo prevent animationend bubling
17843 * @todo itemsScaleUp
17844 * @todo Test Zepto
17845 * @todo stagePadding calculate wrong active classes
17846 */
17847;(function($, window, document, undefined) {
17848
17849	/**
17850	 * Creates a carousel.
17851	 * @class The Owl Carousel.
17852	 * @public
17853	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
17854	 * @param {Object} [options] - The options
17855	 */
17856	function Owl(element, options) {
17857
17858		/**
17859		 * Current settings for the carousel.
17860		 * @public
17861		 */
17862		this.settings = null;
17863
17864		/**
17865		 * Current options set by the caller including defaults.
17866		 * @public
17867		 */
17868		this.options = $.extend({}, Owl.Defaults, options);
17869
17870		/**
17871		 * Plugin element.
17872		 * @public
17873		 */
17874		this.$element = $(element);
17875
17876		/**
17877		 * Proxied event handlers.
17878		 * @protected
17879		 */
17880		this._handlers = {};
17881
17882		/**
17883		 * References to the running plugins of this carousel.
17884		 * @protected
17885		 */
17886		this._plugins = {};
17887
17888		/**
17889		 * Currently suppressed events to prevent them from being retriggered.
17890		 * @protected
17891		 */
17892		this._supress = {};
17893
17894		/**
17895		 * Absolute current position.
17896		 * @protected
17897		 */
17898		this._current = null;
17899
17900		/**
17901		 * Animation speed in milliseconds.
17902		 * @protected
17903		 */
17904		this._speed = null;
17905
17906		/**
17907		 * Coordinates of all items in pixel.
17908		 * @todo The name of this member is missleading.
17909		 * @protected
17910		 */
17911		this._coordinates = [];
17912
17913		/**
17914		 * Current breakpoint.
17915		 * @todo Real media queries would be nice.
17916		 * @protected
17917		 */
17918		this._breakpoint = null;
17919
17920		/**
17921		 * Current width of the plugin element.
17922		 */
17923		this._width = null;
17924
17925		/**
17926		 * All real items.
17927		 * @protected
17928		 */
17929		this._items = [];
17930
17931		/**
17932		 * All cloned items.
17933		 * @protected
17934		 */
17935		this._clones = [];
17936
17937		/**
17938		 * Merge values of all items.
17939		 * @todo Maybe this could be part of a plugin.
17940		 * @protected
17941		 */
17942		this._mergers = [];
17943
17944		/**
17945		 * Widths of all items.
17946		 */
17947		this._widths = [];
17948
17949		/**
17950		 * Invalidated parts within the update process.
17951		 * @protected
17952		 */
17953		this._invalidated = {};
17954
17955		/**
17956		 * Ordered list of workers for the update process.
17957		 * @protected
17958		 */
17959		this._pipe = [];
17960
17961		/**
17962		 * Current state information for the drag operation.
17963		 * @todo #261
17964		 * @protected
17965		 */
17966		this._drag = {
17967			time: null,
17968			target: null,
17969			pointer: null,
17970			stage: {
17971				start: null,
17972				current: null
17973			},
17974			direction: null
17975		};
17976
17977		/**
17978		 * Current state information and their tags.
17979		 * @type {Object}
17980		 * @protected
17981		 */
17982		this._states = {
17983			current: {},
17984			tags: {
17985				'initializing': [ 'busy' ],
17986				'animating': [ 'busy' ],
17987				'dragging': [ 'interacting' ]
17988			}
17989		};
17990
17991		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
17992			this._handlers[handler] = $.proxy(this[handler], this);
17993		}, this));
17994
17995		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
17996			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
17997				= new plugin(this);
17998		}, this));
17999
18000		$.each(Owl.Workers, $.proxy(function(priority, worker) {
18001			this._pipe.push({
18002				'filter': worker.filter,
18003				'run': $.proxy(worker.run, this)
18004			});
18005		}, this));
18006
18007		this.setup();
18008		this.initialize();
18009	}
18010
18011	/**
18012	 * Default options for the carousel.
18013	 * @public
18014	 */
18015	Owl.Defaults = {
18016		items: 3,
18017		loop: false,
18018		center: false,
18019		rewind: false,
18020		checkVisibility: true,
18021
18022		mouseDrag: true,
18023		touchDrag: true,
18024		pullDrag: true,
18025		freeDrag: false,
18026
18027		margin: 0,
18028		stagePadding: 0,
18029
18030		merge: false,
18031		mergeFit: true,
18032		autoWidth: false,
18033
18034		startPosition: 0,
18035		rtl: false,
18036
18037		smartSpeed: 250,
18038		fluidSpeed: false,
18039		dragEndSpeed: false,
18040
18041		responsive: {},
18042		responsiveRefreshRate: 200,
18043		responsiveBaseElement: window,
18044
18045		fallbackEasing: 'swing',
18046		slideTransition: '',
18047
18048		info: false,
18049
18050		nestedItemSelector: false,
18051		itemElement: 'div',
18052		stageElement: 'div',
18053
18054		refreshClass: 'owl-refresh',
18055		loadedClass: 'owl-loaded',
18056		loadingClass: 'owl-loading',
18057		rtlClass: 'owl-rtl',
18058		responsiveClass: 'owl-responsive',
18059		dragClass: 'owl-drag',
18060		itemClass: 'owl-item',
18061		stageClass: 'owl-stage',
18062		stageOuterClass: 'owl-stage-outer',
18063		grabClass: 'owl-grab'
18064	};
18065
18066	/**
18067	 * Enumeration for width.
18068	 * @public
18069	 * @readonly
18070	 * @enum {String}
18071	 */
18072	Owl.Width = {
18073		Default: 'default',
18074		Inner: 'inner',
18075		Outer: 'outer'
18076	};
18077
18078	/**
18079	 * Enumeration for types.
18080	 * @public
18081	 * @readonly
18082	 * @enum {String}
18083	 */
18084	Owl.Type = {
18085		Event: 'event',
18086		State: 'state'
18087	};
18088
18089	/**
18090	 * Contains all registered plugins.
18091	 * @public
18092	 */
18093	Owl.Plugins = {};
18094
18095	/**
18096	 * List of workers involved in the update process.
18097	 */
18098	Owl.Workers = [ {
18099		filter: [ 'width', 'settings' ],
18100		run: function() {
18101			this._width = this.$element.width();
18102		}
18103	}, {
18104		filter: [ 'width', 'items', 'settings' ],
18105		run: function(cache) {
18106			cache.current = this._items && this._items[this.relative(this._current)];
18107		}
18108	}, {
18109		filter: [ 'items', 'settings' ],
18110		run: function() {
18111			this.$stage.children('.cloned').remove();
18112		}
18113	}, {
18114		filter: [ 'width', 'items', 'settings' ],
18115		run: function(cache) {
18116			var margin = this.settings.margin || '',
18117				grid = !this.settings.autoWidth,
18118				rtl = this.settings.rtl,
18119				css = {
18120					'width': 'auto',
18121					'margin-left': rtl ? margin : '',
18122					'margin-right': rtl ? '' : margin
18123				};
18124
18125			!grid && this.$stage.children().css(css);
18126
18127			cache.css = css;
18128		}
18129	}, {
18130		filter: [ 'width', 'items', 'settings' ],
18131		run: function(cache) {
18132			var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
18133				merge = null,
18134				iterator = this._items.length,
18135				grid = !this.settings.autoWidth,
18136				widths = [];
18137
18138			cache.items = {
18139				merge: false,
18140				width: width
18141			};
18142
18143			while (iterator--) {
18144				merge = this._mergers[iterator];
18145				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
18146
18147				cache.items.merge = merge > 1 || cache.items.merge;
18148
18149				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
18150			}
18151
18152			this._widths = widths;
18153		}
18154	}, {
18155		filter: [ 'items', 'settings' ],
18156		run: function() {
18157			var clones = [],
18158				items = this._items,
18159				settings = this.settings,
18160				// TODO: Should be computed from number of min width items in stage
18161				view = Math.max(settings.items * 2, 4),
18162				size = Math.ceil(items.length / 2) * 2,
18163				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
18164				append = '',
18165				prepend = '';
18166
18167			repeat /= 2;
18168
18169			while (repeat > 0) {
18170				// Switch to only using appended clones
18171				clones.push(this.normalize(clones.length / 2, true));
18172				append = append + items[clones[clones.length - 1]][0].outerHTML;
18173				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
18174				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
18175				repeat -= 1;
18176			}
18177
18178			this._clones = clones;
18179
18180			$(append).addClass('cloned').appendTo(this.$stage);
18181			$(prepend).addClass('cloned').prependTo(this.$stage);
18182		}
18183	}, {
18184		filter: [ 'width', 'items', 'settings' ],
18185		run: function() {
18186			var rtl = this.settings.rtl ? 1 : -1,
18187				size = this._clones.length + this._items.length,
18188				iterator = -1,
18189				previous = 0,
18190				current = 0,
18191				coordinates = [];
18192
18193			while (++iterator < size) {
18194				previous = coordinates[iterator - 1] || 0;
18195				current = this._widths[this.relative(iterator)] + this.settings.margin;
18196				coordinates.push(previous + current * rtl);
18197			}
18198
18199			this._coordinates = coordinates;
18200		}
18201	}, {
18202		filter: [ 'width', 'items', 'settings' ],
18203		run: function() {
18204			var padding = this.settings.stagePadding,
18205				coordinates = this._coordinates,
18206				css = {
18207					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
18208					'padding-left': padding || '',
18209					'padding-right': padding || ''
18210				};
18211
18212			this.$stage.css(css);
18213		}
18214	}, {
18215		filter: [ 'width', 'items', 'settings' ],
18216		run: function(cache) {
18217			var iterator = this._coordinates.length,
18218				grid = !this.settings.autoWidth,
18219				items = this.$stage.children();
18220
18221			if (grid && cache.items.merge) {
18222				while (iterator--) {
18223					cache.css.width = this._widths[this.relative(iterator)];
18224					items.eq(iterator).css(cache.css);
18225				}
18226			} else if (grid) {
18227				cache.css.width = cache.items.width;
18228				items.css(cache.css);
18229			}
18230		}
18231	}, {
18232		filter: [ 'items' ],
18233		run: function() {
18234			this._coordinates.length < 1 && this.$stage.removeAttr('style');
18235		}
18236	}, {
18237		filter: [ 'width', 'items', 'settings' ],
18238		run: function(cache) {
18239			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
18240			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
18241			this.reset(cache.current);
18242		}
18243	}, {
18244		filter: [ 'position' ],
18245		run: function() {
18246			this.animate(this.coordinates(this._current));
18247		}
18248	}, {
18249		filter: [ 'width', 'position', 'items', 'settings' ],
18250		run: function() {
18251			var rtl = this.settings.rtl ? 1 : -1,
18252				padding = this.settings.stagePadding * 2,
18253				begin = this.coordinates(this.current()) + padding,
18254				end = begin + this.width() * rtl,
18255				inner, outer, matches = [], i, n;
18256
18257			for (i = 0, n = this._coordinates.length; i < n; i++) {
18258				inner = this._coordinates[i - 1] || 0;
18259				outer = Math.abs(this._coordinates[i]) + padding * rtl;
18260
18261				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
18262					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
18263					matches.push(i);
18264				}
18265			}
18266
18267			this.$stage.children('.active').removeClass('active');
18268			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
18269
18270			this.$stage.children('.center').removeClass('center');
18271			if (this.settings.center) {
18272				this.$stage.children().eq(this.current()).addClass('center');
18273			}
18274		}
18275	} ];
18276
18277	/**
18278	 * Create the stage DOM element
18279	 */
18280	Owl.prototype.initializeStage = function() {
18281		this.$stage = this.$element.find('.' + this.settings.stageClass);
18282
18283		// if the stage is already in the DOM, grab it and skip stage initialization
18284		if (this.$stage.length) {
18285			return;
18286		}
18287
18288		this.$element.addClass(this.options.loadingClass);
18289
18290		// create stage
18291		this.$stage = $('<' + this.settings.stageElement + '>', {
18292			"class": this.settings.stageClass
18293		}).wrap( $( '<div/>', {
18294			"class": this.settings.stageOuterClass
18295		}));
18296
18297		// append stage
18298		this.$element.append(this.$stage.parent());
18299	};
18300
18301	/**
18302	 * Create item DOM elements
18303	 */
18304	Owl.prototype.initializeItems = function() {
18305		var $items = this.$element.find('.owl-item');
18306
18307		// if the items are already in the DOM, grab them and skip item initialization
18308		if ($items.length) {
18309			this._items = $items.get().map(function(item) {
18310				return $(item);
18311			});
18312
18313			this._mergers = this._items.map(function() {
18314				return 1;
18315			});
18316
18317			this.refresh();
18318
18319			return;
18320		}
18321
18322		// append content
18323		this.replace(this.$element.children().not(this.$stage.parent()));
18324
18325		// check visibility
18326		if (this.isVisible()) {
18327			// update view
18328			this.refresh();
18329		} else {
18330			// invalidate width
18331			this.invalidate('width');
18332		}
18333
18334		this.$element
18335			.removeClass(this.options.loadingClass)
18336			.addClass(this.options.loadedClass);
18337	};
18338
18339	/**
18340	 * Initializes the carousel.
18341	 * @protected
18342	 */
18343	Owl.prototype.initialize = function() {
18344		this.enter('initializing');
18345		this.trigger('initialize');
18346
18347		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
18348
18349		if (this.settings.autoWidth && !this.is('pre-loading')) {
18350			var imgs, nestedSelector, width;
18351			imgs = this.$element.find('img');
18352			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
18353			width = this.$element.children(nestedSelector).width();
18354
18355			if (imgs.length && width <= 0) {
18356				this.preloadAutoWidthImages(imgs);
18357			}
18358		}
18359
18360		this.initializeStage();
18361		this.initializeItems();
18362
18363		// register event handlers
18364		this.registerEventHandlers();
18365
18366		this.leave('initializing');
18367		this.trigger('initialized');
18368	};
18369
18370	/**
18371	 * @returns {Boolean} visibility of $element
18372	 *                    if you know the carousel will always be visible you can set `checkVisibility` to `false` to
18373	 *                    prevent the expensive browser layout forced reflow the $element.is(':visible') does
18374	 */
18375	Owl.prototype.isVisible = function() {
18376		return this.settings.checkVisibility
18377			? this.$element.is(':visible')
18378			: true;
18379	};
18380
18381	/**
18382	 * Setups the current settings.
18383	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
18384	 * @todo Support for media queries by using `matchMedia` would be nice.
18385	 * @public
18386	 */
18387	Owl.prototype.setup = function() {
18388		var viewport = this.viewport(),
18389			overwrites = this.options.responsive,
18390			match = -1,
18391			settings = null;
18392
18393		if (!overwrites) {
18394			settings = $.extend({}, this.options);
18395		} else {
18396			$.each(overwrites, function(breakpoint) {
18397				if (breakpoint <= viewport && breakpoint > match) {
18398					match = Number(breakpoint);
18399				}
18400			});
18401
18402			settings = $.extend({}, this.options, overwrites[match]);
18403			if (typeof settings.stagePadding === 'function') {
18404				settings.stagePadding = settings.stagePadding();
18405			}
18406			delete settings.responsive;
18407
18408			// responsive class
18409			if (settings.responsiveClass) {
18410				this.$element.attr('class',
18411					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
18412				);
18413			}
18414		}
18415
18416		this.trigger('change', { property: { name: 'settings', value: settings } });
18417		this._breakpoint = match;
18418		this.settings = settings;
18419		this.invalidate('settings');
18420		this.trigger('changed', { property: { name: 'settings', value: this.settings } });
18421	};
18422
18423	/**
18424	 * Updates option logic if necessery.
18425	 * @protected
18426	 */
18427	Owl.prototype.optionsLogic = function() {
18428		if (this.settings.autoWidth) {
18429			this.settings.stagePadding = false;
18430			this.settings.merge = false;
18431		}
18432	};
18433
18434	/**
18435	 * Prepares an item before add.
18436	 * @todo Rename event parameter `content` to `item`.
18437	 * @protected
18438	 * @returns {jQuery|HTMLElement} - The item container.
18439	 */
18440	Owl.prototype.prepare = function(item) {
18441		var event = this.trigger('prepare', { content: item });
18442
18443		if (!event.data) {
18444			event.data = $('<' + this.settings.itemElement + '/>')
18445				.addClass(this.options.itemClass).append(item)
18446		}
18447
18448		this.trigger('prepared', { content: event.data });
18449
18450		return event.data;
18451	};
18452
18453	/**
18454	 * Updates the view.
18455	 * @public
18456	 */
18457	Owl.prototype.update = function() {
18458		var i = 0,
18459			n = this._pipe.length,
18460			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
18461			cache = {};
18462
18463		while (i < n) {
18464			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
18465				this._pipe[i].run(cache);
18466			}
18467			i++;
18468		}
18469
18470		this._invalidated = {};
18471
18472		!this.is('valid') && this.enter('valid');
18473	};
18474
18475	/**
18476	 * Gets the width of the view.
18477	 * @public
18478	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
18479	 * @returns {Number} - The width of the view in pixel.
18480	 */
18481	Owl.prototype.width = function(dimension) {
18482		dimension = dimension || Owl.Width.Default;
18483		switch (dimension) {
18484			case Owl.Width.Inner:
18485			case Owl.Width.Outer:
18486				return this._width;
18487			default:
18488				return this._width - this.settings.stagePadding * 2 + this.settings.margin;
18489		}
18490	};
18491
18492	/**
18493	 * Refreshes the carousel primarily for adaptive purposes.
18494	 * @public
18495	 */
18496	Owl.prototype.refresh = function() {
18497		this.enter('refreshing');
18498		this.trigger('refresh');
18499
18500		this.setup();
18501
18502		this.optionsLogic();
18503
18504		this.$element.addClass(this.options.refreshClass);
18505
18506		this.update();
18507
18508		this.$element.removeClass(this.options.refreshClass);
18509
18510		this.leave('refreshing');
18511		this.trigger('refreshed');
18512	};
18513
18514	/**
18515	 * Checks window `resize` event.
18516	 * @protected
18517	 */
18518	Owl.prototype.onThrottledResize = function() {
18519		window.clearTimeout(this.resizeTimer);
18520		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
18521	};
18522
18523	/**
18524	 * Checks window `resize` event.
18525	 * @protected
18526	 */
18527	Owl.prototype.onResize = function() {
18528		if (!this._items.length) {
18529			return false;
18530		}
18531
18532		if (this._width === this.$element.width()) {
18533			return false;
18534		}
18535
18536		if (!this.isVisible()) {
18537			return false;
18538		}
18539
18540		this.enter('resizing');
18541
18542		if (this.trigger('resize').isDefaultPrevented()) {
18543			this.leave('resizing');
18544			return false;
18545		}
18546
18547		this.invalidate('width');
18548
18549		this.refresh();
18550
18551		this.leave('resizing');
18552		this.trigger('resized');
18553	};
18554
18555	/**
18556	 * Registers event handlers.
18557	 * @todo Check `msPointerEnabled`
18558	 * @todo #261
18559	 * @protected
18560	 */
18561	Owl.prototype.registerEventHandlers = function() {
18562		if ($.support.transition) {
18563			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
18564		}
18565
18566		if (this.settings.responsive !== false) {
18567			this.on(window, 'resize', this._handlers.onThrottledResize);
18568		}
18569
18570		if (this.settings.mouseDrag) {
18571			this.$element.addClass(this.options.dragClass);
18572			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
18573			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
18574		}
18575
18576		if (this.settings.touchDrag){
18577			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
18578			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
18579		}
18580	};
18581
18582	/**
18583	 * Handles `touchstart` and `mousedown` events.
18584	 * @todo Horizontal swipe threshold as option
18585	 * @todo #261
18586	 * @protected
18587	 * @param {Event} event - The event arguments.
18588	 */
18589	Owl.prototype.onDragStart = function(event) {
18590		var stage = null;
18591
18592		if (event.which === 3) {
18593			return;
18594		}
18595
18596		if ($.support.transform) {
18597			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
18598			stage = {
18599				x: stage[stage.length === 16 ? 12 : 4],
18600				y: stage[stage.length === 16 ? 13 : 5]
18601			};
18602		} else {
18603			stage = this.$stage.position();
18604			stage = {
18605				x: this.settings.rtl ?
18606					stage.left + this.$stage.width() - this.width() + this.settings.margin :
18607					stage.left,
18608				y: stage.top
18609			};
18610		}
18611
18612		if (this.is('animating')) {
18613			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
18614			this.invalidate('position');
18615		}
18616
18617		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
18618
18619		this.speed(0);
18620
18621		this._drag.time = new Date().getTime();
18622		this._drag.target = $(event.target);
18623		this._drag.stage.start = stage;
18624		this._drag.stage.current = stage;
18625		this._drag.pointer = this.pointer(event);
18626
18627		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
18628
18629		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
18630			var delta = this.difference(this._drag.pointer, this.pointer(event));
18631
18632			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
18633
18634			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
18635				return;
18636			}
18637
18638			event.preventDefault();
18639
18640			this.enter('dragging');
18641			this.trigger('drag');
18642		}, this));
18643	};
18644
18645	/**
18646	 * Handles the `touchmove` and `mousemove` events.
18647	 * @todo #261
18648	 * @protected
18649	 * @param {Event} event - The event arguments.
18650	 */
18651	Owl.prototype.onDragMove = function(event) {
18652		var minimum = null,
18653			maximum = null,
18654			pull = null,
18655			delta = this.difference(this._drag.pointer, this.pointer(event)),
18656			stage = this.difference(this._drag.stage.start, delta);
18657
18658		if (!this.is('dragging')) {
18659			return;
18660		}
18661
18662		event.preventDefault();
18663
18664		if (this.settings.loop) {
18665			minimum = this.coordinates(this.minimum());
18666			maximum = this.coordinates(this.maximum() + 1) - minimum;
18667			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
18668		} else {
18669			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
18670			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
18671			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
18672			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
18673		}
18674
18675		this._drag.stage.current = stage;
18676
18677		this.animate(stage.x);
18678	};
18679
18680	/**
18681	 * Handles the `touchend` and `mouseup` events.
18682	 * @todo #261
18683	 * @todo Threshold for click event
18684	 * @protected
18685	 * @param {Event} event - The event arguments.
18686	 */
18687	Owl.prototype.onDragEnd = function(event) {
18688		var delta = this.difference(this._drag.pointer, this.pointer(event)),
18689			stage = this._drag.stage.current,
18690			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
18691
18692		$(document).off('.owl.core');
18693
18694		this.$element.removeClass(this.options.grabClass);
18695
18696		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
18697			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
18698			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
18699			this.invalidate('position');
18700			this.update();
18701
18702			this._drag.direction = direction;
18703
18704			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
18705				this._drag.target.one('click.owl.core', function() { return false; });
18706			}
18707		}
18708
18709		if (!this.is('dragging')) {
18710			return;
18711		}
18712
18713		this.leave('dragging');
18714		this.trigger('dragged');
18715	};
18716
18717	/**
18718	 * Gets absolute position of the closest item for a coordinate.
18719	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
18720	 * @protected
18721	 * @param {Number} coordinate - The coordinate in pixel.
18722	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
18723	 * @return {Number} - The absolute position of the closest item.
18724	 */
18725	Owl.prototype.closest = function(coordinate, direction) {
18726		var position = -1,
18727			pull = 30,
18728			width = this.width(),
18729			coordinates = this.coordinates();
18730
18731		if (!this.settings.freeDrag) {
18732			// check closest item
18733			$.each(coordinates, $.proxy(function(index, value) {
18734				// on a left pull, check on current index
18735				if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
18736					position = index;
18737				// on a right pull, check on previous index
18738				// to do so, subtract width from value and set position = index + 1
18739				} else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
18740					position = index + 1;
18741				} else if (this.op(coordinate, '<', value)
18742					&& this.op(coordinate, '>', coordinates[index + 1] !== undefined ? coordinates[index + 1] : value - width)) {
18743					position = direction === 'left' ? index + 1 : index;
18744				}
18745				return position === -1;
18746			}, this));
18747		}
18748
18749		if (!this.settings.loop) {
18750			// non loop boundries
18751			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
18752				position = coordinate = this.minimum();
18753			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
18754				position = coordinate = this.maximum();
18755			}
18756		}
18757
18758		return position;
18759	};
18760
18761	/**
18762	 * Animates the stage.
18763	 * @todo #270
18764	 * @public
18765	 * @param {Number} coordinate - The coordinate in pixels.
18766	 */
18767	Owl.prototype.animate = function(coordinate) {
18768		var animate = this.speed() > 0;
18769
18770		this.is('animating') && this.onTransitionEnd();
18771
18772		if (animate) {
18773			this.enter('animating');
18774			this.trigger('translate');
18775		}
18776
vendor: 10,524 bytes, lines 18777-19144
18777		if ($.support.transform3d && $.support.transition) {
18778			this.$stage.css({
18779				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
18780				transition: (this.speed() / 1000) + 's' + (
18781					this.settings.slideTransition ? ' ' + this.settings.slideTransition : ''
18782				)
18783			});
18784		} else if (animate) {
18785			this.$stage.animate({
18786				left: coordinate + 'px'
18787			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
18788		} else {
18789			this.$stage.css({
18790				left: coordinate + 'px'
18791			});
18792		}
18793	};
18794
18795	/**
18796	 * Checks whether the carousel is in a specific state or not.
18797	 * @param {String} state - The state to check.
18798	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
18799	 */
18800	Owl.prototype.is = function(state) {
18801		return this._states.current[state] && this._states.current[state] > 0;
18802	};
18803
18804	/**
18805	 * Sets the absolute position of the current item.
18806	 * @public
18807	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
18808	 * @returns {Number} - The absolute position of the current item.
18809	 */
18810	Owl.prototype.current = function(position) {
18811		if (position === undefined) {
18812			return this._current;
18813		}
18814
18815		if (this._items.length === 0) {
18816			return undefined;
18817		}
18818
18819		position = this.normalize(position);
18820
18821		if (this._current !== position) {
18822			var event = this.trigger('change', { property: { name: 'position', value: position } });
18823
18824			if (event.data !== undefined) {
18825				position = this.normalize(event.data);
18826			}
18827
18828			this._current = position;
18829
18830			this.invalidate('position');
18831
18832			this.trigger('changed', { property: { name: 'position', value: this._current } });
18833		}
18834
18835		return this._current;
18836	};
18837
18838	/**
18839	 * Invalidates the given part of the update routine.
18840	 * @param {String} [part] - The part to invalidate.
18841	 * @returns {Array.<String>} - The invalidated parts.
18842	 */
18843	Owl.prototype.invalidate = function(part) {
18844		if ($.type(part) === 'string') {
18845			this._invalidated[part] = true;
18846			this.is('valid') && this.leave('valid');
18847		}
18848		return $.map(this._invalidated, function(v, i) { return i });
18849	};
18850
18851	/**
18852	 * Resets the absolute position of the current item.
18853	 * @public
18854	 * @param {Number} position - The absolute position of the new item.
18855	 */
18856	Owl.prototype.reset = function(position) {
18857		position = this.normalize(position);
18858
18859		if (position === undefined) {
18860			return;
18861		}
18862
18863		this._speed = 0;
18864		this._current = position;
18865
18866		this.suppress([ 'translate', 'translated' ]);
18867
18868		this.animate(this.coordinates(position));
18869
18870		this.release([ 'translate', 'translated' ]);
18871	};
18872
18873	/**
18874	 * Normalizes an absolute or a relative position of an item.
18875	 * @public
18876	 * @param {Number} position - The absolute or relative position to normalize.
18877	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
18878	 * @returns {Number} - The normalized position.
18879	 */
18880	Owl.prototype.normalize = function(position, relative) {
18881		var n = this._items.length,
18882			m = relative ? 0 : this._clones.length;
18883
18884		if (!this.isNumeric(position) || n < 1) {
18885			position = undefined;
18886		} else if (position < 0 || position >= n + m) {
18887			position = ((position - m / 2) % n + n) % n + m / 2;
18888		}
18889
18890		return position;
18891	};
18892
18893	/**
18894	 * Converts an absolute position of an item into a relative one.
18895	 * @public
18896	 * @param {Number} position - The absolute position to convert.
18897	 * @returns {Number} - The converted position.
18898	 */
18899	Owl.prototype.relative = function(position) {
18900		position -= this._clones.length / 2;
18901		return this.normalize(position, true);
18902	};
18903
18904	/**
18905	 * Gets the maximum position for the current item.
18906	 * @public
18907	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
18908	 * @returns {Number}
18909	 */
18910	Owl.prototype.maximum = function(relative) {
18911		var settings = this.settings,
18912			maximum = this._coordinates.length,
18913			iterator,
18914			reciprocalItemsWidth,
18915			elementWidth;
18916
18917		if (settings.loop) {
18918			maximum = this._clones.length / 2 + this._items.length - 1;
18919		} else if (settings.autoWidth || settings.merge) {
18920			iterator = this._items.length;
18921			if (iterator) {
18922				reciprocalItemsWidth = this._items[--iterator].width();
18923				elementWidth = this.$element.width();
18924				while (iterator--) {
18925					reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
18926					if (reciprocalItemsWidth > elementWidth) {
18927						break;
18928					}
18929				}
18930			}
18931			maximum = iterator + 1;
18932		} else if (settings.center) {
18933			maximum = this._items.length - 1;
18934		} else {
18935			maximum = this._items.length - settings.items;
18936		}
18937
18938		if (relative) {
18939			maximum -= this._clones.length / 2;
18940		}
18941
18942		return Math.max(maximum, 0);
18943	};
18944
18945	/**
18946	 * Gets the minimum position for the current item.
18947	 * @public
18948	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
18949	 * @returns {Number}
18950	 */
18951	Owl.prototype.minimum = function(relative) {
18952		return relative ? 0 : this._clones.length / 2;
18953	};
18954
18955	/**
18956	 * Gets an item at the specified relative position.
18957	 * @public
18958	 * @param {Number} [position] - The relative position of the item.
18959	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
18960	 */
18961	Owl.prototype.items = function(position) {
18962		if (position === undefined) {
18963			return this._items.slice();
18964		}
18965
18966		position = this.normalize(position, true);
18967		return this._items[position];
18968	};
18969
18970	/**
18971	 * Gets an item at the specified relative position.
18972	 * @public
18973	 * @param {Number} [position] - The relative position of the item.
18974	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
18975	 */
18976	Owl.prototype.mergers = function(position) {
18977		if (position === undefined) {
18978			return this._mergers.slice();
18979		}
18980
18981		position = this.normalize(position, true);
18982		return this._mergers[position];
18983	};
18984
18985	/**
18986	 * Gets the absolute positions of clones for an item.
18987	 * @public
18988	 * @param {Number} [position] - The relative position of the item.
18989	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
18990	 */
18991	Owl.prototype.clones = function(position) {
18992		var odd = this._clones.length / 2,
18993			even = odd + this._items.length,
18994			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
18995
18996		if (position === undefined) {
18997			return $.map(this._clones, function(v, i) { return map(i) });
18998		}
18999
19000		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
19001	};
19002
19003	/**
19004	 * Sets the current animation speed.
19005	 * @public
19006	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
19007	 * @returns {Number} - The current animation speed in milliseconds.
19008	 */
19009	Owl.prototype.speed = function(speed) {
19010		if (speed !== undefined) {
19011			this._speed = speed;
19012		}
19013
19014		return this._speed;
19015	};
19016
19017	/**
19018	 * Gets the coordinate of an item.
19019	 * @todo The name of this method is missleanding.
19020	 * @public
19021	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
19022	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
19023	 */
19024	Owl.prototype.coordinates = function(position) {
19025		var multiplier = 1,
19026			newPosition = position - 1,
19027			coordinate;
19028
19029		if (position === undefined) {
19030			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
19031				return this.coordinates(index);
19032			}, this));
19033		}
19034
19035		if (this.settings.center) {
19036			if (this.settings.rtl) {
19037				multiplier = -1;
19038				newPosition = position + 1;
19039			}
19040
19041			coordinate = this._coordinates[position];
19042			coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
19043		} else {
19044			coordinate = this._coordinates[newPosition] || 0;
19045		}
19046
19047		coordinate = Math.ceil(coordinate);
19048
19049		return coordinate;
19050	};
19051
19052	/**
19053	 * Calculates the speed for a translation.
19054	 * @protected
19055	 * @param {Number} from - The absolute position of the start item.
19056	 * @param {Number} to - The absolute position of the target item.
19057	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
19058	 * @returns {Number} - The time in milliseconds for the translation.
19059	 */
19060	Owl.prototype.duration = function(from, to, factor) {
19061		if (factor === 0) {
19062			return 0;
19063		}
19064
19065		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
19066	};
19067
19068	/**
19069	 * Slides to the specified item.
19070	 * @public
19071	 * @param {Number} position - The position of the item.
19072	 * @param {Number} [speed] - The time in milliseconds for the transition.
19073	 */
19074	Owl.prototype.to = function(position, speed) {
19075		var current = this.current(),
19076			revert = null,
19077			distance = position - this.relative(current),
19078			direction = (distance > 0) - (distance < 0),
19079			items = this._items.length,
19080			minimum = this.minimum(),
19081			maximum = this.maximum();
19082
19083		if (this.settings.loop) {
19084			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
19085				distance += direction * -1 * items;
19086			}
19087
19088			position = current + distance;
19089			revert = ((position - minimum) % items + items) % items + minimum;
19090
19091			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
19092				current = revert - distance;
19093				position = revert;
19094				this.reset(current);
19095			}
19096		} else if (this.settings.rewind) {
19097			maximum += 1;
19098			position = (position % maximum + maximum) % maximum;
19099		} else {
19100			position = Math.max(minimum, Math.min(maximum, position));
19101		}
19102
19103		this.speed(this.duration(current, position, speed));
19104		this.current(position);
19105
19106		if (this.isVisible()) {
19107			this.update();
19108		}
19109	};
19110
19111	/**
19112	 * Slides to the next item.
19113	 * @public
19114	 * @param {Number} [speed] - The time in milliseconds for the transition.
19115	 */
19116	Owl.prototype.next = function(speed) {
19117		speed = speed || false;
19118		this.to(this.relative(this.current()) + 1, speed);
19119	};
19120
19121	/**
19122	 * Slides to the previous item.
19123	 * @public
19124	 * @param {Number} [speed] - The time in milliseconds for the transition.
19125	 */
19126	Owl.prototype.prev = function(speed) {
19127		speed = speed || false;
19128		this.to(this.relative(this.current()) - 1, speed);
19129	};
19130
19131	/**
19132	 * Handles the end of an animation.
19133	 * @protected
19134	 * @param {Event} event - The event arguments.
19135	 */
19136	Owl.prototype.onTransitionEnd = function(event) {
19137
19138		// if css2 animation then event object is undefined
19139		if (event !== undefined) {
19140			event.stopPropagation();
19141
19142			// Catch only owl-stage transitionEnd event
19143			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
19144				return false;
vendor: 22,957 bytes, lines 19145-19993
19145			}
19146		}
19147
19148		this.leave('animating');
19149		this.trigger('translated');
19150	};
19151
19152	/**
19153	 * Gets viewport width.
19154	 * @protected
19155	 * @return {Number} - The width in pixel.
19156	 */
19157	Owl.prototype.viewport = function() {
19158		var width;
19159		if (this.options.responsiveBaseElement !== window) {
19160			width = $(this.options.responsiveBaseElement).width();
19161		} else if (window.innerWidth) {
19162			width = window.innerWidth;
19163		} else if (document.documentElement && document.documentElement.clientWidth) {
19164			width = document.documentElement.clientWidth;
19165		} else {
19166			console.warn('Can not detect viewport width.');
19167		}
19168		return width;
19169	};
19170
19171	/**
19172	 * Replaces the current content.
19173	 * @public
19174	 * @param {HTMLElement|jQuery|String} content - The new content.
19175	 */
19176	Owl.prototype.replace = function(content) {
19177		this.$stage.empty();
19178		this._items = [];
19179
19180		if (content) {
19181			content = (content instanceof jQuery) ? content : $(content);
19182		}
19183
19184		if (this.settings.nestedItemSelector) {
19185			content = content.find('.' + this.settings.nestedItemSelector);
19186		}
19187
19188		content.filter(function() {
19189			return this.nodeType === 1;
19190		}).each($.proxy(function(index, item) {
19191			item = this.prepare(item);
19192			this.$stage.append(item);
19193			this._items.push(item);
19194			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
19195		}, this));
19196
19197		this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
19198
19199		this.invalidate('items');
19200	};
19201
19202	/**
19203	 * Adds an item.
19204	 * @todo Use `item` instead of `content` for the event arguments.
19205	 * @public
19206	 * @param {HTMLElement|jQuery|String} content - The item content to add.
19207	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
19208	 */
19209	Owl.prototype.add = function(content, position) {
19210		var current = this.relative(this._current);
19211
19212		position = position === undefined ? this._items.length : this.normalize(position, true);
19213		content = content instanceof jQuery ? content : $(content);
19214
19215		this.trigger('add', { content: content, position: position });
19216
19217		content = this.prepare(content);
19218
19219		if (this._items.length === 0 || position === this._items.length) {
19220			this._items.length === 0 && this.$stage.append(content);
19221			this._items.length !== 0 && this._items[position - 1].after(content);
19222			this._items.push(content);
19223			this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
19224		} else {
19225			this._items[position].before(content);
19226			this._items.splice(position, 0, content);
19227			this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
19228		}
19229
19230		this._items[current] && this.reset(this._items[current].index());
19231
19232		this.invalidate('items');
19233
19234		this.trigger('added', { content: content, position: position });
19235	};
19236
19237	/**
19238	 * Removes an item by its position.
19239	 * @todo Use `item` instead of `content` for the event arguments.
19240	 * @public
19241	 * @param {Number} position - The relative position of the item to remove.
19242	 */
19243	Owl.prototype.remove = function(position) {
19244		position = this.normalize(position, true);
19245
19246		if (position === undefined) {
19247			return;
19248		}
19249
19250		this.trigger('remove', { content: this._items[position], position: position });
19251
19252		this._items[position].remove();
19253		this._items.splice(position, 1);
19254		this._mergers.splice(position, 1);
19255
19256		this.invalidate('items');
19257
19258		this.trigger('removed', { content: null, position: position });
19259	};
19260
19261	/**
19262	 * Preloads images with auto width.
19263	 * @todo Replace by a more generic approach
19264	 * @protected
19265	 */
19266	Owl.prototype.preloadAutoWidthImages = function(images) {
19267		images.each($.proxy(function(i, element) {
19268			this.enter('pre-loading');
19269			element = $(element);
19270			$(new Image()).one('load', $.proxy(function(e) {
19271				element.attr('src', e.target.src);
19272				element.css('opacity', 1);
19273				this.leave('pre-loading');
19274				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
19275			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
19276		}, this));
19277	};
19278
19279	/**
19280	 * Destroys the carousel.
19281	 * @public
19282	 */
19283	Owl.prototype.destroy = function() {
19284
19285		this.$element.off('.owl.core');
19286		this.$stage.off('.owl.core');
19287		$(document).off('.owl.core');
19288
19289		if (this.settings.responsive !== false) {
19290			window.clearTimeout(this.resizeTimer);
19291			this.off(window, 'resize', this._handlers.onThrottledResize);
19292		}
19293
19294		for (var i in this._plugins) {
19295			this._plugins[i].destroy();
19296		}
19297
19298		this.$stage.children('.cloned').remove();
19299
19300		this.$stage.unwrap();
19301		this.$stage.children().contents().unwrap();
19302		this.$stage.children().unwrap();
19303		this.$stage.remove();
19304		this.$element
19305			.removeClass(this.options.refreshClass)
19306			.removeClass(this.options.loadingClass)
19307			.removeClass(this.options.loadedClass)
19308			.removeClass(this.options.rtlClass)
19309			.removeClass(this.options.dragClass)
19310			.removeClass(this.options.grabClass)
19311			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
19312			.removeData('owl.carousel');
19313	};
19314
19315	/**
19316	 * Operators to calculate right-to-left and left-to-right.
19317	 * @protected
19318	 * @param {Number} [a] - The left side operand.
19319	 * @param {String} [o] - The operator.
19320	 * @param {Number} [b] - The right side operand.
19321	 */
19322	Owl.prototype.op = function(a, o, b) {
19323		var rtl = this.settings.rtl;
19324		switch (o) {
19325			case '<':
19326				return rtl ? a > b : a < b;
19327			case '>':
19328				return rtl ? a < b : a > b;
19329			case '>=':
19330				return rtl ? a <= b : a >= b;
19331			case '<=':
19332				return rtl ? a >= b : a <= b;
19333			default:
19334				break;
19335		}
19336	};
19337
19338	/**
19339	 * Attaches to an internal event.
19340	 * @protected
19341	 * @param {HTMLElement} element - The event source.
19342	 * @param {String} event - The event name.
19343	 * @param {Function} listener - The event handler to attach.
19344	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
19345	 */
19346	Owl.prototype.on = function(element, event, listener, capture) {
19347		if (element.addEventListener) {
19348			element.addEventListener(event, listener, capture);
19349		} else if (element.attachEvent) {
19350			element.attachEvent('on' + event, listener);
19351		}
19352	};
19353
19354	/**
19355	 * Detaches from an internal event.
19356	 * @protected
19357	 * @param {HTMLElement} element - The event source.
19358	 * @param {String} event - The event name.
19359	 * @param {Function} listener - The attached event handler to detach.
19360	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
19361	 */
19362	Owl.prototype.off = function(element, event, listener, capture) {
19363		if (element.removeEventListener) {
19364			element.removeEventListener(event, listener, capture);
19365		} else if (element.detachEvent) {
19366			element.detachEvent('on' + event, listener);
19367		}
19368	};
19369
19370	/**
19371	 * Triggers a public event.
19372	 * @todo Remove `status`, `relatedTarget` should be used instead.
19373	 * @protected
19374	 * @param {String} name - The event name.
19375	 * @param {*} [data=null] - The event data.
19376	 * @param {String} [namespace=carousel] - The event namespace.
19377	 * @param {String} [state] - The state which is associated with the event.
19378	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
19379	 * @returns {Event} - The event arguments.
19380	 */
19381	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
19382		var status = {
19383			item: { count: this._items.length, index: this.current() }
19384		}, handler = $.camelCase(
19385			$.grep([ 'on', name, namespace ], function(v) { return v })
19386				.join('-').toLowerCase()
19387		), event = $.Event(
19388			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
19389			$.extend({ relatedTarget: this }, status, data)
19390		);
19391
19392		if (!this._supress[name]) {
19393			$.each(this._plugins, function(name, plugin) {
19394				if (plugin.onTrigger) {
19395					plugin.onTrigger(event);
19396				}
19397			});
19398
19399			this.register({ type: Owl.Type.Event, name: name });
19400			this.$element.trigger(event);
19401
19402			if (this.settings && typeof this.settings[handler] === 'function') {
19403				this.settings[handler].call(this, event);
19404			}
19405		}
19406
19407		return event;
19408	};
19409
19410	/**
19411	 * Enters a state.
19412	 * @param name - The state name.
19413	 */
19414	Owl.prototype.enter = function(name) {
19415		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
19416			if (this._states.current[name] === undefined) {
19417				this._states.current[name] = 0;
19418			}
19419
19420			this._states.current[name]++;
19421		}, this));
19422	};
19423
19424	/**
19425	 * Leaves a state.
19426	 * @param name - The state name.
19427	 */
19428	Owl.prototype.leave = function(name) {
19429		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
19430			this._states.current[name]--;
19431		}, this));
19432	};
19433
19434	/**
19435	 * Registers an event or state.
19436	 * @public
19437	 * @param {Object} object - The event or state to register.
19438	 */
19439	Owl.prototype.register = function(object) {
19440		if (object.type === Owl.Type.Event) {
19441			if (!$.event.special[object.name]) {
19442				$.event.special[object.name] = {};
19443			}
19444
19445			if (!$.event.special[object.name].owl) {
19446				var _default = $.event.special[object.name]._default;
19447				$.event.special[object.name]._default = function(e) {
19448					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
19449						return _default.apply(this, arguments);
19450					}
19451					return e.namespace && e.namespace.indexOf('owl') > -1;
19452				};
19453				$.event.special[object.name].owl = true;
19454			}
19455		} else if (object.type === Owl.Type.State) {
19456			if (!this._states.tags[object.name]) {
19457				this._states.tags[object.name] = object.tags;
19458			} else {
19459				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
19460			}
19461
19462			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
19463				return $.inArray(tag, this._states.tags[object.name]) === i;
19464			}, this));
19465		}
19466	};
19467
19468	/**
19469	 * Suppresses events.
19470	 * @protected
19471	 * @param {Array.<String>} events - The events to suppress.
19472	 */
19473	Owl.prototype.suppress = function(events) {
19474		$.each(events, $.proxy(function(index, event) {
19475			this._supress[event] = true;
19476		}, this));
19477	};
19478
19479	/**
19480	 * Releases suppressed events.
19481	 * @protected
19482	 * @param {Array.<String>} events - The events to release.
19483	 */
19484	Owl.prototype.release = function(events) {
19485		$.each(events, $.proxy(function(index, event) {
19486			delete this._supress[event];
19487		}, this));
19488	};
19489
19490	/**
19491	 * Gets unified pointer coordinates from event.
19492	 * @todo #261
19493	 * @protected
19494	 * @param {Event} - The `mousedown` or `touchstart` event.
19495	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
19496	 */
19497	Owl.prototype.pointer = function(event) {
19498		var result = { x: null, y: null };
19499
19500		event = event.originalEvent || event || window.event;
19501
19502		event = event.touches && event.touches.length ?
19503			event.touches[0] : event.changedTouches && event.changedTouches.length ?
19504				event.changedTouches[0] : event;
19505
19506		if (event.pageX) {
19507			result.x = event.pageX;
19508			result.y = event.pageY;
19509		} else {
19510			result.x = event.clientX;
19511			result.y = event.clientY;
19512		}
19513
19514		return result;
19515	};
19516
19517	/**
19518	 * Determines if the input is a Number or something that can be coerced to a Number
19519	 * @protected
19520	 * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
19521	 * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
19522	 */
19523	Owl.prototype.isNumeric = function(number) {
19524		return !isNaN(parseFloat(number));
19525	};
19526
19527	/**
19528	 * Gets the difference of two vectors.
19529	 * @todo #261
19530	 * @protected
19531	 * @param {Object} - The first vector.
19532	 * @param {Object} - The second vector.
19533	 * @returns {Object} - The difference.
19534	 */
19535	Owl.prototype.difference = function(first, second) {
19536		return {
19537			x: first.x - second.x,
19538			y: first.y - second.y
19539		};
19540	};
19541
19542	/**
19543	 * The jQuery Plugin for the Owl Carousel
19544	 * @todo Navigation plugin `next` and `prev`
19545	 * @public
19546	 */
19547	$.fn.owlCarousel = function(option) {
19548		var args = Array.prototype.slice.call(arguments, 1);
19549
19550		return this.each(function() {
19551			var $this = $(this),
19552				data = $this.data('owl.carousel');
19553
19554			if (!data) {
19555				data = new Owl(this, typeof option == 'object' && option);
19556				$this.data('owl.carousel', data);
19557
19558				$.each([
19559					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
19560				], function(i, event) {
19561					data.register({ type: Owl.Type.Event, name: event });
19562					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
19563						if (e.namespace && e.relatedTarget !== this) {
19564							this.suppress([ event ]);
19565							data[event].apply(this, [].slice.call(arguments, 1));
19566							this.release([ event ]);
19567						}
19568					}, data));
19569				});
19570			}
19571
19572			if (typeof option == 'string' && option.charAt(0) !== '_') {
19573				data[option].apply(data, args);
19574			}
19575		});
19576	};
19577
19578	/**
19579	 * The constructor for the jQuery Plugin
19580	 * @public
19581	 */
19582	$.fn.owlCarousel.Constructor = Owl;
19583
19584})(window.Zepto || window.jQuery, window, document);
19585
19586/**
19587 * AutoRefresh Plugin
19588 * @version 2.3.4
19589 * @author Artus Kolanowski
19590 * @author David Deutsch
19591 * @license The MIT License (MIT)
19592 */
19593;(function($, window, document, undefined) {
19594
19595	/**
19596	 * Creates the auto refresh plugin.
19597	 * @class The Auto Refresh Plugin
19598	 * @param {Owl} carousel - The Owl Carousel
19599	 */
19600	var AutoRefresh = function(carousel) {
19601		/**
19602		 * Reference to the core.
19603		 * @protected
19604		 * @type {Owl}
19605		 */
19606		this._core = carousel;
19607
19608		/**
19609		 * Refresh interval.
19610		 * @protected
19611		 * @type {number}
19612		 */
19613		this._interval = null;
19614
19615		/**
19616		 * Whether the element is currently visible or not.
19617		 * @protected
19618		 * @type {Boolean}
19619		 */
19620		this._visible = null;
19621
19622		/**
19623		 * All event handlers.
19624		 * @protected
19625		 * @type {Object}
19626		 */
19627		this._handlers = {
19628			'initialized.owl.carousel': $.proxy(function(e) {
19629				if (e.namespace && this._core.settings.autoRefresh) {
19630					this.watch();
19631				}
19632			}, this)
19633		};
19634
19635		// set default options
19636		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
19637
19638		// register event handlers
19639		this._core.$element.on(this._handlers);
19640	};
19641
19642	/**
19643	 * Default options.
19644	 * @public
19645	 */
19646	AutoRefresh.Defaults = {
19647		autoRefresh: true,
19648		autoRefreshInterval: 500
19649	};
19650
19651	/**
19652	 * Watches the element.
19653	 */
19654	AutoRefresh.prototype.watch = function() {
19655		if (this._interval) {
19656			return;
19657		}
19658
19659		this._visible = this._core.isVisible();
19660		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
19661	};
19662
19663	/**
19664	 * Refreshes the element.
19665	 */
19666	AutoRefresh.prototype.refresh = function() {
19667		if (this._core.isVisible() === this._visible) {
19668			return;
19669		}
19670
19671		this._visible = !this._visible;
19672
19673		this._core.$element.toggleClass('owl-hidden', !this._visible);
19674
19675		this._visible && (this._core.invalidate('width') && this._core.refresh());
19676	};
19677
19678	/**
19679	 * Destroys the plugin.
19680	 */
19681	AutoRefresh.prototype.destroy = function() {
19682		var handler, property;
19683
19684		window.clearInterval(this._interval);
19685
19686		for (handler in this._handlers) {
19687			this._core.$element.off(handler, this._handlers[handler]);
19688		}
19689		for (property in Object.getOwnPropertyNames(this)) {
19690			typeof this[property] != 'function' && (this[property] = null);
19691		}
19692	};
19693
19694	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
19695
19696})(window.Zepto || window.jQuery, window, document);
19697
19698/**
19699 * Lazy Plugin
19700 * @version 2.3.4
19701 * @author Bartosz Wojciechowski
19702 * @author David Deutsch
19703 * @license The MIT License (MIT)
19704 */
19705;(function($, window, document, undefined) {
19706
19707	/**
19708	 * Creates the lazy plugin.
19709	 * @class The Lazy Plugin
19710	 * @param {Owl} carousel - The Owl Carousel
19711	 */
19712	var Lazy = function(carousel) {
19713
19714		/**
19715		 * Reference to the core.
19716		 * @protected
19717		 * @type {Owl}
19718		 */
19719		this._core = carousel;
19720
19721		/**
19722		 * Already loaded items.
19723		 * @protected
19724		 * @type {Array.<jQuery>}
19725		 */
19726		this._loaded = [];
19727
19728		/**
19729		 * Event handlers.
19730		 * @protected
19731		 * @type {Object}
19732		 */
19733		this._handlers = {
19734			'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) {
19735				if (!e.namespace) {
19736					return;
19737				}
19738
19739				if (!this._core.settings || !this._core.settings.lazyLoad) {
19740					return;
19741				}
19742
19743				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
19744					var settings = this._core.settings,
19745						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
19746						i = ((settings.center && n * -1) || 0),
19747						position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,
19748						clones = this._core.clones().length,
19749						load = $.proxy(function(i, v) { this.load(v) }, this);
19750					//TODO: Need documentation for this new option
19751					if (settings.lazyLoadEager > 0) {
19752						n += settings.lazyLoadEager;
19753						// If the carousel is looping also preload images that are to the "left"
19754						if (settings.loop) {
19755              position -= settings.lazyLoadEager;
19756              n++;
19757            }
19758					}
19759
19760					while (i++ < n) {
19761						this.load(clones / 2 + this._core.relative(position));
19762						clones && $.each(this._core.clones(this._core.relative(position)), load);
19763						position++;
19764					}
19765				}
19766			}, this)
19767		};
19768
19769		// set the default options
19770		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
19771
19772		// register event handler
19773		this._core.$element.on(this._handlers);
19774	};
19775
19776	/**
19777	 * Default options.
19778	 * @public
19779	 */
19780	Lazy.Defaults = {
19781		lazyLoad: false,
19782		lazyLoadEager: 0
19783	};
19784
19785	/**
19786	 * Loads all resources of an item at the specified position.
19787	 * @param {Number} position - The absolute position of the item.
19788	 * @protected
19789	 */
19790	Lazy.prototype.load = function(position) {
19791		var $item = this._core.$stage.children().eq(position),
19792			$elements = $item && $item.find('.owl-lazy');
19793
19794		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
19795			return;
19796		}
19797
19798		$elements.each($.proxy(function(index, element) {
19799			var $element = $(element), image,
19800                url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src') || $element.attr('data-srcset');
19801
19802			this._core.trigger('load', { element: $element, url: url }, 'lazy');
19803
19804			if ($element.is('img')) {
19805				$element.one('load.owl.lazy', $.proxy(function() {
19806					$element.css('opacity', 1);
19807					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
19808				}, this)).attr('src', url);
19809            } else if ($element.is('source')) {
19810                $element.one('load.owl.lazy', $.proxy(function() {
19811                    this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
19812                }, this)).attr('srcset', url);
19813			} else {
19814				image = new Image();
19815				image.onload = $.proxy(function() {
19816					$element.css({
19817						'background-image': 'url("' + url + '")',
19818						'opacity': '1'
19819					});
19820					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
19821				}, this);
19822				image.src = url;
19823			}
19824		}, this));
19825
19826		this._loaded.push($item.get(0));
19827	};
19828
19829	/**
19830	 * Destroys the plugin.
19831	 * @public
19832	 */
19833	Lazy.prototype.destroy = function() {
19834		var handler, property;
19835
19836		for (handler in this.handlers) {
19837			this._core.$element.off(handler, this.handlers[handler]);
19838		}
19839		for (property in Object.getOwnPropertyNames(this)) {
19840			typeof this[property] != 'function' && (this[property] = null);
19841		}
19842	};
19843
19844	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
19845
19846})(window.Zepto || window.jQuery, window, document);
19847
19848/**
19849 * AutoHeight Plugin
19850 * @version 2.3.4
19851 * @author Bartosz Wojciechowski
19852 * @author David Deutsch
19853 * @license The MIT License (MIT)
19854 */
19855;(function($, window, document, undefined) {
19856
19857	/**
19858	 * Creates the auto height plugin.
19859	 * @class The Auto Height Plugin
19860	 * @param {Owl} carousel - The Owl Carousel
19861	 */
19862	var AutoHeight = function(carousel) {
19863		/**
19864		 * Reference to the core.
19865		 * @protected
19866		 * @type {Owl}
19867		 */
19868		this._core = carousel;
19869
19870		this._previousHeight = null;
19871
19872		/**
19873		 * All event handlers.
19874		 * @protected
19875		 * @type {Object}
19876		 */
19877		this._handlers = {
19878			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
19879				if (e.namespace && this._core.settings.autoHeight) {
19880					this.update();
19881				}
19882			}, this),
19883			'changed.owl.carousel': $.proxy(function(e) {
19884				if (e.namespace && this._core.settings.autoHeight && e.property.name === 'position'){
19885					this.update();
19886				}
19887			}, this),
19888			'loaded.owl.lazy': $.proxy(function(e) {
19889				if (e.namespace && this._core.settings.autoHeight
19890					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
19891					this.update();
19892				}
19893			}, this)
19894		};
19895
19896		// set default options
19897		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
19898
19899		// register event handlers
19900		this._core.$element.on(this._handlers);
19901		this._intervalId = null;
19902		var refThis = this;
19903
19904		// These changes have been taken from a PR by gavrochelegnou proposed in #1575
19905		// and have been made compatible with the latest jQuery version
19906		$(window).on('load', function() {
19907			if (refThis._core.settings.autoHeight) {
19908				refThis.update();
19909			}
19910		});
19911
19912		// Autoresize the height of the carousel when window is resized
19913		// When carousel has images, the height is dependent on the width
19914		// and should also change on resize
19915		$(window).resize(function() {
19916			if (refThis._core.settings.autoHeight) {
19917				if (refThis._intervalId != null) {
19918					clearTimeout(refThis._intervalId);
19919				}
19920
19921				refThis._intervalId = setTimeout(function() {
19922					refThis.update();
19923				}, 250);
19924			}
19925		});
19926
19927	};
19928
19929	/**
19930	 * Default options.
19931	 * @public
19932	 */
19933	AutoHeight.Defaults = {
19934		autoHeight: false,
19935		autoHeightClass: 'owl-height'
19936	};
19937
19938	/**
19939	 * Updates the view.
19940	 */
19941	AutoHeight.prototype.update = function() {
19942		var start = this._core._current,
19943			end = start + this._core.settings.items,
19944			lazyLoadEnabled = this._core.settings.lazyLoad,
19945			visible = this._core.$stage.children().toArray().slice(start, end),
19946			heights = [],
19947			maxheight = 0;
19948
19949		$.each(visible, function(index, item) {
19950			heights.push($(item).height());
19951		});
19952
19953		maxheight = Math.max.apply(null, heights);
19954
19955		if (maxheight <= 1 && lazyLoadEnabled && this._previousHeight) {
19956			maxheight = this._previousHeight;
19957		}
19958
19959		this._previousHeight = maxheight;
19960
19961		this._core.$stage.parent()
19962			.height(maxheight)
19963			.addClass(this._core.settings.autoHeightClass);
19964	};
19965
19966	AutoHeight.prototype.destroy = function() {
19967		var handler, property;
19968
19969		for (handler in this._handlers) {
19970			this._core.$element.off(handler, this._handlers[handler]);
19971		}
19972		for (property in Object.getOwnPropertyNames(this)) {
19973			typeof this[property] !== 'function' && (this[property] = null);
19974		}
19975	};
19976
19977	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
19978
19979})(window.Zepto || window.jQuery, window, document);
19980
19981/**
19982 * Video Plugin
19983 * @version 2.3.4
19984 * @author Bartosz Wojciechowski
19985 * @author David Deutsch
19986 * @license The MIT License (MIT)
19987 */
19988;(function($, window, document, undefined) {
19989
19990	/**
19991	 * Creates the video plugin.
19992	 * @class The Video Plugin
19993	 * @param {Owl} carousel - The Owl Carousel
vendor: 5,347 bytes, lines 19994-20191
19994	 */
19995	var Video = function(carousel) {
19996		/**
19997		 * Reference to the core.
19998		 * @protected
19999		 * @type {Owl}
20000		 */
20001		this._core = carousel;
20002
20003		/**
20004		 * Cache all video URLs.
20005		 * @protected
20006		 * @type {Object}
20007		 */
20008		this._videos = {};
20009
20010		/**
20011		 * Current playing item.
20012		 * @protected
20013		 * @type {jQuery}
20014		 */
20015		this._playing = null;
20016
20017		/**
20018		 * All event handlers.
20019		 * @todo The cloned content removale is too late
20020		 * @protected
20021		 * @type {Object}
20022		 */
20023		this._handlers = {
20024			'initialized.owl.carousel': $.proxy(function(e) {
20025				if (e.namespace) {
20026					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
20027				}
20028			}, this),
20029			'resize.owl.carousel': $.proxy(function(e) {
20030				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
20031					e.preventDefault();
20032				}
20033			}, this),
20034			'refreshed.owl.carousel': $.proxy(function(e) {
20035				if (e.namespace && this._core.is('resizing')) {
20036					this._core.$stage.find('.cloned .owl-video-frame').remove();
20037				}
20038			}, this),
20039			'changed.owl.carousel': $.proxy(function(e) {
20040				if (e.namespace && e.property.name === 'position' && this._playing) {
20041					this.stop();
20042				}
20043			}, this),
20044			'prepared.owl.carousel': $.proxy(function(e) {
20045				if (!e.namespace) {
20046					return;
20047				}
20048
20049				var $element = $(e.content).find('.owl-video');
20050
20051				if ($element.length) {
20052					$element.css('display', 'none');
20053					this.fetch($element, $(e.content));
20054				}
20055			}, this)
20056		};
20057
20058		// set default options
20059		this._core.options = $.extend({}, Video.Defaults, this._core.options);
20060
20061		// register event handlers
20062		this._core.$element.on(this._handlers);
20063
20064		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
20065			this.play(e);
20066		}, this));
20067	};
20068
20069	/**
20070	 * Default options.
20071	 * @public
20072	 */
20073	Video.Defaults = {
20074		video: false,
20075		videoHeight: false,
20076		videoWidth: false
20077	};
20078
20079	/**
20080	 * Gets the video ID and the type (YouTube/Vimeo/vzaar only).
20081	 * @protected
20082	 * @param {jQuery} target - The target containing the video data.
20083	 * @param {jQuery} item - The item containing the video.
20084	 */
20085	Video.prototype.fetch = function(target, item) {
20086			var type = (function() {
20087					if (target.attr('data-vimeo-id')) {
20088						return 'vimeo';
20089					} else if (target.attr('data-vzaar-id')) {
20090						return 'vzaar'
20091					} else {
20092						return 'youtube';
20093					}
20094				})(),
20095				id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),
20096				width = target.attr('data-width') || this._core.settings.videoWidth,
20097				height = target.attr('data-height') || this._core.settings.videoHeight,
20098				url = target.attr('href');
20099
20100		if (url) {
20101
20102			/*
20103					Parses the id's out of the following urls (and probably more):
20104					https://www.youtube.com/watch?v=:id
20105					https://youtu.be/:id
20106					https://vimeo.com/:id
20107					https://vimeo.com/channels/:channel/:id
20108					https://vimeo.com/groups/:group/videos/:id
20109					https://app.vzaar.com/videos/:id
20110
20111					Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F
20112			*/
20113
20114			id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com|be\-nocookie\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
20115
20116			if (id[3].indexOf('youtu') > -1) {
20117				type = 'youtube';
20118			} else if (id[3].indexOf('vimeo') > -1) {
20119				type = 'vimeo';
20120			} else if (id[3].indexOf('vzaar') > -1) {
20121				type = 'vzaar';
20122			} else {
20123				throw new Error('Video URL not supported.');
20124			}
20125			id = id[6];
20126		} else {
20127			throw new Error('Missing video URL.');
20128		}
20129
20130		this._videos[url] = {
20131			type: type,
20132			id: id,
20133			width: width,
20134			height: height
20135		};
20136
20137		item.attr('data-video', url);
20138
20139		this.thumbnail(target, this._videos[url]);
20140	};
20141
20142	/**
20143	 * Creates video thumbnail.
20144	 * @protected
20145	 * @param {jQuery} target - The target containing the video data.
20146	 * @param {Object} info - The video info object.
20147	 * @see `fetch`
20148	 */
20149	Video.prototype.thumbnail = function(target, video) {
20150		var tnLink,
20151			icon,
20152			path,
20153			dimensions = video.width && video.height ? 'width:' + video.width + 'px;height:' + video.height + 'px;' : '',
20154			customTn = target.find('img'),
20155			srcType = 'src',
20156			lazyClass = '',
20157			settings = this._core.settings,
20158			create = function(path) {
20159				icon = '<div class="owl-video-play-icon"></div>';
20160
20161				if (settings.lazyLoad) {
20162					tnLink = $('<div/>',{
20163						"class": 'owl-video-tn ' + lazyClass,
20164						"srcType": path
20165					});
20166				} else {
20167					tnLink = $( '<div/>', {
20168						"class": "owl-video-tn",
20169						"style": 'opacity:1;background-image:url(' + path + ')'
20170					});
20171				}
20172				target.after(tnLink);
20173				target.after(icon);
20174			};
20175
20176		// wrap video content into owl-video-wrapper div
20177		target.wrap( $( '<div/>', {
20178			"class": "owl-video-wrapper",
20179			"style": dimensions
20180		}));
20181
20182		if (this._core.settings.lazyLoad) {
20183			srcType = 'data-src';
20184			lazyClass = 'owl-lazy';
20185		}
20186
20187		// custom thumbnail
20188		if (customTn.length) {
20189			create(customTn.attr(srcType));
20190			customTn.remove();
20191			return false;
vendor: 15,908 bytes, lines 20192-20829
20192		}
20193
20194		if (video.type === 'youtube') {
20195			path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
20196			create(path);
20197		} else if (video.type === 'vimeo') {
20198			$.ajax({
20199				type: 'GET',
20200				url: '//vimeo.com/api/v2/video/' + video.id + '.json',
20201				jsonp: 'callback',
20202				dataType: 'jsonp',
20203				success: function(data) {
20204					path = data[0].thumbnail_large;
20205					create(path);
20206				}
20207			});
20208		} else if (video.type === 'vzaar') {
20209			$.ajax({
20210				type: 'GET',
20211				url: '//vzaar.com/api/videos/' + video.id + '.json',
20212				jsonp: 'callback',
20213				dataType: 'jsonp',
20214				success: function(data) {
20215					path = data.framegrab_url;
20216					create(path);
20217				}
20218			});
20219		}
20220	};
20221
20222	/**
20223	 * Stops the current video.
20224	 * @public
20225	 */
20226	Video.prototype.stop = function() {
20227		this._core.trigger('stop', null, 'video');
20228		this._playing.find('.owl-video-frame').remove();
20229		this._playing.removeClass('owl-video-playing');
20230		this._playing = null;
20231		this._core.leave('playing');
20232		this._core.trigger('stopped', null, 'video');
20233	};
20234
20235	/**
20236	 * Starts the current video.
20237	 * @public
20238	 * @param {Event} event - The event arguments.
20239	 */
20240	Video.prototype.play = function(event) {
20241		var target = $(event.target),
20242			item = target.closest('.' + this._core.settings.itemClass),
20243			video = this._videos[item.attr('data-video')],
20244			width = video.width || '100%',
20245			height = video.height || this._core.$stage.height(),
20246			html,
20247			iframe;
20248
20249		if (this._playing) {
20250			return;
20251		}
20252
20253		this._core.enter('playing');
20254		this._core.trigger('play', null, 'video');
20255
20256		item = this._core.items(this._core.relative(item.index()));
20257
20258		this._core.reset(item.index());
20259
20260		html = $( '<iframe frameborder="0" allowfullscreen mozallowfullscreen webkitAllowFullScreen ></iframe>' );
20261		html.attr( 'height', height );
20262		html.attr( 'width', width );
20263		if (video.type === 'youtube') {
20264			html.attr( 'src', '//www.youtube.com/embed/' + video.id + '?autoplay=1&rel=0&v=' + video.id );
20265		} else if (video.type === 'vimeo') {
20266			html.attr( 'src', '//player.vimeo.com/video/' + video.id + '?autoplay=1' );
20267		} else if (video.type === 'vzaar') {
20268			html.attr( 'src', '//view.vzaar.com/' + video.id + '/player?autoplay=true' );
20269		}
20270
20271		iframe = $(html).wrap( '<div class="owl-video-frame" />' ).insertAfter(item.find('.owl-video'));
20272
20273		this._playing = item.addClass('owl-video-playing');
20274	};
20275
20276	/**
20277	 * Checks whether an video is currently in full screen mode or not.
20278	 * @todo Bad style because looks like a readonly method but changes members.
20279	 * @protected
20280	 * @returns {Boolean}
20281	 */
20282	Video.prototype.isInFullScreen = function() {
20283		var element = document.fullscreenElement || document.mozFullScreenElement ||
20284				document.webkitFullscreenElement;
20285
20286		return element && $(element).parent().hasClass('owl-video-frame');
20287	};
20288
20289	/**
20290	 * Destroys the plugin.
20291	 */
20292	Video.prototype.destroy = function() {
20293		var handler, property;
20294
20295		this._core.$element.off('click.owl.video');
20296
20297		for (handler in this._handlers) {
20298			this._core.$element.off(handler, this._handlers[handler]);
20299		}
20300		for (property in Object.getOwnPropertyNames(this)) {
20301			typeof this[property] != 'function' && (this[property] = null);
20302		}
20303	};
20304
20305	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
20306
20307})(window.Zepto || window.jQuery, window, document);
20308
20309/**
20310 * Animate Plugin
20311 * @version 2.3.4
20312 * @author Bartosz Wojciechowski
20313 * @author David Deutsch
20314 * @license The MIT License (MIT)
20315 */
20316;(function($, window, document, undefined) {
20317
20318	/**
20319	 * Creates the animate plugin.
20320	 * @class The Navigation Plugin
20321	 * @param {Owl} scope - The Owl Carousel
20322	 */
20323	var Animate = function(scope) {
20324		this.core = scope;
20325		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
20326		this.swapping = true;
20327		this.previous = undefined;
20328		this.next = undefined;
20329
20330		this.handlers = {
20331			'change.owl.carousel': $.proxy(function(e) {
20332				if (e.namespace && e.property.name == 'position') {
20333					this.previous = this.core.current();
20334					this.next = e.property.value;
20335				}
20336			}, this),
20337			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
20338				if (e.namespace) {
20339					this.swapping = e.type == 'translated';
20340				}
20341			}, this),
20342			'translate.owl.carousel': $.proxy(function(e) {
20343				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
20344					this.swap();
20345				}
20346			}, this)
20347		};
20348
20349		this.core.$element.on(this.handlers);
20350	};
20351
20352	/**
20353	 * Default options.
20354	 * @public
20355	 */
20356	Animate.Defaults = {
20357		animateOut: false,
20358		animateIn: false
20359	};
20360
20361	/**
20362	 * Toggles the animation classes whenever an translations starts.
20363	 * @protected
20364	 * @returns {Boolean|undefined}
20365	 */
20366	Animate.prototype.swap = function() {
20367
20368		if (this.core.settings.items !== 1) {
20369			return;
20370		}
20371
20372		if (!$.support.animation || !$.support.transition) {
20373			return;
20374		}
20375
20376		this.core.speed(0);
20377
20378		var left,
20379			clear = $.proxy(this.clear, this),
20380			previous = this.core.$stage.children().eq(this.previous),
20381			next = this.core.$stage.children().eq(this.next),
20382			incoming = this.core.settings.animateIn,
20383			outgoing = this.core.settings.animateOut;
20384
20385		if (this.core.current() === this.previous) {
20386			return;
20387		}
20388
20389		if (outgoing) {
20390			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
20391			previous.one($.support.animation.end, clear)
20392				.css( { 'left': left + 'px' } )
20393				.addClass('animated owl-animated-out')
20394				.addClass(outgoing);
20395		}
20396
20397		if (incoming) {
20398			next.one($.support.animation.end, clear)
20399				.addClass('animated owl-animated-in')
20400				.addClass(incoming);
20401		}
20402	};
20403
20404	Animate.prototype.clear = function(e) {
20405		$(e.target).css( { 'left': '' } )
20406			.removeClass('animated owl-animated-out owl-animated-in')
20407			.removeClass(this.core.settings.animateIn)
20408			.removeClass(this.core.settings.animateOut);
20409		this.core.onTransitionEnd();
20410	};
20411
20412	/**
20413	 * Destroys the plugin.
20414	 * @public
20415	 */
20416	Animate.prototype.destroy = function() {
20417		var handler, property;
20418
20419		for (handler in this.handlers) {
20420			this.core.$element.off(handler, this.handlers[handler]);
20421		}
20422		for (property in Object.getOwnPropertyNames(this)) {
20423			typeof this[property] != 'function' && (this[property] = null);
20424		}
20425	};
20426
20427	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
20428
20429})(window.Zepto || window.jQuery, window, document);
20430
20431/**
20432 * Autoplay Plugin
20433 * @version 2.3.4
20434 * @author Bartosz Wojciechowski
20435 * @author Artus Kolanowski
20436 * @author David Deutsch
20437 * @author Tom De Caluwé
20438 * @license The MIT License (MIT)
20439 */
20440;(function($, window, document, undefined) {
20441
20442	/**
20443	 * Creates the autoplay plugin.
20444	 * @class The Autoplay Plugin
20445	 * @param {Owl} scope - The Owl Carousel
20446	 */
20447	var Autoplay = function(carousel) {
20448		/**
20449		 * Reference to the core.
20450		 * @protected
20451		 * @type {Owl}
20452		 */
20453		this._core = carousel;
20454
20455		/**
20456		 * The autoplay timeout id.
20457		 * @type {Number}
20458		 */
20459		this._call = null;
20460
20461		/**
20462		 * Depending on the state of the plugin, this variable contains either
20463		 * the start time of the timer or the current timer value if it's
20464		 * paused. Since we start in a paused state we initialize the timer
20465		 * value.
20466		 * @type {Number}
20467		 */
20468		this._time = 0;
20469
20470		/**
20471		 * Stores the timeout currently used.
20472		 * @type {Number}
20473		 */
20474		this._timeout = 0;
20475
20476		/**
20477		 * Indicates whenever the autoplay is paused.
20478		 * @type {Boolean}
20479		 */
20480		this._paused = true;
20481
20482		/**
20483		 * All event handlers.
20484		 * @protected
20485		 * @type {Object}
20486		 */
20487		this._handlers = {
20488			'changed.owl.carousel': $.proxy(function(e) {
20489				if (e.namespace && e.property.name === 'settings') {
20490					if (this._core.settings.autoplay) {
20491						this.play();
20492					} else {
20493						this.stop();
20494					}
20495				} else if (e.namespace && e.property.name === 'position' && this._paused) {
20496					// Reset the timer. This code is triggered when the position
20497					// of the carousel was changed through user interaction.
20498					this._time = 0;
20499				}
20500			}, this),
20501			'initialized.owl.carousel': $.proxy(function(e) {
20502				if (e.namespace && this._core.settings.autoplay) {
20503					this.play();
20504				}
20505			}, this),
20506			'play.owl.autoplay': $.proxy(function(e, t, s) {
20507				if (e.namespace) {
20508					this.play(t, s);
20509				}
20510			}, this),
20511			'stop.owl.autoplay': $.proxy(function(e) {
20512				if (e.namespace) {
20513					this.stop();
20514				}
20515			}, this),
20516			'mouseover.owl.autoplay': $.proxy(function() {
20517				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
20518					this.pause();
20519				}
20520			}, this),
20521			'mouseleave.owl.autoplay': $.proxy(function() {
20522				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
20523					this.play();
20524				}
20525			}, this),
20526			'touchstart.owl.core': $.proxy(function() {
20527				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
20528					this.pause();
20529				}
20530			}, this),
20531			'touchend.owl.core': $.proxy(function() {
20532				if (this._core.settings.autoplayHoverPause) {
20533					this.play();
20534				}
20535			}, this)
20536		};
20537
20538		// register event handlers
20539		this._core.$element.on(this._handlers);
20540
20541		// set default options
20542		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
20543	};
20544
20545	/**
20546	 * Default options.
20547	 * @public
20548	 */
20549	Autoplay.Defaults = {
20550		autoplay: false,
20551		autoplayTimeout: 5000,
20552		autoplayHoverPause: false,
20553		autoplaySpeed: false
20554	};
20555
20556	/**
20557	 * Transition to the next slide and set a timeout for the next transition.
20558	 * @private
20559	 * @param {Number} [speed] - The animation speed for the animations.
20560	 */
20561	Autoplay.prototype._next = function(speed) {
20562		this._call = window.setTimeout(
20563			$.proxy(this._next, this, speed),
20564			this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read()
20565		);
20566
20567		if (this._core.is('interacting') || document.hidden) {
20568			return;
20569		}
20570		this._core.next(speed || this._core.settings.autoplaySpeed);
20571	}
20572
20573	/**
20574	 * Reads the current timer value when the timer is playing.
20575	 * @public
20576	 */
20577	Autoplay.prototype.read = function() {
20578		return new Date().getTime() - this._time;
20579	};
20580
20581	/**
20582	 * Starts the autoplay.
20583	 * @public
20584	 * @param {Number} [timeout] - The interval before the next animation starts.
20585	 * @param {Number} [speed] - The animation speed for the animations.
20586	 */
20587	Autoplay.prototype.play = function(timeout, speed) {
20588		var elapsed;
20589
20590		if (!this._core.is('rotating')) {
20591			this._core.enter('rotating');
20592		}
20593
20594		timeout = timeout || this._core.settings.autoplayTimeout;
20595
20596		// Calculate the elapsed time since the last transition. If the carousel
20597		// wasn't playing this calculation will yield zero.
20598		elapsed = Math.min(this._time % (this._timeout || timeout), timeout);
20599
20600		if (this._paused) {
20601			// Start the clock.
20602			this._time = this.read();
20603			this._paused = false;
20604		} else {
20605			// Clear the active timeout to allow replacement.
20606			window.clearTimeout(this._call);
20607		}
20608
20609		// Adjust the origin of the timer to match the new timeout value.
20610		this._time += this.read() % timeout - elapsed;
20611
20612		this._timeout = timeout;
20613		this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed);
20614	};
20615
20616	/**
20617	 * Stops the autoplay.
20618	 * @public
20619	 */
20620	Autoplay.prototype.stop = function() {
20621		if (this._core.is('rotating')) {
20622			// Reset the clock.
20623			this._time = 0;
20624			this._paused = true;
20625
20626			window.clearTimeout(this._call);
20627			this._core.leave('rotating');
20628		}
20629	};
20630
20631	/**
20632	 * Pauses the autoplay.
20633	 * @public
20634	 */
20635	Autoplay.prototype.pause = function() {
20636		if (this._core.is('rotating') && !this._paused) {
20637			// Pause the clock.
20638			this._time = this.read();
20639			this._paused = true;
20640
20641			window.clearTimeout(this._call);
20642		}
20643	};
20644
20645	/**
20646	 * Destroys the plugin.
20647	 */
20648	Autoplay.prototype.destroy = function() {
20649		var handler, property;
20650
20651		this.stop();
20652
20653		for (handler in this._handlers) {
20654			this._core.$element.off(handler, this._handlers[handler]);
20655		}
20656		for (property in Object.getOwnPropertyNames(this)) {
20657			typeof this[property] != 'function' && (this[property] = null);
20658		}
20659	};
20660
20661	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
20662
20663})(window.Zepto || window.jQuery, window, document);
20664
20665/**
20666 * Navigation Plugin
20667 * @version 2.3.4
20668 * @author Artus Kolanowski
20669 * @author David Deutsch
20670 * @license The MIT License (MIT)
20671 */
20672;(function($, window, document, undefined) {
20673	'use strict';
20674
20675	/**
20676	 * Creates the navigation plugin.
20677	 * @class The Navigation Plugin
20678	 * @param {Owl} carousel - The Owl Carousel.
20679	 */
20680	var Navigation = function(carousel) {
20681		/**
20682		 * Reference to the core.
20683		 * @protected
20684		 * @type {Owl}
20685		 */
20686		this._core = carousel;
20687
20688		/**
20689		 * Indicates whether the plugin is initialized or not.
20690		 * @protected
20691		 * @type {Boolean}
20692		 */
20693		this._initialized = false;
20694
20695		/**
20696		 * The current paging indexes.
20697		 * @protected
20698		 * @type {Array}
20699		 */
20700		this._pages = [];
20701
20702		/**
20703		 * All DOM elements of the user interface.
20704		 * @protected
20705		 * @type {Object}
20706		 */
20707		this._controls = {};
20708
20709		/**
20710		 * Markup for an indicator.
20711		 * @protected
20712		 * @type {Array.<String>}
20713		 */
20714		this._templates = [];
20715
20716		/**
20717		 * The carousel element.
20718		 * @type {jQuery}
20719		 */
20720		this.$element = this._core.$element;
20721
20722		/**
20723		 * Overridden methods of the carousel.
20724		 * @protected
20725		 * @type {Object}
20726		 */
20727		this._overrides = {
20728			next: this._core.next,
20729			prev: this._core.prev,
20730			to: this._core.to
20731		};
20732
20733		/**
20734		 * All event handlers.
20735		 * @protected
20736		 * @type {Object}
20737		 */
20738		this._handlers = {
20739			'prepared.owl.carousel': $.proxy(function(e) {
20740				if (e.namespace && this._core.settings.dotsData) {
20741					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
20742						$(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '</div>');
20743				}
20744			}, this),
20745			'added.owl.carousel': $.proxy(function(e) {
20746				if (e.namespace && this._core.settings.dotsData) {
20747					this._templates.splice(e.position, 0, this._templates.pop());
20748				}
20749			}, this),
20750			'remove.owl.carousel': $.proxy(function(e) {
20751				if (e.namespace && this._core.settings.dotsData) {
20752					this._templates.splice(e.position, 1);
20753				}
20754			}, this),
20755			'changed.owl.carousel': $.proxy(function(e) {
20756				if (e.namespace && e.property.name == 'position') {
20757					this.draw();
20758				}
20759			}, this),
20760			'initialized.owl.carousel': $.proxy(function(e) {
20761				if (e.namespace && !this._initialized) {
20762					this._core.trigger('initialize', null, 'navigation');
20763					this.initialize();
20764					this.update();
20765					this.draw();
20766					this._initialized = true;
20767					this._core.trigger('initialized', null, 'navigation');
20768				}
20769			}, this),
20770			'refreshed.owl.carousel': $.proxy(function(e) {
20771				if (e.namespace && this._initialized) {
20772					this._core.trigger('refresh', null, 'navigation');
20773					this.update();
20774					this.draw();
20775					this._core.trigger('refreshed', null, 'navigation');
20776				}
20777			}, this)
20778		};
20779
20780		// set default options
20781		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
20782
20783		// register event handlers
20784		this.$element.on(this._handlers);
20785	};
20786
20787	/**
20788	 * Default options.
20789	 * @public
20790	 * @todo Rename `slideBy` to `navBy`
20791	 */
20792	Navigation.Defaults = {
20793		nav: false,
20794		navText: [
20795			'<span aria-label="' + 'Previous' + '">&#x2039;</span>',
20796			'<span aria-label="' + 'Next' + '">&#x203a;</span>'
20797		],
20798		navSpeed: false,
20799		navElement: 'button type="button" role="presentation"',
20800		navContainer: false,
20801		navContainerClass: 'owl-nav',
20802		navClass: [
20803			'owl-prev',
20804			'owl-next'
20805		],
20806		slideBy: 1,
20807		dotClass: 'owl-dot',
20808		dotsClass: 'owl-dots',
20809		dots: true,
20810		dotsEach: false,
20811		dotsData: false,
20812		dotsSpeed: false,
20813		dotsContainer: false
20814	};
20815
20816	/**
20817	 * Initializes the layout of the plugin and extends the carousel.
20818	 * @protected
20819	 */
20820	Navigation.prototype.initialize = function() {
20821		var override,
20822			settings = this._core.settings;
20823
20824		// create DOM structure for relative navigation
20825		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
20826			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
20827
20828		this._controls.$previous = $('<' + settings.navElement + '>')
20829			.addClass(settings.navClass[0])
vendor: 4,756 bytes, lines 20830-20991
20830			.html(settings.navText[0])
20831			.prependTo(this._controls.$relative)
20832			.on('click', $.proxy(function(e) {
20833				this.prev(settings.navSpeed);
20834			}, this));
20835		this._controls.$next = $('<' + settings.navElement + '>')
20836			.addClass(settings.navClass[1])
20837			.html(settings.navText[1])
20838			.appendTo(this._controls.$relative)
20839			.on('click', $.proxy(function(e) {
20840				this.next(settings.navSpeed);
20841			}, this));
20842
20843		// create DOM structure for absolute navigation
20844		if (!settings.dotsData) {
20845			this._templates = [ $('<button role="button">')
20846				.addClass(settings.dotClass)
20847				.append($('<span>'))
20848				.prop('outerHTML') ];
20849		}
20850
20851		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
20852			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
20853
20854		this._controls.$absolute.on('click', 'button', $.proxy(function(e) {
20855			var index = $(e.target).parent().is(this._controls.$absolute)
20856				? $(e.target).index() : $(e.target).parent().index();
20857
20858			e.preventDefault();
20859
20860			this.to(index, settings.dotsSpeed);
20861		}, this));
20862
20863		/*$el.on('focusin', function() {
20864			$(document).off(".carousel");
20865
20866			$(document).on('keydown.carousel', function(e) {
20867				if(e.keyCode == 37) {
20868					$el.trigger('prev.owl')
20869				}
20870				if(e.keyCode == 39) {
20871					$el.trigger('next.owl')
20872				}
20873			});
20874		});*/
20875
20876		// override public methods of the carousel
20877		for (override in this._overrides) {
20878			this._core[override] = $.proxy(this[override], this);
20879		}
20880	};
20881
20882	/**
20883	 * Destroys the plugin.
20884	 * @protected
20885	 */
20886	Navigation.prototype.destroy = function() {
20887		var handler, control, property, override, settings;
20888		settings = this._core.settings;
20889
20890		for (handler in this._handlers) {
20891			this.$element.off(handler, this._handlers[handler]);
20892		}
20893		for (control in this._controls) {
20894			if (control === '$relative' && settings.navContainer) {
20895				this._controls[control].html('');
20896			} else {
20897				this._controls[control].remove();
20898			}
20899		}
20900		for (override in this.overides) {
20901			this._core[override] = this._overrides[override];
20902		}
20903		for (property in Object.getOwnPropertyNames(this)) {
20904			typeof this[property] != 'function' && (this[property] = null);
20905		}
20906	};
20907
20908	/**
20909	 * Updates the internal state.
20910	 * @protected
20911	 */
20912	Navigation.prototype.update = function() {
20913		var i, j, k,
20914			lower = this._core.clones().length / 2,
20915			upper = lower + this._core.items().length,
20916			maximum = this._core.maximum(true),
20917			settings = this._core.settings,
20918			size = settings.center || settings.autoWidth || settings.dotsData
20919				? 1 : settings.dotsEach || settings.items;
20920
20921		if (settings.slideBy !== 'page') {
20922			settings.slideBy = Math.min(settings.slideBy, settings.items);
20923		}
20924
20925		if (settings.dots || settings.slideBy == 'page') {
20926			this._pages = [];
20927
20928			for (i = lower, j = 0, k = 0; i < upper; i++) {
20929				if (j >= size || j === 0) {
20930					this._pages.push({
20931						start: Math.min(maximum, i - lower),
20932						end: i - lower + size - 1
20933					});
20934					if (Math.min(maximum, i - lower) === maximum) {
20935						break;
20936					}
20937					j = 0, ++k;
20938				}
20939				j += this._core.mergers(this._core.relative(i));
20940			}
20941		}
20942	};
20943
20944	/**
20945	 * Draws the user interface.
20946	 * @todo The option `dotsData` wont work.
20947	 * @protected
20948	 */
20949	Navigation.prototype.draw = function() {
20950		var difference,
20951			settings = this._core.settings,
20952			disabled = this._core.items().length <= settings.items,
20953			index = this._core.relative(this._core.current()),
20954			loop = settings.loop || settings.rewind;
20955
20956		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
20957
20958		if (settings.nav) {
20959			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
20960			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
20961		}
20962
20963		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
20964
20965		if (settings.dots) {
20966			difference = this._pages.length - this._controls.$absolute.children().length;
20967
20968			if (settings.dotsData && difference !== 0) {
20969				this._controls.$absolute.html(this._templates.join(''));
20970			} else if (difference > 0) {
20971				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
20972			} else if (difference < 0) {
20973				this._controls.$absolute.children().slice(difference).remove();
20974			}
20975
20976			this._controls.$absolute.find('.active').removeClass('active');
20977			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
20978		}
20979	};
20980
20981	/**
20982	 * Extends event data.
20983	 * @protected
20984	 * @param {Event} event - The event object which gets thrown.
20985	 */
20986	Navigation.prototype.onTrigger = function(event) {
20987		var settings = this._core.settings;
20988
20989		event.page = {
20990			index: $.inArray(this.current(), this._pages),
20991			count: this._pages.length,
vendor: 7,284 bytes, lines 20992-21277
20992			size: settings && (settings.center || settings.autoWidth || settings.dotsData
20993				? 1 : settings.dotsEach || settings.items)
20994		};
20995	};
20996
20997	/**
20998	 * Gets the current page position of the carousel.
20999	 * @protected
21000	 * @returns {Number}
21001	 */
21002	Navigation.prototype.current = function() {
21003		var current = this._core.relative(this._core.current());
21004		return $.grep(this._pages, $.proxy(function(page, index) {
21005			return page.start <= current && page.end >= current;
21006		}, this)).pop();
21007	};
21008
21009	/**
21010	 * Gets the current succesor/predecessor position.
21011	 * @protected
21012	 * @returns {Number}
21013	 */
21014	Navigation.prototype.getPosition = function(successor) {
21015		var position, length,
21016			settings = this._core.settings;
21017
21018		if (settings.slideBy == 'page') {
21019			position = $.inArray(this.current(), this._pages);
21020			length = this._pages.length;
21021			successor ? ++position : --position;
21022			position = this._pages[((position % length) + length) % length].start;
21023		} else {
21024			position = this._core.relative(this._core.current());
21025			length = this._core.items().length;
21026			successor ? position += settings.slideBy : position -= settings.slideBy;
21027		}
21028
21029		return position;
21030	};
21031
21032	/**
21033	 * Slides to the next item or page.
21034	 * @public
21035	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
21036	 */
21037	Navigation.prototype.next = function(speed) {
21038		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
21039	};
21040
21041	/**
21042	 * Slides to the previous item or page.
21043	 * @public
21044	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
21045	 */
21046	Navigation.prototype.prev = function(speed) {
21047		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
21048	};
21049
21050	/**
21051	 * Slides to the specified item or page.
21052	 * @public
21053	 * @param {Number} position - The position of the item or page.
21054	 * @param {Number} [speed] - The time in milliseconds for the transition.
21055	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
21056	 */
21057	Navigation.prototype.to = function(position, speed, standard) {
21058		var length;
21059
21060		if (!standard && this._pages.length) {
21061			length = this._pages.length;
21062			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
21063		} else {
21064			$.proxy(this._overrides.to, this._core)(position, speed);
21065		}
21066	};
21067
21068	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
21069
21070})(window.Zepto || window.jQuery, window, document);
21071
21072/**
21073 * Hash Plugin
21074 * @version 2.3.4
21075 * @author Artus Kolanowski
21076 * @author David Deutsch
21077 * @license The MIT License (MIT)
21078 */
21079;(function($, window, document, undefined) {
21080	'use strict';
21081
21082	/**
21083	 * Creates the hash plugin.
21084	 * @class The Hash Plugin
21085	 * @param {Owl} carousel - The Owl Carousel
21086	 */
21087	var Hash = function(carousel) {
21088		/**
21089		 * Reference to the core.
21090		 * @protected
21091		 * @type {Owl}
21092		 */
21093		this._core = carousel;
21094
21095		/**
21096		 * Hash index for the items.
21097		 * @protected
21098		 * @type {Object}
21099		 */
21100		this._hashes = {};
21101
21102		/**
21103		 * The carousel element.
21104		 * @type {jQuery}
21105		 */
21106		this.$element = this._core.$element;
21107
21108		/**
21109		 * All event handlers.
21110		 * @protected
21111		 * @type {Object}
21112		 */
21113		this._handlers = {
21114			'initialized.owl.carousel': $.proxy(function(e) {
21115				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
21116					$(window).trigger('hashchange.owl.navigation');
21117				}
21118			}, this),
21119			'prepared.owl.carousel': $.proxy(function(e) {
21120				if (e.namespace) {
21121					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
21122
21123					if (!hash) {
21124						return;
21125					}
21126
21127					this._hashes[hash] = e.content;
21128				}
21129			}, this),
21130			'changed.owl.carousel': $.proxy(function(e) {
21131				if (e.namespace && e.property.name === 'position') {
21132					var current = this._core.items(this._core.relative(this._core.current())),
21133						hash = $.map(this._hashes, function(item, hash) {
21134							return item === current ? hash : null;
21135						}).join();
21136
21137					if (!hash || window.location.hash.slice(1) === hash) {
21138						return;
21139					}
21140
21141					window.location.hash = hash;
21142				}
21143			}, this)
21144		};
21145
21146		// set default options
21147		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
21148
21149		// register the event handlers
21150		this.$element.on(this._handlers);
21151
21152		// register event listener for hash navigation
21153		$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
21154			var hash = window.location.hash.substring(1),
21155				items = this._core.$stage.children(),
21156				position = this._hashes[hash] && items.index(this._hashes[hash]);
21157
21158			if (position === undefined || position === this._core.current()) {
21159				return;
21160			}
21161
21162			this._core.to(this._core.relative(position), false, true);
21163		}, this));
21164	};
21165
21166	/**
21167	 * Default options.
21168	 * @public
21169	 */
21170	Hash.Defaults = {
21171		URLhashListener: false
21172	};
21173
21174	/**
21175	 * Destroys the plugin.
21176	 * @public
21177	 */
21178	Hash.prototype.destroy = function() {
21179		var handler, property;
21180
21181		$(window).off('hashchange.owl.navigation');
21182
21183		for (handler in this._handlers) {
21184			this._core.$element.off(handler, this._handlers[handler]);
21185		}
21186		for (property in Object.getOwnPropertyNames(this)) {
21187			typeof this[property] != 'function' && (this[property] = null);
21188		}
21189	};
21190
21191	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
21192
21193})(window.Zepto || window.jQuery, window, document);
21194
21195/**
21196 * Support Plugin
21197 *
21198 * @version 2.3.4
21199 * @author Vivid Planet Software GmbH
21200 * @author Artus Kolanowski
21201 * @author David Deutsch
21202 * @license The MIT License (MIT)
21203 */
21204;(function($, window, document, undefined) {
21205
21206	var style = $('<support>').get(0).style,
21207		prefixes = 'Webkit Moz O ms'.split(' '),
21208		events = {
21209			transition: {
21210				end: {
21211					WebkitTransition: 'webkitTransitionEnd',
21212					MozTransition: 'transitionend',
21213					OTransition: 'oTransitionEnd',
21214					transition: 'transitionend'
21215				}
21216			},
21217			animation: {
21218				end: {
21219					WebkitAnimation: 'webkitAnimationEnd',
21220					MozAnimation: 'animationend',
21221					OAnimation: 'oAnimationEnd',
21222					animation: 'animationend'
21223				}
21224			}
21225		},
21226		tests = {
21227			csstransforms: function() {
21228				return !!test('transform');
21229			},
21230			csstransforms3d: function() {
21231				return !!test('perspective');
21232			},
21233			csstransitions: function() {
21234				return !!test('transition');
21235			},
21236			cssanimations: function() {
21237				return !!test('animation');
21238			}
21239		};
21240
21241	function test(property, prefixed) {
21242		var result = false,
21243			upper = property.charAt(0).toUpperCase() + property.slice(1);
21244
21245		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
21246			if (style[property] !== undefined) {
21247				result = prefixed ? property : true;
21248				return false;
21249			}
21250		});
21251
21252		return result;
21253	}
21254
21255	function prefixed(property) {
21256		return test(property, true);
21257	}
21258
21259	if (tests.csstransitions()) {
21260		/* jshint -W053 */
21261		$.support.transition = new String(prefixed('transition'))
21262		$.support.transition.end = events.transition.end[ $.support.transition ];
21263	}
21264
21265	if (tests.cssanimations()) {
21266		/* jshint -W053 */
21267		$.support.animation = new String(prefixed('animation'))
21268		$.support.animation.end = events.animation.end[ $.support.animation ];
21269	}
21270
21271	if (tests.csstransforms()) {
21272		/* jshint -W053 */
21273		$.support.transform = new String(prefixed('transform'));
21274		$.support.transform3d = tests.csstransforms3d();
21275	}
21276
21277})(window.Zepto || window.jQuery, window, document);
21278
21279/* End */
21280;
21281; /* Start:"a:4:{s:4:"full";s:104:"/bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.navigation.js?16768708944401";s:6:"source";s:89:"/bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.navigation.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
21282/**
21283 * Navigation
21284 * @since 2.0.0
21285 */
21286;(function ($, window, document, undefined) {
21287    var plugin;
21288
21289    plugin = function (core) {
21290        this._core = core;
21291
21292        /**
21293         * Статус инициализации плагина.
21294         * @protected
21295         * @type {Boolean}
21296         */
21297        this._initialized = false;
21298
21299        /**
21300         * Главный элемент.
21301         * @type {jQuery}
21302         */
21303        this.$element = this._core.$element;
21304
21305        /**
21306         * Элемент со слайдами.
21307         * @type {jQuery}
21308         */
21309        this.$stage = null;
21310
21311        /**
21312         * Обертка элемента со слайдами.
21313         * @type {jQuery}
21314         */
21315        this.$overlay = null;
21316
21317        /**
21318         * Обработчики событий элемента со слайдами.
21319         * @type {jQuery}
21320         */
21321        this._overlayHandlers = {
21322            'mousemove': $.proxy(function (e) {
21323                if (this._initialized) {
21324                    var settings = this._core.settings;
21325                    var node = this.$overlay;
21326
21327                    if (settings['overlayNav']) {
21328                        var pages = 0;
21329                        var side = 0;
21330                        var position = 0;
21331
21332                        if (settings['overlayNavByPages'] && this._core._plugins.navigation) {
21333                            pages = Math.ceil(this._core.items().length / settings.items);
21334                        } else {
21335                            pages = this._core.items().length - settings.items + 1;
21336                        }
21337
21338                        if (pages < 0)
21339                            pages = 1;
21340
21341                        if (settings['overlayNavOrientation'] === 'horizontal') {
21342                            side = node.outerWidth(false);
21343                            position = e.pageX - node.offset().left;
21344                        } else {
21345                            side = node.outerHeight(false);
21346                            position = e.pageY - node.offset().top;
21347                        }
21348
21349                        var slide = Math.ceil(position / (side / pages));
21350
21351                        if (slide < 1)
21352                            slide = 1;
21353
21354                        if (slide > pages)
21355                            slide = pages;
21356
21357                        if (this._core._plugins.navigation) {
21358                            this._core.to(slide - 1, null, !settings['overlayNavByPages']);
21359                        } else {
21360                            this._core.to(slide - 1);
21361                        }
21362                    }
21363                }
21364            }, this)
21365        };
21366
21367        /**
21368         * Обработчики событий плагина.
21369         * @protected
21370         * @type {Object}
21371         */
21372        this._handlers = {
21373            'initialized.owl.carousel': $.proxy(function (e) {
21374                if (!this._initialized) {
21375                    this.initialize();
21376                    this._initialized = true;
21377                }
21378            }, this)
21379        };
21380
21381        // Настройки по умолчанию
21382        this._core.options = $.extend({}, plugin.Defaults, this._core.options);
21383
21384        this.$element.on(this._handlers);
21385    };
21386
21387    plugin.Defaults = {
21388        'overlayNav': false, // Включить навигацию при наведении
21389        'overlayNavByPages': false, // Навигация по страницам (Если подключен плагин Navigation)
21390        'overlayNavOrientation': 'horizontal' // Ориентация навигации при наведении (horizontal|vertical)
21391    };
21392
21393    plugin.prototype.initialize = function () {
21394        this.$stage = this._core.$stage;
21395        this.$overlay = this.$stage.parent();
21396        this.$overlay.on(this._overlayHandlers);
21397    };
21398
21399    plugin.prototype.destroy = function() {
21400        $.each(this._handlers, function (event, handler) {
21401            this.$element.off(event, handler);
21402        });
21403
21404        $.each(this._overlayHandlers, function (event, handler) {
21405            this.$overlay.off(event, handler);
21406        });
21407    };
21408
21409    $.fn.owlCarousel.Constructor.Plugins['OverlayNavigation'] = plugin;
21410})(window.Zepto || window.jQuery, window, document);
21411/* End */
21412;
21413; /* Start:"a:4:{s:4:"full";s:97:"/bitrix/templates/universe_s5/plugins/jquery.animateNumber/jquery.animateNumber.js?16768708945301";s:6:"source";s:82:"/bitrix/templates/universe_s5/plugins/jquery.animateNumber/jquery.animateNumber.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
21414/** @preserve jQuery animateNumber plugin v0.0.14
21415 */
21416
21417// ['...'] notation using to avoid names minification by Google Closure Compiler
21418(function($) {
21419  var reverse = function(value) {
21420    return value.split('').reverse().join('');
21421  };
21422
21423  var defaults = {
21424    numberStep: function(now, tween) {
21425      var floored_number = Math.floor(now),
21426          target = $(tween.elem);
21427
21428      target.text(floored_number);
21429    }
21430  };
21431
21432  var handle = function( tween ) {
21433    var elem = tween.elem;
21434    if ( elem.nodeType && elem.parentNode ) {
21435      var handler = elem._animateNumberSetter;
21436      if (!handler) {
21437        handler = defaults.numberStep;
21438      }
21439      handler(tween.now, tween);
21440    }
21441  };
21442
21443  if (!$.Tween || !$.Tween.propHooks) {
21444    $.fx.step.number = handle;
21445  } else {
21446    $.Tween.propHooks.number = {
21447      set: handle
21448    };
21449  }
21450
21451  var extract_number_parts = function(separated_number, group_length) {
21452    var numbers = separated_number.split('').reverse(),
21453        number_parts = [],
21454        current_number_part,
21455        current_index,
21456        q;
21457
21458    for(var i = 0, l = Math.ceil(separated_number.length / group_length); i < l; i++) {
21459      current_number_part = '';
21460      for(q = 0; q < group_length; q++) {
21461        current_index = i * group_length + q;
21462        if (current_index === separated_number.length) {
21463          break;
21464        }
21465
21466        current_number_part = current_number_part + numbers[current_index];
21467      }
21468      number_parts.push(current_number_part);
21469    }
21470
21471    return number_parts;
21472  };
21473
21474  var remove_precending_zeros = function(number_parts) {
21475    var last_index = number_parts.length - 1,
21476        last = reverse(number_parts[last_index]);
21477
21478    number_parts[last_index] = reverse(parseInt(last, 10).toString());
21479    return number_parts;
21480  };
21481
21482  $.animateNumber = {
21483    numberStepFactories: {
21484      /**
21485       * Creates numberStep handler, which appends string to floored animated number on each step.
21486       *
21487       * @example
21488       * // will animate to 100 with "1 %", "2 %", "3 %", ...
21489       * $('#someid').animateNumber({
21490       *   number: 100,
21491       *   numberStep: $.animateNumber.numberStepFactories.append(' %')
21492       * });
21493       *
21494       * @params {String} suffix string to append to animated number
21495       * @returns {Function} numberStep-compatible function for use in animateNumber's parameters
21496       */
21497      append: function(suffix) {
21498        return function(now, tween) {
21499          var floored_number = Math.floor(now),
21500              target = $(tween.elem);
21501
21502          target.prop('number', now).text(floored_number + suffix);
21503        };
21504      },
21505
21506      /**
21507       * Creates numberStep handler, which format floored numbers by separating them to groups.
21508       *
21509       * @example
21510       * // will animate with 1 ... 217,980 ... 95,217,980 ... 7,095,217,980
21511       * $('#world-population').animateNumber({
21512       *    number: 7095217980,
21513       *    numberStep: $.animateNumber.numberStepFactories.separator(',')
21514       * });
21515       * @example
21516       * // will animate with 1% ... 217,980% ... 95,217,980% ... 7,095,217,980%
21517       * $('#salesIncrease').animateNumber({
21518       *   number: 7095217980,
21519       *   numberStep: $.animateNumber.numberStepFactories.separator(',', 3, '%')
21520       * });
21521       *
21522       * @params {String} [separator=' '] string to separate number groups
21523       * @params {String} [group_length=3] number group length
21524       * @params {String} [suffix=''] suffix to append to number
21525       * @returns {Function} numberStep-compatible function for use in animateNumber's parameters
21526       */
21527      separator: function(separator, group_length, suffix) {
21528        separator = separator || ' ';
21529        group_length = group_length || 3;
21530        suffix = suffix || '';
21531
21532        return function(now, tween) {
21533          var negative = now < 0,
21534              floored_number = Math.floor((negative ? -1 : 1) * now),
21535              separated_number = floored_number.toString(),
21536              target = $(tween.elem);
21537
21538          if (separated_number.length > group_length) {
21539            var number_parts = extract_number_parts(separated_number, group_length);
21540
21541            separated_number = remove_precending_zeros(number_parts).join(separator);
21542            separated_number = reverse(separated_number);
21543          }
21544
21545          target.prop('number', now).text((negative ? '-' : '') + separated_number + suffix);
21546        };
21547      }
21548    }
21549  };
21550
21551  $.fn.animateNumber = function() {
21552    var options = arguments[0],
21553        settings = $.extend({}, defaults, options),
21554
21555        target = $(this),
21556        args = [settings];
21557
21558    for(var i = 1, l = arguments.length; i < l; i++) {
21559      args.push(arguments[i]);
21560    }
21561
21562    // needs of custom step function usage
21563    if (options.numberStep) {
21564      // assigns custom step functions
21565      var items = this.each(function(){
21566        this._animateNumberSetter = options.numberStep;
21567      });
21568
21569      // cleanup of custom step functions after animation
21570      var generic_complete = settings.complete;
21571      settings.complete = function() {
21572        items.each(function(){
21573          delete this._animateNumberSetter;
21574        });
21575
21576        if ( generic_complete ) {
21577          generic_complete.apply(this, arguments);
21578        }
21579      };
21580    }
21581
21582    return target.animate.apply(target, args);
21583  };
21584
21585}(jQuery));
21586
21587/* End */
21588;
21589; /* Start:"a:4:{s:4:"full";s:80:"/bitrix/templates/universe_s5/plugins/picturefill/picturefill.js?167687089423302";s:6:"source";s:64:"/bitrix/templates/universe_s5/plugins/picturefill/picturefill.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
21590/*! Picturefill - v2.3.1 - 2015-04-09
21591* http://scottjehl.github.io/picturefill
21592* Copyright (c) 2015 https://github.com/scottjehl/picturefill/blob/master/Authors.txt; Licensed MIT */
21593/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license */
21594
21595window.matchMedia || (window.matchMedia = function() {
21596	"use strict";
21597
21598	// For browsers that support matchMedium api such as IE 9 and webkit
21599	var styleMedia = (window.styleMedia || window.media);
21600
21601	// For those that don't support matchMedium
21602	if (!styleMedia) {
21603		var style       = document.createElement('style'),
21604			script      = document.getElementsByTagName('script')[0],
21605			info        = null;
21606
21607		style.type  = 'text/css';
21608		style.id    = 'matchmediajs-test';
21609
21610		script.parentNode.insertBefore(style, script);
21611
21612		// 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
21613		info = ('getComputedStyle' in window) && window.getComputedStyle(style, null) || style.currentStyle;
21614
21615		styleMedia = {
21616			matchMedium: function(media) {
21617				var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';
21618
21619				// 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
21620				if (style.styleSheet) {
21621					style.styleSheet.cssText = text;
21622				} else {
21623					style.textContent = text;
21624				}
21625
21626				// Test if media query is true or false
21627				return info.width === '1px';
21628			}
21629		};
21630	}
21631
21632	return function(media) {
21633		return {
21634			matches: styleMedia.matchMedium(media || 'all'),
21635			media: media || 'all'
21636		};
21637	};
21638}());
21639/*! Picturefill - Responsive Images that work today.
21640*  Author: Scott Jehl, Filament Group, 2012 ( new proposal implemented by Shawn Jansepar )
21641*  License: MIT/GPLv2
21642*  Spec: http://picture.responsiveimages.org/
21643*/
21644(function( w, doc, image ) {
21645	// Enable strict mode
21646	"use strict";
21647
21648	function expose(picturefill) {
21649		/* expose picturefill */
21650		if ( typeof module === "object" && typeof module.exports === "object" ) {
21651			// CommonJS, just export
21652			module.exports = picturefill;
21653		} else if ( typeof define === "function" && define.amd ) {
21654			// AMD support
21655			define( "picturefill", function() { return picturefill; } );
21656		}
21657		if ( typeof w === "object" ) {
21658			// If no AMD and we are in the browser, attach to window
21659			w.picturefill = picturefill;
21660		}
21661	}
21662
21663	// If picture is supported, well, that's awesome. Let's get outta here...
21664	if ( w.HTMLPictureElement ) {
21665		expose(function() { });
21666		return;
21667	}
21668
21669	// HTML shim|v it for old IE (IE9 will still need the HTML video tag workaround)
21670	doc.createElement( "picture" );
21671
21672	// local object for method references and testing exposure
21673	var pf = w.picturefill || {};
21674
21675	var regWDesc = /\s+\+?\d+(e\d+)?w/;
21676
21677	// namespace
21678	pf.ns = "picturefill";
21679
21680	// srcset support test
21681	(function() {
21682		pf.srcsetSupported = "srcset" in image;
21683		pf.sizesSupported = "sizes" in image;
21684		pf.curSrcSupported = "currentSrc" in image;
21685	})();
21686
21687	// just a string trim workaround
21688	pf.trim = function( str ) {
21689		return str.trim ? str.trim() : str.replace( /^\s+|\s+$/g, "" );
21690	};
21691
21692	/**
21693	 * Gets a string and returns the absolute URL
21694	 * @param src
21695	 * @returns {String} absolute URL
21696	 */
21697	pf.makeUrl = (function() {
21698		var anchor = doc.createElement( "a" );
21699		return function(src) {
21700			anchor.href = src;
21701			return anchor.href;
21702		};
21703	})();
21704
21705	/**
21706	 * Shortcut method for https://w3c.github.io/webappsec/specs/mixedcontent/#restricts-mixed-content ( for easy overriding in tests )
21707	 */
21708	pf.restrictsMixedContent = function() {
21709		return w.location.protocol === "https:";
21710	};
21711	/**
21712	 * Shortcut method for matchMedia ( for easy overriding in tests )
21713	 */
21714
21715	pf.matchesMedia = function( media ) {
21716		return w.matchMedia && w.matchMedia( media ).matches;
21717	};
21718
21719	// Shortcut method for `devicePixelRatio` ( for easy overriding in tests )
21720	pf.getDpr = function() {
21721		return ( w.devicePixelRatio || 1 );
21722	};
21723
21724	/**
21725	 * Get width in css pixel value from a "length" value
21726	 * http://dev.w3.org/csswg/css-values-3/#length-value
21727	 */
21728	pf.getWidthFromLength = function( length ) {
21729		var cssValue;
21730		// If a length is specified and doesn’t contain a percentage, and it is greater than 0 or using `calc`, use it. Else, abort.
21731        if ( !(length && length.indexOf( "%" ) > -1 === false && ( parseFloat( length ) > 0 || length.indexOf( "calc(" ) > -1 )) ) {
21732            return false;
21733        }
21734
21735		/**
21736		 * If length is specified in  `vw` units, use `%` instead since the div we’re measuring
21737		 * is injected at the top of the document.
21738		 *
21739		 * TODO: maybe we should put this behind a feature test for `vw`? The risk of doing this is possible browser inconsistancies with vw vs %
21740		 */
21741		length = length.replace( "vw", "%" );
21742
21743		// Create a cached element for getting length value widths
21744		if ( !pf.lengthEl ) {
21745			pf.lengthEl = doc.createElement( "div" );
21746
21747			// Positioning styles help prevent padding/margin/width on `html` or `body` from throwing calculations off.
21748			pf.lengthEl.style.cssText = "border:0;display:block;font-size:1em;left:0;margin:0;padding:0;position:absolute;visibility:hidden";
21749
21750			// Add a class, so that everyone knows where this element comes from
21751			pf.lengthEl.className = "helper-from-picturefill-js";
21752		}
21753
21754		pf.lengthEl.style.width = "0px";
21755
21756        try {
21757		    pf.lengthEl.style.width = length;
21758        } catch ( e ) {}
21759
21760		doc.body.appendChild(pf.lengthEl);
21761
21762		cssValue = pf.lengthEl.offsetWidth;
21763
21764		if ( cssValue <= 0 ) {
21765			cssValue = false;
21766		}
21767
21768		doc.body.removeChild( pf.lengthEl );
21769
21770		return cssValue;
21771	};
21772
21773    pf.detectTypeSupport = function( type, typeUri ) {
21774        // based on Modernizr's lossless img-webp test
21775        // note: asynchronous
21776        var image = new w.Image();
21777        image.onerror = function() {
21778            pf.types[ type ] = false;
21779            picturefill();
21780        };
21781        image.onload = function() {
21782            pf.types[ type ] = image.width === 1;
21783            picturefill();
21784        };
21785        image.src = typeUri;
21786
21787        return "pending";
21788    };
21789	// container of supported mime types that one might need to qualify before using
21790	pf.types = pf.types || {};
21791
21792	pf.initTypeDetects = function() {
21793        // Add support for standard mime types
21794        pf.types[ "image/jpeg" ] = true;
21795        pf.types[ "image/gif" ] = true;
21796        pf.types[ "image/png" ] = true;
21797        pf.types[ "image/svg+xml" ] = doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image", "1.1");
21798        pf.types[ "image/webp" ] = pf.detectTypeSupport("image/webp", "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=");
21799    };
21800
21801	pf.verifyTypeSupport = function( source ) {
21802		var type = source.getAttribute( "type" );
21803		// if type attribute exists, return test result, otherwise return true
21804		if ( type === null || type === "" ) {
21805			return true;
21806		} else {
21807				var pfType = pf.types[ type ];
21808			// if the type test is a function, run it and return "pending" status. The function will rerun picturefill on pending elements once finished.
21809			if ( typeof pfType === "string" && pfType !== "pending") {
21810				pf.types[ type ] = pf.detectTypeSupport( type, pfType );
21811				return "pending";
21812			} else if ( typeof pfType === "function" ) {
21813				pfType();
21814				return "pending";
21815			} else {
21816				return pfType;
21817			}
21818		}
21819	};
21820
21821	// Parses an individual `size` and returns the length, and optional media query
21822	pf.parseSize = function( sourceSizeStr ) {
21823		var match = /(\([^)]+\))?\s*(.+)/g.exec( sourceSizeStr );
21824		return {
21825			media: match && match[1],
21826			length: match && match[2]
21827		};
21828	};
21829
21830	// Takes a string of sizes and returns the width in pixels as a number
21831	pf.findWidthFromSourceSize = function( sourceSizeListStr ) {
21832		// Split up source size list, ie ( max-width: 30em ) 100%, ( max-width: 50em ) 50%, 33%
21833		//                            or (min-width:30em) calc(30% - 15px)
21834		var sourceSizeList = pf.trim( sourceSizeListStr ).split( /\s*,\s*/ ),
21835			winningLength;
21836
21837		for ( var i = 0, len = sourceSizeList.length; i < len; i++ ) {
21838			// Match <media-condition>? length, ie ( min-width: 50em ) 100%
21839			var sourceSize = sourceSizeList[ i ],
21840				// Split "( min-width: 50em ) 100%" into separate strings
21841				parsedSize = pf.parseSize( sourceSize ),
21842				length = parsedSize.length,
21843				media = parsedSize.media;
21844
21845			if ( !length ) {
21846				continue;
21847			}
21848			// if there is no media query or it matches, choose this as our winning length
21849			if ( (!media || pf.matchesMedia( media )) &&
21850				// pass the length to a method that can properly determine length
21851				// in pixels based on these formats: http://dev.w3.org/csswg/css-values-3/#length-value
21852				(winningLength = pf.getWidthFromLength( length )) ) {
21853				break;
21854			}
21855		}
21856
21857		//if we have no winningLength fallback to 100vw
21858		return winningLength || Math.max(w.innerWidth || 0, doc.documentElement.clientWidth);
21859	};
21860
21861	pf.parseSrcset = function( srcset ) {
21862		/**
21863		 * A lot of this was pulled from Boris Smus’ parser for the now-defunct WHATWG `srcset`
21864		 * https://github.com/borismus/srcset-polyfill/blob/master/js/sr
21864cset-info.js
21865		 *
21866		 * 1. Let input (`srcset`) be the value passed to this algorithm.
21867		 * 2. Let position be a pointer into input, initially pointing at the start of the string.
21868		 * 3. Let raw candidates be an initially empty ordered list of URLs with associated
21869		 *    unparsed descriptors. The order of entries in the list is the order in which entries
21870		 *    are added to the list.
21871		 */
21872		var candidates = [];
21873
21874		while ( srcset !== "" ) {
21875			srcset = srcset.replace( /^\s+/g, "" );
21876
21877			// 5. Collect a sequence of characters that are not space characters, and let that be url.
21878			var pos = srcset.search(/\s/g),
21879				url, descriptor = null;
21880
21881			if ( pos !== -1 ) {
21882				url = srcset.slice( 0, pos );
21883
21884				var last = url.slice(-1);
21885
21886				// 6. If url ends with a U+002C COMMA character (,), remove that character from url
21887				// and let descriptors be the empty string. Otherwise, follow these substeps
21888				// 6.1. If url is empty, then jump to the step labeled descriptor parser.
21889
21890				if ( last === "," || url === "" ) {
21891					url = url.replace( /,+$/, "" );
21892					descriptor = "";
21893				}
21894				srcset = srcset.slice( pos + 1 );
21895
21896				// 6.2. Collect a sequence of characters that are not U+002C COMMA characters (,), and
21897				// let that be descriptors.
21898				if ( descriptor === null ) {
21899					var descpos = srcset.indexOf( "," );
21900					if ( descpos !== -1 ) {
21901						descriptor = srcset.slice( 0, descpos );
21902						srcset = srcset.slice( descpos + 1 );
21903					} else {
21904						descriptor = srcset;
21905						srcset = "";
21906					}
21907				}
21908			} else {
21909				url = srcset;
21910				srcset = "";
21911			}
21912
21913			// 7. Add url to raw candidates, associated with descriptors.
21914			if ( url || descriptor ) {
21915				candidates.push({
21916					url: url,
21917					descriptor: descriptor
21918				});
21919			}
21920		}
21921		return candidates;
21922	};
21923
21924	pf.parseDescriptor = function( descriptor, sizesattr ) {
21925		// 11. Descriptor parser: Let candidates be an initially empty source set. The order of entries in the list
21926		// is the order in which entries are added to the list.
21927		var sizes = sizesattr || "100vw",
21928			sizeDescriptor = descriptor && descriptor.replace( /(^\s+|\s+$)/g, "" ),
21929			widthInCssPixels = pf.findWidthFromSourceSize( sizes ),
21930			resCandidate;
21931
21932			if ( sizeDescriptor ) {
21933				var splitDescriptor = sizeDescriptor.split(" ");
21934
21935				for (var i = splitDescriptor.length - 1; i >= 0; i--) {
21936					var curr = splitDescriptor[ i ],
21937						lastchar = curr && curr.slice( curr.length - 1 );
21938
21939					if ( ( lastchar === "h" || lastchar === "w" ) && !pf.sizesSupported ) {
21940						resCandidate = parseFloat( ( parseInt( curr, 10 ) / widthInCssPixels ) );
21941					} else if ( lastchar === "x" ) {
21942						var res = curr && parseFloat( curr, 10 );
21943						resCandidate = res && !isNaN( res ) ? res : 1;
21944					}
21945				}
21946			}
21947		return resCandidate || 1;
21948	};
21949
21950	/**
21951	 * Takes a srcset in the form of url/
21952	 * ex. "images/pic-medium.png 1x, images/pic-medium-2x.png 2x" or
21953	 *     "images/pic-medium.png 400w, images/pic-medium-2x.png 800w" or
21954	 *     "images/pic-small.png"
21955	 * Get an array of image candidates in the form of
21956	 *      {url: "/foo/bar.png", resolution: 1}
21957	 * where resolution is http://dev.w3.org/csswg/css-values-3/#resolution-value
21958	 * If sizes is specified, resolution is calculated
21959	 */
21960	pf.getCandidatesFromSourceSet = function( srcset, sizes ) {
21961		var candidates = pf.parseSrcset( srcset ),
21962			formattedCandidates = [];
21963
21964		for ( var i = 0, len = candidates.length; i < len; i++ ) {
21965			var candidate = candidates[ i ];
21966
21967			formattedCandidates.push({
21968				url: candidate.url,
21969				resolution: pf.parseDescriptor( candidate.descriptor, sizes )
21970			});
21971		}
21972		return formattedCandidates;
21973	};
21974
21975	/**
21976	 * if it's an img element and it has a srcset property,
21977	 * we need to remove the attribute so we can manipulate src
21978	 * (the property's existence infers native srcset support, and a srcset-supporting browser will prioritize srcset's value over our winning picture candidate)
21979	 * this moves srcset's value to memory for later use and removes the attr
21980	 */
21981	pf.dodgeSrcset = function( img ) {
21982		if ( img.srcset ) {
21983			img[ pf.ns ].srcset = img.srcset;
21984			img.srcset = "";
21985			img.setAttribute( "data-pfsrcset", img[ pf.ns ].srcset );
21986		}
21987	};
21988
21989	// Accept a source or img element and process its srcset and sizes attrs
21990	pf.processSourceSet = function( el ) {
21991		var srcset = el.getAttribute( "srcset" ),
21992			sizes = el.getAttribute( "sizes" ),
21993			candidates = [];
21994
21995		// if it's an img element, use the cached srcset property (defined or not)
21996		if ( el.nodeName.toUpperCase() === "IMG" && el[ pf.ns ] && el[ pf.ns ].srcset ) {
21997			srcset = el[ pf.ns ].srcset;
21998		}
21999
22000		if ( srcset ) {
22001			candidates = pf.getCandidatesFromSourceSet( srcset, sizes );
22002		}
22003		return candidates;
22004	};
22005
22006	pf.backfaceVisibilityFix = function( picImg ) {
22007		// See: https://github.com/scottjehl/picturefill/issues/332
22008		var style = picImg.style || {},
22009			WebkitBackfaceVisibility = "webkitBackfaceVisibility" in style,
22010			currentZoom = style.zoom;
22011
22012		if (WebkitBackfaceVisibility) {
22013			style.zoom = ".999";
22014
22015			WebkitBackfaceVisibility = picImg.offsetWidth;
22016
22017			style.zoom = currentZoom;
22018		}
22019	};
22020
22021	pf.setIntrinsicSize = (function() {
22022		var urlCache = {};
22023		var setSize = function( picImg, width, res ) {
22024            if ( width ) {
22025			    picImg.setAttribute( "width", parseInt(width / res, 10) );
22026            }
22027		};
22028		return function( picImg, bestCandidate ) {
22029			var img;
22030			if ( !picImg[ pf.ns ] || w.pfStopIntrinsicSize ) {
22031				return;
22032			}
22033			if ( picImg[ pf.ns ].dims === undefined ) {
22034				picImg[ pf.ns].dims = picImg.getAttribute("width") || picImg.getAttribute("height");
22035			}
22036			if ( picImg[ pf.ns].dims ) { return; }
22037
22038			if ( bestCandidate.url in urlCache ) {
22039				setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution );
22040			} else {
22041				img = doc.createElement( "img" );
22042				img.onload = function() {
22043					urlCache[bestCandidate.url] = img.width;
22044
22045                    //IE 10/11 don't calculate width for svg outside document
22046                    if ( !urlCache[bestCandidate.url] ) {
22047                        try {
22048                            doc.body.appendChild( img );
22049                            urlCache[bestCandidate.url] = img.width || img.offsetWidth;
22050                            doc.body.removeChild( img );
22051                        } catch(e){}
22052                    }
22053
22054					if ( picImg.src === bestCandidate.url ) {
22055						setSize( picImg, urlCache[bestCandidate.url], bestCandidate.resolution );
22056					}
22057					picImg = null;
22058					img.onload = null;
22059					img = null;
22060				};
22061				img.src = bestCandidate.url;
22062			}
22063		};
22064	})();
22065
22066	pf.applyBestCandidate = function( candidates, picImg ) {
22067		var candidate,
22068			length,
22069			bestCandidate;
22070
22071		candidates.sort( pf.ascendingSort );
22072
22073		length = candidates.length;
22074		bestCandidate = candidates[ length - 1 ];
22075
22076		for ( var i = 0; i < length; i++ ) {
22077			candidate = candidates[ i ];
22078			if ( candidate.resolution >= pf.getDpr() ) {
22079				bestCandidate = candidate;
22080				break;
22081			}
22082		}
22083
22084		if ( bestCandidate ) {
22085
22086			bestCandidate.url = pf.makeUrl( bestCandidate.url );
22087
22088			if ( picImg.src !== bestCandidate.url ) {
22089				if ( pf.restrictsMixedContent() && bestCandidate.url.substr(0, "http:".length).toLowerCase() === "http:" ) {
22090					if ( window.console !== undefined ) {
22091						console.warn( "Blocked mixed content image " + bestCandidate.url );
22092					}
22093				} else {
22094					picImg.src = bestCandidate.url;
22095					// currentSrc attribute and property to match
22096					// http://picture.responsiveimages.org/#the-img-element
22097					if ( !pf.curSrcSupported ) {
22098						picImg.currentSrc = picImg.src;
22099					}
22100
22101					pf.backfaceVisibilityFix( picImg );
22102				}
22103			}
22104
22105			pf.setIntrinsicSize(picImg, bestCandidate);
22106		}
22107	};
22108
22109	pf.ascendingSort = function( a, b ) {
22110		return a.resolution - b.resolution;
22111	};
22112
22113	/**
22114	 * In IE9, <source> elements get removed if they aren't children of
22115	 * video elements. Thus, we conditionally wrap source elements
22116	 * using <!--[if IE 9]><video style="display: none;"><![endif]-->
22117	 * and must account for that here by moving those source elements
22118	 * back into the picture element.
22119	 */
22120	pf.removeVideoShim = function( picture ) {
22121		var videos = picture.getElementsByTagName( "video" );
22122		if ( videos.length ) {
22123			var video = videos[ 0 ],
22124				vsources = video.getElementsByTagName( "source" );
22125			while ( vsources.length ) {
22126				picture.insertBefore( vsources[ 0 ], video );
22127			}
22128			// Remove the video element once we're finished removing its children
22129			video.parentNode.removeChild( video );
22130		}
22131	};
22132
22133	/**
22134	 * Find all `img` elements, and add them to the candidate list if they have
22135	 * a `picture` parent, a `sizes` attribute in basic `srcset` supporting browsers,
22136	 * a `srcset` attribute at all, and they haven’t been evaluated already.
22137	 */
22138	pf.getAllElements = function() {
22139		var elems = [],
22140			imgs = doc.getElementsByTagName( "img" );
22141
22142		for ( var h = 0, len = imgs.length; h < len; h++ ) {
22143			var currImg = imgs[ h ];
22144
22145			if ( currImg.parentNode.nodeName.toUpperCase() === "PICTURE" ||
22146			( currImg.getAttribute( "srcset" ) !== null ) || currImg[ pf.ns ] && currImg[ pf.ns ].srcset !== null ) {
22147				elems.push( currImg );
22148			}
22149		}
22150		return elems;
22151	};
22152
22153	pf.getMatch = function( img, picture ) {
22154		var sources = picture.childNodes,
22155			match;
22156
22157		// Go through each child, and if they have media queries, evaluate them
22158		for ( var j = 0, slen = sources.length; j < slen; j++ ) {
22159			var source = sources[ j ];
22160
22161			// ignore non-element nodes
22162			if ( source.nodeType !== 1 ) {
22163				continue;
22164			}
22165
22166			// Hitting the `img` element that started everything stops the search for `sources`.
22167			// If no previous `source` matches, the `img` itself is evaluated later.
22168			if ( source === img ) {
22169				return match;
22170			}
22171
22172			// ignore non-`source` nodes
22173			if ( source.nodeName.toUpperCase() !== "SOURCE" ) {
22174				continue;
22175			}
22176			// if it's a source element that has the `src` property set, throw a warning in the console
22177			if ( source.getAttribute( "src" ) !== null && typeof console !== undefined ) {
22178				console.warn("The `src` attribute is invalid on `picture` `source` element; instead, use `srcset`.");
22179			}
22180
22181			var media = source.getAttribute( "media" );
22182
22183			// if source does not have a srcset attribute, skip
22184			if ( !source.getAttribute( "srcset" ) ) {
22185				continue;
22186			}
22187
22188			// if there's no media specified, OR w.matchMedia is supported
22189			if ( ( !media || pf.matchesMedia( media ) ) ) {
22190				var typeSupported = pf.verifyTypeSupport( source );
22191
22192				if ( typeSupported === true ) {
22193					match = source;
22194					break;
22195				} else if ( typeSupported === "pending" ) {
22196					return false;
22197				}
22198			}
22199		}
22200
22201		return match;
22202	};
22203
22204	function picturefill( opt ) {
22205		var elements,
22206			element,
22207			parent,
22208			firstMatch,
22209			candidates,
22210			options = opt || {};
22211
22212		elements = options.elements || pf.getAllElements();
22213
22214		// Loop through all elements
22215		for ( var i = 0, plen = elements.length; i < plen; i++ ) {
22216			element = elements[ i ];
22217			parent = element.parentNode;
22218			firstMatch = undefined;
22219			candidates = undefined;
22220
22221			// immediately skip non-`img` nodes
22222			if ( element.nodeName.toUpperCase() !== "IMG" ) {
22223				continue;
22224			}
22225
22226			// expando for caching data on the img
22227			if ( !element[ pf.ns ] ) {
22228				element[ pf.ns ] = {};
22229			}
22230
22231			// if the element has already been evaluated, skip it unless
22232			// `options.reevaluate` is set to true ( this, for example,
22233			// is set to true when running `picturefill` on `resize` ).
22234			if ( !options.reevaluate && element[ pf.ns ].evaluated ) {
22235				continue;
22236			}
22237
22238			// if `img` is in a `picture` element
22239			if ( parent && parent.nodeName.toUpperCase() === "PICTURE" ) {
22240
22241				// IE9 video workaround
22242				pf.removeVideoShim( parent );
22243
22244				// return the first match which might undefined
22245				// returns false if there is a pending source
22246				// TODO the return type here is brutal, cleanup
22247				firstMatch = pf.getMatch( element, parent );
22248
22249				// if any sources are pending in this picture due to async type test(s)
22250				// remove the evaluated attr and skip for now ( the pending test will
22251				// rerun picturefill on this element when complete)
22252				if ( firstMatch === false ) {
22253					continue;
22254				}
22255			} else {
22256				firstMatch = undefined;
22257			}
22258
22259			// Cache and remove `srcset` if present and we’re going to be doing `picture`/`srcset`/`sizes` polyfilling to it.
22260			if ( ( parent && parent.nodeName.toUpperCase() === "PICTURE" ) ||
22261			( !pf.sizesSupported && ( element.srcset && regWDesc.test( element.srcset ) ) ) ) {
22262				pf.dodgeSrcset( element );
22263			}
22264
22265			if ( firstMatch ) {
22266				candidates = pf.processSourceSet( firstMatch );
22267				pf.applyBestCandidate( candidates, element );
22268			} else {
22269				// No sources matched, so we’re down to processing the inner `img` as a source.
22270				candidates = pf.processSourceSet( element );
22271
22272				if ( element.srcset === undefined || element[ pf.ns ].srcset ) {
22273					// Either `srcset` is completely unsupported, or we need to polyfill `sizes` functionality.
22274					pf.applyBestCandidate( candidates, element );
22275				} // Else, resolution-only `srcset` is supported natively.
22276			}
22277
22278			// set evaluated to true to avoid unnecessary reparsing
22279			element[ pf.ns ].evaluated = true;
22280		}
22281	}
22282
22283	/**
22284	 * Sets up picture polyfill by polling the document and running
22285	 * the polyfill every 250ms until the document is ready.
22286	 * Also attaches picturefill on resize
22287	 */
22288	function runPicturefill() {
22289		pf.initTypeDetects();
22290		picturefill();
22291		var intervalId = setInterval( function() {
22292			// When the document has finished loading, stop checking for new images
22293			// https://github.com/ded/domready/blob/master/ready.js#L15
22294			picturefill();
22295
22296			if ( /^loaded|^i|^c/.test( doc.readyState ) ) {
22297				clearInterval( intervalId );
22298				return;
22299			}
22300		}, 250 );
22301
22302		var resizeTimer;
22303		var handleResize = function() {
22304	        picturefill({ reevaluate: true });
22305	    };
22306		function checkResize() {
22307		    clearTimeout(resizeTimer);
22308		    resizeTimer = setTimeout( handleResize, 60 );
22309		}
22310
22311		if ( w.addEventListener ) {
22312			w.addEventListener( "resize", checkResize, false );
22313		} else if ( w.attachEvent ) {
22314			w.attachEvent( "onresize", checkResize );
22315		}
22316	}
22317
22318	runPicturefill();
22319
22320	/* expose methods for testing */
22321	picturefill._ = pf;
22322
22323	expose( picturefill );
22324
22325} )( window, window.document, new window.Image() );
22326
22327/* End */
22328;
22329; /* Start:"a:4:{s:4:"full";
22329s:97:"/bitrix/templates/universe_s5/plugins/jquery.lightGallery/jquery.lightGallery.js?1676870894110674";s:6:"source";s:80:"/bitrix/templates/universe_s5/plugins/jquery.lightGallery/jquery.lightGallery.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
22330/*! lightgallery - v1.6.0 - 2017-08-08
22331* http://sachinchoolur.github.io/lightGallery/
22332* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
22333/*! lightgallery - v1.6.0 - 2017-08-08
22334* http://sachinchoolur.github.io/lightGallery/
22335* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
22336(function (root, factory) {
22337  if (typeof define === 'function' && define.amd) {
22338    // AMD. Register as an anonymous module unless amdModuleId is set
22339    define(['jquery'], function (a0) {
22340      return (factory(a0));
22341    });
22342  } else if (typeof exports === 'object') {
22343    // Node. Does not work with strict CommonJS, but
22344    // only CommonJS-like environments that support module.exports,
22345    // like Node.
22346    module.exports = factory(require('jquery'));
22347  } else {
22348    factory(root["jQuery"]);
22349  }
22350}(this, function ($) {
22351
22352(function() {
22353    'use strict';
22354
22355    var defaults = {
22356
22357        mode: 'lg-slide',
22358
22359        // Ex : 'ease'
22360        cssEasing: 'ease',
22361
22362        //'for jquery animation'
22363        easing: 'linear',
22364        speed: 600,
22365        height: '100%',
22366        width: '100%',
22367        addClass: '',
22368        startClass: 'lg-start-zoom',
22369        backdropDuration: 150,
22370        hideBarsDelay: 6000,
22371
22372        useLeft: false,
22373
22374        closable: true,
22375        loop: true,
22376        escKey: true,
22377        keyPress: true,
22378        controls: true,
22379        slideEndAnimatoin: true,
22380        hideControlOnEnd: false,
22381        mousewheel: true,
22382
22383        getCaptionFromTitleOrAlt: true,
22384
22385        // .lg-item || '.lg-sub-html'
22386        appendSubHtmlTo: '.lg-sub-html',
22387
22388        subHtmlSelectorRelative: false,
22389
22390        /**
22391         * @desc number of preload slides
22392         * will exicute only after the current slide is fully loaded.
22393         *
22394         * @ex you clicked on 4th image and if preload = 1 then 3rd slide and 5th
22395         * slide will be loaded in the background after the 4th slide is fully loaded..
22396         * if preload is 2 then 2nd 3rd 5th 6th slides will be preloaded.. ... ...
22397         *
22398         */
22399        preload: 1,
22400        showAfterLoad: true,
22401        selector: '',
22402        selectWithin: '',
22403        nextHtml: '',
22404        prevHtml: '',
22405
22406        // 0, 1
22407        index: false,
22408
22409        iframeMaxWidth: '100%',
22410
22411        download: true,
22412        counter: true,
22413        appendCounterTo: '.lg-toolbar',
22414
22415        swipeThreshold: 50,
22416        enableSwipe: true,
22417        enableDrag: true,
22418
22419        dynamic: false,
22420        dynamicEl: [],
22421        galleryId: 1
22422    };
22423
22424    function Plugin(element, options) {
22425
22426        // Current lightGallery element
22427        this.el = element;
22428
22429        // Current jquery element
22430        this.$el = $(element);
22431
22432        // lightGallery settings
22433        this.s = $.extend({}, defaults, options);
22434
22435        // When using dynamic mode, ensure dynamicEl is an array
22436        if (this.s.dynamic && this.s.dynamicEl !== 'undefined' && this.s.dynamicEl.constructor === Array && !this.s.dynamicEl.length) {
22437            throw ('When using dynamic mode, you must also define dynamicEl as an Array.');
22438        }
22439
22440        // lightGallery modules
22441        this.modules = {};
22442
22443        // false when lightgallery complete first slide;
22444        this.lGalleryOn = false;
22445
22446        this.lgBusy = false;
22447
22448        // Timeout function for hiding controls;
22449        this.hideBartimeout = false;
22450
22451        // To determine browser supports for touch events;
22452        this.isTouch = ('ontouchstart' in document.documentElement);
22453
22454        // Disable hideControlOnEnd if sildeEndAnimation is true
22455        if (this.s.slideEndAnimatoin) {
22456            this.s.hideControlOnEnd = false;
22457        }
22458
22459        // Gallery items
22460        if (this.s.dynamic) {
22461            this.$items = this.s.dynamicEl;
22462        } else {
22463            if (this.s.selector === 'this') {
22464                this.$items = this.$el;
22465            } else if (this.s.selector !== '') {
22466                if (this.s.selectWithin) {
22467                    this.$items = $(this.s.selectWithin).find(this.s.selector);
22468                } else {
22469                    this.$items = this.$el.find($(this.s.selector));
22470                }
22471            } else {
22472                this.$items = this.$el.children();
22473            }
22474        }
22475
22476        // .lg-item
22477        this.$slide = '';
22478
22479        // .lg-outer
22480        this.$outer = '';
22481
22482        this.init();
22483
22484        return this;
22485    }
22486
22487    Plugin.prototype.init = function() {
22488
22489        var _this = this;
22490
22491        // s.preload should not be more than $item.length
22492        if (_this.s.preload > _this.$items.length) {
22493            _this.s.preload = _this.$items.length;
22494        }
22495
22496        // if dynamic option is enabled execute immediately
22497        var _hash = window.location.hash;
22498        if (_hash.indexOf('lg=' + this.s.galleryId) > 0) {
22499
22500            _this.index = parseInt(_hash.split('&slide=')[1], 10);
22501
22502            $('body').addClass('lg-from-hash');
22503            if (!$('body').hasClass('lg-on')) {
22504                setTimeout(function() {
22505                    _this.build(_this.index);
22506                });
22507
22508                $('body').addClass('lg-on');
22509            }
22510        }
22511
22512        if (_this.s.dynamic) {
22513
22514            _this.$el.trigger('onBeforeOpen.lg');
22515
22516            _this.index = _this.s.index || 0;
22517
22518            // prevent accidental double execution
22519            if (!$('body').hasClass('lg-on')) {
22520                setTimeout(function() {
22521                    _this.build(_this.index);
22522                    $('body').addClass('lg-on');
22523                });
22524            }
22525        } else {
22526
22527            // Using different namespace for click because click event should not unbind if selector is same object('this')
22528            _this.$items.on('click.lgcustom', function(event) {
22529
22530                // For IE8
22531                try {
22532                    event.preventDefault();
22533                    event.preventDefault();
22534                } catch (er) {
22535                    event.returnValue = false;
22536                }
22537
22538                _this.$el.trigger('onBeforeOpen.lg');
22539
22540                _this.index = _this.s.index || _this.$items.index(this);
22541
22542                // prevent accidental double execution
22543                if (!$('body').hasClass('lg-on')) {
22544                    _this.build(_this.index);
22545                    $('body').addClass('lg-on');
22546                }
22547            });
22548        }
22549
22550    };
22551
22552    Plugin.prototype.build = function(index) {
22553
22554        var _this = this;
22555
22556        _this.structure();
22557
22558        // module constructor
22559        $.each($.fn.lightGallery.modules, function(key) {
22560            _this.modules[key] = new $.fn.lightGallery.modules[key](_this.el);
22561        });
22562
22563        // initiate slide function
22564        _this.slide(index, false, false, false);
22565
22566        if (_this.s.keyPress) {
22567            _this.keyPress();
22568        }
22569
22570        if (_this.$items.length > 1) {
22571
22572            _this.arrow();
22573
22574            setTimeout(function() {
22575                _this.enableDrag();
22576                _this.enableSwipe();
22577            }, 50);
22578
22579            if (_this.s.mousewheel) {
22580                _this.mousewheel();
22581            }
22582        } else {
22583            _this.$slide.on('click.lg', function() {
22584                _this.$el.trigger('onSlideClick.lg');
22585            });
22586        }
22587
22588        _this.counter();
22589
22590        _this.closeGallery();
22591
22592        _this.$el.trigger('onAfterOpen.lg');
22593
22594        // Hide controllers if mouse doesn't move for some period
22595        _this.$outer.on('mousemove.lg click.lg touchstart.lg', function() {
22596
22597            _this.$outer.removeClass('lg-hide-items');
22598
22599            clearTimeout(_this.hideBartimeout);
22600
22601            // Timeout will be cleared on each slide movement also
22602            _this.hideBartimeout = setTimeout(function() {
22603                _this.$outer.addClass('lg-hide-items');
22604            }, _this.s.hideBarsDelay);
22605
22606        });
22607
22608        _this.$outer.trigger('mousemove.lg');
22609
22610    };
22611
22612    Plugin.prototype.structure = function() {
22613        var list = '';
22614        var controls = '';
22615        var i = 0;
22616        var subHtmlCont = '';
22617        var template;
22618        var _this = this;
22619
22620        $('body').append('<div class="lg-backdrop"></div>');
22621        $('.lg-backdrop').css('transition-duration', this.s.backdropDuration + 'ms');
22622
22623        // Create gallery items
22624        for (i = 0; i < this.$items.length; i++) {
22625            list += '<div class="lg-item"></div>';
22626        }
22627
22628        // Create controlls
22629        if (this.s.controls && this.$items.length > 1) {
22630            controls = '<div class="lg-actions">' +
22631                '<button class="lg-prev lg-icon">' + this.s.prevHtml + '</button>' +
22632                '<button class="lg-next lg-icon">' + this.s.nextHtml + '</button>' +
22633                '</div>';
22634        }
22635
22636        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
22637            subHtmlCont = '<div class="lg-sub-html"></div>';
22638        }
22639
22640        template = '<div class="lg-outer ' + this.s.addClass + ' ' + this.s.startClass + '">' +
22641            '<div class="lg" style="width:' + this.s.width + '; height:' + this.s.height + '">' +
22642            '<div class="lg-inner">' + list + '</div>' +
22643            '<div class="lg-toolbar lg-group">' +
22644            '<span class="lg-close lg-icon"></span>' +
22645            '</div>' +
22646            controls +
22647            subHtmlCont +
22648            '</div>' +
22649            '</div>';
22650
22651        $('body').append(template);
22652        this.$outer = $('.lg-outer');
22653        this.$slide = this.$outer.find('.lg-item');
22654
22655        if (this.s.useLeft) {
22656            this.$outer.addClass('lg-use-left');
22657
22658            // Set mode lg-slide if use left is true;
22659            this.s.mode = 'lg-slide';
22660        } else {
22661            this.$outer.addClass('lg-use-css3');
22662        }
22663
22664        // For fixed height gallery
22665        _this.setTop();
22666        $(window).on('resize.lg orientationchange.lg', function() {
22667            setTimeout(function() {
22668                _this.setTop();
22669            }, 100);
22670        });
22671
22672        // add class lg-current to remove initial transition
22673        this.$slide.eq(this.index).addClass('lg-current');
22674
22675        // add Class for css support and transition mode
22676        if (this.doCss()) {
22677            this.$outer.addClass('lg-css3');
22678        } else {
22679            this.$outer.addClass('lg-css');
22680
22681            // Set speed 0 because no animation will happen if browser doesn't support css3
22682            this.s.speed = 0;
22683        }
22684
22685        this.$outer.addClass(this.s.mode);
22686
22687        if (this.s.enableDrag && this.$items.length > 1) {
22688            this.$outer.addClass('lg-grab');
22689        }
22690
22691        if (this.s.showAfterLoad) {
22692            this.$outer.addClass('lg-show-after-load');
22693        }
22694
22695        if (this.doCss()) {
22696            var $inner = this.$outer.find('.lg-inner');
22697            $inner.css('transition-timing-function', this.s.cssEasing);
22698            $inner.css('transition-duration', this.s.speed + 'ms');
22699        }
22700
22701        setTimeout(function() {
22702            $('.lg-backdrop').addClass('in');
22703        });
22704
22705        setTimeout(function() {
22706            _this.$outer.addClass('lg-visible');
22707        }, this.s.backdropDuration);
22708
22709        if (this.s.download) {
22710            this.$outer.find('.lg-toolbar').append('<a id="lg-download" target="_blank" download class="lg-download lg-icon"></a>');
22711        }
22712
22713        // Store the current scroll top value to scroll back after closing the gallery..
22714        this.prevScrollTop = $(window).scrollTop();
22715
22716    };
22717
22718    // For fixed height gallery
22719    Plugin.prototype.setTop = function() {
22720        if (this.s.height !== '100%') {
22721            var wH = $(window).height();
22722            var top = (wH - parseInt(this.s.height, 10)) / 2;
22723            var $lGallery = this.$outer.find('.lg');
22724            if (wH >= parseInt(this.s.height, 10)) {
22725                $lGallery.css('top', top + 'px');
22726            } else {
22727                $lGallery.css('top', '0px');
22728            }
22729        }
22730    };
22731
22732    // Find css3 support
22733    Plugin.prototype.doCss = function() {
22734        // check for css animation support
22735        var support = function() {
22736            var transition = ['transition', 'MozTransition', 'WebkitTransition', 'OTransition', 'msTransition', 'KhtmlTransition'];
22737            var root = document.documentElement;
22738            var i = 0;
22739            for (i = 0; i < transition.length; i++) {
22740                if (transition[i] in root.style) {
22741                    return true;
22742                }
22743            }
22744        };
22745
22746        if (support()) {
22747            return true;
22748        }
22749
22750        return false;
22751    };
22752
22753    /**
22754     *  @desc Check the given src is video
22755     *  @param {String} src
22756     *  @return {Object} video type
22757     *  Ex:{ youtube  :  ["//www.youtube.com/watch?v=c0asJgSyxcY", "c0asJgSyxcY"] }
22758     */
22759    Plugin.prototype.isVideo = function(src, index) {
22760
22761        var html;
22762        if (this.s.dynamic) {
22763            html = this.s.dynamicEl[index].html;
22764        } else {
22765            html = this.$items.eq(index).attr('data-html');
22766        }
22767
22768        if (!src) {
22769            if(html) {
22770                return {
22771                    html5: true
22772                };
22773            } else {
22774                console.error('lightGallery :- data-src is not pvovided on slide item ' + (index + 1) + '. Please make sure the selector property is properly configured. More info - http://sachinchoolur.github.io/lightGallery/demos/html-markup.html');
22775                return false;
22776            }
22777        }
22778
22779        var youtube = src.match(/\/\/(?:www\.)?youtu(?:\.be|be\.com)\/(?:watch\?v=|embed\/)?([a-z0-9\-\_\%]+)/i);
22780        var vimeo = src.match(/\/\/(?:www\.)?vimeo.com\/([0-9a-z\-_]+)/i);
22781        var dailymotion = src.match(/\/\/(?:www\.)?dai.ly\/([0-9a-z\-_]+)/i);
22782        var vk = src.match(/\/\/(?:www\.)?(?:vk\.com|vkontakte\.ru)\/(?:video_ext\.php\?)(.*)/i);
22783
22784        if (youtube) {
22785            return {
22786                youtube: youtube
22787            };
22788        } else if (vimeo) {
22789            return {
22790                vimeo: vimeo
22791            };
22792        } else if (dailymotion) {
22793            return {
22794                dailymotion: dailymotion
22795            };
22796        } else if (vk) {
22797            return {
22798                vk: vk
22799            };
22800        }
22801    };
22802
22803    /**
22804     *  @desc Create image counter
22805     *  Ex: 1/10
22806     */
22807    Plugin.prototype.counter = function() {
22808        if (this.s.counter) {
22809            $(this.s.appendCounterTo).append('<div id="lg-counter"><span id="lg-counter-current">' + (parseInt(this.index, 10) + 1) + '</span> / <span id="lg-counter-all">' + this.$items.length + '</span></div>');
22810        }
22811    };
22812
22813    /**
22814     *  @desc add sub-html into the slide
22815     *  @param {Number} index - index of the slide
22816     */
22817    Plugin.prototype.addHtml = function(index) {
22818        var subHtml = null;
22819        var subHtmlUrl;
22820        var $currentEle;
22821        if (this.s.dynamic) {
22822            if (this.s.dynamicEl[index].subHtmlUrl) {
22823                subHtmlUrl = this.s.dynamicEl[index].subHtmlUrl;
22824            } else {
22825                subHtml = this.s.dynamicEl[index].subHtml;
22826            }
22827        } else {
22828            $currentEle = this.$items.eq(index);
22829            if ($currentEle.attr('data-sub-html-url')) {
22830                subHtmlUrl = $currentEle.attr('data-sub-html-url');
22831            } else {
22832                subHtml = $currentEle.attr('data-sub-html');
22833                if (this.s.getCaptionFromTitleOrAlt && !subHtml) {
22834                    subHtml = $currentEle.attr('title') || $currentEle.find('img').first().attr('alt');
22835                }
22836            }
22837        }
22838
22839        if (!subHtmlUrl) {
22840            if (typeof subHtml !== 'undefined' && subHtml !== null) {
22841
22842                // get first letter of subhtml
22843                // if first letter starts with . or # get the html form the jQuery object
22844                var fL = subHtml.substring(0, 1);
22845                if (fL === '.' || fL === '#') {
22846                    if (this.s.subHtmlSelectorRelative && !this.s.dynamic) {
22847                        subHtml = $currentEle.find(subHtml).html();
22848                    } else {
22849                        subHtml = $(subHtml).html();
22850                    }
22851                }
22852            } else {
22853                subHtml = '';
22854            }
22855        }
22856
22857        if (this.s.appendSubHtmlTo === '.lg-sub-html') {
22858
22859            if (subHtmlUrl) {
22860                this.$outer.find(this.s.appendSubHtmlTo).load(subHtmlUrl);
22861            } else {
22862                this.$outer.find(this.s.appendSubHtmlTo).html(subHtml);
22863            }
22864
22865        } else {
22866
22867            if (subHtmlUrl) {
22868                this.$slide.eq(index).load(subHtmlUrl);
22869            } else {
22870                this.$slide.eq(index).append(subHtml);
22871            }
22872        }
22873
22874        // Add lg-empty-html class if title doesn't exist
22875        if (typeof subHtml !== 'undefined' && subHtml !== null) {
22876            if (subHtml === '') {
22877                this.$outer.find(this.s.appendSubHtmlTo).addClass('lg-empty-html');
22878            } else {
22879                this.$outer.find(this.s.appendSubHtmlTo).removeClass('lg-empty-html');
22880            }
22881        }
22882
22883        this.$el.trigger('onAfterAppendSubHtml.lg', [index]);
22884    };
22885
22886    /**
22887     *  @desc Preload slides
22888     *  @param {Number} index - index of the slide
22889     */
22890    Plugin.prototype.preload = function(index) {
22891        var i = 1;
22892        var j = 1;
22893        for (i = 1; i <= this.s.preload; i++) {
22894            if (i >= this.$items.length - index) {
22895                break;
22896            }
22897
22898            this.loadContent(index + i, false, 0);
22899        }
22900
22901        for (j = 1; j <= this.s.preload; j++) {
22902            if (index - j < 0) {
22903                break;
22904            }
22905
22906            this.loadContent(index - j, false, 0);
22907        }
22908    };
22909
22910    /**
22911     *  @desc Load slide content into slide.
22912     *  @param {Number} index - index of the slide.
22913     *  @param {Boolean} rec - if true call loadcontent() function again.
22914     *  @param {Boolean} delay - delay for adding complete class. it is 0 except first time.
22915     */
22916    Plugin.prototype.loadContent = function(index, rec, delay) {
22917
22918        var _this = this;
22919        var _hasPoster = false;
22920        var _$img;
22921        var _src;
22922        var _poster;
22923        var _srcset;
22924        var _sizes;
22925        var _html;
22926        var getResponsiveSrc = function(srcItms) {
22927            var rsWidth = [];
22928            var rsSrc = [];
22929            for (var i = 0; i < srcItms.length; i++) {
22930                var __src = srcItms[i].split(' ');
22931
22932                // Manage empty space
22933                if (__src[0] === '') {
22934                    __src.splice(0, 1);
22935                }
22936
22937                rsSrc.push(__src[0]);
22938                rsWidth.push(__src[1]);
22939            }
22940
22941            var wWidth = $(window).width();
22942            for (var j = 0; j < rsWidth.length; j++) {
22943                if (parseInt(rsWidth[j], 10) > wWidth) {
22944                    _src = rsSrc[j];
22945                    break;
22946                }
22947            }
22948        };
22949
22950        if (_this.s.dynamic) {
22951
22952            if (_this.s.dynamicEl[index].poster) {
22953                _hasPoster = true;
22954                _poster = _this.s.dynamicEl[index].poster;
22955            }
22956
22957            _html = _this.s.dynamicEl[index].html;
22958            _src = _this.s.dynamicEl[index].src;
22959
22960            if (_this.s.dynamicEl[index].responsive) {
22961                var srcDyItms = _this.s.dynamicEl[index].responsive.split(',');
22962                getResponsiveSrc(srcDyItms);
22963            }
22964
22965            _srcset = _this.s.dynamicEl[index].srcset;
22966            _sizes = _this.s.dynamicEl[index].sizes;
22967
22968        } else {
22969
22970            if (_this.$items.eq(index).attr('data-poster')) {
22971                _hasPoster = true;
22972                _poster = _this.$items.eq(index).attr('data-poster');
22973            }
22974
22975            _html = _this.$items.eq(index).attr('data-html');
22976            _src = _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src');
22977
22978            if (_this.$items.eq(index).attr('data-responsive')) {
22979                var srcItms = _this.$items.eq(index).attr('data-responsive').split(',');
22980                getResponsiveSrc(srcItms);
22981            }
22982
22983            _srcset = _this.$items.eq(index).attr('data-srcset');
22984            _sizes = _this.$items.eq(index).attr('data-sizes');
22985
22986        }
22987
22988        //if (_src || _srcset || _sizes || _poster) {
22989
22990        var iframe = false;
22991        if (_this.s.dynamic) {
22992            if (_this.s.dynamicEl[index].iframe) {
22993                iframe = true;
22994            }
22995        } else {
22996            if (_this.$items.eq(index).attr('data-iframe') === 'true') {
22997                iframe = true;
22998            }
22999        }
23000
23001        var _isVideo = _this.isVideo(_src, index);
23002        if (!_this.$slide.eq(index).hasClass('lg-loaded')) {
23003            if (iframe) {
23004                _this.$slide.eq(index).prepend('<div class="lg-video-cont lg-has-iframe" style="max-width:' + _this.s.iframeMaxWidth + '"><div class="lg-video"><iframe class="lg-object" frameborder="0" src="' + _src + '"  allowfullscreen="true"></iframe></div></div>');
23005            } else if (_hasPoster) {
23006                var videoClass = '';
23007                if (_isVideo && _isVideo.youtube) {
23008                    videoClass = 'lg-has-youtube';
23009                } else if (_isVideo && _isVideo.vimeo) {
23010                    videoClass = 'lg-has-vimeo';
23011                } else {
23012                    videoClass = 'lg-has-html5';
23013                }
23014
23015                _this.$slide.eq(index).prepend('<div class="lg-video-cont ' + videoClass + ' "><div class="lg-video"><span class="lg-video-play"></span><img class="lg-object lg-has-poster" src="' + _poster + '" /></div></div>');
23016
23017            } else if (_isVideo) {
23018                _this.$slide.eq(index).prepend('<div class="lg-video-cont "><div class="lg-video"></div></div>');
23019                _this.$el.trigger('hasVideo.lg', [index, _src, _html]);
23020            } else {
23021                _this.$slide.eq(index).prepend('<div class="lg-img-wrap"><img class="lg-object lg-image" src="' + _src + '" /></div>');
23022            }
23023
23024            _this.$el.trigger('onAferAppendSlide.lg', [index]);
23025
23026            _$img = _this.$slide.eq(index).find('.lg-object');
23027            if (_sizes) {
23028                _$img.attr('sizes', _sizes);
23029            }
23030
23031            if (_srcset) {
23032                _$img.attr('srcset', _srcset);
23033                try {
23034                    picturefill({
23035                        elements: [_$img[0]]
23036                    });
23037                } catch (e) {
23038                    console.warn('lightGallery :- If you want srcset to be supported for older browser please include picturefil version 2 javascript library in your document.');
23039                }
23040            }
23041
23042            if (this.s.appendSubHtmlTo !== '.lg-sub-html') {
23043                _this.addHtml(index);
23044            }
23045
23046            _this.$slide.eq(index).addClass('lg-loaded');
23047        }
23048
23049        _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
23050
23051            // For first time add some delay for displaying the start animation.
23052            var _speed = 0;
23053
23054            // Do not change the delay value because it is required for zoom plugin.
23055            // If gallery opened from direct url (hash) speed value should be 0
23056            if (delay && !$('body').hasClass('lg-from-hash')) {
23057                _speed = delay;
23058            }
23059
23060            setTimeout(function() {
23061                _this.$slide.eq(index).addClass('lg-complete');
23062                _this.$el.trigger('onSlideItemLoad.lg', [index, delay || 0]);
23063            }, _speed);
23064
23065        });
23066
23067        // @todo check load state for html5 videos
23068        if (_isVideo && _isVideo.html5 && !_hasPoster) {
23069            _this.$slide.eq(index).addClass('lg-complete');
23070        }
23071
23072        if (rec === true) {
23073            if (!_this.$slide.eq(index).hasClass('lg-complete')) {
23074                _this.$slide.eq(index).find('.lg-object').on('load.lg error.lg', function() {
23075                    _this.preload(index);
23076                });
23077            } else {
23078                _this.preload(index);
23079            }
23080        }
23081
23082        //}
23083    };
23084
23085    /**
23086    *   @desc slide function for lightgallery
23087        ** Slide() gets call on start
23088        ** ** Set lg.on true once slide() function gets called.
23089        ** Call loadContent() on slide() function inside setTimeout
23090        ** ** On first slide we do not want any animation like slide of fade
23091        ** ** So on first slide( if lg.on if false that is first slide) loadContent() should start loading immediately
23092        ** ** Else loadContent() should wait for the transition to complete.
23093        ** ** So set timeout s.speed + 50
23094    <=> ** loadContent() will load slide content in to the particular slide
23095        ** ** It has recursion (rec) parameter. if rec === true loadContent() will call preload() function.
23096        ** ** preload will execute only when the previous slide is fully loaded (images iframe)
23097        ** ** avoid simultaneous image load
23098    <=> ** Preload() will check for s.preload value and call loadContent() again accoring to preload value
23099        ** loadContent()  <====> Preload();
23100
23101    *   @param {Number} index - index of the slide
23102    *   @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag
23103    *   @param {Boolean} fromThumb - true if slide function called via thumbnail click
23104    *   @param {String} direction - Direction of the slide(next/prev)
23105    */
23106    Plugin.prototype.slide = function(index, fromTouch, fromThumb, direction) {
23107
23108        var _prevIndex = this.$outer.find('.lg-current').index();
23109        var _this = this;
23110
23111        // Prevent if multiple call
23112        // Required for hsh plugin
23113        if (_this.lGalleryOn && (_prevIndex === index)) {
23114            return;
23115        }
23116
23117        var _length = this.$slide.length;
23118        var _time = _this.lGalleryOn ? this.s.speed : 0;
23119
23120        if (!_this.lgBusy) {
23121
23122            if (this.s.download) {
23123                var _src;
23124                if (_this.s.dynamic) {
23125                    _src = _this.s.dynamicEl[index].downloadUrl !== false && (_this.s.dynamicEl[index].downloadUrl || _this.s.dynamicEl[index].src);
23126                } else {
23127                    _src = _this.$items.eq(index).attr('data-download-url') !== 'false' && (_this.$items.eq(index).attr('data-download-url') || _this.$items.eq(index).attr('href') || _this.$items.eq(index).attr('data-src'));
23128
23129                }
23130
23131                if (_src) {
23132                    $('#lg-download').attr('href', _src);
23133                    _this.$outer.removeClass('lg-hide-download');
23134                } else {
23135                    _this.$outer.addClass('lg-hide-download');
23136                }
23137            }
23138
23139            this.$el.trigger('onBeforeSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
23140
23141            _this.lgBusy = true;
23142
23143            clearTimeout(_this.hideBartimeout);
23144
23145            // Add title if this.s.appendSubHtmlTo === lg-sub-html
23146            if (this.s.appendSubHtmlTo === '.lg-sub-html') {
23147
23148                // wait for slide animation to complete
23149                setTimeout(function() {
23150                    _this.addHtml(index);
23151                }, _time);
23152            }
23153
23154            this.arrowDisable(index);
23155
23156            if (!direction) {
23157                if (index < _prevIndex) {
23158                    direction = 'prev';
23159                } else if (index > _prevIndex) {
23160                    direction = 'next';
23161                }
23162            }
23163
23164            if (!fromTouch) {
23165
23166                // remove all transitions
23167                _this.$outer.addClass('lg-no-trans');
23168
23169                this.$slide.removeClass('lg-prev-slide lg-next-slide');
23170
23171                if (direction === 'prev') {
23172
23173                    //prevslide
23174                    this.$slide.eq(index).addClass('lg-prev-slide');
23175                    this.$slide.eq(_prevIndex).addClass('lg-next-slide');
23176                } else {
23177
23178                    // next slide
23179                    this.$slide.eq(index).addClass('lg-next-slide');
23180                    this.$slide.eq(_prevIndex).addClass('lg-prev-slide');
23181                }
23182
23183                // give 50 ms for browser to add/remove class
23184                setTimeout(function() {
23185                    _this.$slide.removeClass('lg-current');
23186
23187                    //_this.$slide.eq(_prevIndex).removeClass('lg-current');
23188                    _this.$slide.eq(index).addClass('lg-current');
23189
23190                    // reset all transitions
23191                    _this.$outer.removeClass('lg-no-trans');
23192                }, 50);
23193            } else {
23194
23195                this.$slide.removeClass('lg-prev-slide lg-current lg-next-slide');
23196                var touchPrev;
23197                var touchNext;
23198                if (_length > 2) {
23199                    touchPrev = index - 1;
23200                    touchNext = index + 1;
23201
23202                    if ((index === 0) && (_prevIndex === _length - 1)) {
23203
23204                        // next slide
23205                        touchNext = 0;
23206                        touchPrev = _length - 1;
23207                    } else if ((index === _length - 1) && (_prevIndex === 0)) {
23208
23209                        // prev slide
23210                        touchNext = 0;
23211                        touchPrev = _length - 1;
23212                    }
23213
23214                } else {
23215                    touchPrev = 0;
23216                    touchNext = 1;
23217                }
23218
23219                if (direction === 'prev') {
23220                    _this.$slide.eq(touchNext).addClass('lg-next-slide');
23221                } else {
23222                    _this.$slide.eq(touchPrev).addClass('lg-prev-slide');
23223                }
23224
23225                _this.$slide.eq(index).addClass('lg-current');
23226            }
23227
23228            if (_this.lGalleryOn) {
23229                setTimeout(function() {
23230                    _this.loadContent(index, true, 0);
23231                }, this.s.speed + 50);
23232
23233                setTimeout(function() {
23234                    _this.lgBusy = false;
23235                    _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
23236                }, this.s.speed);
23237
23238            } else {
23239                _this.loadContent(index, true, _this.s.backdropDuration);
23240
23241                _this.lgBusy = false;
23242                _this.$el.trigger('onAfterSlide.lg', [_prevIndex, index, fromTouch, fromThumb]);
23243            }
23244
23245            _this.lGalleryOn = true;
23246
23247            if (this.s.counter) {
23248                $('#lg-counter-current').text(index + 1);
23249            }
23250
23251        }
23252
23253    };
23254
23255    /**
23256     *  @desc Go to next slide
23257     *  @param {Boolean} fromTouch - true if slide function called via touch event
23258     */
23259    Plugin.prototype.goToNextSlide = function(fromTouch) {
23260        var _this = this;
23261        var _loop = _this.s.loop;
23262        if (fromTouch && _this.$slide.length < 3) {
23263            _loop = false;
23264        }
23265
23266        if (!_this.lgBusy) {
23267            if ((_this.index + 1) < _this.$slide.length) {
23268                _this.index++;
23269                _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
23270                _this.slide(_this.index, fromTouch, false, 'next');
23271            } else {
23272                if (_loop) {
23273                    _this.index = 0;
23274                    _this.$el.trigger('onBeforeNextSlide.lg', [_this.index]);
23275                    _this.slide(_this.index, fromTouch, false, 'next');
23276                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
23277                    _this.$outer.addClass('lg-right-end');
23278                    setTimeout(function() {
23279                        _this.$outer.removeClass('lg-right-end');
23280                    }, 400);
23281                }
23282            }
23283        }
23284    };
23285
23286    /**
23287     *  @desc Go to previous slide
23288     *  @param {Boolean} fromTouch - true if slide function called via touch event
23289     */
23290    Plugin.prototype.goToPrevSlide = function(fromTouch) {
23291        var _this = this;
23292        var _loop = _this.s.loop;
23293        if (fromTouch && _this.$slide.length < 3) {
23294            _loop = false;
23295        }
23296
23297        if (!_this.lgBusy) {
23298            if (_this.index > 0) {
23299                _this.index--;
23300                _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
23301                _this.slide(_this.index, fromTouch, false, 'prev');
23302            } else {
23303                if (_loop) {
23304                    _this.index = _this.$items.length - 1;
23305                    _this.$el.trigger('onBeforePrevSlide.lg', [_this.index, fromTouch]);
23306                    _this.slide(_this.index, fromTouch, false, 'prev');
23307                } else if (_this.s.slideEndAnimatoin && !fromTouch) {
23308                    _this.$outer.addClass('lg-left-end');
23309                    setTimeout(function() {
23310                        _this.$outer.removeClass('lg-left-end');
23311                    }, 400);
23312                }
23313            }
23314        }
23315    };
23316
23317    Plugin.prototype.keyPress = function() {
23318        var _this = this;
23319        if (this.$items.length > 1) {
23320            $(window).on('keyup.lg', function(e) {
23321                if (_this.$items.length > 1) {
23322                    if (e.keyCode === 37) {
23323                        e.preventDefault();
23324                        _this.goToPrevSlide();
23325                    }
23326
23327                    if (e.keyCode === 39) {
23328                        e.preventDefault();
23329                        _this.goToNextSlide();
23330                    }
23331                }
23332            });
23333        }
23334
23335        $(window).on('keydown.lg', function(e) {
23336            if (_this.s.escKey === true && e.keyCode === 27) {
23337                e.preventDefault();
23338                if (!_this.$outer.hasClass('lg-thumb-open')) {
23339                    _this.destroy();
23340                } else {
23341                    _this.$outer.removeClass('lg-thumb-open');
23342                }
23343            }
23344        });
23345    };
23346
23347    Plugin.prototype.arrow = function() {
23348        var _this = this;
23349        this.$outer.find('.lg-prev').on('click.lg', function() {
23350            _this.goToPrevSlide();
23351        });
23352
23353        this.$outer.find('.lg-next').on('click.lg', function() {
23354            _this.goToNextSlide();
23355        });
23356    };
23357
23358    Plugin.prototype.arrowDisable = function(index) {
23359
23360        // Disable arrows if s.hideControlOnEnd is true
23361        if (!this.s.loop && this.s.hideControlOnEnd) {
23362            if ((index + 1) < this.$slide.length) {
23363                this.$outer.find('.lg-next').removeAttr('disabled').removeClass('disabled');
23364            } else {
23365                this.$outer.find('.lg-next').attr('disabled', 'disabled').addClass('disabled');
23366            }
23367
23368            if (index > 0) {
23369                this.$outer.find('.lg-prev').removeAttr('disabled').removeClass('disabled');
23370            } else {
23371                this.$outer.find('.lg-prev').attr('disabled', 'disabled').addClass('disabled');
23372            }
23373        }
23374    };
23375
23376    Plugin.prototype.setTranslate = function($el, xValue, yValue) {
23377        // jQuery supports Automatic CSS prefixing since jQuery 1.8.0
23378        if (this.s.useLeft) {
23379            $el.css('left', xValue);
23380        } else {
23381            $el.css({
23382                transform: 'translate3d(' + (xValue) + 'px, ' + yValue + 'px, 0px)'
23383            });
23384        }
23385    };
23386
23387    Plugin.prototype.touchMove = function(startCoords, endCoords) {
23388
23389        var distance = endCoords - startCoords;
23390
23391        if (Math.abs(distance) > 15) {
23392            // reset opacity and transition duration
23393            this.$outer.addClass('lg-dragging');
23394
23395            // move current slide
23396            this.setTranslate(this.$slide.eq(this.index), distance, 0);
23397
23398            // move next and prev slide with current slide
23399            this.setTranslate($('.lg-prev-slide'), -this.$slide.eq(this.index).width() + distance, 0);
23400            this.setTranslate($('.lg-next-slide'), this.$slide.eq(this.index).width() + distance, 0);
23401        }
23402    };
23403
23404    Plugin.prototype.touchEnd = function(distance) {
23405        var _this = this;
23406
23407        // keep slide animation for any mode while dragg/swipe
23408        if (_this.s.mode !== 'lg-slide') {
23409            _this.$outer.addClass('lg-slide');
23410        }
23411
23412        this.$slide.not('.lg-current, .lg-prev-slide, .lg-next-slide').css('opacity', '0');
23413
23414        // set transition duration
23415        setTimeout(function() {
23416            _this.$outer.removeClass('lg-dragging');
23417            if ((distance < 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
23418                _this.goToNextSlide(true);
23419            } else if ((distance > 0) && (Math.abs(distance) > _this.s.swipeThreshold)) {
23420                _this.goToPrevSlide(true);
23421            } else if (Math.abs(distance) < 5) {
23422
23423                // Trigger click if distance is less than 5 pix
23424                _this.$el.trigger('onSlideClick.lg');
23425            }
23426
23427            _this.$slide.removeAttr('style');
23428        });
23429
23430        // remove slide class once drag/swipe is completed if mode is not slide
23431        setTimeout(function() {
23432            if (!_this.$outer.hasClass('lg-dragging') && _this.s.mode !== 'lg-slide') {
23433                _this.$outer.removeClass('lg-slide');
23434            }
23435        }, _this.s.speed + 100);
23436
23437    };
23438
23439    Plugin.prototype.enableSwipe = function() {
23440        var _this = this;
23441        var startCoords = 0;
23442        var endCoords = 0;
23443        var isMoved = false;
23444
23445        if (_this.s.enableSwipe && _this.doCss()) {
23446
23447            _this.$slide.on('touchstart.lg', function(e) {
23448                if (!_this.$outer.hasClass('lg-zoomed') && !_this.lgBusy) {
23449                    e.preventDefault();
23450                    _this.manageSwipeClass();
23451                    startCoords = e.originalEvent.targetTouches[0].pageX;
23452                }
23453            });
23454
23455            _this.$slide.on('touchmove.lg', function(e) {
23456                if (!_this.$outer.hasClass('lg-zoomed')) {
23457                    e.preventDefault();
23458                    endCoords = e.originalEvent.targetTouches[0].pageX;
23459                    _this.touchMove(startCoords, endCoords);
23460                    isMoved = true;
23461                }
23462            });
23463
23464            _this.$slide.on('touchend.lg', function() {
23465                if (!_this.$outer.hasClass('lg-zoomed')) {
23466                    if (isMoved) {
23467                        isMoved = false;
23468                        _this.touchEnd(endCoords - startCoords);
23469                    } else {
23470                        _this.$el.trigger('onSlideClick.lg');
23471                    }
23472                }
23473            });
23474        }
23475
23476    };
23477
23478    Plugin.prototype.enableDrag = function() {
23479        var _this = this;
23480        var startCoords = 0;
23481        var endCoords = 0;
23482        var isDraging = false;
23483        var isMoved = false;
23484        if (_this.s.enableDrag && _this.doCss()) {
23485            _this.$slide.on('mousedown.lg', function(e) {
23486                // execute only on .lg-object
23487                if (!_this.$outer.hasClass('lg-zoomed')) {
23488                    if ($(e.target).hasClass('lg-object') || $(e.target).hasClass('lg-video-play')) {
23489                        e.preventDefault();
23490
23491                        if (!_this.lgBusy) {
23492                            _this.manageSwipeClass();
23493                            startCoords = e.pageX;
23494                            isDraging = true;
23495
23496                            // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
23497                            _this.$outer.scrollLeft += 1;
23498                            _this.$outer.scrollLeft -= 1;
23499
23500                            // *
23501
23502                            _this.$outer.removeClass('lg-grab').addClass('lg-grabbing');
23503
23504                            _this.$el.trigger('onDragstart.lg');
23505                        }
23506
23507                    }
23508                }
23509            });
23510
23511            $(window).on('mousemove.lg', function(e) {
23512                if (isDraging) {
23513                    isMoved = true;
23514                    endCoords = e.pageX;
23515                    _this.touchMove(startCoords, endCoords);
23516                    _this.$el.trigger('onDragmove.lg');
23517                }
23518            });
23519
23520            $(window).on('mouseup.lg', function(e) {
23521                if (isMoved) {
23522                    isMoved = false;
23523                    _this.touchEnd(endCoords - startCoords);
23524                    _this.$el.trigger('onDragend.lg');
23525                } else if ($(e.target).hasClass('lg-object') || $(e.target).hasClass('lg-video-play')) {
23526                    _this.$el.trigger('onSlideClick.lg');
23527                }
23528
23529                // Prevent execution on click
23530                if (isDraging) {
23531                    isDraging = false;
23532                    _this.$outer.removeClass('lg-grabbing').addClass('lg-grab');
23533                }
23534            });
23535
23536        }
23537    };
23538
23539    Plugin.prototype.manageSwipeClass = function() {
23540        var _touchNext = this.index + 1;
23541        var _touchPrev = this.index - 1;
23542        if (this.s.loop && this.$slide.length > 2) {
23543            if (this.index === 0) {
23544                _touchPrev = this.$slide.length - 1;
23545            } else if (this.index === this.$slide.length - 1) {
23546                _touchNext = 0;
23547            }
23548        }
23549
23550        this.$slide.removeClass('lg-next-slide lg-prev-slide');
23551        if (_touchPrev > -1) {
23552            this.$slide.eq(_touchPrev).addClass('lg-prev-slide');
23553        }
23554
23555        this.$slide.eq(_touchNext).addClass('lg-next-slide');
23556    };
23557
23558    Plugin.prototype.mousewheel = function() {
23559        var _this = this;
23560        _this.$outer.on('mousewheel.lg', function(e) {
23561
23562            if (!e.deltaY) {
23563                return;
23564            }
23565
23566            if (e.deltaY > 0) {
23567                _this.goToPrevSlide();
23568            } else {
23569                _this.goToNextSlide();
23570            }
23571
23572            e.preventDefault();
23573        });
23574
23575    };
23576
23577    Plugin.prototype.closeGallery = function() {
23578
23579        var _this = this;
23580        var mousedown = false;
23581        this.$outer.find('.lg-close').on('click.lg', function() {
23582            _this.destroy();
23583        });
23584
23585        if (_this.s.closable) {
23586
23587            // If you drag the slide and release outside gallery gets close on chrome
23588            // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer
23589            _this.$outer.on('mousedown.lg', function(e) {
23590
23591                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap')) {
23592                    mousedown = true;
23593                } else {
23594                    mousedown = false;
23595                }
23596
23597            });
23598
23599            _this.$outer.on('mouseup.lg', function(e) {
23600
23601                if ($(e.target).is('.lg-outer') || $(e.target).is('.lg-item ') || $(e.target).is('.lg-img-wrap') && mousedown) {
23602                    if (!_this.$outer.hasClass('lg-dragging')) {
23603                        _this.destroy();
23604                    }
23605                }
23606
23607            });
23608
23609        }
23610
23611    };
23612
23613    Plugin.prototype.destroy = function(d) {
23614
23615        var _this = this;
23616
23617        if (!d) {
23618            _this.$el.trigger('onBeforeClose.lg');
23619            $(window).scrollTop(_this.prevScrollTop);
23620        }
23621
23622
23623        /**
23624         * if d is false or undefined destroy will only close the gallery
23625         * plugins instance remains with the element
23626         *
23627         * if d is true destroy will completely remove the plugin
23628         */
23629
23630        if (d) {
23631            if (!_this.s.dynamic) {
23632                // only when not using dynamic mode is $items a jquery collection
23633                this.$items.off('click.lg click.lgcustom');
23634            }
23635
23636            $.removeData(_this.el, 'lightGallery');
23637        }
23638
23639        // Unbind all events added by lightGallery
23640        this.$el.off('.lg.tm');
23641
23642        // Distroy all lightGallery modules
23643        $.each($.fn.lightGallery.modules, function(key) {
23644            if (_this.modules[key]) {
23645                _this.modules[key].destroy();
23646            }
23647        });
23648
23649        this.lGalleryOn = false;
23650
23651        clearTimeout(_this.hideBartimeout);
23652        this.hideBartimeout = false;
23653        $(window).off('.lg');
23654        $('body').removeClass('lg-on lg-from-hash');
23655
23656        if (_this.$outer) {
23657            _this.$outer.removeClass('lg-visible');
23658        }
23659
23660        $('.lg-backdrop').removeClass('in');
23661
23662        setTimeout(function() {
23663            if (_this.$outer) {
23664                _this.$outer.remove();
23665            }
23666
23667            $('.lg-backdrop').remove();
23668
23669            if (!d) {
23670                _this.$el.trigger('onCloseAfter.lg');
23671            }
23672
23673        }, _this.s.backdropDuration + 50);
23674    };
23675
23676    $.fn.lightGallery = function(options) {
23677        return this.each(function() {
23678            if (!$.data(this, 'lightGallery')) {
23679                $.data(this, 'lightGallery', new Plugin(this, options));
23680            } else {
23681                try {
23682                    $(this).data('lightGallery').init();
23683                } catch (err) {
23684                    console.error('lightGallery has not initiated properly');
23685                }
23686            }
23687        });
23688    };
23689
23690    $.fn.lightGallery.modules = {};
23691
23692})();
23693
23694
23695}));
23696
23697/*! lg-autoplay - v1.0.4 - 2017-03-28
23698* http://sachinchoolur.github.io/lightGallery
23699* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
23700
23701(function (root, factory) {
23702  if (typeof define === 'function' && define.amd) {
23703    // AMD. Register as an anonymous module unless amdModuleId is set
23704    define(['jquery'], function (a0) {
23705      return (factory(a0));
23706    });
23707  } else if (typeof exports === 'object') {
23708    // Node. Does not work with strict CommonJS, but
23709    // only CommonJS-like environments that support module.exports,
23710    // like Node.
23711    module.exports = factory(require('jquery'));
23712  } else {
23713    factory(jQuery);
23714  }
23715}(this, function ($) {
23716
23717
23718(function() {
23719
23720    'use strict';
23721
23722    var defaults = {
23723        autoplay: false,
23724        pause: 5000,
23725        progressBar: true,
23726        fourceAutoplay: false,
23727        autoplayControls: true,
23728        appendAutoplayControlsTo: '.lg-toolbar'
23729    };
23730
23731    /**
23732     * Creates the autoplay plugin.
23733     * @param {object} element - lightGallery element
23734     */
23735    var Autoplay = function(element) {
23736
23737        this.core = $(element).data('lightGallery');
23738
23739        this.$el = $(element);
23740
23741        // Execute only if items are above 1
23742        if (this.core.$items.length < 2) {
23743            return false;
vendor: 4,651 bytes, lines 23744-23885
23744        }
23745
23746        this.core.s = $.extend({}, defaults, this.core.s);
23747        this.interval = false;
23748
23749        // Identify if slide happened from autoplay
23750        this.fromAuto = true;
23751
23752        // Identify if autoplay canceled from touch/drag
23753        this.canceledOnTouch = false;
23754
23755        // save fourceautoplay value
23756        this.fourceAutoplayTemp = this.core.s.fourceAutoplay;
23757
23758        // do not allow progress bar if browser does not support css3 transitions
23759        if (!this.core.doCss()) {
23760            this.core.s.progressBar = false;
23761        }
23762
23763        this.init();
23764
23765        return this;
23766    };
23767
23768    Autoplay.prototype.init = function() {
23769        var _this = this;
23770
23771        // append autoplay controls
23772        if (_this.core.s.autoplayControls) {
23773            _this.controls();
23774        }
23775
23776        // Create progress bar
23777        if (_this.core.s.progressBar) {
23778            _this.core.$outer.find('.lg').append('<div class="lg-progress-bar"><div class="lg-progress"></div></div>');
23779        }
23780
23781        // set progress
23782        _this.progress();
23783
23784        // Start autoplay
23785        if (_this.core.s.autoplay) {
23786            _this.$el.one('onSlideItemLoad.lg.tm', function() {
23787                _this.startlAuto();
23788            });
23789        }
23790
23791        // cancel interval on touchstart and dragstart
23792        _this.$el.on('onDragstart.lg.tm touchstart.lg.tm', function() {
23793            if (_this.interval) {
23794                _this.cancelAuto();
23795                _this.canceledOnTouch = true;
23796            }
23797        });
23798
23799        // restore autoplay if autoplay canceled from touchstart / dragstart
23800        _this.$el.on('onDragend.lg.tm touchend.lg.tm onSlideClick.lg.tm', function() {
23801            if (!_this.interval && _this.canceledOnTouch) {
23802                _this.startlAuto();
23803                _this.canceledOnTouch = false;
23804            }
23805        });
23806
23807    };
23808
23809    Autoplay.prototype.progress = function() {
23810
23811        var _this = this;
23812        var _$progressBar;
23813        var _$progress;
23814
23815        _this.$el.on('onBeforeSlide.lg.tm', function() {
23816
23817            // start progress bar animation
23818            if (_this.core.s.progressBar && _this.fromAuto) {
23819                _$progressBar = _this.core.$outer.find('.lg-progress-bar');
23820                _$progress = _this.core.$outer.find('.lg-progress');
23821                if (_this.interval) {
23822                    _$progress.removeAttr('style');
23823                    _$progressBar.removeClass('lg-start');
23824                    setTimeout(function() {
23825                        _$progress.css('transition', 'width ' + (_this.core.s.speed + _this.core.s.pause) + 'ms ease 0s');
23826                        _$progressBar.addClass('lg-start');
23827                    }, 20);
23828                }
23829            }
23830
23831            // Remove setinterval if slide is triggered manually and fourceautoplay is false
23832            if (!_this.fromAuto && !_this.core.s.fourceAutoplay) {
23833                _this.cancelAuto();
23834            }
23835
23836            _this.fromAuto = false;
23837
23838        });
23839    };
23840
23841    // Manage autoplay via play/stop buttons
23842    Autoplay.prototype.controls = function() {
23843        var _this = this;
23844        var _html = '<span class="lg-autoplay-button lg-icon"></span>';
23845
23846        // Append autoplay controls
23847        $(this.core.s.appendAutoplayControlsTo).append(_html);
23848
23849        _this.core.$outer.find('.lg-autoplay-button').on('click.lg', function() {
23850            if ($(_this.core.$outer).hasClass('lg-show-autoplay')) {
23851                _this.cancelAuto();
23852                _this.core.s.fourceAutoplay = false;
23853            } else {
23854                if (!_this.interval) {
23855                    _this.startlAuto();
23856                    _this.core.s.fourceAutoplay = _this.fourceAutoplayTemp;
23857                }
23858            }
23859        });
23860    };
23861
23862    // Autostart gallery
23863    Autoplay.prototype.startlAuto = function() {
23864        var _this = this;
23865
23866        _this.core.$outer.find('.lg-progress').css('transition', 'width ' + (_this.core.s.speed + _this.core.s.pause) + 'ms ease 0s');
23867        _this.core.$outer.addClass('lg-show-autoplay');
23868        _this.core.$outer.find('.lg-progress-bar').addClass('lg-start');
23869
23870        _this.interval = setInterval(function() {
23871            if (_this.core.index + 1 < _this.core.$items.length) {
23872                _this.core.index++;
23873            } else {
23874                _this.core.index = 0;
23875            }
23876
23877            _this.fromAuto = true;
23878            _this.core.slide(_this.core.index, false, false, 'next');
23879        }, _this.core.s.speed + _this.core.s.pause);
23880    };
23881
23882    // cancel Autostart
23883    Autoplay.prototype.cancelAuto = function() {
23884        clearInterval(this.interval);
23885        this.interval = false;
23886        this.core.$outer.find('.lg-progress').removeAttr('style');
23887        this.core.$outer.removeClass('lg-show-autoplay');
23888        this.core.$outer.find('.lg-progress-bar').removeClass('lg-start');
23889    };
23890
23891    Autoplay.prototype.destroy = function() {
23892
23893        this.cancelAuto();
23894        this.core.$outer.find('.lg-progress-bar').remove();
23895    };
23896
23897    $.fn.lightGallery.modules.autoplay = Autoplay;
23898
23899})();
23900
23901
23902}));
23903
23904/*! lg-fullscreen - v1.0.1 - 2016-09-30
23905* http://sachinchoolur.github.io/lightGallery
23906* Copyright (c) 2016 Sachin N; Licensed GPLv3 */
23907
23908(function (root, factory) {
23909  if (typeof define === 'function' && define.amd) {
23910    // AMD. Register as an anonymous module unless amdModuleId is set
23911    define(['jquery'], function (a0) {
23912      return (factory(a0));
23913    });
23914  } else if (typeof exports === 'object') {
23915    // Node. Does not work with strict CommonJS, but
23916    // only CommonJS-like environments that support module.exports,
23917    // like Node.
23918    module.exports = factory(require('jquery'));
23919  } else {
23920    factory(jQuery);
23921  }
23922}(this, function ($) {
23923
23924(function() {
23925
23926    'use strict';
23927
23928    var defaults = {
23929        fullScreen: true
23930    };
23931
23932    var Fullscreen = function(element) {
23933
23934        // get lightGallery core plugin data
23935        this.core = $(element).data('lightGallery');
23936
23937        this.$el = $(element);
23938
23939        // extend module defalut settings with lightGallery core settings
23940        this.core.s = $.extend({}, defaults, this.core.s);
23941
23942        this.init();
23943
23944        return this;
23945    };
23946
23947    Fullscreen.prototype.init = function() {
23948        var fullScreen = '';
23949        if (this.core.s.fullScreen) {
23950
23951            // check for fullscreen browser support
23952            if (!document.fullscreenEnabled && !document.webkitFullscreenEnabled &&
23953                !document.mozFullScreenEnabled && !document.msFullscreenEnabled) {
23954                return;
23955            } else {
23956                fullScreen = '<span class="lg-fullscreen lg-icon"></span>';
23957                this.core.$outer.find('.lg-toolbar').append(fullScreen);
23958                this.fullScreen();
23959            }
23960        }
23961    };
23962
23963    Fullscreen.prototype.requestFullscreen = function() {
23964        var el = document.documentElement;
23965        if (el.requestFullscreen) {
23966            el.requestFullscreen();
23967        } else if (el.msRequestFullscreen) {
23968            el.msRequestFullscreen();
23969        } else if (el.mozRequestFullScreen) {
23970            el.mozRequestFullScreen();
23971        } else if (el.webkitRequestFullscreen) {
23972            el.webkitRequestFullscreen();
23973        }
23974    };
23975
23976    Fullscreen.prototype.exitFullscreen = function() {
23977        if (document.exitFullscreen) {
23978            document.exitFullscreen();
23979        } else if (document.msExitFullscreen) {
23980            document.msExitFullscreen();
23981        } else if (document.mozCancelFullScreen) {
23982            document.mozCancelFullScreen();
23983        } else if (document.webkitExitFullscreen) {
23984            document.webkitExitFullscreen();
23985        }
23986    };
23987
23988    // https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
23989    Fullscreen.prototype.fullScreen = function() {
23990        var _this = this;
23991
23992        $(document).on('fullscreenchange.lg webkitfullscreenchange.lg mozfullscreenchange.lg MSFullscreenChange.lg', function() {
23993            _this.core.$outer.toggleClass('lg-fullscreen-on');
23994        });
23995
23996        this.core.$outer.find('.lg-fullscreen').on('click.lg', function() {
23997            if (!document.fullscreenElement &&
23998                !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
23999                _this.requestFullscreen();
24000            } else {
24001                _this.exitFullscreen();
24002            }
24003        });
24004
24005    };
24006
24007    Fullscreen.prototype.destroy = function() {
24008
24009        // exit from fullscreen if activated
24010        this.exitFullscreen();
24011
24012        $(document).off('fullscreenchange.lg webkitfullscreenchange.lg mozfullscreenchange.lg MSFullscreenChange.lg');
24013    };
24014
24015    $.fn.lightGallery.modules.fullscreen = Fullscreen;
24016
24017})();
24018
24019}));
24020
24021/*! lg-pager - v1.0.2 - 2017-01-22
24022* http://sachinchoolur.github.io/lightGallery
24023* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
24024
24025(function (root, factory) {
24026  if (typeof define === 'function' && define.amd) {
24027    // AMD. Register as an anonymous module unless amdModuleId is set
24028    define(['jquery'], function (a0) {
24029      return (factory(a0));
24030    });
24031  } else if (typeof exports === 'object') {
24032    // Node. Does not work with strict CommonJS, but
24033    // only CommonJS-like environments that support module.exports,
24034    // like Node.
24035    module.exports = factory(require('jquery'));
24036  } else {
24037    factory(jQuery);
24038  }
24039}(this, function ($) {
24040
24041(function() {
24042
24043    'use strict';
24044
24045    var defaults = {
24046        pager: false
24047    };
24048
24049    var Pager = function(element) {
24050
24051        this.core = $(element).data('lightGallery');
24052
24053        this.$el = $(element);
24054        this.core.s = $.extend({}, defaults, this.core.s);
24055        if (this.core.s.pager && this.core.$items.length > 1) {
24056            this.init();
24057        }
24058
24059        return this;
24060    };
24061
24062    Pager.prototype.init = function() {
24063        var _this = this;
24064        var pagerList = '';
24065        var $pagerCont;
24066        var $pagerOuter;
24067        var timeout;
24068
24069        _this.core.$outer.find('.lg').append('<div class="lg-pager-outer"></div>');
24070
24071        if (_this.core.s.dynamic) {
24072            for (var i = 0; i < _this.core.s.dynamicEl.length; i++) {
24073                pagerList += '<span class="lg-pager-cont"> <span class="lg-pager"></span><div class="lg-pager-thumb-cont"><span class="lg-caret"></span> <img src="' + _this.core.s.dynamicEl[i].thumb + '" /></div></span>';
24074            }
24075        } else {
24076            _this.core.$items.each(function() {
24077
24078                if (!_this.core.s.exThumbImage) {
24079                    pagerList += '<span class="lg-pager-cont"> <span class="lg-pager"></span><div class="lg-pager-thumb-cont"><span class="lg-caret"></span> <img src="' + $(this).find('img').attr('src') + '" /></div></span>';
24080                } else {
24081                    pagerList += '<span class="lg-pager-cont"> <span class="lg-pager"></span><div class="lg-pager-thumb-cont"><span class="lg-caret"></span> <img src="' + $(this).attr(_this.core.s.exThumbImage) + '" /></div></span>';
24082                }
24083
24084            });
24085        }
24086
24087        $pagerOuter = _this.core.$outer.find('.lg-pager-outer');
24088
vendor: 17,675 bytes, lines 24089-24635
24089        $pagerOuter.html(pagerList);
24090
24091        $pagerCont = _this.core.$outer.find('.lg-pager-cont');
24092        $pagerCont.on('click.lg touchend.lg', function() {
24093            var _$this = $(this);
24094            _this.core.index = _$this.index();
24095            _this.core.slide(_this.core.index, false, true, false);
24096        });
24097
24098        $pagerOuter.on('mouseover.lg', function() {
24099            clearTimeout(timeout);
24100            $pagerOuter.addClass('lg-pager-hover');
24101        });
24102
24103        $pagerOuter.on('mouseout.lg', function() {
24104            timeout = setTimeout(function() {
24105                $pagerOuter.removeClass('lg-pager-hover');
24106            });
24107        });
24108
24109        _this.core.$el.on('onBeforeSlide.lg.tm', function(e, prevIndex, index) {
24110            $pagerCont.removeClass('lg-pager-active');
24111            $pagerCont.eq(index).addClass('lg-pager-active');
24112        });
24113
24114    };
24115
24116    Pager.prototype.destroy = function() {
24117
24118    };
24119
24120    $.fn.lightGallery.modules.pager = Pager;
24121
24122})();
24123
24124
24125}));
24126
24127/*! lg-thumbnail - v1.1.0 - 2017-08-08
24128* http://sachinchoolur.github.io/lightGallery
24129* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
24130
24131(function (root, factory) {
24132  if (typeof define === 'function' && define.amd) {
24133    // AMD. Register as an anonymous module unless amdModuleId is set
24134    define(['jquery'], function (a0) {
24135      return (factory(a0));
24136    });
24137  } else if (typeof exports === 'object') {
24138    // Node. Does not work with strict CommonJS, but
24139    // only CommonJS-like environments that support module.exports,
24140    // like Node.
24141    module.exports = factory(require('jquery'));
24142  } else {
24143    factory(jQuery);
24144  }
24145}(this, function ($) {
24146
24147(function() {
24148
24149    'use strict';
24150
24151    var defaults = {
24152        thumbnail: true,
24153
24154        animateThumb: true,
24155        currentPagerPosition: 'middle',
24156
24157        thumbWidth: 100,
24158        thumbHeight: '80px',
24159        thumbContHeight: 100,
24160        thumbMargin: 5,
24161
24162        exThumbImage: false,
24163        showThumbByDefault: true,
24164        toogleThumb: true,
24165        pullCaptionUp: true,
24166
24167        enableThumbDrag: true,
24168        enableThumbSwipe: true,
24169        swipeThreshold: 50,
24170
24171        loadYoutubeThumbnail: true,
24172        youtubeThumbSize: 1,
24173
24174        loadVimeoThumbnail: true,
24175        vimeoThumbSize: 'thumbnail_small',
24176
24177        loadDailymotionThumbnail: true
24178    };
24179
24180    var Thumbnail = function(element) {
24181
24182        // get lightGallery core plugin data
24183        this.core = $(element).data('lightGallery');
24184
24185        // extend module default settings with lightGallery core settings
24186        this.core.s = $.extend({}, defaults, this.core.s);
24187
24188        this.$el = $(element);
24189        this.$thumbOuter = null;
24190        this.thumbOuterWidth = 0;
24191        this.thumbTotalWidth = (this.core.$items.length * (this.core.s.thumbWidth + this.core.s.thumbMargin));
24192        this.thumbIndex = this.core.index;
24193
24194        if (this.core.s.animateThumb) {
24195            this.core.s.thumbHeight = '100%';
24196        }
24197
24198        // Thumbnail animation value
24199        this.left = 0;
24200
24201        this.init();
24202
24203        return this;
24204    };
24205
24206    Thumbnail.prototype.init = function() {
24207        var _this = this;
24208        if (this.core.s.thumbnail && this.core.$items.length > 1) {
24209            if (this.core.s.showThumbByDefault) {
24210                setTimeout(function(){
24211                    _this.core.$outer.addClass('lg-thumb-open');
24212                }, 700);
24213            }
24214
24215            if (this.core.s.pullCaptionUp) {
24216                this.core.$outer.addClass('lg-pull-caption-up');
24217            }
24218
24219            this.build();
24220            if (this.core.s.animateThumb && this.core.doCss()) {
24221                if (this.core.s.enableThumbDrag) {
24222                    this.enableThumbDrag();
24223                }
24224
24225                if (this.core.s.enableThumbSwipe) {
24226                    this.enableThumbSwipe();
24227                }
24228
24229                this.thumbClickable = false;
24230            } else {
24231                this.thumbClickable = true;
24232            }
24233
24234            this.toogle();
24235            this.thumbkeyPress();
24236        }
24237    };
24238
24239    Thumbnail.prototype.build = function() {
24240        var _this = this;
24241        var thumbList = '';
24242        var vimeoErrorThumbSize = '';
24243        var $thumb;
24244        var html = '<div class="lg-thumb-outer">' +
24245            '<div class="lg-thumb lg-group">' +
24246            '</div>' +
24247            '</div>';
24248
24249        switch (this.core.s.vimeoThumbSize) {
24250            case 'thumbnail_large':
24251                vimeoErrorThumbSize = '640';
24252                break;
24253            case 'thumbnail_medium':
24254                vimeoErrorThumbSize = '200x150';
24255                break;
24256            case 'thumbnail_small':
24257                vimeoErrorThumbSize = '100x75';
24258        }
24259
24260        _this.core.$outer.addClass('lg-has-thumb');
24261
24262        _this.core.$outer.find('.lg').append(html);
24263
24264        _this.$thumbOuter = _this.core.$outer.find('.lg-thumb-outer');
24265        _this.thumbOuterWidth = _this.$thumbOuter.width();
24266
24267        if (_this.core.s.animateThumb) {
24268            _this.core.$outer.find('.lg-thumb').css({
24269                width: _this.thumbTotalWidth + 'px',
24270                position: 'relative'
24271            });
24272        }
24273
24274        if (this.core.s.animateThumb) {
24275            _this.$thumbOuter.css('height', _this.core.s.thumbContHeight + 'px');
24276        }
24277
24278        function getThumb(src, thumb, index) {
24279            var isVideo = _this.core.isVideo(src, index) || {};
24280            var thumbImg;
24281            var vimeoId = '';
24282
24283            if (isVideo.youtube || isVideo.vimeo || isVideo.dailymotion) {
24284                if (isVideo.youtube) {
24285                    if (_this.core.s.loadYoutubeThumbnail) {
24286                        thumbImg = '//img.youtube.com/vi/' + isVideo.youtube[1] + '/' + _this.core.s.youtubeThumbSize + '.jpg';
24287                    } else {
24288                        thumbImg = thumb;
24289                    }
24290                } else if (isVideo.vimeo) {
24291                    if (_this.core.s.loadVimeoThumbnail) {
24292                        thumbImg = '//i.vimeocdn.com/video/error_' + vimeoErrorThumbSize + '.jpg';
24293                        vimeoId = isVideo.vimeo[1];
24294                    } else {
24295                        thumbImg = thumb;
24296                    }
24297                } else if (isVideo.dailymotion) {
24298                    if (_this.core.s.loadDailymotionThumbnail) {
24299                        thumbImg = '//www.dailymotion.com/thumbnail/video/' + isVideo.dailymotion[1];
24300                    } else {
24301                        thumbImg = thumb;
24302                    }
24303                }
24304            } else {
24305                thumbImg = thumb;
24306            }
24307
24308            thumbList += '<div data-vimeo-id="' + vimeoId + '" class="lg-thumb-item" style="width:' + _this.core.s.thumbWidth + 'px; height: ' + _this.core.s.thumbHeight + '; margin-right: ' + _this.core.s.thumbMargin + 'px"><img src="' + thumbImg + '" /></div>';
24309            vimeoId = '';
24310        }
24311
24312        if (_this.core.s.dynamic) {
24313            for (var i = 0; i < _this.core.s.dynamicEl.length; i++) {
24314                getThumb(_this.core.s.dynamicEl[i].src, _this.core.s.dynamicEl[i].thumb, i);
24315            }
24316        } else {
24317            _this.core.$items.each(function(i) {
24318
24319                if (!_this.core.s.exThumbImage) {
24320                    getThumb($(this).attr('href') || $(this).attr('data-src'), $(this).find('img').attr('src'), i);
24321                } else {
24322                    getThumb($(this).attr('href') || $(this).attr('data-src'), $(this).attr(_this.core.s.exThumbImage), i);
24323                }
24324
24325            });
24326        }
24327
24328        _this.core.$outer.find('.lg-thumb').html(thumbList);
24329
24330        $thumb = _this.core.$outer.find('.lg-thumb-item');
24331
24332        // Load vimeo thumbnails
24333        $thumb.each(function() {
24334            var $this = $(this);
24335            var vimeoVideoId = $this.attr('data-vimeo-id');
24336
24337            if (vimeoVideoId) {
24338                $.getJSON('//www.vimeo.com/api/v2/video/' + vimeoVideoId + '.json?callback=?', {
24339                    format: 'json'
24340                }, function(data) {
24341                    $this.find('img').attr('src', data[0][_this.core.s.vimeoThumbSize]);
24342                });
24343            }
24344        });
24345
24346        // manage active class for thumbnail
24347        $thumb.eq(_this.core.index).addClass('active');
24348        _this.core.$el.on('onBeforeSlide.lg.tm', function() {
24349            $thumb.removeClass('active');
24350            $thumb.eq(_this.core.index).addClass('active');
24351        });
24352
24353        $thumb.on('click.lg touchend.lg', function() {
24354            var _$this = $(this);
24355            setTimeout(function() {
24356
24357                // In IE9 and bellow touch does not support
24358                // Go to slide if browser does not support css transitions
24359                if ((_this.thumbClickable && !_this.core.lgBusy) || !_this.core.doCss()) {
24360                    _this.core.index = _$this.index();
24361                    _this.core.slide(_this.core.index, false, true, false);
24362                }
24363            }, 50);
24364        });
24365
24366        _this.core.$el.on('onBeforeSlide.lg.tm', function() {
24367            _this.animateThumb(_this.core.index);
24368        });
24369
24370        $(window).on('resize.lg.thumb orientationchange.lg.thumb', function() {
24371            setTimeout(function() {
24372                _this.animateThumb(_this.core.index);
24373                _this.thumbOuterWidth = _this.$thumbOuter.width();
24374            }, 200);
24375        });
24376
24377    };
24378
24379    Thumbnail.prototype.setTranslate = function(value) {
24380        // jQuery supports Automatic CSS prefixing since jQuery 1.8.0
24381        this.core.$outer.find('.lg-thumb').css({
24382            transform: 'translate3d(-' + (value) + 'px, 0px, 0px)'
24383        });
24384    };
24385
24386    Thumbnail.prototype.animateThumb = function(index) {
24387        var $thumb = this.core.$outer.find('.lg-thumb');
24388        if (this.core.s.animateThumb) {
24389            var position;
24390            switch (this.core.s.currentPagerPosition) {
24391                case 'left':
24392                    position = 0;
24393                    break;
24394                case 'middle':
24395                    position = (this.thumbOuterWidth / 2) - (this.core.s.thumbWidth / 2);
24396                    break;
24397                case 'right':
24398                    position = this.thumbOuterWidth - this.core.s.thumbWidth;
24399            }
24400            this.left = ((this.core.s.thumbWidth + this.core.s.thumbMargin) * index - 1) - position;
24401            if (this.left > (this.thumbTotalWidth - this.thumbOuterWidth)) {
24402                this.left = this.thumbTotalWidth - this.thumbOuterWidth;
24403            }
24404
24405            if (this.left < 0) {
24406                this.left = 0;
24407            }
24408
24409            if (this.core.lGalleryOn) {
24410                if (!$thumb.hasClass('on')) {
24411                    this.core.$outer.find('.lg-thumb').css('transition-duration', this.core.s.speed + 'ms');
24412                }
24413
24414                if (!this.core.doCss()) {
24415                    $thumb.animate({
24416                        left: -this.left + 'px'
24417                    }, this.core.s.speed);
24418                }
24419            } else {
24420                if (!this.core.doCss()) {
24421                    $thumb.css('left', -this.left + 'px');
24422                }
24423            }
24424
24425            this.setTranslate(this.left);
24426
24427        }
24428    };
24429
24430    // Enable thumbnail dragging and swiping
24431    Thumbnail.prototype.enableThumbDrag = function() {
24432
24433        var _this = this;
24434        var startCoords = 0;
24435        var endCoords = 0;
24436        var isDraging = false;
24437        var isMoved = false;
24438        var tempLeft = 0;
24439
24440        _this.$thumbOuter.addClass('lg-grab');
24441
24442        _this.core.$outer.find('.lg-thumb').on('mousedown.lg.thumb', function(e) {
24443            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
24444                // execute only on .lg-object
24445                e.preventDefault();
24446                startCoords = e.pageX;
24447                isDraging = true;
24448
24449                // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
24450                _this.core.$outer.scrollLeft += 1;
24451                _this.core.$outer.scrollLeft -= 1;
24452
24453                // *
24454                _this.thumbClickable = false;
24455                _this.$thumbOuter.removeClass('lg-grab').addClass('lg-grabbing');
24456            }
24457        });
24458
24459        $(window).on('mousemove.lg.thumb', function(e) {
24460            if (isDraging) {
24461                tempLeft = _this.left;
24462                isMoved = true;
24463                endCoords = e.pageX;
24464
24465                _this.$thumbOuter.addClass('lg-dragging');
24466
24467                tempLeft = tempLeft - (endCoords - startCoords);
24468
24469                if (tempLeft > (_this.thumbTotalWidth - _this.thumbOuterWidth)) {
24470                    tempLeft = _this.thumbTotalWidth - _this.thumbOuterWidth;
24471                }
24472
24473                if (tempLeft < 0) {
24474                    tempLeft = 0;
24475                }
24476
24477                // move current slide
24478                _this.setTranslate(tempLeft);
24479
24480            }
24481        });
24482
24483        $(window).on('mouseup.lg.thumb', function() {
24484            if (isMoved) {
24485                isMoved = false;
24486                _this.$thumbOuter.removeClass('lg-dragging');
24487
24488                _this.left = tempLeft;
24489
24490                if (Math.abs(endCoords - startCoords) < _this.core.s.swipeThreshold) {
24491                    _this.thumbClickable = true;
24492                }
24493
24494            } else {
24495                _this.thumbClickable = true;
24496            }
24497
24498            if (isDraging) {
24499                isDraging = false;
24500                _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab');
24501            }
24502        });
24503
24504    };
24505
24506    Thumbnail.prototype.enableThumbSwipe = function() {
24507        var _this = this;
24508        var startCoords = 0;
24509        var endCoords = 0;
24510        var isMoved = false;
24511        var tempLeft = 0;
24512
24513        _this.core.$outer.find('.lg-thumb').on('touchstart.lg', function(e) {
24514            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
24515                e.preventDefault();
24516                startCoords = e.originalEvent.targetTouches[0].pageX;
24517                _this.thumbClickable = false;
24518            }
24519        });
24520
24521        _this.core.$outer.find('.lg-thumb').on('touchmove.lg', function(e) {
24522            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
24523                e.preventDefault();
24524                endCoords = e.originalEvent.targetTouches[0].pageX;
24525                isMoved = true;
24526
24527                _this.$thumbOuter.addClass('lg-dragging');
24528
24529                tempLeft = _this.left;
24530
24531                tempLeft = tempLeft - (endCoords - startCoords);
24532
24533                if (tempLeft > (_this.thumbTotalWidth - _this.thumbOuterWidth)) {
24534                    tempLeft = _this.thumbTotalWidth - _this.thumbOuterWidth;
24535                }
24536
24537                if (tempLeft < 0) {
24538                    tempLeft = 0;
24539                }
24540
24541                // move current slide
24542                _this.setTranslate(tempLeft);
24543
24544            }
24545        });
24546
24547        _this.core.$outer.find('.lg-thumb').on('touchend.lg', function() {
24548            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {
24549
24550                if (isMoved) {
24551                    isMoved = false;
24552                    _this.$thumbOuter.removeClass('lg-dragging');
24553                    if (Math.abs(endCoords - startCoords) < _this.core.s.swipeThreshold) {
24554                        _this.thumbClickable = true;
24555                    }
24556
24557                    _this.left = tempLeft;
24558                } else {
24559                    _this.thumbClickable = true;
24560                }
24561            } else {
24562                _this.thumbClickable = true;
24563            }
24564        });
24565
24566    };
24567
24568    Thumbnail.prototype.toogle = function() {
24569        var _this = this;
24570        if (_this.core.s.toogleThumb) {
24571            _this.core.$outer.addClass('lg-can-toggle');
24572            _this.$thumbOuter.append('<span class="lg-toogle-thumb lg-icon"></span>');
24573            _this.core.$outer.find('.lg-toogle-thumb').on('click.lg', function() {
24574                _this.core.$outer.toggleClass('lg-thumb-open');
24575            });
24576        }
24577    };
24578
24579    Thumbnail.prototype.thumbkeyPress = function() {
24580        var _this = this;
24581        $(window).on('keydown.lg.thumb', function(e) {
24582            if (e.keyCode === 38) {
24583                e.preventDefault();
24584                _this.core.$outer.addClass('lg-thumb-open');
24585            } else if (e.keyCode === 40) {
24586                e.preventDefault();
24587                _this.core.$outer.removeClass('lg-thumb-open');
24588            }
24589        });
24590    };
24591
24592    Thumbnail.prototype.destroy = function() {
24593        if (this.core.s.thumbnail && this.core.$items.length > 1) {
24594            $(window).off('resize.lg.thumb orientationchange.lg.thumb keydown.lg.thumb');
24595            this.$thumbOuter.remove();
24596            this.core.$outer.removeClass('lg-has-thumb');
24597        }
24598    };
24599
24600    $.fn.lightGallery.modules.Thumbnail = Thumbnail;
24601
24602})();
24603
24604}));
24605
24606/*! lg-video - v1.1.0 - 2017-08-08
24607* http://sachinchoolur.github.io/lightGallery
24608* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
24609
24610(function (root, factory) {
24611  if (typeof define === 'function' && define.amd) {
24612    // AMD. Register as an anonymous module unless amdModuleId is set
24613    define(['jquery'], function (a0) {
24614      return (factory(a0));
24615    });
24616  } else if (typeof exports === 'object') {
24617    // Node. Does not work with strict CommonJS, but
24618    // only CommonJS-like environments that support module.exports,
24619    // like Node.
24620    module.exports = factory(require('jquery'));
24621  } else {
24622    factory(jQuery);
24623  }
24624}(this, function ($) {
24625
24626(function() {
24627
24628    'use strict';
24629
24630    var defaults = {
24631        videoMaxWidth: '855px',
24632        youtubePlayerParams: false,
24633        vimeoPlayerParams: false,
24634        dailymotionPlayerParams: false,
24635        vkPlayerParams: false,
vendor: 11,174 bytes, lines 24636-24914
24636        videojs: false,
24637        videojsOptions: {}
24638    };
24639
24640    var Video = function(element) {
24641
24642        this.core = $(element).data('lightGallery');
24643
24644        this.$el = $(element);
24645        this.core.s = $.extend({}, defaults, this.core.s);
24646        this.videoLoaded = false;
24647
24648        this.init();
24649
24650        return this;
24651    };
24652
24653    Video.prototype.init = function() {
24654        var _this = this;
24655
24656        // Event triggered when video url found without poster
24657        _this.core.$el.on('hasVideo.lg.tm', function(event, index, src, html) {
24658            _this.core.$slide.eq(index).find('.lg-video').append(_this.loadVideo(src, 'lg-object', true, index, html));
24659            if (html) {
24660                if (_this.core.s.videojs) {
24661                    try {
24662                        videojs(_this.core.$slide.eq(index).find('.lg-html5').get(0), _this.core.s.videojsOptions, function() {
24663                            if (!_this.videoLoaded) {
24664                                this.play();
24665                            }
24666                        });
24667                    } catch (e) {
24668                        console.error('Make sure you have included videojs');
24669                    }
24670                } else {
24671                    if(!_this.videoLoaded) {
24672                        _this.core.$slide.eq(index).find('.lg-html5').get(0).play();
24673                    }
24674                }
24675            }
24676        });
24677
24678        // Set max width for video
24679        _this.core.$el.on('onAferAppendSlide.lg.tm', function(event, index) {
24680            var $videoCont = _this.core.$slide.eq(index).find('.lg-video-cont');
24681            if (!$videoCont.hasClass('lg-has-iframe')) {
24682                $videoCont.css('max-width', _this.core.s.videoMaxWidth);
24683                _this.videoLoaded = true;
24684            }
24685        });
24686
24687        var loadOnClick = function($el) {
24688            // check slide has poster
24689            if ($el.find('.lg-object').hasClass('lg-has-poster') && $el.find('.lg-object').is(':visible')) {
24690
24691                // check already video element present
24692                if (!$el.hasClass('lg-has-video')) {
24693
24694                    $el.addClass('lg-video-playing lg-has-video');
24695
24696                    var _src;
24697                    var _html;
24698                    var _loadVideo = function(_src, _html) {
24699
24700                        $el.find('.lg-video').append(_this.loadVideo(_src, '', false, _this.core.index, _html));
24701
24702                        if (_html) {
24703                            if (_this.core.s.videojs) {
24704                                try {
24705                                    videojs(_this.core.$slide.eq(_this.core.index).find('.lg-html5').get(0), _this.core.s.videojsOptions, function() {
24706                                        this.play();
24707                                    });
24708                                } catch (e) {
24709                                    console.error('Make sure you have included videojs');
24710                                }
24711                            } else {
24712                                _this.core.$slide.eq(_this.core.index).find('.lg-html5').get(0).play();
24713                            }
24714                        }
24715
24716                    };
24717
24718                    if (_this.core.s.dynamic) {
24719
24720                        _src = _this.core.s.dynamicEl[_this.core.index].src;
24721                        _html = _this.core.s.dynamicEl[_this.core.index].html;
24722
24723                        _loadVideo(_src, _html);
24724
24725                    } else {
24726
24727                        _src = _this.core.$items.eq(_this.core.index).attr('href') || _this.core.$items.eq(_this.core.index).attr('data-src');
24728                        _html = _this.core.$items.eq(_this.core.index).attr('data-html');
24729
24730                        _loadVideo(_src, _html);
24731
24732                    }
24733
24734                    var $tempImg = $el.find('.lg-object');
24735                    $el.find('.lg-video').append($tempImg);
24736
24737                    // @todo loading icon for html5 videos also
24738                    // for showing the loading indicator while loading video
24739                    if (!$el.find('.lg-video-object').hasClass('lg-html5')) {
24740                        $el.removeClass('lg-complete');
24741                        $el.find('.lg-video-object').on('load.lg error.lg', function() {
24742                            $el.addClass('lg-complete');
24743                        });
24744                    }
24745
24746                } else {
24747
24748                    var youtubePlayer = $el.find('.lg-youtube').get(0);
24749                    var vimeoPlayer = $el.find('.lg-vimeo').get(0);
24750                    var dailymotionPlayer = $el.find('.lg-dailymotion').get(0);
24751                    var html5Player = $el.find('.lg-html5').get(0);
24752                    if (youtubePlayer) {
24753                        youtubePlayer.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*');
24754                    } else if (vimeoPlayer) {
24755                        try {
24756                            $f(vimeoPlayer).api('play');
24757                        } catch (e) {
24758                            console.error('Make sure you have included froogaloop2 js');
24759                        }
24760                    } else if (dailymotionPlayer) {
24761                        dailymotionPlayer.contentWindow.postMessage('play', '*');
24762
24763                    } else if (html5Player) {
24764                        if (_this.core.s.videojs) {
24765                            try {
24766                                videojs(html5Player).play();
24767                            } catch (e) {
24768                                console.error('Make sure you have included videojs');
24769                            }
24770                        } else {
24771                            html5Player.play();
24772                        }
24773                    }
24774
24775                    $el.addClass('lg-video-playing');
24776
24777                }
24778            }
24779        };
24780
24781        if (_this.core.doCss() && (_this.core.$items.length > 1) && (_this.core.s.enableSwipe || _this.core.s.enableDrag)) {
24782            _this.core.$el.on('onSlideClick.lg.tm', function() {
24783                var $el = _this.core.$slide.eq(_this.core.index);
24784                loadOnClick($el);
24785            });
24786        } else {
24787
24788            // For IE 9 and bellow
24789            _this.core.$slide.on('click.lg', function() {
24790                loadOnClick($(this));
24791            });
24792        }
24793
24794        _this.core.$el.on('onBeforeSlide.lg.tm', function(event, prevIndex, index) {
24795
24796            var $videoSlide = _this.core.$slide.eq(prevIndex);
24797            var youtubePlayer = $videoSlide.find('.lg-youtube').get(0);
24798            var vimeoPlayer = $videoSlide.find('.lg-vimeo').get(0);
24799            var dailymotionPlayer = $videoSlide.find('.lg-dailymotion').get(0);
24800            var vkPlayer = $videoSlide.find('.lg-vk').get(0);
24801            var html5Player = $videoSlide.find('.lg-html5').get(0);
24802            if (youtubePlayer) {
24803                youtubePlayer.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*');
24804            } else if (vimeoPlayer) {
24805                try {
24806                    $f(vimeoPlayer).api('pause');
24807                } catch (e) {
24808                    console.error('Make sure you have included froogaloop2 js');
24809                }
24810            } else if (dailymotionPlayer) {
24811                dailymotionPlayer.contentWindow.postMessage('pause', '*');
24812
24813            } else if (html5Player) {
24814                if (_this.core.s.videojs) {
24815                    try {
24816                        videojs(html5Player).pause();
24817                    } catch (e) {
24818                        console.error('Make sure you have included videojs');
24819                    }
24820                } else {
24821                    html5Player.pause();
24822                }
24823            } if (vkPlayer) {
24824                $(vkPlayer).attr('src', $(vkPlayer).attr('src').replace('&autoplay', '&noplay'));
24825            }
24826
24827            var _src;
24828            if (_this.core.s.dynamic) {
24829                _src = _this.core.s.dynamicEl[index].src;
24830            } else {
24831                _src = _this.core.$items.eq(index).attr('href') || _this.core.$items.eq(index).attr('data-src');
24832
24833            }
24834
24835            var _isVideo = _this.core.isVideo(_src, index) || {};
24836            if (_isVideo.youtube || _isVideo.vimeo || _isVideo.dailymotion || _isVideo.vk) {
24837                _this.core.$outer.addClass('lg-hide-download');
24838            }
24839
24840            //$videoSlide.addClass('lg-complete');
24841
24842        });
24843
24844        _this.core.$el.on('onAfterSlide.lg.tm', function(event, prevIndex) {
24845            _this.core.$slide.eq(prevIndex).removeClass('lg-video-playing');
24846        });
24847    };
24848
24849    Video.prototype.loadVideo = function(src, addClass, noposter, index, html) {
24850        var video = '';
24851        var autoplay = 1;
24852        var a = '';
24853        var isVideo = this.core.isVideo(src, index) || {};
24854
24855        // Enable autoplay for first video if poster doesn't exist
24856        if (noposter) {
24857            if (this.videoLoaded) {
24858                autoplay = 0;
24859            } else {
24860                autoplay = 1;
24861            }
24862        }
24863
24864        if (isVideo.youtube) {
24865
24866            a = '?wmode=opaque&autoplay=' + autoplay + '&enablejsapi=1';
24867            if (this.core.s.youtubePlayerParams) {
24868                a = a + '&' + $.param(this.core.s.youtubePlayerParams);
24869            }
24870
24871            video = '<iframe class="lg-video-object lg-youtube ' + addClass + '" width="560" height="315" src="//www.youtube.com/embed/' + isVideo.youtube[1] + a + '" frameborder="0" allowfullscreen></iframe>';
24872
24873        } else if (isVideo.vimeo) {
24874
24875            a = '?autoplay=' + autoplay + '&api=1';
24876            if (this.core.s.vimeoPlayerParams) {
24877                a = a + '&' + $.param(this.core.s.vimeoPlayerParams);
24878            }
24879
24880            video = '<iframe class="lg-video-object lg-vimeo ' + addClass + '" width="560" height="315"  src="//player.vimeo.com/video/' + isVideo.vimeo[1] + a + '" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';
24881
24882        } else if (isVideo.dailymotion) {
24883
24884            a = '?wmode=opaque&autoplay=' + autoplay + '&api=postMessage';
24885            if (this.core.s.dailymotionPlayerParams) {
24886                a = a + '&' + $.param(this.core.s.dailymotionPlayerParams);
24887            }
24888
24889            video = '<iframe class="lg-video-object lg-dailymotion ' + addClass + '" width="560" height="315" src="//www.dailymotion.com/embed/video/' + isVideo.dailymotion[1] + a + '" frameborder="0" allowfullscreen></iframe>';
24890
24891        } else if (isVideo.html5) {
24892            var fL = html.substring(0, 1);
24893            if (fL === '.' || fL === '#') {
24894                html = $(html).html();
24895            }
24896
24897            video = html;
24898
24899        } else if (isVideo.vk) {
24900
24901            a = '&autoplay=' + autoplay;
24902            if (this.core.s.vkPlayerParams) {
24903                a = a + '&' + $.param(this.core.s.vkPlayerParams);
24904            }
24905
24906            video = '<iframe class="lg-video-object lg-vk ' + addClass + '" width="560" height="315" src="http://vk.com/video_ext.php?' + isVideo.vk[1] + a + '" frameborder="0" allowfullscreen></iframe>';
24907
24908        }
24909
24910        return video;
24911    };
24912
24913    Video.prototype.destroy = function() {
24914        this.videoLoaded = false;
vendor: 11,365 bytes, lines 24915-25265
24915    };
24916
24917    $.fn.lightGallery.modules.video = Video;
24918
24919})();
24920
24921
24922}));
24923
24924/*! lg-zoom - v1.1.0 - 2017-08-08
24925* http://sachinchoolur.github.io/lightGallery
24926* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
24927
24928(function (root, factory) {
24929  if (typeof define === 'function' && define.amd) {
24930    // AMD. Register as an anonymous module unless amdModuleId is set
24931    define(['jquery'], function (a0) {
24932      return (factory(a0));
24933    });
24934  } else if (typeof exports === 'object') {
24935    // Node. Does not work with strict CommonJS, but
24936    // only CommonJS-like environments that support module.exports,
24937    // like Node.
24938    module.exports = factory(require('jquery'));
24939  } else {
24940    factory(jQuery);
24941  }
24942}(this, function ($) {
24943
24944(function() {
24945
24946    'use strict';
24947
24948    var getUseLeft = function() {
24949        var useLeft = false;
24950        var isChrome = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
24951        if (isChrome && parseInt(isChrome[2], 10) < 54) {
24952            useLeft = true;
24953        }
24954
24955        return useLeft;
24956    };
24957
24958    var defaults = {
24959        scale: 1,
24960        zoom: true,
24961        actualSize: true,
24962        enableZoomAfter: 300,
24963        useLeftForZoom: getUseLeft()
24964    };
24965
24966    var Zoom = function(element) {
24967
24968        this.core = $(element).data('lightGallery');
24969
24970        this.core.s = $.extend({}, defaults, this.core.s);
24971
24972        if (this.core.s.zoom && this.core.doCss()) {
24973            this.init();
24974
24975            // Store the zoomable timeout value just to clear it while closing
24976            this.zoomabletimeout = false;
24977
24978            // Set the initial value center
24979            this.pageX = $(window).width() / 2;
24980            this.pageY = ($(window).height() / 2) + $(window).scrollTop();
24981        }
24982
24983        return this;
24984    };
24985
24986    Zoom.prototype.init = function() {
24987
24988        var _this = this;
24989        var zoomIcons = '<span id="lg-zoom-in" class="lg-icon"></span><span id="lg-zoom-out" class="lg-icon"></span>';
24990
24991        if (_this.core.s.actualSize) {
24992            zoomIcons += '<span id="lg-actual-size" class="lg-icon"></span>';
24993        }
24994
24995        if (_this.core.s.useLeftForZoom) {
24996            _this.core.$outer.addClass('lg-use-left-for-zoom');
24997        } else {
24998            _this.core.$outer.addClass('lg-use-transition-for-zoom');
24999        }
25000
25001        this.core.$outer.find('.lg-toolbar').append(zoomIcons);
25002
25003        // Add zoomable class
25004        _this.core.$el.on('onSlideItemLoad.lg.tm.zoom', function(event, index, delay) {
25005
25006            // delay will be 0 except first time
25007            var _speed = _this.core.s.enableZoomAfter + delay;
25008
25009            // set _speed value 0 if gallery opened from direct url and if it is first slide
25010            if ($('body').hasClass('lg-from-hash') && delay) {
25011
25012                // will execute only once
25013                _speed = 0;
25014            } else {
25015
25016                // Remove lg-from-hash to enable starting animation.
25017                $('body').removeClass('lg-from-hash');
25018            }
25019
25020            _this.zoomabletimeout = setTimeout(function() {
25021                _this.core.$slide.eq(index).addClass('lg-zoomable');
25022            }, _speed + 30);
25023        });
25024
25025        var scale = 1;
25026        /**
25027         * @desc Image zoom
25028         * Translate the wrap and scale the image to get better user experience
25029         *
25030         * @param {String} scaleVal - Zoom decrement/increment value
25031         */
25032        var zoom = function(scaleVal) {
25033
25034            var $image = _this.core.$outer.find('.lg-current .lg-image');
25035            var _x;
25036            var _y;
25037
25038            // Find offset manually to avoid issue after zoom
25039            var offsetX = ($(window).width() - $image.prop('offsetWidth')) / 2;
25040            var offsetY = (($(window).height() - $image.prop('offsetHeight')) / 2) + $(window).scrollTop();
25041
25042            _x = _this.pageX - offsetX;
25043            _y = _this.pageY - offsetY;
25044
25045            var x = (scaleVal - 1) * (_x);
25046            var y = (scaleVal - 1) * (_y);
25047
25048            $image.css('transform', 'scale3d(' + scaleVal + ', ' + scaleVal + ', 1)').attr('data-scale', scaleVal);
25049
25050            if (_this.core.s.useLeftForZoom) {
25051                $image.parent().css({
25052                    left: -x + 'px',
25053                    top: -y + 'px'
25054                }).attr('data-x', x).attr('data-y', y);
25055            } else {
25056                $image.parent().css('transform', 'translate3d(-' + x + 'px, -' + y + 'px, 0)').attr('data-x', x).attr('data-y', y);
25057            }
25058        };
25059
25060        var callScale = function() {
25061            if (scale > 1) {
25062                _this.core.$outer.addClass('lg-zoomed');
25063            } else {
25064                _this.resetZoom();
25065            }
25066
25067            if (scale < 1) {
25068                scale = 1;
25069            }
25070
25071            zoom(scale);
25072        };
25073
25074        var actualSize = function(event, $image, index, fromIcon) {
25075            var w = $image.prop('offsetWidth');
25076            var nw;
25077            if (_this.core.s.dynamic) {
25078                nw = _this.core.s.dynamicEl[index].width || $image[0].naturalWidth || w;
25079            } else {
25080                nw = _this.core.$items.eq(index).attr('data-width') || $image[0].naturalWidth || w;
25081            }
25082
25083            var _scale;
25084
25085            if (_this.core.$outer.hasClass('lg-zoomed')) {
25086                scale = 1;
25087            } else {
25088                if (nw > w) {
25089                    _scale = nw / w;
25090                    scale = _scale || 2;
25091                }
25092            }
25093
25094            if (fromIcon) {
25095                _this.pageX = $(window).width() / 2;
25096                _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
25097            } else {
25098                _this.pageX = event.pageX || event.originalEvent.targetTouches[0].pageX;
25099                _this.pageY = event.pageY || event.originalEvent.targetTouches[0].pageY;
25100            }
25101
25102            callScale();
25103            setTimeout(function() {
25104                _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
25105            }, 10);
25106        };
25107
25108        var tapped = false;
25109
25110        // event triggered after appending slide content
25111        _this.core.$el.on('onAferAppendSlide.lg.tm.zoom', function(event, index) {
25112
25113            // Get the current element
25114            var $image = _this.core.$slide.eq(index).find('.lg-image');
25115
25116            $image.on('dblclick', function(event) {
25117                actualSize(event, $image, index);
25118            });
25119
25120            $image.on('touchstart', function(event) {
25121                if (!tapped) {
25122                    tapped = setTimeout(function() {
25123                        tapped = null;
25124                    }, 300);
25125                } else {
25126                    clearTimeout(tapped);
25127                    tapped = null;
25128                    actualSize(event, $image, index);
25129                }
25130
25131                event.preventDefault();
25132            });
25133
25134        });
25135
25136        // Update zoom on resize and orientationchange
25137        $(window).on('resize.lg.zoom scroll.lg.zoom orientationchange.lg.zoom', function() {
25138            _this.pageX = $(window).width() / 2;
25139            _this.pageY = ($(window).height() / 2) + $(window).scrollTop();
25140            zoom(scale);
25141        });
25142
25143        $('#lg-zoom-out').on('click.lg', function() {
25144            if (_this.core.$outer.find('.lg-current .lg-image').length) {
25145                scale -= _this.core.s.scale;
25146                callScale();
25147            }
25148        });
25149
25150        $('#lg-zoom-in').on('click.lg', function() {
25151            if (_this.core.$outer.find('.lg-current .lg-image').length) {
25152                scale += _this.core.s.scale;
25153                callScale();
25154            }
25155        });
25156
25157        $('#lg-actual-size').on('click.lg', function(event) {
25158            actualSize(event, _this.core.$slide.eq(_this.core.index).find('.lg-image'), _this.core.index, true);
25159        });
25160
25161        // Reset zoom on slide change
25162        _this.core.$el.on('onBeforeSlide.lg.tm', function() {
25163            scale = 1;
25164            _this.resetZoom();
25165        });
25166
25167        // Drag option after zoom
25168        _this.zoomDrag();
25169
25170        _this.zoomSwipe();
25171
25172    };
25173
25174    // Reset zoom effect
25175    Zoom.prototype.resetZoom = function() {
25176        this.core.$outer.removeClass('lg-zoomed');
25177        this.core.$slide.find('.lg-img-wrap').removeAttr('style data-x data-y');
25178        this.core.$slide.find('.lg-image').removeAttr('style data-scale');
25179
25180        // Reset pagx pagy values to center
25181        this.pageX = $(window).width() / 2;
25182        this.pageY = ($(window).height() / 2) + $(window).scrollTop();
25183    };
25184
25185    Zoom.prototype.zoomSwipe = function() {
25186        var _this = this;
25187        var startCoords = {};
25188        var endCoords = {};
25189        var isMoved = false;
25190
25191        // Allow x direction drag
25192        var allowX = false;
25193
25194        // Allow Y direction drag
25195        var allowY = false;
25196
25197        _this.core.$slide.on('touchstart.lg', function(e) {
25198
25199            if (_this.core.$outer.hasClass('lg-zoomed')) {
25200                var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
25201
25202                allowY = $image.prop('offsetHeight') * $image.attr('data-scale') > _this.core.$outer.find('.lg').height();
25203                allowX = $image.prop('offsetWidth') * $image.attr('data-scale') > _this.core.$outer.find('.lg').width();
25204                if ((allowX || allowY)) {
25205                    e.preventDefault();
25206                    startCoords = {
25207                        x: e.originalEvent.targetTouches[0].pageX,
25208                        y: e.originalEvent.targetTouches[0].pageY
25209                    };
25210                }
25211            }
25212
25213        });
25214
25215        _this.core.$slide.on('touchmove.lg', function(e) {
25216
25217            if (_this.core.$outer.hasClass('lg-zoomed')) {
25218
25219                var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
25220                var distanceX;
25221                var distanceY;
25222
25223                e.preventDefault();
25224                isMoved = true;
25225
25226                endCoords = {
25227                    x: e.originalEvent.targetTouches[0].pageX,
25228                    y: e.originalEvent.targetTouches[0].pageY
25229                };
25230
25231                // reset opacity and transition duration
25232                _this.core.$outer.addClass('lg-zoom-dragging');
25233
25234                if (allowY) {
25235                    distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
25236                } else {
25237                    distanceY = -Math.abs(_$el.attr('data-y'));
25238                }
25239
25240                if (allowX) {
25241                    distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
25242                } else {
25243                    distanceX = -Math.abs(_$el.attr('data-x'));
25244                }
25245
25246                if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
25247
25248                    if (_this.core.s.useLeftForZoom) {
25249                        _$el.css({
25250                            left: distanceX + 'px',
25251                            top: distanceY + 'px'
25252                        });
25253                    } else {
25254                        _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
25255                    }
25256                }
25257
25258            }
25259
25260        });
25261
25262        _this.core.$slide.on('touchend.lg', function() {
25263            if (_this.core.$outer.hasClass('lg-zoomed')) {
25264                if (isMoved) {
25265                    isMoved = false;
25266                    _this.core.$outer.removeClass('lg-zoom-dragging');
25267                    _this.touchendZoom(startCoords, endCoords, allowX, allowY);
25268
25269                }
25270            }
25271        });
25272
25273    };
25274
25275    Zoom.prototype.zoomDrag = function() {
25276
25277        var _this = this;
25278        var startCoords = {};
25279        var endCoords = {};
25280        var isDraging = false;
25281        var isMoved = false;
25282
25283        // Allow x direction drag
25284        var allowX = false;
25285
25286        // Allow Y direction drag
25287        var allowY = false;
25288
25289        _this.core.$slide.on('mousedown.lg.zoom', function(e) {
25290
25291            // execute only on .lg-object
25292            var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
25293
25294            allowY = $image.prop('offsetHeight') * $image.attr('data-scale') > _this.core.$outer.find('.lg').height();
25295            allowX = $image.prop('offsetWidth') * $image.attr('data-scale') > _this.core.$outer.find('.lg').width();
25296
25297            if (_this.core.$outer.hasClass('lg-zoomed')) {
25298                if ($(e.target).hasClass('lg-object') && (allowX || allowY)) {
25299                    e.preventDefault();
25300                    startCoords = {
25301                        x: e.pageX,
25302                        y: e.pageY
25303                    };
25304
25305                    isDraging = true;
25306
25307                    // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723
25308                    _this.core.$outer.scrollLeft += 1;
25309                    _this.core.$outer.scrollLeft -= 1;
25310
25311                    _this.core.$outer.removeClass('lg-grab').addClass('lg-grabbing');
25312                }
25313            }
25314        });
25315
25316        $(window).on('mousemove.lg.zoom', function(e) {
25317            if (isDraging) {
25318                var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
25319                var distanceX;
25320                var distanceY;
25321
25322                isMoved = true;
25323                endCoords = {
25324                    x: e.pageX,
25325                    y: e.pageY
25326                };
25327
25328                // reset opacity and transition duration
25329                _this.core.$outer.addClass('lg-zoom-dragging');
25330
25331                if (allowY) {
25332                    distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
25333                } else {
25334                    distanceY = -Math.abs(_$el.attr('data-y'));
25335                }
25336
25337                if (allowX) {
25338                    distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
25339                } else {
25340                    distanceX = -Math.abs(_$el.attr('data-x'));
25341                }
25342
25343                if (_this.core.s.useLeftForZoom) {
25344                    _$el.css({
25345                        left: distanceX + 'px',
25346                        top: distanceY + 'px'
25347                    });
25348                } else {
25349                    _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
25350                }
25351            }
25352        });
25353
25354        $(window).on('mouseup.lg.zoom', function(e) {
25355
25356            if (isDraging) {
25357                isDraging = false;
25358                _this.core.$outer.removeClass('lg-zoom-dragging');
25359
25360                // Fix for chrome mouse move on click
25361                if (isMoved && ((startCoords.x !== endCoords.x) || (startCoords.y !== endCoords.y))) {
25362                    endCoords = {
25363                        x: e.pageX,
25364                        y: e.pageY
25365                    };
25366                    _this.touchendZoom(startCoords, endCoords, allowX, allowY);
25367
25368                }
25369
25370                isMoved = false;
25371            }
25372
25373            _this.core.$outer.removeClass('lg-grabbing').addClass('lg-grab');
25374
25375        });
25376    };
25377
25378    Zoom.prototype.touchendZoom = function(startCoords, endCoords, allowX, allowY) {
25379
25380        var _this = this;
25381        var _$el = _this.core.$slide.eq(_this.core.index).find('.lg-img-wrap');
25382        var $image = _this.core.$slide.eq(_this.core.index).find('.lg-object');
25383        var distanceX = (-Math.abs(_$el.attr('data-x'))) + (endCoords.x - startCoords.x);
25384        var distanceY = (-Math.abs(_$el.attr('data-y'))) + (endCoords.y - startCoords.y);
25385        var minY = (_this.core.$outer.find('.lg').height() - $image.prop('offsetHeight')) / 2;
25386        var maxY = Math.abs(($image.prop('offsetHeight') * Math.abs($image.attr('data-scale'))) - _this.core.$outer.find('.lg').height() + minY);
25387        var minX = (_this.core.$outer.find('.lg').width() - $image.prop('offsetWidth')) / 2;
25388        var maxX = Math.abs(($image.prop('offsetWidth') * Math.abs($image.attr('data-scale'))) - _this.core.$outer.find('.lg').width() + minX);
25389
25390        if ((Math.abs(endCoords.x - startCoords.x) > 15) || (Math.abs(endCoords.y - startCoords.y) > 15)) {
25391            if (allowY) {
25392                if (distanceY <= -maxY) {
25393                    distanceY = -maxY;
25394                } else if (distanceY >= -minY) {
25395                    distanceY = -minY;
25396                }
25397            }
25398
25399            if (allowX) {
25400                if (distanceX <= -maxX) {
25401                    distanceX = -maxX;
25402                } else if (distanceX >= -minX) {
25403                    distanceX = -minX;
25404                }
25405            }
25406
25407            if (allowY) {
25408                _$el.attr('data-y', Math.abs(distanceY));
25409            } else {
25410                distanceY = -Math.abs(_$el.attr('data-y'));
25411            }
25412
25413            if (allowX) {
25414                _$el.attr('data-x', Math.abs(distanceX));
25415            } else {
25416                distanceX = -Math.abs(_$el.attr('data-x'));
25417            }
25418
25419            if (_this.core.s.useLeftForZoom) {
25420                _$el.css({
25421                    left: distanceX + 'px',
25422                    top: distanceY + 'px'
25423                });
25424            } else {
25425                _$el.css('transform', 'translate3d(' + distanceX + 'px, ' + distanceY + 'px, 0)');
25426            }
25427
25428        }
25429    };
25430
25431    Zoom.prototype.destroy = function() {
25432
25433        var _this = this;
25434
25435        // Unbind all events added by lightGallery zoom plugin
25436        _this.core.$el.off('.lg.zoom');
25437        $(window).off('.lg.zoom');
25438        _this.core.$slide.off('.lg.zoom');
25439        _this.core.$el.off('.lg.tm.zoom');
25440        _this.resetZoom();
25441        clearTimeout(_this.zoomabletimeout);
25442        _this.zoomabletimeout = false;
25443    };
25444
25445    $.fn.lightGallery.modules.zoom = Zoom;
25446
25447})();
25448
25449
25450}));
25451
25452/*! lg-hash - v1.0.2 - 2017-06-03
25453* http://sachinchoolur.github.io/lightGallery
25454* Copyright (c) 2017 Sachin N; Licensed GPLv3 */
25455
25456(function (root, factory) {
25457  if (typeof define === 'function' && define.amd) {
25458    // AMD. Register as an anonymous module unless amdModuleId is set
25459    define(['jquery'], function (a0) {
25460      return (factory(a0));
25461    });
25462  } else if (typeof exports === 'object') {
25463    // Node. Does not work with strict CommonJS, but
25464    // only CommonJS-like environments that support module.exports,
25465    // like Node.
25466    module.exports = factory(require('jquery'));
25467  } else {
25468    factory(jQuery);
25469  }
25470}(this, function ($) {
25471
25472(function() {
25473
25474    'use strict';
25475
25476    var defaults = {
25477        hash: true
25478    };
25479
25480    var Hash = function(element) {
25481
25482        this.core = $(element).data('lightGallery');
25483
25484        this.core.s = $.extend({}, defaults, this.core.s);
25485
25486        if (this.core.s.hash) {
25487            this.oldHash = window.location.hash;
25488            this.init();
25489        }
25490
25491        return this;
25492    };
25493
25494    Hash.prototype.init = function() {
25495        var _this = this;
25496        var _hash;
25497
25498        // Change hash value on after each slide transition
25499        _this.core.$el.on('onAfterSlide.lg.tm', function(event, prevIndex, index) {
25500            if (history.replaceState) {
25501                history.replaceState(null, null, '#lg=' + _this.core.s.galleryId + '&slide=' + index);
25502            } else {
25503                window.location.hash = 'lg=' + _this.core.s.galleryId + '&slide=' + index;
25504            }
25505        });
25506
25507        // Listen hash change and change the slide according to slide value
25508        $(window).on('hashchange.lg.hash', function() {
25509            _hash = window.location.hash;
25510            var _idx = parseInt(_hash.split('&slide=')[1], 10);
25511
25512            // it galleryId doesn't exist in the url close the gallery
25513            if ((_hash.indexOf('lg=' + _this.core.s.galleryId) > -1)) {
25514                _this.core.slide(_idx, false, false);
25515            } else if (_this.core.lGalleryOn) {
25516                _this.core.destroy();
25517            }
25518
25519        });
25520    };
25521
25522    Hash.prototype.destroy = function() {
25523
25524        if (!this.core.s.hash) {
25525            return;
25526        }
25527
25528        // Reset to old hash value
25529        if (this.oldHash && this.oldHash.indexOf('lg=' + this.core.s.galleryId) < 0) {
25530            if (history.replaceState) {
25531                history.replaceState(null, null, this.oldHash);
25532            } else {
25533                window.location.hash = this.oldHash;
25534            }
25535        } else {
25536            if (history.replaceState) {
25537                history.replaceState(null, document.title, window.location.pathname + window.location.search);
25538            } else {
25539                window.location.hash = '';
25540            }
25541        }
25542
25543        this.core.$el.off('.lg.hash');
25544
25545    };
25546
25547    $.fn.lightGallery.modules.hash = Hash;
25548
25549})();
25550
25551}));
25552
25553/*! lg-share - v1.0.2 - 2016-11-26
25554* http://sachinchoolur.github.io/lightGallery
25555* Copyright (c) 2016 Sachin N; Licensed GPLv3 */
25556
25557(function (root, factory) {
25558  if (typeof define === 'function' && define.amd) {
25559    // AMD. Register as an anonymous module unless amdModuleId is set
25560    define(['jquery'], function (a0) {
25561      return (factory(a0));
25562    });
25563  } else if (typeof exports === 'object') {
25564    // Node. Does not work with strict CommonJS, but
25565    // only CommonJS-like environments that support module.exports,
25566    // like Node.
25567    module.exports = factory(require('jquery'));
25568  } else {
25569    factory(jQuery);
25570  }
25571}(this, function ($) {
25572
25573(function() {
25574
25575    'use strict';
25576
25577    var defaults = {
25578        share: true,
25579        facebook: true,
25580        facebookDropdownText: 'Facebook',
25581        twitter: true,
25582        twitterDropdownText: 'Twitter',
25583        googlePlus: true,
25584        googlePlusDropdownText: 'GooglePlus',
25585        pinterest: true,
25586        pinterestDropdownText: 'Pinterest'
25587    };
25588
25589    var Share = function(element) {
25590
25591        this.core = $(element).data('lightGallery');
25592
25593        this.core.s = $.extend({}, defaults, this.core.s);
25594        if (this.core.s.share) {
25595            this.init();
25596        }
25597
25598        return this;
25599    };
25600
25601    Share.prototype.init = function() {
25602        var _this = this;
25603        var shareHtml = '<span id="lg-share" class="lg-icon">' +
25604            '<ul class="lg-dropdown" style="position: absolute;">';
25605        shareHtml += _this.core.s.facebook ? '<li><a id="lg-share-facebook" target="_blank"><span class="lg-icon"></span><span class="lg-dropdown-text">' + this.core.s.facebookDropdownText + '</span></a></li>' : '';
25606        shareHtml += _this.core.s.twitter ? '<li><a id="lg-share-twitter" target="_blank"><span class="lg-icon"></span><span class="lg-dropdown-text">' + this.core.s.twitterDropdownText + '</span></a></li>' : '';
25607        shareHtml += _this.core.s.googlePlus ? '<li><a id="lg-share-googleplus" target="_blank"><span class="lg-icon"></span><span class="lg-dropdown-text">' + this.core.s.googlePlusDropdownText + '</span></a></li>' : '';
25608        shareHtml += _this.core.s.pinterest ? '<li><a id="lg-share-pinterest" target="_blank"><span class="lg-icon"></span><span class="lg-dropdown-text">' + this.core.s.pinterestDropdownText + '</span></a></li>' : '';
25609        shareHtml += '</ul></span>';
25610
25611        this.core.$outer.find('.lg-toolbar').append(shareHtml);
25612        this.core.$outer.find('.lg').append('<div id="lg-dropdown-overlay"></div>');
25613        $('#lg-share').on('click.lg', function(){
25614            _this.core.$outer.toggleClass('lg-dropdown-active');
25615        });
25616
25617        $('#lg-dropdown-overlay').on('click.lg', function(){
25618            _this.core.$outer.removeClass('lg-dropdown-active');
25619        });
25620
25621        _this.core.$el.on('onAfterSlide.lg.tm', function(event, prevIndex, index) {
25622
25623            setTimeout(function() { 
25624                $('#lg-share-facebook').attr('href', 'https://www.facebook.com/sharer/sharer.php?u=' + (encodeURIComponent(_this.core.$items.eq(index).attr('data-facebook-share-url') || window.location.href)));
25625
25626                $('#lg-share-twitter').attr('href', 'https://twitter.com/intent/tweet?text=' + _this.core.$items.eq(index).attr('data-tweet-text') + '&url=' + (encodeURIComponent(_this.core.$items.eq(index).attr('data-twitter-share-url') || window.location.href)));
25627
25628                $('#lg-share-googleplus').attr('href', 'https://plus.google.com/share?url=' + (encodeURIComponent(_this.core.$items.eq(index).attr('data-googleplus-share-url') || window.location.href)));
25629
25630                $('#lg-share-pinterest').attr('href', 'http://www.pinterest.com/pin/create/button/?url=' + (encodeURIComponent(_this.core.$items.eq(index).attr('data-pinterest-share-url') || window.location.href)) + '&media=' + encodeURIComponent(_this.core.$items.eq(index).attr('href') || _this.core.$items.eq(index).attr('data-src')) + '&description=' + _this.core.$items.eq(index).attr('data-pinterest-text'));
25631
25632            }, 100);
25633        });
25634    };
25635
25636    Share.prototype.destroy = function() {
25637
25638    };
25639
25640    $.fn.lightGallery.modules.share = Share;
25641
25642})();
25643
25644
25645
25646}));
25647
25648/* End */
25649;
25650; /* Start:"a:4:{s:4:"full";s:90:"/bitrix/templates/universe_s5/plugins/jquery.scrollbar/jquery.scrollbar.
25650js?167687089432171";s:6:"source";s:74:"/bitrix/templates/universe_s5/plugins/jquery.scrollbar/jquery.scrollbar.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
25651/**
25652 * jQuery CSS Customizable Scrollbar
25653 *
25654 * Copyright 2015, Yuriy Khabarov
25655 * Dual licensed under the MIT or GPL Version 2 licenses.
25656 *
25657 * If you found bug, please contact me via email <[email protected]>
25658 *
25659 * @author Yuriy Khabarov aka Gromo
25660 * @version 0.2.10
25661 * @url https://github.com/gromo/jquery.scrollbar/
25662 *
25663 */
25664;
25665(function (root, factory) {
25666    if (typeof define === 'function' && define.amd) {
25667        define(['jquery'], factory);
25668    } else {
25669        factory(root.jQuery);
25670    }
25671}(this, function ($) {
25672    'use strict';
25673
25674    // init flags & variables
25675    var debug = false;
25676
25677    var browser = {
25678        data: {
25679            index: 0,
25680            name: 'scrollbar'
25681        },
25682        macosx: /mac/i.test(navigator.platform),
25683        mobile: /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent),
25684        overlay: null,
25685        scroll: null,
25686        scrolls: [],
25687        webkit: /webkit/i.test(navigator.userAgent) && !/edge\/\d+/i.test(navigator.userAgent)
25688    };
25689
25690    browser.scrolls.add = function (instance) {
25691        this.remove(instance).push(instance);
25692    };
25693    browser.scrolls.remove = function (instance) {
25694        while ($.inArray(instance, this) >= 0) {
25695            this.splice($.inArray(instance, this), 1);
25696        }
25697        return this;
25698    };
25699
25700    var defaults = {
25701        "autoScrollSize": true,     // automatically calculate scrollsize
25702        "autoUpdate": true,         // update scrollbar if content/container size changed
25703        "debug": false,             // debug mode
25704        "disableBodyScroll": false, // disable body scroll if mouse over container
25705        "duration": 200,            // scroll animate duration in ms
25706        "ignoreMobile": false,      // ignore mobile devices
25707        "ignoreOverlay": false,     // ignore browsers with overlay scrollbars (mobile, MacOS)
25708        "scrollStep": 30,           // scroll step for scrollbar arrows
25709        "showArrows": false,        // add class to show arrows
25710        "stepScrolling": true,      // when scrolling to scrollbar mousedown position
25711
25712        "scrollx": null,            // horizontal scroll element
25713        "scrolly": null,            // vertical scroll element
25714
25715        "onDestroy": null,          // callback function on destroy,
25716        "onInit": null,             // callback function on first initialization
25717        "onScroll": null,           // callback function on content scrolling
25718        "onUpdate": null            // callback function on init/resize (before scrollbar size calculation)
25719    };
25720
25721
25722    var BaseScrollbar = function (container) {
25723
25724        if (!browser.scroll) {
25725            browser.overlay = isScrollOverlaysContent();
25726            browser.scroll = getBrowserScrollSize();
25727            updateScrollbars();
25728
25729            $(window).resize(function () {
25730                var forceUpdate = false;
25731                if (browser.scroll && (browser.scroll.height || browser.scroll.width)) {
25732                    var scroll = getBrowserScrollSize();
25733                    if (scroll.height !== browser.scroll.height || scroll.width !== browser.scroll.width) {
25734                        browser.scroll = scroll;
25735                        forceUpdate = true; // handle page zoom
25736                    }
25737                }
25738                updateScrollbars(forceUpdate);
25739            });
25740        }
25741
25742        this.container = container;
25743        this.namespace = '.scrollbar_' + browser.data.index++;
25744        this.options = $.extend({}, defaults, window.jQueryScrollbarOptions || {});
25745        this.scrollTo = null;
25746        this.scrollx = {};
25747        this.scrolly = {};
25748
25749        container.data(browser.data.name, this);
25750        browser.scrolls.add(this);
25751    };
25752
25753    BaseScrollbar.prototype = {
25754
25755        destroy: function () {
25756
25757            if (!this.wrapper) {
25758                return;
25759            }
25760
25761            this.container.removeData(browser.data.name);
25762            browser.scrolls.remove(this);
25763
25764            // init variables
25765            var scrollLeft = this.container.scrollLeft();
25766            var scrollTop = this.container.scrollTop();
25767
25768            this.container.insertBefore(this.wrapper).css({
25769                "height": "",
25770                "margin": "",
25771                "max-height": ""
25772            })
25773                .removeClass('scroll-content scroll-scrollx_visible scroll-scrolly_visible')
25774                .off(this.namespace)
25775                .scrollLeft(scrollLeft)
25776                .scrollTop(scrollTop);
25777
25778            this.scrollx.scroll.removeClass('scroll-scrollx_visible').find('div').andSelf().off(this.namespace);
25779            this.scrolly.scroll.removeClass('scroll-scrolly_visible').find('div').andSelf().off(this.namespace);
25780
25781            this.wrapper.remove();
25782
25783            $(document).add('body').off(this.namespace);
25784
25785            if ($.isFunction(this.options.onDestroy)){
25786                this.options.onDestroy.apply(this, [this.container]);
25787            }
25788        },
25789        init: function (options) {
25790
25791            // init variables
25792            var S = this,
25793                c = this.container,
25794                cw = this.containerWrapper || c,
25795                namespace = this.namespace,
25796                o = $.extend(this.options, options || {}),
25797                s = {x: this.scrollx, y: this.scrolly},
25798                w = this.wrapper;
25799
25800            var initScroll = {
25801                "scrollLeft": c.scrollLeft(),
25802                "scrollTop": c.scrollTop()
25803            };
25804
25805            // do not init if in ignorable browser
25806            if ((browser.mobile && o.ignoreMobile)
25807                || (browser.overlay && o.ignoreOverlay)
25808                || (browser.macosx && !browser.webkit) // still required to ignore nonWebKit browsers on Mac
25809                ) {
25810                return false;
25811            }
25812
25813            // init scroll container
25814            if (!w) {
25815                this.wrapper = w = $('<div>').addClass('scroll-wrapper').addClass(c.attr('class'))
25816                    .css('position', c.css('position') == 'absolute' ? 'absolute' : 'relative')
25817                    .insertBefore(c).append(c);
25818
25819                if (c.is('textarea')) {
25820                    this.containerWrapper = cw = $('<div>').insertBefore(c).append(c);
25821                    w.addClass('scroll-textarea');
25822                }
25823
25824                cw.addClass('scroll-content').css({
25825                    "height": "auto",
25826                    "margin-bottom": browser.scroll.height * -1 + 'px',
25827                    "margin-right": browser.scroll.width * -1 + 'px',
25828                    "max-height": ""
25829                });
25830
25831                c.on('scroll' + namespace, function (event) {
25832                    if ($.isFunction(o.onScroll)) {
25833                        o.onScroll.call(S, {
25834                            "maxScroll": s.y.maxScrollOffset,
25835                            "scroll": c.scrollTop(),
25836                            "size": s.y.size,
25837                            "visible": s.y.visible
25838                        }, {
25839                            "maxScroll": s.x.maxScrollOffset,
25840                            "scroll": c.scrollLeft(),
25841                            "size": s.x.size,
25842                            "visible": s.x.visible
25843                        });
25844                    }
25845                    s.x.isVisible && s.x.scroll.bar.css('left', c.scrollLeft() * s.x.kx + 'px');
25846                    s.y.isVisible && s.y.scroll.bar.css('top', c.scrollTop() * s.y.kx + 'px');
25847                });
25848
25849                /* prevent native scrollbars to be visible on #anchor click */
25850                w.on('scroll' + namespace, function () {
25851                    w.scrollTop(0).scrollLeft(0);
25852                });
25853
25854                if (o.disableBodyScroll) {
25855                    var handleMouseScroll = function (event) {
25856                        isVerticalScroll(event) ?
25857                            s.y.isVisible && s.y.mousewheel(event) :
25858                            s.x.isVisible && s.x.mousewheel(event);
25859                    };
25860                    w.on('MozMousePixelScroll' + namespace, handleMouseScroll);
25861                    w.on('mousewheel' + namespace, handleMouseScroll);
25862
25863                    if (browser.mobile) {
25864                        w.on('touchstart' + namespace, function (event) {
25865                            var touch = event.originalEvent.touches && event.originalEvent.touches[0] || event;
25866                            var originalTouch = {
25867                                "pageX": touch.pageX,
25868                                "pageY": touch.pageY
25869                            };
25870                            var originalScroll = {
25871                                "left": c.scrollLeft(),
25872                                "top": c.scrollTop()
25873                            };
25874                            $(document).on('touchmove' + namespace, function (event) {
25875                                var touch = event.originalEvent.targetTouches && event.originalEvent.targetTouches[0] || event;
25876                                c.scrollLeft(originalScroll.left + originalTouch.pageX - touch.pageX);
25877                                c.scrollTop(originalScroll.top + originalTouch.pageY - touch.pageY);
25878                                event.preventDefault();
25879                            });
25880                            $(document).on('touchend' + namespace, function () {
25881                                $(document).off(namespace);
25882                            });
25883                        });
25884                    }
25885                }
25886                if ($.isFunction(o.onInit)){
25887                    o.onInit.apply(this, [c]);
25888                }
25889            } else {
25890                cw.css({
25891                    "height": "auto",
25892                    "margin-bottom": browser.scroll.height * -1 + 'px',
25893                    "margin-right": browser.scroll.width * -1 + 'px',
25894                    "max-height": ""
25895                });
25896            }
25897
25898            // init scrollbars & recalculate sizes
25899            $.each(s, function (d, scrollx) {
25900
25901                var scrollCallback = null;
25902                var scrollForward = 1;
25903                var scrollOffset = (d === 'x') ? 'scrollLeft' : 'scrollTop';
25904                var scrollStep = o.scrollStep;
25905                var scrollTo = function () {
25906                    var currentOffset = c[scrollOffset]();
25907                    c[scrollOffset](currentOffset + scrollStep);
25908                    if (scrollForward == 1 && (currentOffset + scrollStep) >= scrollToValue)
25909                        currentOffset = c[scrollOffset]();
25910                    if (scrollForward == -1 && (currentOffset + scrollStep) <= scrollToValue)
25911                        currentOffset = c[scrollOffset]();
25912                    if (c[scrollOffset]() == currentOffset && scrollCallback) {
25913                        scrollCallback();
25914                    }
25915                }
25916                var scrollToValue = 0;
25917
25918                if (!scrollx.scroll) {
25919
25920                    scrollx.scroll = S._getScroll(o['scroll' + d]).addClass('scroll-' + d);
25921
25922                    if(o.showArrows){
25923                        scrollx.scroll.addClass('scroll-element_arrows_visible');
25924                    }
25925
25926                    scrollx.mousewheel = function (event) {
25927
25928                        if (!scrollx.isVisible || (d === 'x' && isVerticalScroll(event))) {
25929                            return true;
25930                        }
25931                        if (d === 'y' && !isVerticalScroll(event)) {
25932                            s.x.mousewheel(event);
25933                            return true;
25934                        }
25935
25936                        var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
25937                        var maxScrollValue = scrollx.size - scrollx.visible - scrollx.offset;
25938
25939                        if ((delta > 0 && scrollToValue < maxScrollValue) || (delta < 0 && scrollToValue > 0)) {
25940                            scrollToValue = scrollToValue + delta;
25941                            if (scrollToValue < 0)
25942                                scrollToValue = 0;
25943                            if (scrollToValue > maxScrollValue)
25944                                scrollToValue = maxScrollValue;
25945
25946                            S.scrollTo = S.scrollTo || {};
25947                            S.scrollTo[scrollOffset] = scrollToValue;
25948                            setTimeout(function () {
25949                                if (S.scrollTo) {
25950                                    c.stop().animate(S.scrollTo, 240, 'linear', function () {
25951                                        scrollToValue = c[scrollOffset]();
25952                                    });
25953                                    S.scrollTo = null;
25954                                }
25955                            }, 1);
25956                        }
25957
25958                        event.preventDefault();
25959                        return false;
vendor: 21,755 bytes, lines 25960-26475
25960                    };
25961
25962                    scrollx.scroll
25963                        .on('MozMousePixelScroll' + namespace, scrollx.mousewheel)
25964                        .on('mousewheel' + namespace, scrollx.mousewheel)
25965                        .on('mouseenter' + namespace, function () {
25966                            scrollToValue = c[scrollOffset]();
25967                        });
25968
25969                    // handle arrows & scroll inner mousedown event
25970                    scrollx.scroll.find('.scroll-arrow, .scroll-element_track')
25971                        .on('mousedown' + namespace, function (event) {
25972
25973                            if (event.which != 1) // lmb
25974                                return true;
25975
25976                            scrollForward = 1;
25977
25978                            var data = {
25979                                "eventOffset": event[(d === 'x') ? 'pageX' : 'pageY'],
25980                                "maxScrollValue": scrollx.size - scrollx.visible - scrollx.offset,
25981                                "scrollbarOffset": scrollx.scroll.bar.offset()[(d === 'x') ? 'left' : 'top'],
25982                                "scrollbarSize": scrollx.scroll.bar[(d === 'x') ? 'outerWidth' : 'outerHeight']()
25983                            };
25984                            var timeout = 0, timer = 0;
25985
25986                            if ($(this).hasClass('scroll-arrow')) {
25987                                scrollForward = $(this).hasClass("scroll-arrow_more") ? 1 : -1;
25988                                scrollStep = o.scrollStep * scrollForward;
25989                                scrollToValue = scrollForward > 0 ? data.maxScrollValue : 0;
25990                            } else {
25991                                scrollForward = (data.eventOffset > (data.scrollbarOffset + data.scrollbarSize) ? 1
25992                                    : (data.eventOffset < data.scrollbarOffset ? -1 : 0));
25993                                scrollStep = Math.round(scrollx.visible * 0.75) * scrollForward;
25994                                scrollToValue = (data.eventOffset - data.scrollbarOffset -
25995                                    (o.stepScrolling ? (scrollForward == 1 ? data.scrollbarSize : 0)
25996                                        : Math.round(data.scrollbarSize / 2)));
25997                                scrollToValue = c[scrollOffset]() + (scrollToValue / scrollx.kx);
25998                            }
25999
26000                            S.scrollTo = S.scrollTo || {};
26001                            S.scrollTo[scrollOffset] = o.stepScrolling ? c[scrollOffset]() + scrollStep : scrollToValue;
26002
26003                            if (o.stepScrolling) {
26004                                scrollCallback = function () {
26005                                    scrollToValue = c[scrollOffset]();
26006                                    clearInterval(timer);
26007                                    clearTimeout(timeout);
26008                                    timeout = 0;
26009                                    timer = 0;
26010                                };
26011                                timeout = setTimeout(function () {
26012                                    timer = setInterval(scrollTo, 40);
26013                                }, o.duration + 100);
26014                            }
26015
26016                            setTimeout(function () {
26017                                if (S.scrollTo) {
26018                                    c.animate(S.scrollTo, o.duration);
26019                                    S.scrollTo = null;
26020                                }
26021                            }, 1);
26022
26023                            return S._handleMouseDown(scrollCallback, event);
26024                        });
26025
26026                    // handle scrollbar drag'n'drop
26027                    scrollx.scroll.bar.on('mousedown' + namespace, function (event) {
26028
26029                        if (event.which != 1) // lmb
26030                            return true;
26031
26032                        var eventPosition = event[(d === 'x') ? 'pageX' : 'pageY'];
26033                        var initOffset = c[scrollOffset]();
26034
26035                        scrollx.scroll.addClass('scroll-draggable');
26036
26037                        $(document).on('mousemove' + namespace, function (event) {
26038                            var diff = parseInt((event[(d === 'x') ? 'pageX' : 'pageY'] - eventPosition) / scrollx.kx, 10);
26039                            c[scrollOffset](initOffset + diff);
26040                        });
26041
26042                        return S._handleMouseDown(function () {
26043                            scrollx.scroll.removeClass('scroll-draggable');
26044                            scrollToValue = c[scrollOffset]();
26045                        }, event);
26046                    });
26047                }
26048            });
26049
26050            // remove classes & reset applied styles
26051            $.each(s, function (d, scrollx) {
26052                var scrollClass = 'scroll-scroll' + d + '_visible';
26053                var scrolly = (d == "x") ? s.y : s.x;
26054
26055                scrollx.scroll.removeClass(scrollClass);
26056                scrolly.scroll.removeClass(scrollClass);
26057                cw.removeClass(scrollClass);
26058            });
26059
26060            // calculate init sizes
26061            $.each(s, function (d, scrollx) {
26062                $.extend(scrollx, (d == "x") ? {
26063                    "offset": parseInt(c.css('left'), 10) || 0,
26064                    "size": c.prop('scrollWidth'),
26065                    "visible": w.width()
26066                } : {
26067                    "offset": parseInt(c.css('top'), 10) || 0,
26068                    "size": c.prop('scrollHeight'),
26069                    "visible": w.height()
26070                });
26071            });
26072
26073            // update scrollbar visibility/dimensions
26074            this._updateScroll('x', this.scrollx);
26075            this._updateScroll('y', this.scrolly);
26076
26077            if ($.isFunction(o.onUpdate)){
26078                o.onUpdate.apply(this, [c]);
26079            }
26080
26081            // calculate scroll size
26082            $.each(s, function (d, scrollx) {
26083
26084                var cssOffset = (d === 'x') ? 'left' : 'top';
26085                var cssFullSize = (d === 'x') ? 'outerWidth' : 'outerHeight';
26086                var cssSize = (d === 'x') ? 'width' : 'height';
26087                var offset = parseInt(c.css(cssOffset), 10) || 0;
26088
26089                var AreaSize = scrollx.size;
26090                var AreaVisible = scrollx.visible + offset;
26091
26092                var scrollSize = scrollx.scroll.size[cssFullSize]() + (parseInt(scrollx.scroll.size.css(cssOffset), 10) || 0);
26093
26094                if (o.autoScrollSize) {
26095                    scrollx.scrollbarSize = parseInt(scrollSize * AreaVisible / AreaSize, 10);
26096                    scrollx.scroll.bar.css(cssSize, scrollx.scrollbarSize + 'px');
26097                }
26098
26099                scrollx.scrollbarSize = scrollx.scroll.bar[cssFullSize]();
26100                scrollx.kx = ((scrollSize - scrollx.scrollbarSize) / (AreaSize - AreaVisible)) || 1;
26101                scrollx.maxScrollOffset = AreaSize - AreaVisible;
26102            });
26103
26104            c.scrollLeft(initScroll.scrollLeft).scrollTop(initScroll.scrollTop).trigger('scroll');
26105        },
26106
26107        /**
26108         * Get scrollx/scrolly object
26109         *
26110         * @param {Mixed} scroll
26111         * @returns {jQuery} scroll object
26112         */
26113        _getScroll: function (scroll) {
26114            var types = {
26115                advanced: [
26116                    '<div class="scroll-element">',
26117                    '<div class="scroll-element_corner"></div>',
26118                    '<div class="scroll-arrow scroll-arrow_less"></div>',
26119                    '<div class="scroll-arrow scroll-arrow_more"></div>',
26120                    '<div class="scroll-element_outer">',
26121                    '<div class="scroll-element_size"></div>', // required! used for scrollbar size calculation !
26122                    '<div class="scroll-element_inner-wrapper">',
26123                    '<div class="scroll-element_inner scroll-element_track">', // used for handling scrollbar click
26124                    '<div class="scroll-element_inner-bottom"></div>',
26125                    '</div>',
26126                    '</div>',
26127                    '<div class="scroll-bar">', // required
26128                    '<div class="scroll-bar_body">',
26129                    '<div class="scroll-bar_body-inner"></div>',
26130                    '</div>',
26131                    '<div class="scroll-bar_bottom"></div>',
26132                    '<div class="scroll-bar_center"></div>',
26133                    '</div>',
26134                    '</div>',
26135                    '</div>'
26136                ].join(''),
26137                simple: [
26138                    '<div class="scroll-element">',
26139                    '<div class="scroll-element_outer">',
26140                    '<div class="scroll-element_size"></div>', // required! used for scrollbar size calculation !
26141                    '<div class="scroll-element_track"></div>', // used for handling scrollbar click
26142                    '<div class="scroll-bar"></div>', // required
26143                    '</div>',
26144                    '</div>'
26145                ].join('')
26146            };
26147            if (types[scroll]) {
26148                scroll = types[scroll];
26149            }
26150            if (!scroll) {
26151                scroll = types['simple'];
26152            }
26153            if (typeof (scroll) == 'string') {
26154                scroll = $(scroll).appendTo(this.wrapper);
26155            } else {
26156                scroll = $(scroll);
26157            }
26158            $.extend(scroll, {
26159                bar: scroll.find('.scroll-bar'),
26160                size: scroll.find('.scroll-element_size'),
26161                track: scroll.find('.scroll-element_track')
26162            });
26163            return scroll;
26164        },
26165
26166        _handleMouseDown: function(callback, event) {
26167
26168            var namespace = this.namespace;
26169
26170            $(document).on('blur' + namespace, function () {
26171                $(document).add('body').off(namespace);
26172                callback && callback();
26173            });
26174            $(document).on('dragstart' + namespace, function (event) {
26175                event.preventDefault();
26176                return false;
26177            });
26178            $(document).on('mouseup' + namespace, function () {
26179                $(document).add('body').off(namespace);
26180                callback && callback();
26181            });
26182            $('body').on('selectstart' + namespace, function (event) {
26183                event.preventDefault();
26184                return false;
26185            });
26186
26187            event && event.preventDefault();
26188            return false;
26189        },
26190
26191        _updateScroll: function (d, scrollx) {
26192
26193            var container = this.container,
26194                containerWrapper = this.containerWrapper || container,
26195                scrollClass = 'scroll-scroll' + d + '_visible',
26196                scrolly = (d === 'x') ? this.scrolly : this.scrollx,
26197                offset = parseInt(this.container.css((d === 'x') ? 'left' : 'top'), 10) || 0,
26198                wrapper = this.wrapper;
26199
26200            var AreaSize = scrollx.size;
26201            var AreaVisible = scrollx.visible + offset;
26202
26203            scrollx.isVisible = (AreaSize - AreaVisible) > 1; // bug in IE9/11 with 1px diff
26204            if (scrollx.isVisible) {
26205                scrollx.scroll.addClass(scrollClass);
26206                scrolly.scroll.addClass(scrollClass);
26207                containerWrapper.addClass(scrollClass);
26208            } else {
26209                scrollx.scroll.removeClass(scrollClass);
26210                scrolly.scroll.removeClass(scrollClass);
26211                containerWrapper.removeClass(scrollClass);
26212            }
26213
26214            if (d === 'y') {
26215                if(container.is('textarea') || AreaSize < AreaVisible){
26216                    containerWrapper.css({
26217                        "height": (AreaVisible + browser.scroll.height) + 'px',
26218                        "max-height": "none"
26219                    });
26220                } else {
26221                    containerWrapper.css({
26222                        //"height": "auto", // do not reset height value: issue with height:100%!
26223                        "max-height": (AreaVisible + browser.scroll.height) + 'px'
26224                    });
26225                }
26226            }
26227
26228            if (scrollx.size != container.prop('scrollWidth')
26229                || scrolly.size != container.prop('scrollHeight')
26230                || scrollx.visible != wrapper.width()
26231                || scrolly.visible != wrapper.height()
26232                || scrollx.offset != (parseInt(container.css('left'), 10) || 0)
26233                || scrolly.offset != (parseInt(container.css('top'), 10) || 0)
26234                ) {
26235                $.extend(this.scrollx, {
26236                    "offset": parseInt(container.css('left'), 10) || 0,
26237                    "size": container.prop('scrollWidth'),
26238                    "visible": wrapper.width()
26239                });
26240                $.extend(this.scrolly, {
26241                    "offset": parseInt(container.css('top'), 10) || 0,
26242                    "size": this.container.prop('scrollHeight'),
26243                    "visible": wrapper.height()
26244                });
26245                this._updateScroll(d === 'x' ? 'y' : 'x', scrolly);
26246            }
26247        }
26248    };
26249
26250    var CustomScrollbar = BaseScrollbar;
26251
26252    /*
26253     * Extend jQuery as plugin
26254     *
26255     * @param {Mixed} command to execute
26256     * @param {Mixed} arguments as Array
26257     * @return {jQuery}
26258     */
26259    $.fn.scrollbar = function (command, args) {
26260        if (typeof command !== 'string') {
26261            args = command;
26262            command = 'init';
26263        }
26264        if (typeof args === 'undefined') {
26265            args = [];
26266        }
26267        if (!$.isArray(args)) {
26268            args = [args];
26269        }
26270        this.not('body, .scroll-wrapper').each(function () {
26271            var element = $(this),
26272                instance = element.data(browser.data.name);
26273            if (instance || command === 'init') {
26274                if (!instance) {
26275                    instance = new CustomScrollbar(element);
26276                }
26277                if (instance[command]) {
26278                    instance[command].apply(instance, args);
26279                }
26280            }
26281        });
26282        return this;
26283    };
26284
26285    /**
26286     * Connect default options to global object
26287     */
26288    $.fn.scrollbar.options = defaults;
26289
26290
26291    /**
26292     * Check if scroll content/container size is changed
26293     */
26294
26295    var updateScrollbars = (function () {
26296        var timer = 0,
26297            timerCounter = 0;
26298
26299        return function (force) {
26300            var i, container, options, scroll, wrapper, scrollx, scrolly;
26301            for (i = 0; i < browser.scrolls.length; i++) {
26302                scroll = browser.scrolls[i];
26303                container = scroll.container;
26304                options = scroll.options;
26305                wrapper = scroll.wrapper;
26306                scrollx = scroll.scrollx;
26307                scrolly = scroll.scrolly;
26308                if (force || (options.autoUpdate && wrapper && wrapper.is(':visible') &&
26309                    (container.prop('scrollWidth') != scrollx.size || container.prop('scrollHeight') != scrolly.size || wrapper.width() != scrollx.visible || wrapper.height() != scrolly.visible))) {
26310                    scroll.init();
26311
26312                    if (options.debug) {
26313                        window.console && console.log({
26314                            scrollHeight: container.prop('scrollHeight') + ':' + scroll.scrolly.size,
26315                            scrollWidth: container.prop('scrollWidth') + ':' + scroll.scrollx.size,
26316                            visibleHeight: wrapper.height() + ':' + scroll.scrolly.visible,
26317                            visibleWidth: wrapper.width() + ':' + scroll.scrollx.visible
26318                        }, true);
26319                        timerCounter++;
26320                    }
26321                }
26322            }
26323            if (debug && timerCounter > 10) {
26324                window.console && console.log('Scroll updates exceed 10');
26325                updateScrollbars = function () {};
26326            } else {
26327                clearTimeout(timer);
26328                timer = setTimeout(updateScrollbars, 300);
26329            }
26330        };
26331    })();
26332
26333    /* ADDITIONAL FUNCTIONS */
26334    /**
26335     * Get native browser scrollbar size (height/width)
26336     *
26337     * @param {Boolean} actual size or CSS size, default - CSS size
26338     * @returns {Object} with height, width
26339     */
26340    function getBrowserScrollSize(actualSize) {
26341
26342        if (browser.webkit && !actualSize) {
26343            return {
26344                "height": 0,
26345                "width": 0
26346            };
26347        }
26348
26349        if (!browser.data.outer) {
26350            var css = {
26351                "border": "none",
26352                "box-sizing": "content-box",
26353                "height": "200px",
26354                "margin": "0",
26355                "padding": "0",
26356                "width": "200px"
26357            };
26358            browser.data.inner = $("<div>").css($.extend({}, css));
26359            browser.data.outer = $("<div>").css($.extend({
26360                "left": "-1000px",
26361                "overflow": "scroll",
26362                "position": "absolute",
26363                "top": "-1000px"
26364            }, css)).append(browser.data.inner).appendTo("body");
26365        }
26366
26367        browser.data.outer.scrollLeft(1000).scrollTop(1000);
26368
26369        return {
26370            "height": Math.ceil((browser.data.outer.offset().top - browser.data.inner.offset().top) || 0),
26371            "width": Math.ceil((browser.data.outer.offset().left - browser.data.inner.offset().left) || 0)
26372        };
26373    }
26374
26375    /**
26376     * Check if native browser scrollbars overlay content
26377     *
26378     * @returns {Boolean}
26379     */
26380    function isScrollOverlaysContent() {
26381        var scrollSize = getBrowserScrollSize(true);
26382        return !(scrollSize.height || scrollSize.width);
26383    }
26384
26385    function isVerticalScroll(event) {
26386        var e = event.originalEvent;
26387        if (e.axis && e.axis === e.HORIZONTAL_AXIS)
26388            return false;
26389        if (e.wheelDeltaX)
26390            return false;
26391        return true;
26392    }
26393
26394
26395    /**
26396     * Extend AngularJS as UI directive
26397     * and expose a provider for override default config
26398     *
26399     */
26400    if (window.angular) {
26401        (function (angular) {
26402            angular.module('jQueryScrollbar', [])
26403                .provider('jQueryScrollbar', function () {
26404                    var defaultOptions = defaults;
26405                    return {
26406                        setOptions: function (options) {
26407                            angular.extend(defaultOptions, options);
26408                        },
26409                        $get: function () {
26410                            return {
26411                                options: angular.copy(defaultOptions)
26412                            };
26413                        }
26414                    };
26415                })
26416                .directive('jqueryScrollbar', ['jQueryScrollbar', '$parse', function (jQueryScrollbar, $parse) {
26417                    return {
26418                        "restrict": "AC",
26419                        "link": function (scope, element, attrs) {
26420                            var model = $parse(attrs.jqueryScrollbar),
26421                                options = model(scope);
26422                            element.scrollbar(options || jQueryScrollbar.options)
26423                                .on('$destroy', function () {
26424                                    element.scrollbar('destroy');
26425                                });
26426                        }
26427                    };
26428                }]);
26429        })(window.angular);
26430    }
26431}));
26432
26433/* End */
26434;
26435; /* Start:"a:4:{s:4:"full";s:90:"/bitrix/templates/universe_s5/plugins/jquery.printThis/jquery.printThis.js?167687089413950";s:6:"source";s:74:"/bitrix/templates/universe_s5/plugins/jquery.printThis/jquery.printThis.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
26436/*
26437 * printThis v1.15.1
26438 * @desc Printing plug-in for jQuery
26439 * @author Jason Day
26440 *
26441 * Resources (based on):
26442 * - jPrintArea: http://plugins.jquery.com/project/jPrintArea
26443 * - jqPrint: https://github.com/permanenttourist/jquery.jqprint
26444 * - Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
26445 *
26446 * Licensed under the MIT licence:
26447 *              http://www.opensource.org/licenses/mit-license.php
26448 *
26449 * (c) Jason Day 2015-2019
26450 *
26451 * Usage:
26452 *
26453 *  $("#mySelector").printThis({
26454 *      debug: false,                   // show the iframe for debugging
26455 *      importCSS: true,                // import parent page css
26456 *      importStyle: false,             // import style tags
26457 *      printContainer: true,           // grab outer container as well as the contents of the selector
26458 *      loadCSS: "path/to/my.css",      // path to additional css file - use an array [] for multiple
26459 *      pageTitle: "",                  // add title to print page
26460 *      removeInline: false,            // remove all inline styles from print elements
26461 *      removeInlineSelector: "body *", // custom selectors to filter inline styles. removeInline must be true
26462 *      printDelay: 333,                // variable print delay
26463 *      header: null,                   // prefix to html
26464 *      footer: null,                   // postfix to html
26465 *      base: false,                    // preserve the BASE tag, or accept a string for the URL
26466 *      formValues: true,               // preserve input/form values
26467 *      canvas: false,                  // copy canvas elements
26468 *      doctypeString: '...',           // enter a different doctype for older markup
26469 *      removeScripts: false,           // remove script tags from print content
26470 *      copyTagClasses: false           // copy classes from the html & body tag
26471 *      beforePrintEvent: null,         // callback function for printEvent in iframe
26472 *      beforePrint: null,              // function called before iframe is filled
26473 *      afterPrint: null                // function called before iframe is removed
26474 *  });
26475 *
vendor: 11,274 bytes, lines 26476-26761
26476 * Notes:
26477 *  - the loadCSS will load additional CSS (with or without @media print) into the iframe, adjusting layout
26478 */
26479;
26480(function($) {
26481
26482    function appendContent($el, content) {
26483        if (!content) return;
26484
26485        // Simple test for a jQuery element
26486        $el.append(content.jquery ? content.clone() : content);
26487    }
26488
26489    function appendBody($body, $element, opt) {
26490        // Clone for safety and convenience
26491        // Calls clone(withDataAndEvents = true) to copy form values.
26492        var $content = $element.clone(opt.formValues);
26493
26494        if (opt.formValues) {
26495            // Copy original select and textarea values to their cloned counterpart
26496            // Makes up for inability to clone select and textarea values with clone(true)
26497            copyValues($element, $content, 'select, textarea');
26498        }
26499
26500        if (opt.removeScripts) {
26501            $content.find('script').remove();
26502        }
26503
26504        if (opt.printContainer) {
26505            // grab $.selector as container
26506            $content.appendTo($body);
26507        } else {
26508            // otherwise just print interior elements of container
26509            $content.each(function() {
26510                $(this).children().appendTo($body)
26511            });
26512        }
26513    }
26514
26515    // Copies values from origin to clone for passed in elementSelector
26516    function copyValues(origin, clone, elementSelector) {
26517        var $originalElements = origin.find(elementSelector);
26518
26519        clone.find(elementSelector).each(function(index, item) {
26520            $(item).val($originalElements.eq(index).val());
26521        });
26522    }
26523
26524    var opt;
26525    $.fn.printThis = function(options) {
26526        opt = $.extend({}, $.fn.printThis.defaults, options);
26527        var $element = this instanceof jQuery ? this : $(this);
26528
26529        var strFrameName = "printThis-" + (new Date()).getTime();
26530
26531        if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
26532            // Ugly IE hacks due to IE not inheriting document.domain from parent
26533            // checks if document.domain is set by comparing the host name against document.domain
26534            var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")";
26535            var printI = document.createElement('iframe');
26536            printI.name = "printIframe";
26537            printI.id = strFrameName;
26538            printI.className = "MSIE";
26539            document.body.appendChild(printI);
26540            printI.src = iframeSrc;
26541
26542        } else {
26543            // other browsers inherit document.domain, and IE works if document.domain is not explicitly set
26544            var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
26545            $frame.appendTo("body");
26546        }
26547
26548        var $iframe = $("#" + strFrameName);
26549
26550        // show frame if in debug mode
26551        if (!opt.debug) $iframe.css({
26552            position: "absolute",
26553            width: "0px",
26554            height: "0px",
26555            left: "-600px",
26556            top: "-600px"
26557        });
26558
26559        // before print callback
26560        if (typeof opt.beforePrint === "function") {
26561            opt.beforePrint();
26562        }
26563
26564        // $iframe.ready() and $iframe.load were inconsistent between browsers
26565        setTimeout(function() {
26566
26567            // Add doctype to fix the style difference between printing and render
26568            function setDocType($iframe, doctype){
26569                var win, doc;
26570                win = $iframe.get(0);
26571                win = win.contentWindow || win.contentDocument || win;
26572                doc = win.document || win.contentDocument || win;
26573                doc.open();
26574                doc.write(doctype);
26575                doc.close();
26576            }
26577
26578            if (opt.doctypeString){
26579                setDocType($iframe, opt.doctypeString);
26580            }
26581
26582            var $doc = $iframe.contents(),
26583                $head = $doc.find("head"),
26584                $body = $doc.find("body"),
26585                $base = $('base'),
26586                baseURL;
26587
26588            // add base tag to ensure elements use the parent domain
26589            if (opt.base === true && $base.length > 0) {
26590                // take the base tag from the original page
26591                baseURL = $base.attr('href');
26592            } else if (typeof opt.base === 'string') {
26593                // An exact base string is provided
26594                baseURL = opt.base;
26595            } else {
26596                // Use the page URL as the base
26597                baseURL = document.location.protocol + '//' + document.location.host;
26598            }
26599
26600            $head.append('<base href="' + baseURL + '">');
26601
26602            // import page stylesheets
26603            if (opt.importCSS) $("link[rel=stylesheet]").each(function() {
26604                var href = $(this).attr("href");
26605                if (href) {
26606                    var media = $(this).attr("media") || "all";
26607                    $head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>");
26608                }
26609            });
26610
26611            // import style tags
26612            if (opt.importStyle) $("style").each(function() {
26613                $head.append(this.outerHTML);
26614            });
26615
26616            // add title of the page
26617            if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");
26618
26619            // import additional stylesheet(s)
26620            if (opt.loadCSS) {
26621                if ($.isArray(opt.loadCSS)) {
26622                    jQuery.each(opt.loadCSS, function(index, value) {
26623                        $head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
26624                    });
26625                } else {
26626                    $head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
26627                }
26628            }
26629
26630            var pageHtml = $('html')[0];
26631
26632            // CSS VAR in html tag when dynamic apply e.g.  document.documentElement.style.setProperty("--foo", bar);
26633            $doc.find('html').prop('style', pageHtml.style.cssText);
26634
26635            // copy 'root' tag classes
26636            var tag = opt.copyTagClasses;
26637            if (tag) {
26638                tag = tag === true ? 'bh' : tag;
26639                if (tag.indexOf('b') !== -1) {
26640                    $body.addClass($('body')[0].className);
26641                }
26642                if (tag.indexOf('h') !== -1) {
26643                    $doc.find('html').addClass(pageHtml.className);
26644                }
26645            }
26646
26647            // print header
26648            appendContent($body, opt.header);
26649
26650            if (opt.canvas) {
26651                // add canvas data-ids for easy access after cloning.
26652                var canvasId = 0;
26653                // .addBack('canvas') adds the top-level element if it is a canvas.
26654                $element.find('canvas').addBack('canvas').each(function(){
26655                    $(this).attr('data-printthis', canvasId++);
26656                });
26657            }
26658
26659            appendBody($body, $element, opt);
26660
26661            if (opt.canvas) {
26662                // Re-draw new canvases by referencing the originals
26663                $body.find('canvas').each(function(){
26664                    var cid = $(this).data('printthis'),
26665                        $src = $('[data-printthis="' + cid + '"]');
26666
26667                    this.getContext('2d').drawImage($src[0], 0, 0);
26668
26669                    // Remove the markup from the original
26670                    if ($.isFunction($.fn.removeAttr)) {
26671                        $src.removeAttr('data-printthis');
26672                    } else {
26673                        $.each($src, function(i, el) {
26674                            el.removeAttribute('data-printthis');
26675                        });
26676                    }
26677                });
26678            }
26679
26680            // remove inline styles
26681            if (opt.removeInline) {
26682                // Ensure there is a selector, even if it's been mistakenly removed
26683                var selector = opt.removeInlineSelector || '*';
26684                // $.removeAttr available jQuery 1.7+
26685                if ($.isFunction($.removeAttr)) {
26686                    $body.find(selector).removeAttr("style");
26687                } else {
26688                    $body.find(selector).attr("style", "");
26689                }
26690            }
26691
26692            // print "footer"
26693            appendContent($body, opt.footer);
26694
26695            // attach event handler function to beforePrint event
26696            function attachOnBeforePrintEvent($iframe, beforePrintHandler) {
26697                var win = $iframe.get(0);
26698                win = win.contentWindow || win.contentDocument || win;
26699
26700                if (typeof beforePrintHandler === "function") {
26701                    if ('matchMedia' in win) {
26702                        win.matchMedia('print').addListener(function(mql) {
26703                            if(mql.matches)  beforePrintHandler();
26704                        });
26705                    } else {
26706                        win.onbeforeprint = beforePrintHandler;
26707                    }
26708                }
26709            }
26710            attachOnBeforePrintEvent($iframe, opt.beforePrintEvent);
26711
26712            setTimeout(function() {
26713                if ($iframe.hasClass("MSIE")) {
26714                    // check if the iframe was created with the ugly hack
26715                    // and perform another ugly hack out of neccessity
26716                    window.frames["printIframe"].focus();
26717                    $head.append("<script>  window.print(); </s" + "cript>");
26718                } else {
26719                    // proper method
26720                    if (document.queryCommandSupported("print")) {
26721                        $iframe[0].contentWindow.document.execCommand("print", false, null);
26722                    } else {
26723                        $iframe[0].contentWindow.focus();
26724                        $iframe[0].contentWindow.print();
26725                    }
26726                }
26727
26728                // remove iframe after print
26729                if (!opt.debug) {
26730                    setTimeout(function() {
26731                        $iframe.remove();
26732
26733                    }, 1000);
26734                }
26735
26736                // after print callback
26737                if (typeof opt.afterPrint === "function") {
26738                    opt.afterPrint();
26739                }
26740
26741            }, opt.printDelay);
26742
26743        }, 333);
26744
26745    };
26746
26747    // defaults
26748    $.fn.printThis.defaults = {
26749        debug: false,               // show the iframe for debugging
26750        importCSS: true,            // import parent page css
26751        importStyle: false,         // import style tags
26752        printContainer: true,       // print outer container/$.selector
26753        loadCSS: "",                // path to additional css file - use an array [] for multiple
26754        pageTitle: "",              // add title to print page
26755        removeInline: false,        // remove inline styles from print elements
26756        removeInlineSelector: "*",  // custom selectors to filter inline styles. removeInline must be true
26757        printDelay: 333,            // variable print delay
26758        header: null,               // prefix to html
26759        footer: null,               // postfix to html
26760        base: false,                // preserve the BASE tag or accept a string for the URL
26761        formValues: true,           // preserve input/form values
26762        canvas: false,              // copy canvas content
26763        doctypeString: '<!DOCTYPE html>', // enter a different doctype for older markup
26764        removeScripts: false,       // remove script tags from print content
26765        copyTagClasses: false,      // copy classes from the html & body tag
26766        beforePrintEvent: null,     // callback function for printEvent in iframe
26767        beforePrint: null,          // function called before iframe is filled
26768        afterPrint: null            // function called before iframe is removed
26769    };
26770})(jQuery);
26771/* End */
26772;
26773; /* Start:"a:4:{s:4:"full";s:59:"/bitrix/templates/universe_s5/js/universe.js?16768708901570";s:6:"source";s:44:"/bitrix/templates/universe_s5/js/universe.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
26774universe = (function ($, api) {
26775    var self;
26776
26777    self = {};
26778    self = api.extend(self, api.ext.events(self));
26779    self.site = {
26780        'id': null,
26781        'directory': null
26782    };
26783
26784    self.template = {
26785        'id': null,
26786        'directory': null
26787    };
26788
26789    self.ajax = function(action, data, callback) {
26790        if (!api.isFunction(callback))
26791            callback = function () {};
26792
26793        $.ajax({
26794            'type': 'POST',
26795            'url': self.site.directory,
26796            'cache': false,
26797            'dataType': 'json',
26798            'data': {
26799                'ajax': {
26800                    'action': action,
26801                    'data': data,
26802                    'request': 'y'
26803                }
26804            },
26805            success: callback,
26806            error: function(response){
26807                console.error(response);
26808            }
26809        });
26810    };
26811
26812    self.page = function (page, query, data, callback) {
26813        if (!api.isFunction(callback))
26814            callback = function () {};
26815
26816        var url = self.site.directory;
26817
26818        query = api.extend({}, query, {
26819            'page': {
26820                'page': page,
26821                'request': 'y'
26822            }
26823        });
26824        query = $.param(query);
26825
26826        url = url + '?' + query;
26827
26828        $.ajax({
26829            'type': 'POST',
26830            'url': url,
26831            'cache': false,
26832            'data': data,
26833            'success': callback,
26834            'error': function (response) {
26835                console.error(response);
26836            }
26837        });
26838    };
26839
26840    return self;
26841})(jQuery, intec);
26842/* End */
26843;
26844; /* Start:"a:4:{s:4:"full";s:57:"/bitrix/templates/universe_s5/js/basket.js?16768708902039";s:6:"source";s:42:"/bitrix/templates/universe_s5/js/basket.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
26845universe.basket = (function ($, api) {
26846    var self = {};
26847    var request = function (action, data, callback) {
26848        universe.ajax('basket.' + action, data, callback);
26849    };
26850
26851    api.extend(self, api.ext.events(self, ['add', 'setQuantity', 'get', 'remove', 'clear', 'update', 'process', 'processed']));
26852
26853    self.on('update', function(){
26854        self.trigger('processed');
26855    });
26856
26857    self.add = function (data, callback) {
26858        self.trigger('process', data.id);
26859        request('add', data, function (response) {
26860            if (response === true) {
26861                if (api.isFunction(callback))
26862                    callback.apply(null);
26863
26864                self.trigger('add', data);
26865                self.trigger('update', 'add', data);
26866            }
26867        });
26868    };
26869
26870    self.setQuantity = function (data, callback) {
26871        self.trigger('process', data.id);
26872        request('setQuantity', data, function (response) {
26873            if (response === true) {
26874                if (api.isFunction(callback))
26875                    callback.apply(null);
26876
26877                self.trigger('setQuantity', data);
26878                self.trigger('update', 'setQuantity', data);
26879            }
26880        });
26881    };
26882
26883    self.remove = function (data, callback) {
26884        request('remove', data, function (response) {
26885            if (response === true) {
26886                if (api.isFunction(callback))
26887                    callback.apply(null);
26888
26889                self.trigger('remove', data);
26890                self.trigger('update', 'remove', data);
26891            }
26892        });
26893    };
26894
26895    self.clear = function (data, callback) {
26896        request('clear', data, function (response) {
26897            if (response === true) {
26898                if (api.isFunction(callback))
26899                    callback.apply(null);
26900
26901                self.trigger('clear', data);
26902                self.trigger('update', 'clear', data);
26903            }
26904        });
26905    };
26906
26907    self.update = function () {
26908        self.trigger('update', 'update');
26909    };
26910
26911    return self;
26912})(jQuery, intec);
26913/* End */
26914;
26915; /* Start:"a:4:{s:4:"full";s:58:"/bitrix/templates/universe_s5/js/compare.js?16768708901830";s:6:"source";s:43:"/bitrix/templates/universe_s5/js/compare.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
26916if (universe) {
26917    universe.compare = (function ($, api) {
26918        var self = {};
26919        var request = function (action, data, callback) {
26920            universe.ajax('compare.' + action, data, callback);
26921        };
26922
26923        api.extend(self, api.ext.events(self, ['add', 'remove', 'clear', 'update']));
26924
26925        self.add = function (data, callback) {
26926            request('add', data, function (response) {
26927                if (response === true) {
26928                    if (api.isFunction(callback))
26929                        callback.apply(null);
26930
26931                    self.trigger('add');
26932                    self.trigger('update');
26933                }
26934            });
26935        };
26936
26937        self.get = function (data, callback) {
26938            request('get', data, function (response) {
26939                if (api.isDeclared(response)) {
26940                    if (api.isFunction(callback))
26941                        callback.call(null, response);
26942
26943                    self.trigger('get', response);
26944                }
26945            });
26946        };
26947
26948        self.remove = function (data, callback) {
26949            request('remove', data, function (response) {
26950                if (response === true) {
26951                    if (api.isFunction(callback))
26952                        callback.apply(null);
26953
26954                    self.trigger('remove');
26955                    self.trigger('update');
26956                }
26957            });
26958        };
26959
26960        self.clear = function (data, callback) {
26961            request('clear', data, function (response) {
26962                if (response === true) {
26963                    if (api.isFunction(callback))
26964                        callback.apply(null);
26965
26966                    self.trigger('clear');
26967                    self.trigger('update');
26968                }
26969            });
26970        };
26971
26972        return self;
26973    })(jQuery, intec);
26974}
26975/* End */
26976;
26977; /* Start:"a:4:{s:4:"full";s:58:"/bitrix/templates/universe_s5/js/catalog.js?16768708905846";s:6:"source";s:43:"/bitrix/templates/universe_s5/js/catalog.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
26978universe.catalog = (function ($, api) {
26979    var catalog = {};
26980
26981    catalog.offers = function (settings) {
26982        var self = this;
26983        var properties = [];
26984        var list = [];
26985        var current = null;
26986
26987        settings = api.extend({}, settings);
26988
26989        api.each(settings.properties, function (index, property) {
26990            properties.push(property);
26991        });
26992
26993        api.each(settings.list, function (index, offer) {
26994            list.push(offer);
26995        });
26996
26997        self.getProperties = function () {
26998            return properties;
26999        };
27000
27001        self.getList = function () {
27002            return list;
27003        };
27004
27005        self.getCurrent = function () {
27006            return current;
27007        };
27008
27009        self.setCurrentById = function (id) {
27010            var offer = self.getById(id);
27011            var changed = false;
27012
27013            if (offer !== null) {
27014                changed = current !== offer;
27015                current = offer;
27016            }
27017
27018            if (changed) {
27019                self.trigger('change', current, self.getValues());
27020                return current;
27021            }
27022
27023            return null;
27024        };
27025
27026        api.extend(self, api.ext.events(self));
27027    };
27028
27029    catalog.offers.prototype.getById = function (id) {
27030        var result = null;
27031
27032        api.each(this.getList(), function (index, offer) {
27033            if (offer.id === id) {
27034                result = offer;
27035                return false;
27036            }
27037        });
27038
27039        return result;
27040    };
27041
27042    catalog.offers.prototype.getByValues = function (values) {
27043        var self = this;
27044        var result = null;
27045
27046        api.each(self.getList(), function (index, offer) {
27047            var equal = true;
27048
27049            api.each(self.getProperties(), function(index, property) {
27050                var value = offer.values[property.code];
27051
27052                if (!api.isEmpty(value) && !api.isEmpty(values[property.code])) {
27053                    if (value != values[property.code])
27054                        equal = false;
27055                }
27056            });
27057
27058            if (equal) {
27059                result = offer;
27060                return false;
27061            }
27062        });
27063
27064        return result;
27065    };
27066
27067    catalog.offers.prototype.setCurrentByValue = function (code, value) {
27068        var offer = this.getCurrent();
27069        var result = null;
27070        var values;
27071
27072        if (offer === null)
27073            return result;
27074
27075        values = api.extend({}, offer.values);
27076        values[code] = value;
27077
27078        result = this.getByValues(values);
27079
27080        if (result !== null)
27081            return this.setCurrentById(result.id);
27082
27083        values = {};
27084
27085        api.each(offer.values, function (offerValueCode, offerValue) {
27086            values[offerValueCode] = offerValue;
27087
27088            if (offerValueCode == code) {
27089                values[offerValueCode] = value;
27090                return false;
27091            }
27092        });
27093
27094        result = this.getByValues(values);
27095
27096        if (result !== null)
27097            return this.setCurrentById(result.id);
27098
27099        return result;
27100    };
27101
27102    catalog.offers.prototype.setCurrentByValues = function (values) {
27103        var result = this.getByValues(values);
27104
27105        if (result !== null)
27106            return this.setCurrentById(result.id);
27107
27108        return result;
27109    };
27110
27111    catalog.offers.prototype.getValues = function () {
27112        var self = this;
27113        var current = self.getCurrent();
27114        var properties = [];
27115        var result = {
27116            'displayed': {},
27117            'disabled': {},
27118            'enabled': {},
27119            'selected': {}
27120        };
27121
27122        api.each(self.getList(), function (index, offer) {
27123            api.each(offer.values, function (code, value) {
27124                if (!api.isDeclared(result.displayed[code]))
27125                    result.displayed[code] = [];
27126
27127                if (!api.inArray(value, result.displayed[code]))
27128                    result.displayed[code].push(value);
27129            });
27130        });
27131
27132        api.each(self.getProperties(), function (index, property) {
27133            var code = property.code;
27134
27135            api.each(self.getList(), function (index, offer) {
27136                var compared = true;
27137                var value = offer.values[property.code];
27138
27139                if (current !== null) {
27140                    intec.each(properties, function (index, property) {
27141                        if (offer.values[property.code] != current.values[property.code]) {
27142                            compared = false;
27143                            return false;
27144                        }
27145                    });
27146                } else if (properties.length > 0) {
27147                    compared = false;
27148                }
27149
27150                if (compared) {
27151                    if (!api.isDeclared(result.enabled[code]))
27152                        result.enabled[code] = [];
27153
27154                    if (!api.inArray(value, result.enabled[code]))
27155                        result.enabled[code].push(value);
27156                }
27157            });
27158
27159            properties.push(property);
27160        });
27161
27162        api.each(result.displayed, function (code, values) {
27163            if (!api.isDeclared(result.disabled[code]))
27164                result.disabled[code] = [];
27165
27166            api.each(values, function (index, value) {
27167                if (!api.inArray(value, result.enabled[code]))
27168                    result.disabled[code].push(value);
27169            });
27170        });
27171
27172        if (current !== null)
27173            intec.each(current.values, function (code, value) {
27174                if (!api.isDeclared(result.selected[code]))
27175                    result.selected[code] = [];
27176
27177                result.selected[code].push(value);
27178            });
27179
27180        return result;
27181    };
27182
27183    catalog.offers.prototype.isEmpty = function () {
27184        return this.getList().length === 0;
27185    };
27186
27187    return catalog;
27188})(jQuery, intec);
27189/* End */
27190;
27191; /* Start:"a:4:{s:4:"full";s:57:"/bitrix/templates/universe_s5/js/common.js?16768708902044";s:6:"source";s:42:"/bitrix/templates/universe_s5/js/common.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27192(function ($, api) {
27193    $(document).on('ready', function () {
27194        var adapt;
27195        var area;
27196        var container;
27197        var template;
27198        var height;
27199
27200        area = $(window);
27201        container = $('body');
27202        template = container.find('.intec-template');
27203        template.content = template.find('.intec-template-content');
27204        template.footer = template.find('.intec-template-footer');
27205
27206        adapt = function () {
27207            container.css({'height': 'auto'});
27208            template.footer.css({'position': ''});
27209            template.content.css({'padding-bottom': ''});
27210
27211            if (container.height() < area.height()) {
27212                container.css({'height': '100%'});
27213
27214                if (template.footer.size() === 1) {
27215                    template.footer.css({'position': 'absolute'});
27216                    template.content.css({'padding-bottom': template.footer.height + 'px'});
27217                }
27218            }
27219        };
27220
27221        $(window).on('resize', adapt);
27222        setInterval(adapt, 250);
27223        adapt();
27224    });
27225
27226    $(document).on('ready', function () {
27227        if (api.isFunction($.fn.stellar)) {
27228            $(window).stellar({
27229                'horizontalScrolling': false,
27230                'verticalScrolling': true,
27231                'horizontalOffset': 0,
27232                'verticalOffset': 0,
27233                'responsive': true,
27234                'scrollProperty': 'scroll',
27235                'positionProperty': 'position',
27236                'parallaxBackgrounds': true,
27237                'parallaxElements': false,
27238                'hideDistantElements': false
27239            });
27240        }
27241    });
27242
27243    $(document).on('ready', function () {
27244        $('body').lazyLoad({
27245            'autoRunUse': true,
27246            'autoRunInterval': 500,
27247            'busyUse': true,
27248            'busyTimeout': 500,
27249            'enableAttributeName': 'data-lazyload-use',
27250            'sourceAttributeName': 'data-original',
27251            'sourceSetAttributeName': 'data-original-set'
27252        });
27253    });
27254})(jQuery, intec);
27255/* End */
27256;
27257; /* Start:"a:4:{s:4:"full";s:56:"/bitrix/templates/universe_s5/js/forms.js?16768708903217";s:6:"source";s:41:"/bitrix/templates/universe_s5/js/forms.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27258universe.forms = (function (universe, $, api) {
27259    var self = {};
27260    var popup;
27261
27262    /**
27263     * @param options
27264     * @option id Web form identifier
27265     * @option template Template of component
27266     * @option parameters Parameters of component
27267     * @option fields Fields of form
27268     * @param callback Callback function when given form code
27269     */
27270    self.get = function (options, callback) {
27271        var data = {};
27272
27273        options = api.extend({
27274            'id': null,
27275            'template': null,
27276            'parameters': null,
27277            'fields': null
27278        }, options);
27279
27280        if (api.isObject(options.fields))
27281            data.fields = options.fields;
27282
27283        universe.page('forms.get', {
27284            'id': options.id,
27285            'template': options.template,
27286            'parameters': options.parameters
27287        }, data, callback);
27288    };
27289
27290    /**
27291     *
27292     * @param options
27293     * @option id Web form identifier
27294     * @option template Template of component
27295     * @option parameters Parameters of component
27296     * @option settings
27297     * Object like:
27298     * {
27299     *     title: 'Title of popup',
27300     *     parameters: {Parameters of BX.PopupWindow}
27301     * }
27302     * @option fields Fields of form
27303     * @param callback Callback function when end
27304     * Callback variables:
27305     * - this - BX.PopupWindow instance
27306     * - options - Options object
27307     * - settings - Settings of popup
27308     */
27309    self.show = function (options, callback) {
27310        self.get(options, function (response) {
27311            var container;
27312            var settings;
27313            var parameters;
27314
27315            if (popup) {
27316                popup.destroy();
27317            }
27318
27319            options = api.extend({}, options);
27320            settings = api.extend({}, options.settings);
27321            options.settings = undefined;
27322
27323            container = $('<div>', {
27324                'style': 'display: none'
27325            }).append(response).appendTo($('body'));
27326            container = container.get(0);
27327
27328            parameters = api.extend({
27329                content: container,
27330                closeIcon: {},
27331                zIndex: 0,
27332                offsetLeft: 0,
27333                offsetTop: 0,
27334                width: 450,
27335                overlay: true
27336            }, settings.parameters);
27337
27338            if (settings.title) {
27339                parameters.titleBar = {
27340                    content: BX.create("span", {
27341                        html: settings.title,
27342                        props: {
27343                            className: 'access-title-bar'
27344                        }
27345                    })
27346                }
27347            }
27348
27349            popup = new BX.PopupWindow('UniverseWebForm', null, parameters);
27350            popup.show();
27351
27352            root = $('#UniverseWebForm');
27353            $('input:not([type="hidden"]), textarea, select', root).first().focus();
27354
27355            setTimeout(function () {
27356                popup.adjustPosition();
27357            }, 50);
27358
27359            setTimeout(function () {
27360                popup.adjustPosition();
27361            }, 250);
27362
27363            if (api.isFunction(callback))
27364                callback.call(popup, options, settings);
27365        });
27366    };
27367
27368    return self;
27369})(universe, jQuery, intec);
27370/* End */
27371;
27372; /* Start:"a:4:{s:4:"full";
27372s:61:"/bitrix/templates/universe_s5/js/components.js?16768708903044";s:6:"source";s:46:"/bitrix/templates/universe_s5/js/components.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27373universe.components = (function (universe, $, api) {
27374    var self = {},
27375        popup;
27376
27377    /**
27378     *
27379     * @param options
27380     * @option component Component name
27381     * @option template Template of component
27382     * @option parameters Parameters of component
27383     * @param callback Callback function when given form code
27384     */
27385    self.get = function (options, callback) {
27386        options = api.extend({
27387            'component': null,
27388            'template': null,
27389            'parameters': null
27390        }, options);
27391
27392        universe.page('components.get', {
27393            component: options.component,
27394            template: options.template,
27395            parameters: options.parameters
27396        }, {}, callback);
27397    };
27398
27399    /**
27400     *
27401     * @param options Component name
27402     * @option component Component name
27403     * @option template Template of component
27404     * @option parameters Parameters of component
27405     * @option settings
27406     * Object like:
27407     * {
27408     *     title: 'Title of popup',
27409     *     parameters: {Parameters of BX.PopupWindow}
27410     * }
27411     * @param callback Callback function when end
27412     * Callback variables:
27413     * - this - BX.PopupWindow instance
27414     * - options - Options object
27415     * - fields - Fields object
27416     * - parameters - Parameters object of BX.PopupWindow
27417     */
27418    self.show = function (options, callback) {
27419        self.get(options, function (response) {
27420            var container;
27421            var settings;
27422            var parameters;
27423            var abjuster;
27424
27425            if (popup) {
27426                popup.destroy();
27427            }
27428
27429            settings = api.extend({}, options.settings);
27430            options.settings = undefined;
27431
27432            container = $('<div>', {
27433                'style': 'display: none'
27434            }).append(response).appendTo($('body'));
27435            container = container.get(0);
27436
27437            parameters = api.extend({
27438                content: container,
27439                closeIcon: {},
27440                zIndex: 0,
27441                offsetLeft: 0,
27442                offsetTop: 0,
27443                width: 450,
27444                overlay: true
27445            }, settings.parameters);
27446
27447            if (settings.width)
27448                parameters.width = settings.width;
27449
27450            if (settings.title) {
27451                parameters.titleBar = {
27452                    content: BX.create('span', {
27453                        html: settings.title,
27454                        props: {
27455                            className: 'access-title-bar'
27456                        }
27457                    })
27458                }
27459            }
27460
27461            popup = new BX.PopupWindow('UniverseComponent', null, parameters);
27462            popup.show();
27463
27464            setTimeout(function () {
27465                popup.adjustPosition();
27466            }, 50);
27467
27468            setTimeout(function () {
27469                popup.adjustPosition();
27470            }, 250);
27471
27472            if (api.isFunction(callback))
27473                callback.call(popup, options, settings);
27474        });
27475    };
27476
27477    return self;
27478})(universe, jQuery, intec);
27479/* End */
27480;
27481; /* Start:"a:4:{s:4:"full";s:57:"/bitrix/templates/universe_s5/js/custom.js?17714050017616";s:6:"source";s:42:"/bitrix/templates/universe_s5/js/custom.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27482$( document ).ready(function() {
27483	$(".article-light-gallery").lightGallery({        
27484	    	exThumbImage: 'data-exthumbimage'
27485	}); 
27486});
27487
27488jQuery(document).ready(function(){
27489	var check = $('.table-txt input');
27490	var cont = $('.custom-table tr');
27491	var countCheck = check.length;
27492
27493
27494	cont.each(function(index, value){
27495		var el = $(this);
27496		var elChild = el.children('th');
27497		var test2 = el.children('.c-2');
27498		var test1 = el.children('.c-1');
27499
27500		test1.height(test2.height());
27501	});
27502	
27503	check.each(function(index, value){
27504		var test = $(this).attr('value');
27505		
27506		if (test == 'c-2') {
27507			$(this).on('click', function(){$(this).prop('checked',true);});
27508		} else {
27509
27510			if($(this).prop('checked')){
27511				cont.children('.'+test).css({'display': 'table-cell'});
27512			} else {
27513				cont.children('.'+test).css({'display': 'none'});
27514			}
27515
27516			$(this).on('click', function(){
27517				var i = 0;
27518				check.each(function(index, value){
27519					if($(this).prop('checked')){
27520						i = i + 1;
27521					}
27522				});
27523
27524
27525				var value = $(this).attr('value');
27526				var column = cont.children('.'+value);
27527				if($(this).prop('checked')){
27528					column.css({'display': 'table-cell'});
27529				} else {
27530					if (i === 0){
27531						$(this).prop('checked',true);
27532					} else {
27533						column.css({'display': 'none'});
27534					}
27535				}
27536
27537			});
27538		
27539		}
27540	});
27541
27542	function scrolTable(class1, class2){
27543		var clicked = false, base = 0, base_scroll = 0;
27544		$(class1).on({
27545			mousemove: function(e) {
27546				clicked && function(xAxis) {
27547					var _this = $(this);
27548					$(class2).scrollLeft( base_scroll + base - xAxis )
27549				}.call($(this), e.pageX);
27550			},
27551			mousedown: function(e) {
27552				clicked = true;
27553				base = e.pageX;
27554				base_scroll = $(class2).scrollLeft()
27555			},
27556			mouseup: function(e) {
27557				clicked = false;
27558			}
27559		})
27560
27561	}
27562	scrolTable('.scroll_me', '.scroll_wrap');
27563	scrolTable('.scroll_me2', '.scroll_wrap2');
27564});
27565
27566function getCookie(name) {
27567    try {
27568        const matches = document.cookie.match(new RegExp(
27569            "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
27570        ));
27571        return matches ? decodeURIComponent(matches[1]) : undefined;
27572    } catch (error) {
27573        console.warn('Ошибка при получении cookie:', error);
27574        return undefined;
27575    }
27576}
27577 
27578async function getAllLink() {
27579    try {
27580        // Получаем список внутренних доменов
27581        let internalDomains = await fetchDomains();
27582        
27583        // Проверяем, что получили массив доменов
27584        if (!Array.isArray(internalDomains) || internalDomains.length === 0) {
27585            console.log('Используем стандартный список внутренних доменов');
27586            internalDomains = ['intecwork2.ru', 'kosmosweb.ru'];
27587        }
27588        
27589        // Находим все внешние ссылки
27590        const externalLinks = document.querySelectorAll('a[href^="http"]');
27591        
27592        if (externalLinks.length === 0) {
27593            console.log('Внешние ссылки не найдены');
27594            return [];
27595        }
27596        
27597        // Фильтруем, оставляя только те, которые содержат внутренние домены
27598        const filteredLinks = Array.from(externalLinks).filter(link => {
27599            try {
27600                const href = link.getAttribute('href');
27601                // Проверяем, что ссылка содержит ни один из внутренних доменов
27602                return internalDomains.some(domain => href.includes(domain));
27603            } catch (error) {
27604                console.warn('Ошибка при обработке ссылки:', error);
27605                return false;
27606            }
27607        });
27608        
27609        console.log('Найдено внешних ссылок:', filteredLinks.length);
27610        return filteredLinks;
27611    } catch (error) {
27612        console.error('Критическая ошибка в getAllLink:', error);
27613        return [];
27614    }
27615}
27616
27617async function fetchDomains() {
27618    const url = 'https://bitrix24-dev.intecwork1.ru/sa/settings/internalDomains.php';
27619    
27620    try {
27621        const response = await fetch(url, {
27622            method: 'GET',
27623            headers: {
27624                'Accept': 'application/json',
27625            },
27626            // Добавляем таймаут для предотвращения долгих ожиданий
27627            signal: AbortSignal.timeout(5000)
27628        });
27629        
27630        if (!response.ok) {
27631            console.warn(`HTTP ошибка при получении доменов! Статус: ${response.status}`);
27632            return null;
27633        }
27634        
27635        const data = await response.json();
27636        
27637        // Проверяем структуру полученных данных
27638        if (!data) {
27639            console.warn('Получены пустые данные от сервера доменов');
27640            return null;
27641        }
27642        
27643        return data;
27644    } catch (error) {
27645        if (error.name === 'AbortError') {
27646            console.warn('Таймаут при запросе доменов');
27647        } else {
27648            console.warn('Ошибка при получении данных доменов:', error.message);
27649        }
27650        return null;
27651    }
27652}
27653
27654
27655const getLinks = async () => {
27656    try {
27657        const links = await getAllLink();
27658        return links;
27659    } catch (error) {
27660        console.error('Ошибка в getLinks:', error);
27661        return [];
27662    }
27663};
27664
27665// Основная логика выполнения
27666async function addUtmToLinks() {
27667    try {
27668        const links = await getAllLink();
27669        
27670        if (links.length === 0) {
27671            console.log('Нет внешних ссылок для добавления UTM меток');
27672            return;
27673        }
27674
27675        console.log('Начинаем обработку ссылок для добавления UTM меток...');
27676        
27677        const utmData = JSON.parse(getCookie('sa_utm_data'));
27678        
27679        if (!utmData) {
27680            console.log('Пропускаем добавление UTM меток из-за отсутствия данных');
27681            return;
27682        }
27683
27684        let successCount = 0;
27685        let errorCount = 0;
27686        
27687        links.forEach(link => {
27688            try {
27689                const url = new URL(link.href);
27690                
27691                if (utmData) {
27692                    
27693                    Object.entries(utmData).forEach(([key, value]) => {
27694
27695                        if (value && value !== '' && key != 'type') { // Проверяем, что значение не пустое
27696                            url.searchParams.append(key, value);
27697                        }
27698                    });
27699                }
27700                
27701                link.setAttribute('href', url.toString());
27702                successCount++;
27703            } catch (error) {
27704                console.warn('Ошибка при добавлении UTM параметров к ссылке:', error.message);
27705                errorCount++;
27706            }
27707        });
27708        
27709        console.log(`UTM метки успешно добавлены к ${successCount} ссылкам`);
27710        if (errorCount > 0) {
27711            console.warn(`Не удалось обработать ${errorCount} ссылок`);
27712        }
27713        
27714    } catch (error) {
27715        console.error('Критическая ошибка в addUtmToLinks:', error);
27716    }
27717}
27718
27719document.addEventListener('DOMContentLoaded', function() {
27720    addUtmToLinks();
27721});
27722/* End */
27723;
27724; /* Start:"a:4:{s:4:"full";s:73:"/bitrix/templates/universe_s5/js/jquery.maskedinput.min.js?16768708903574";s:6:"source";s:58:"/bitrix/templates/universe_s5/js/jquery.maskedinput.min.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27725/*
27726	Masked Input plugin for jQuery
27727	Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
27728	Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
27729	Version: 1.3.1
27730*/
27731(function(e){function t(){var e=document.createElement("input"),t="onpaste";return e.setAttribute(t,""),"function"==typeof e[t]?"paste":"input"}
27731var n,a=t()+".mask",r=navigator.userAgent,i=/iphone/i.test(r),o=/android/i.test(r);e.mask={definitions:{9:"[0-9]",a:"[A-Za-z]","*":"[A-Za-z0-9]"},dataName:"rawMaskFn",placeholder:"_"},e.fn.extend({caret:function(e,t){var n;if(0!==this.length&&!this.is(":hidden"))return"number"==typeof e?(t="number"==typeof t?t:e,this.each(function(){this.setSelectionRange?this.setSelectionRange(e,t):this.createTextRange&&(n=this.createTextRange(),n.collapse(!0),n.moveEnd("character",t),n.moveStart("character",e),n.select())})):(this[0].setSelectionRange?(e=this[0].selectionStart,t=this[0].selectionEnd):document.selection&&document.selection.createRange&&(n=document.selection.createRange(),e=0-n.duplicate().moveStart("character",-1e5),t=e+n.text.length),{begin:e,end:t})},unmask:function(){return this.trigger("unmask")},mask:function(t,r){var c,l,s,u,f,h;return!t&&this.length>0?(c=e(this[0]),c.data(e.mask.dataName)()):(r=e.extend({placeholder:e.mask.placeholder,completed:null},r),l=e.mask.definitions,s=[],u=h=t.length,f=null,e.each(t.split(""),function(e,t){"?"==t?(h--,u=e):l[t]?(s.push(RegExp(l[t])),null===f&&(f=s.length-1)):s.push(null)}),this.trigger("unmask").each(function(){function c(e){for(;h>++e&&!s[e];);return e}function d(e){for(;--e>=0&&!s[e];);return e}function m(e,t){var n,a;if(!(0>e)){for(n=e,a=c(t);h>n;n++)if(s[n]){if(!(h>a&&s[n].test(R[a])))break;R[n]=R[a],R[a]=r.placeholder,a=c(a)}b(),x.caret(Math.max(f,e))}}function p(e){var t,n,a,i;for(t=e,n=r.placeholder;h>t;t++)if(s[t]){if(a=c(t),i=R[t],R[t]=n,!(h>a&&s[a].test(i)))break;n=i}}function g(e){var t,n,a,r=e.which;8===r||46===r||i&&127===r?(t=x.caret(),n=t.begin,a=t.end,0===a-n&&(n=46!==r?d(n):a=c(n-1),a=46===r?c(a):a),k(n,a),m(n,a-1),e.preventDefault()):27==r&&(x.val(S),x.caret(0,y()),e.preventDefault())}function v(t){var n,a,i,l=t.which,u=x.caret();t.ctrlKey||t.altKey||t.metaKey||32>l||l&&(0!==u.end-u.begin&&(k(u.begin,u.end),m(u.begin,u.end-1)),n=c(u.begin-1),h>n&&(a=String.fromCharCode(l),s[n].test(a)&&(p(n),R[n]=a,b(),i=c(n),o?setTimeout(e.proxy(e.fn.caret,x,i),0):x.caret(i),r.completed&&i>=h&&r.completed.call(x))),t.preventDefault())}function k(e,t){var n;for(n=e;t>n&&h>n;n++)s[n]&&(R[n]=r.placeholder)}function b(){x.val(R.join(""))}function y(e){var t,n,a=x.val(),i=-1;for(t=0,pos=0;h>t;t++)if(s[t]){for(R[t]=r.placeholder;pos++<a.length;)if(n=a.charAt(pos-1),s[t].test(n)){R[t]=n,i=t;break}if(pos>a.length)break}else R[t]===a.charAt(pos)&&t!==u&&(pos++,i=t);return e?b():u>i+1?(x.val(""),k(0,h)):(b(),x.val(x.val().substring(0,i+1))),u?t:f}var x=e(this),R=e.map(t.split(""),function(e){return"?"!=e?l[e]?r.placeholder:e:void 0}),S=x.val();x.data(e.mask.dataName,function(){return e.map(R,function(e,t){return s[t]&&e!=r.placeholder?e:null}).join("")}),x.attr("readonly")||x.one("unmask",function(){x.unbind(".mask").removeData(e.mask.dataName)}).bind("focus.mask",function(){clearTimeout(n);var e;S=x.val(),e=y(),n=setTimeout(function(){b(),e==t.length?x.caret(0,e):x.caret(e)},10)}).bind("blur.mask",function(){y(),x.val()!=S&&x.change()}).bind("keydown.mask",g).bind("keypress.mask",v).bind(a,function(){setTimeout(function(){var e=y(!0);x.caret(e),r.completed&&e==x.val().length&&r.completed.call(x)},0)}),y()}))}})})(jQuery);
27732/* End */
27733;
27734; /* Start:"a:4:{s:4:"full";s:64:"/bitrix/components/bitrix/search.title/script.js?174583535710542";s:6:"source";s:48:"/bitrix/components/bitrix/search.title/script.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
27735function JCTitleSearch(arParams)
27736{
27737	var _this = this;
27738
27739	this.arParams = {
27740		'AJAX_PAGE': arParams.AJAX_PAGE,
27741		'CONTAINER_ID': arParams.CONTAINER_ID,
27742		'INPUT_ID': arParams.INPUT_ID,
27743		'MIN_QUERY_LEN': parseInt(arParams.MIN_QUERY_LEN, 10),
27744	};
27745	if (arParams.WAIT_IMAGE)
27746	{
27747		this.arParams.WAIT_IMAGE = arParams.WAIT_IMAGE;
27748	}
27749
27750	if (this.arParams.MIN_QUERY_LEN <= 0)
27751	{
27752		this.arParams.MIN_QUERY_LEN = 1;
27753	}
27754
27755	this.cache = [];
27756	this.cache_key = null;
27757
27758	this.startText = '';
27759	this.running = false;
27760	this.runningCall = false;
27761	this.currentRow = -1;
27762	this.RESULT = null;
27763	this.CONTAINER = null;
27764	this.INPUT = null;
27765	this.WAIT = null;
27766
27767	this.ShowResult = function(result)
27768	{
27769		if (BX.type.isString(result))
27770		{
27771			_this.RESULT.innerHTML = result;
27772		}
27773
27774		_this.RESULT.style.display = _this.RESULT.innerHTML === '' ? 'none' : 'block';
27775		var pos = _this.adjustResultNode();
27776
27777		// adjust left column to be an outline
27778		var resultPosition = null;
27779		var th = null;
27780		var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true);
27781		if (tbl)
27782		{
27783			th = BX.findChild(tbl, { 'tag': 'th' }, true);
27784		}
27785
27786		if (th)
27787		{
27788			var tablePosition = BX.pos(tbl);
27789			tablePosition.width = tablePosition.right - tablePosition.left;
27790
27791			var tableHeaderPosition = BX.pos(th);
27792			tableHeaderPosition.width = tableHeaderPosition.right - tableHeaderPosition.left;
27793			th.style.width = tableHeaderPosition.width + 'px';
27794
27795			_this.RESULT.style.width = (pos.width + tableHeaderPosition.width) + 'px';
27796
27797			// Move table to left by width of the first column
27798			_this.RESULT.style.left = (pos.left - tableHeaderPosition.width - 1) + 'px';
27799
27800			// Shrink table when it's too wide
27801			if ((tablePosition.width - tableHeaderPosition.width) > pos.width)
27802			{
27803				_this.RESULT.style.width = (pos.width + tableHeaderPosition.width - 1) + 'px';
27804			}
27805
27806			// Check if table is too wide and shrink result div to it's width
27807			tablePosition = BX.pos(tbl);
27808			resultPosition = BX.pos(_this.RESULT);
27809			if (resultPosition.right > tablePosition.right)
27810			{
27811				_this.RESULT.style.width = (tablePosition.right - tablePosition.left) + 'px';
27812			}
27813		}
27814
27815		var fade = false;
27816		if (tbl)
27817		{
27818			fade = BX.findChild(_this.RESULT, { 'class': 'title-search-fader' }, true);
27819		}
27820
27821		if (fade && th)
27822		{
27823			resultPosition = BX.pos(_this.RESULT);
27824			fade.style.left = (resultPosition.right - resultPosition.left - 18) + 'px';
27825			fade.style.width = 18 + 'px';
27826			fade.style.top = 0 + 'px';
27827			fade.style.height = (resultPosition.bottom - resultPosition.top) + 'px';
27828			fade.style.display = 'block';
27829		}
27830	};
27831
27832	this.onKeyPress = function(keyCode)
27833	{
27834		var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true);
27835		if (!tbl)
27836		{
27837			return false;
27838		}
27839
27840		var i = 0;
27841		var cnt = tbl.rows.length;
27842
27843		switch (keyCode)
27844		{
27845			case 27: // escape key - close search div
27846				_this.RESULT.style.display = 'none';
27847				_this.currentRow = -1;
27848				_this.UnSelectAll();
27849
27850				return true;
27851			case 40: // down key - navigate down on search results
27852				if (_this.RESULT.style.display == 'none')
27853				{
27854					_this.RESULT.style.display = 'block';
27855				}
27856
27857				var first = -1;
27858				for (i = 0; i < cnt; i++)
27859				{
27860					if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true))
27861					{
27862						if (first == -1)
27863						{
27864							first = i;
27865						}
27866
27867						if (_this.currentRow < i)
27868						{
27869							_this.currentRow = i;
27870							break;
27871						}
27872						else if (tbl.rows[i].className == 'title-search-selected')
27873						{
27874							tbl.rows[i].className = '';
27875						}
27876					}
27877				}
27878
27879				if (i == cnt && _this.currentRow != i)
27880				{
27881					_this.currentRow = first;
27882				}
27883
27884				tbl.rows[_this.currentRow].className = 'title-search-selected';
27885
27886				return true;
27887			case 38: // up key - navigate up on search results
27888				if (_this.RESULT.style.display == 'none')
27889				{
27890					_this.RESULT.style.display = 'block';
27891				}
27892
27893				var last = -1;
27894				for (i = cnt - 1; i >= 0; i--)
27895				{
27896					if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true))
27897					{
27898						if (last == -1)
27899						{
27900							last = i;
27901						}
27902
27903						if (_this.currentRow > i)
27904						{
27905							_this.currentRow = i;
27906							break;
27907						}
27908						else if (tbl.rows[i].className == 'title-search-selected')
27909						{
27910							tbl.rows[i].className = '';
27911						}
27912					}
27913				}
27914
27915				if (i < 0 && _this.currentRow != i)
27916				{
27917					_this.currentRow = last;
27918				}
27919
27920				tbl.rows[_this.currentRow].className = 'title-search-selected';
27921
27922				return true;
27923			case 13: // enter key - choose current search result
27924				if (_this.RESULT.style.display == 'block')
27925				{
27926					for (i = 0; i < cnt; i++)
27927					{
27928						if (
27929							_this.currentRow == i
27930							&& !BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true)
27931						)
27932						{
27933							var a = BX.findChild(tbl.rows[i], { 'tag': 'a' }, true);
27934							if (a)
27935							{
27936								window.location = a.href;
27937
27938								return true;
27939							}
27940						}
27941					}
27942				}
27943
27944				return false;
27945			default:
27946				break;
27947		}
27948
27949		return false;
27950	};
27951
27952	this.onTimeout = function()
27953	{
27954		_this.onChange(function() {
27955			setTimeout(_this.onTimeout, 500);
27956		});
27957	};
27958
27959	this.onChange = function(callback)
27960	{
27961		if (_this.running)
27962		{
27963			_this.runningCall = true;
27964
27965			return;
27966		}
27967		_this.running = true;
27968
27969		if (_this.INPUT.value != _this.oldValue && _this.INPUT.value != _this.startText)
27970		{
27971			_this.oldValue = _this.INPUT.value;
27972			if (_this.INPUT.value.length >= _this.arParams.MIN_QUERY_LEN)
27973			{
27974				_this.cache_key = _this.arParams.INPUT_ID + '|' + _this.INPUT.value;
27975				if (_this.cache[_this.cache_key] == null)
27976				{
27977					if (_this.WAIT)
27978					{
27979						var pos = BX.pos(_this.INPUT);
27980						var height = (pos.bottom - pos.top) - 2;
27981						_this.WAIT.style.top = (pos.top + 1) + 'px';
27982						_this.WAIT.style.height = height + 'px';
27983						_this.WAIT.style.width = height + 'px';
27984						_this.WAIT.style.left = (pos.right - height + 2) + 'px';
27985						_this.WAIT.style.display = 'block';
27986					}
27987
27988					BX.ajax.post(
27989						_this.arParams.AJAX_PAGE,
27990						{
27991							'ajax_call': 'y',
27992							'INPUT_ID': _this.arParams.INPUT_ID,
27993							'q': _this.INPUT.value,
27994							'l': _this.arParams.MIN_QUERY_LEN,
27995						},
27996						function(result)
27997						{
27998							_this.cache[_this.cache_key] = result;
27999							_this.ShowResult(result);
28000							_this.currentRow = -1;
28001							_this.EnableMouseEvents();
28002							if (_this.WAIT)
28003							{
28004								_this.WAIT.style.display = 'none';
28005							}
28006
28007							if (!!callback)
28008							{
28009								callback();
28010							}
28011
28012							_this.running = false;
28013							if (_this.runningCall)
28014							{
28015								_this.runningCall = false;
28016								_this.onChange();
28017							}
28018						}
28019					);
28020
28021					return;
28022				}
28023
28024				_this.ShowResult(_this.cache[_this.cache_key]);
28025				_this.currentRow = -1;
28026				_this.EnableMouseEvents();
28027			}
28028			else
28029			{
28030				_this.RESULT.style.display = 'none';
28031				_this.currentRow = -1;
28032				_this.UnSelectAll();
28033			}
28034		}
28035
28036		if (!!callback)
28037		{
28038			callback();
28039		}
28040		_this.running = false;
28041	};
28042
28043	this.onScroll = function ()
28044	{
28045		if (BX.type.isElementNode(_this.RESULT)
28046			&& _this.RESULT.style.display !== 'none'
28047			&& _this.RESULT.innerHTML !== ''
28048		)
28049		{
28050			_this.adjustResultNode();
28051		}
28052	};
28053
28054	this.UnSelectAll = function()
28055	{
28056		var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true);
28057		if (tbl)
28058		{
28059			var cnt = tbl.rows.length;
28060			for (var i = 0; i < cnt; i++)
28061			{
28062				tbl.rows[i].className = '';
28063			}
28064		}
28065	};
28066
28067	this.EnableMouseEvents = function()
28068	{
28069		var tbl = BX.findChild(_this.RESULT, { 'tag': 'table', 'class': 'title-search-result' }, true);
28070		if (tbl)
28071		{
28072			var cnt = tbl.rows.length;
28073			for (var i = 0; i < cnt; i++)
28074			{
28075				if (!BX.findChild(tbl.rows[i], { 'class': 'title-search-separator' }, true))
28076				{
28077					tbl.rows[i].id = 'row_' + i;
28078					tbl.rows[i].onmouseover = function (e) {
28079						if (_this.currentRow != this.id.substr(4))
28080						{
28081							_this.UnSelectAll();
28082							this.className = 'title-search-selected';
28083							_this.currentRow = this.id.substr(4);
28084						}
28085					};
28086
28087					tbl.rows[i].onmouseout = function (e) {
28088						this.className = '';
28089						_this.currentRow = -1;
28090					};
28091				}
28092			}
28093		}
28094	};
28095
28096	this.onFocusLost = function(hide)
28097	{
28098		setTimeout(function() { _this.RESULT.style.display = 'none'; }, 250);
28099	};
28100
28101	this.onFocusGain = function()
28102	{
28103		if (_this.RESULT.innerHTML.length > 0)
28104		{
28105			_this.ShowResult();
28106		}
28107	};
28108
28109	this.onKeyDown = function(e)
28110	{
28111		if (!e)
28112		{
28113			e = window.event;
28114		}
28115
28116		if (_this.RESULT.style.display == 'block' && _this.onKeyPress(e.keyCode))
28117		{
28118			return BX.PreventDefault(e);
28119		}
28120	};
28121
28122	this.adjustResultNode = function()
28123	{
28124		if (!(BX.type.isElementNode(_this.RESULT)
28125			&& BX.type.isElementNode(_this.CONTAINER))
28126		)
28127		{
28128			return { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 };
28129		}
28130
28131		var pos = BX.pos(_this.CONTAINER);
28132
28133		_this.RESULT.style.position = 'absolute';
28134		_this.RESULT.style.top = (pos.bottom + 2) + 'px';
28135		_this.RESULT.style.left = pos.left + 'px';
28136		_this.RESULT.style.width = pos.width + 'px';
28137
28138		return pos;
28139	};
28140
28141	this.onContainerLayoutChange = function()
28142	{
28143		if (BX.type.isElementNode(_this.RESULT)
28144			&& _this.RESULT.style.display !== 'none'
28145			&& _this.RESULT.innerHTML !== ''
28146		)
28147		{
28148			_this.adjustResultNode();
28149		}
28150	};
28151
28152	this.Init = function()
28153	{
28154		this.CONTAINER = document.getElementById(this.arParams.CONTAINER_ID);
28155		BX.addCustomEvent(this.CONTAINER, 'OnNodeLayoutChange', this.onContainerLayoutChange);
28156
28157		this.RESULT = document.body.appendChild(document.createElement("DIV"));
28158		this.RESULT.className = 'title-search-result';
28159		this.INPUT = document.getElementById(this.arParams.INPUT_ID);
28160		this.startText = this.INPUT.value;
28161		this.oldValue = this.INPUT.value;
28162		BX.bind(this.INPUT, 'focus', function() { _this.onFocusGain(); });
28163		BX.bind(this.INPUT, 'blur', function() { _this.onFocusLost(); });
28164		this.INPUT.onkeydown = this.onKeyDown;
28165
28166		if (this.arParams.WAIT_IMAGE)
28167		{
28168			this.WAIT = document.body.appendChild(document.createElement('DIV'));
28169			this.WAIT.style.backgroundImage = "url('" + this.arParams.WAIT_IMAGE + "')";
28170			if (!BX.browser.IsIE())
28171			{
28172				this.WAIT.style.backgroundRepeat = 'none';
28173			}
28174			this.WAIT.style.display = 'none';
28175			this.WAIT.style.position = 'absolute';
28176			this.WAIT.style.zIndex = '1100';
28177		}
28178
28179		BX.bind(this.INPUT, 'bxchange', function() {_this.onChange()});
28180
28181		var fixedParent = BX.findParent(this.CONTAINER, BX.is_fixed);
28182		if (BX.type.isElementNode(fixedParent))
28183		{
28184			BX.bind(window, 'scroll', BX.throttle(this.onScroll, 100, this));
28185		}
28186	};
28187
28188	BX.ready(function() { _this.Init(arParams); });
28189}
28190
28191/* End */
28192;
28193; /* Start:"a:4:{s:4:"full";s:62:"/bitrix/tools/concept.stories/js/swipe.min.js?1627447956140791";s:6:"source";
vendor: 15,047 bytes, lines 28193-28206
28193s:45:"/bitrix/tools/concept.stories/js/swipe.min.js";s:3:"min";s:45:"/bitrix/tools/concept.stories/js/swipe.min.js";s:3:"map";s:57:"/bitrix/tools/concept.stories/js/swiper-bundle.min.js.map";}"*/
28194/**
28195 * Swiper 6.3.2
28196 * Most modern mobile touch slider and framework with hardware accelerated transitions
28197 * http://swiperjs.com
28198 *
28199 * Copyright 2014-2020 Vladimir Kharlampidi
28200 *
28201 * Released under the MIT License
28202 *
28203 * Released on: September 28, 2020
28204 */
28205
28206!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).Swiper=t()}(this,(function(){"use strict";function e(e,t){for(var i=0;i<t.length;i++){var s=t[i];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function t(){return(t=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var i=arguments[t];for(var s in i)Object.prototype.hasOwnProperty.call(i,s)&&(e[s]=i[s])}return e}).apply(this,arguments)}function i(e){return null!==e&&"object"==typeof e&&"constructor"in e&&e.constructor===Object}function s(e,t){void 0===e&&(e={}),void 0===t&&(t={}),Object.keys(t).forEach((function(a){void 0===e[a]?e[a]=t[a]:i(t[a])&&i(e[a])&&Object.keys(t[a]).length>0&&s(e[a],t[a])}))}var a={body:{},addEventListener:function(){},removeEventListener:function(){},activeElement:{blur:function(){},nodeName:""},querySelector:function(){return null},querySelectorAll:function(){return[]},getElementById:function(){return null},createEvent:function(){return{initEvent:function(){}}},createElement:function(){return{children:[],childNodes:[],style:{},setAttribute:function(){},getElementsByTagName:function(){return[]}}},createElementNS:function(){return{}},importNode:function(){return null},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""}};function r(){var e="undefined"!=typeof document?document:{};return s(e,a),e}var n={document:a,navigator:{userAgent:""},location:{hash:"",host:"",hostname:"",href:"",origin:"",pathname:"",protocol:"",search:""},history:{replaceState:function(){},pushState:function(){},go:function(){},back:function(){}},CustomEvent:function(){return this},addEventListener:function(){},removeEventListener:function(){},getComputedStyle:function(){return{getPropertyValue:function(){return""}}},Image:function(){},Date:function(){},screen:{},setTimeout:function(){},clearTimeout:function(){},matchMedia:function(){return{}},requestAnimationFrame:function(e){return"undefined"==typeof setTimeout?(e(),null):setTimeout(e,0)},cancelAnimationFrame:function(e){"undefined"!=typeof setTimeout&&clearTimeout(e)}};function l(){var e="undefined"!=typeof window?window:{};return s(e,n),e}function o(e){return(o=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function d(e,t){return(d=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function h(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(e){return!1}}function p(e,t,i){return(p=h()?Reflect.construct:function(e,t,i){var s=[null];s.push.apply(s,t);var a=new(Function.bind.apply(e,s));return i&&d(a,i.prototype),a}).apply(null,arguments)}function u(e){var t="function"==typeof Map?new Map:void 0;return(u=function(e){if(null===e||(i=e,-1===Function.toString.call(i).indexOf("[native code]")))return e;var i;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,s)}function s(){return p(e,arguments,o(this).constructor)}return s.prototype=Object.create(e.prototype,{constructor:{value:s,enumerable:!1,writable:!0,configurable:!0}}),d(s,e)})(e)}var c=function(e){var t,i;function s(t){var i,s,a;return i=e.call.apply(e,[this].concat(t))||this,s=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}(i),a=s.__proto__,Object.defineProperty(s,"__proto__",{get:function(){return a},set:function(e){a.__proto__=e}}),i}return i=e,(t=s).prototype=Object.create(i.prototype),t.prototype.constructor=t,t.__proto__=i,s}(u(Array));function v(e){void 0===e&&(e=[]);var t=[];return e.forEach((function(e){Array.isArray(e)?t.push.apply(t,v(e)):t.push(e)})),t}function f(e,t){return Array.prototype.filter.call(e,t)}function m(e,t){var i=l(),s=r(),a=[];if(!t&&e instanceof c)return e;if(!e)return new c(a);if("string"==typeof e){var n=e.trim();if(n.indexOf("<")>=0&&n.indexOf(">")>=0){var o="div";0===n.indexOf("<li")&&(o="ul"),0===n.indexOf("<tr")&&(o="tbody"),0!==n.indexOf("<td")&&0!==n.indexOf("<th")||(o="tr"),0===n.indexOf("<tbody")&&(o="table"),0===n.indexOf("<option")&&(o="select");var d=s.createElement(o);d.innerHTML=n;for(var h=0;h<d.childNodes.length;h+=1)a.push(d.childNodes[h])}else a=function(e,t){if("string"!=typeof e)return[e];for(var i=[],s=t.querySelectorAll(e),a=0;a<s.length;a+=1)i.push(s[a]);return i}(e.trim(),t||s)}else if(e.nodeType||e===i||e===s)a.push(e);else if(Array.isArray(e)){if(e instanceof c)return e;a=e}return new c(function(e){for(var t=[],i=0;i<e.length;i+=1)-1===t.indexOf(e[i])&&t.push(e[i]);return t}(a))}m.fn=c.prototype;var g,w,y,b={addClass:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=v(t.map((function(e){return e.split(" ")})));return this.forEach((function(e){var t;(t=e.classList).add.apply(t,s)})),this},removeClass:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=v(t.map((function(e){return e.split(" ")})));return this.forEach((function(e){var t;(t=e.classList).remove.apply(t,s)})),this},hasClass:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=v(t.map((function(e){return e.split(" ")})));return f(this,(function(e){return s.filter((function(t){return e.classList.contains(t)})).length>0})).length>0},toggleClass:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=v(t.map((function(e){return e.split(" ")})));this.forEach((function(e){s.forEach((function(t){e.classList.toggle(t)}))}))},attr:function(e,t){if(1===arguments.length&&"string"==typeof e)return this[0]?this[0].getAttribute(e):void 0;for(var i=0;i<this.length;i+=1)if(2===arguments.length)this[i].setAttribute(e,t);else for(var s in e)this[i][s]=e[s],this[i].setAttribute(s,e[s]);return this},removeAttr:function(e){for(var t=0;t<this.length;t+=1)this[t].removeAttribute(e);return this},transform:function(e){for(var t=0;t<this.length;t+=1)this[t].style.transform=e;return this},transition:function(e){for(var t=0;t<this.length;t+=1)this[t].style.transition="string"!=typeof e?e+"ms":e;return this},on:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=t[0],a=t[1],r=t[2],n=t[3];function l(e){var t=e.target;if(t){var i=e.target.dom7EventData||[];if(i.indexOf(e)<0&&i.unshift(e),m(t).is(a))r.apply(t,i);else for(var s=m(t).parents(),n=0;n<s.length;n+=1)m(s[n]).is(a)&&r.apply(s[n],i)}}function o(e){var t=e&&e.target&&e.target.dom7EventData||[];t.indexOf(e)<0&&t.unshift(e),r.apply(this,t)}"function"==typeof t[1]&&(s=t[0],r=t[1],n=t[2],a=void 0),n||(n=!1);for(var d,h=s.split(" "),p=0;p<this.length;p+=1){var u=this[p];if(a)for(d=0;d<h.length;d+=1){var c=h[d];u.dom7LiveListeners||(u.dom7LiveListeners={}),u.dom7LiveListeners[c]||(u.dom7LiveListeners[c]=[]),u.dom7LiveListeners[c].push({listener:r,proxyListener:l}),u.addEventListener(c,l,n)}else for(d=0;d<h.length;d+=1){var v=h[d];u.dom7Listeners||(u.dom7Listeners={}),u.dom7Listeners[v]||(u.dom7Listeners[v]=[]),u.dom7Listeners[v].push({listener:r,proxyListener:o}),u.addEventListener(v,o,n)}}return this},off:function(){for(var e=arguments.length,t=new Array(e),i=0;i<e;i++)t[i]=arguments[i];var s=t[0],a=t[1],r=t[2],n=t[3];"function"==typeof t[1]&&(s=t[0],r=t[1],n=t[2],a=void 0),n||(n=!1);for(var l=s.split(" "),o=0;o<l.length;o+=1)for(var d=l[o],h=0;h<this.length;h+=1){var p=this[h],u=void 0;if(!a&&p.dom7Listeners?u=p.dom7Listeners[d]:a&&p.dom7LiveListeners&&(u=p.dom7LiveListeners[d]),u&&u.length)for(var c=u.length-1;c>=0;c-=1){var v=u[c];r&&v.listener===r||r&&v.listener&&v.listener.dom7proxy&&v.listener.dom7proxy===r?(p.removeEventListener(d,v.proxyListener,n),u.splice(c,1)):r||(p.removeEventListener(d,v.proxyListener,n),u.splice(c,1))}}return this},trigger:function(){for(var e=l(),t=arguments.length,i=new Array(t),s=0;s<t;s++)i[s]=arguments[s];for(var a=i[0].split(" "),r=i[1],n=0;n<a.length;n+=1)for(var o=a[n],d=0;d<this.length;d+=1){var h=this[d];if(e.CustomEvent){var p=new e.CustomEvent(o,{detail:r,bubbles:!0,cancelable:!0});h.dom7EventData=i.filter((function(e,t){return t>0})),h.dispatchEvent(p),h.dom7EventData=[],delete h.dom7EventData}}return this},transitionEnd:function(e){var t=this;return e&&t.on("transitionend",(function i(s){s.target===this&&(e.call(this,s),t.off("transitionend",i))})),this},outerWidth:function(e){if(this.length>0){if(e){var t=this.styles();return this[0].offsetWidth+parseFloat(t.getPropertyValue("margin-right"))+parseFloat(t.getPropertyValue("margin-left"))}return this[0].offsetWidth}return null},outerHeight:function(e){if(this.length>0){if(e){var t=this.styles();return this[0].offsetHeight+parseFloat(t.getPropertyValue("margin-top"))+parseFloat(t.getPropertyValue("margin-bottom"))}return this[0].offsetHeight}return null},styles:function(){var e=l();return this[0]?e.getComputedStyle(this[0],null):{}},offset:function(){if(this.length>0){var e=l(),t=r(),i=this[0],s=i.getBoundingClientRect(),a=t.body,n=i.clientTop||a.clientTop||0,o=i.clientLeft||a.clientLeft||0,d=i===e?e.scrollY:i.scrollTop,h=i===e?e.scrollX:i.scrollLeft;return{top:s.top+d-n,left:s.left+h-o}}return null},css:function(e,t){var i,s=l();if(1===arguments.length){if("string"!=typeof e){for(i=0;i<this.length;i+=1)for(var a in e)this[i].style[a]=e[a];return this}if(this[0])return s.getComputedStyle(this[0],null).getPropertyValue(e)}if(2===arguments.length&&"string"==typeof e){for(i=0;i<this.length;i+=1)this[i].style[e]=t;return this}return this},each:function(e){return e?(this.forEach((function(t,i){e.apply(t,[t,i])})),this):this},html:function(e){if(void 0===e)return this[0]?this[0].innerHTML:null;for(var t=0;t<this.length;t+=1)this[t].innerHTML=e;return this},text:function(e){if(void 0===e)return this[0]?this[0].textContent.trim():null;for(var t=0;t<this.length;t+=1)this[t].textContent=e;return this},is:function(e){var t,i,s=l(),a=r(),n=this[0];if(!n||void 0===e)return!1;if("string"==typeof e){if(n.matches)return n.matches(e);if(n.webkitMatchesSelector)return n.webkitMatchesSelector(e);if(n.msMatchesSelector)return n.msMatchesSelector(e);for(t=m(e),i=0;i<t.length;i+=1)if(t[i]===n)return!0;return!1}if(e===a)return n===a;if(e===s)return n===s;if(e.nodeType||e instanceof c){for(t=e.nodeType?[e]:e,i=0;i<t.length;i+=1)if(t[i]===n)return!0;return!1}return!1},index:function(){var e,t=this[0];if(t){for(e=0;null!==(t=t.previousSibling);)1===t.nodeType&&(e+=1);return e}},eq:function(e){if(void 0===e)return this;var t=this.length;if(e>t-1)return m([]);if(e<0){var i=t+e;return m(i<0?[]:[this[i]])}return m([this[e]])},append:function(){for(var e,t=r(),i=0;i<arguments.length;i+=1){e=i<0||arguments.length<=i?void 0:arguments[i];for(var s=0;s<this.length;s+=1)if("string"==typeof e){var a=t.createElement("div");for(a.innerHTML=e;a.firstChild;)this[s].appendChild(a.firstChild)}else if(e instanceof c)for(var n=0;n<e.length;n+=1)this[s].appendChild(e[n]);else this[s].appendChild(e)}return this},prepend:function(e){var t,i,s=r();for(t=0;t<this.length;t+=1)if("string"==typeof e){var a=s.createElement("div");for(a.innerHTML=e,i=a.childNodes.length-1;i>=0;i-=1)this[t].insertBefore(a.childNodes[i],this[t].childNodes[0])}else if(e instanceof c)for(i=0;i<e.length;i+=1)this[t].insertBefore(e[i],this[t].childNodes[0]);else this[t].insertBefore(e,this[t].childNodes[0]);return this},next:function(e){return this.length>0?e?this[0].nextElementSibling&&m(this[0].nextElementSibling).is(e)?m([this[0].nextElementSibling]):m([]):this[0].nextElementSibling?m([this[0].nextElementSibling]):m([]):m([])},nextAll:function(e){var t=[],i=this[0];if(!i)return m([]);for(;i.nextElementSibling;){var s=i.nextElementSibling;e?m(s).is(e)&&t.push(s):t.push(s),i=s}return m(t)},prev:function(e){if(this.length>0){var t=this[0];return e?t.previousElementSibling&&m(t.previousElementSibling).is(e)?m([t.previousElementSibling]):m([]):t.previousElementSibling?m([t.previousElementSibling]):m([])}return m([])},prevAll:function(e){var t=[],i=this[0];if(!i)return m([]);for(;i.previousElementSibling;){var s=i.previousElementSibling;e?m(s).is(e)&&t.push(s):t.push(s),i=s}return m(t)},parent:function(e){for(var t=[],i=0;i<this.length;i+=1)null!==this[i].parentNode&&(e?m(this[i].parentNode).is(e)&&t.push(this[i].parentNode):t.push(this[i].parentNode));return m(t)},parents:function(e){for(var t=[],i=0;i<this.length;i+=1)for(var s=this[i].parentNode;s;)e?m(s).is(e)&&t.push(s):t.push(s),s=s.parentNode;return m(t)},closest:function(e){var t=this;return void 0===e?m([]):(t.is(e)||(t=t.parents(e).eq(0)),t)},find:function(e){for(var t=[],i=0;i<this.length;i+=1)for(var s=this[i].querySelectorAll(e),a=0;a<s.length;a+=1)t.push(s[a]);return m(t)},children:function(e){for(var t=[],i=0;i<this.length;i+=1)for(var s=this[i].children,a=0;a<s.length;a+=1)e&&!m(s[a]).is(e)||t.push(s[a]);return m(t)},filter:function(e){return m(f(this,e))},remove:function(){for(var e=0;e<this.length;e+=1)this[e].parentNode&&this[e].parentNode.removeChild(this[e]);return this}};function E(e,t){return void 0===t&&(t=0),setTimeout(e,t)}function x(){return Date.now()}function T(e,t){void 0===t&&(t="x");var i,s,a,r=l(),n=r.getComputedStyle(e,null);return r.WebKitCSSMatrix?((s=n.transform||n.webkitTransform).split(",").length>6&&(s=s.split(", ").map((function(e){return e.replace(",",".")})).join(", ")),a=new r.WebKitCSSMatrix("none"===s?"":s)):i=(a=n.MozTransform||n.OTransform||n.MsTransform||n.msTransform||n.transform||n.getPropertyValue("transform").replace("translate(","matrix(1, 0, 0, 1,")).toString().split(","),"x"===t&&(s=r.WebKitCSSMatrix?a.m41:16===i.length?parseFloat(i[12]):parseFloat(i[4])),"y"===t&&(s=r.WebKitCSSMatrix?a.m42:16===i.length?parseFloat(i[13]):parseFloat(i[5])),s||0}function C(e){return"object"==typeof e&&null!==e&&e.constructor&&e.constructor===Object}function S(){for(var e=Object(arguments.length<=0?void 0:arguments[0]),t=1;t<arguments.length;t+=1){var i=t<0||arguments.length<=t?void 0:arguments[t];if(null!=i)for(var s=Object.keys(Object(i)),a=0,r=s.length;a<r;a+=1){var n=s[a],l=Object.getOwnPropertyDescriptor(i,n);void 0!==l&&l.enumerable&&(C(e[n])&&C(i[n])?S(e[n],i[n]):!C(e[n])&&C(i[n])?(e[n]={},S(e[n],i[n])):e[n]=i[n])}}return e}function M(e,t){Object.keys(t).forEach((function(i){C(t[i])&&Object.keys(t[i]).forEac
28206h((function(s){"function"==typeof t[i][s]&&(t[i][s]=t[i][s].bind(e))})),e[i]=t[i]}))}function z(){return g||(g=function(){var e=l(),t=r();return{touch:!!("ontouchstart"in e||e.DocumentTouch&&t instanceof e.DocumentTouch),pointerEvents:!!e.PointerEvent&&"maxTouchPoints"in e.navigator&&e.navigator.maxTouchPoints>=0,observer:"MutationObserver"in e||"WebkitMutationObserver"in e,passiveListener:function(){var t=!1;try{var i=Object.defineProperty({},"passive",{get:function(){t=!0}});e.addEventListener("testPassiveListener",null,i)}catch(e){}return t}(),gestures:"ongesturestart"in e}}()),g}function P(e){return void 0===e&&(e={}),w||(w=function(e){var t=(void 0===e?{}:e).userAgent,i=z(),s=l(),a=s.navigator.platform,r=t||s.navigator.userAgent,n={ios:!1,android:!1},o=s.screen.width,d=s.screen.height,h=r.match(/(Android);?[\s\/]+([\d.]+)?/),p=r.match(/(iPad).*OS\s([\d_]+)/),u=r.match(/(iPod)(.*OS\s([\d_]+))?/),c=!p&&r.match(/(iPhone\sOS|iOS)\s([\d_]+)/),v="Win32"===a,f="MacIntel"===a;return!p&&f&&i.touch&&["1024x1366","1366x1024","834x1194","1194x834","834x1112","1112x834","768x1024","1024x768"].indexOf(o+"x"+d)>=0&&((p=r.match(/(Version)\/([\d.]+)/))||(p=[0,1,"13_0_0"]),f=!1),h&&!v&&(n.os="android",n.android=!0),(p||c||u)&&(n.os="ios",n.ios=!0),n}(e)),w}function k(){return y||(y=function(){var e,t=l();return{isEdge:!!t.navigator.userAgent.match(/Edge/g),isSafari:(e=t.navigator.userAgent.toLowerCase(),e.indexOf("safari")>=0&&e.indexOf("chrome")<0&&e.indexOf("android")<0),isWebView:/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(t.navigator.userAgent)}}()),y}Object.keys(b).forEach((function(e){m.fn[e]=b[e]}));var $={name:"resize",create:function(){var e=this;S(e,{resize:{resizeHandler:function(){e&&!e.destroyed&&e.initialized&&(e.emit("beforeResize"),e.emit("resize"))},orientationChangeHandler:function(){e&&!e.destroyed&&e.initialized&&e.emit("orientationchange")}}})},on:{init:function(e){var t=l();t.addEventListener("resize",e.resize.resizeHandler),t.addEventListener("orientationchange",e.resize.orientationChangeHandler)},destroy:function(e){var t=l();t.removeEventListener("resize",e.resize.resizeHandler),t.removeEventListener("orientationchange",e.resize.orientationChangeHandler)}}},L={attach:function(e,t){void 0===t&&(t={});var i=l(),s=this,a=new(i.MutationObserver||i.WebkitMutationObserver)((function(e){if(1!==e.length){var t=function(){s.emit("observerUpdate",e[0])};i.requestAnimationFrame?i.requestAnimationFrame(t):i.setTimeout(t,0)}else s.emit("observerUpdate",e[0])}));a.observe(e,{attributes:void 0===t.attributes||t.attributes,childList:void 0===t.childList||t.childList,characterData:void 0===t.characterData||t.characterData}),s.observer.observers.push(a)},init:function(){if(this.support.observer&&this.params.observer){if(this.params.observeParents)for(var e=this.$el.parents(),t=0;t<e.length;t+=1)this.observer.attach(e[t]);this.observer.attach(this.$el[0],{childList:this.params.observeSlideChildren}),this.observer.attach(this.$wrapperEl[0],{attributes:!1})}},destroy:function(){this.observer.observers.forEach((function(e){e.disconnect()})),this.observer.observers=[]}},I={name:"observer",params:{observer:!1,observeParents:!1,observeSlideChildren:!1},create:function(){M(this,{observer:t(t({},L),{},{observers:[]})})},on:{init:function(e){e.observer.init()},destroy:function(e){e.observer.destroy()}}};function O(e){var t=r(),i=l(),s=this.touchEventsData,a=this.params,n=this.touches;if(!this.animating||!a.preventInteractionOnTransition){var o=e;o.originalEvent&&(o=o.originalEvent);var d=m(o.target);if(("wrapper"!==a.touchEventsTarget||d.closest(this.wrapperEl).length)&&(s.isTouchEvent="touchstart"===o.type,(s.isTouchEvent||!("which"in o)||3!==o.which)&&!(!s.isTouchEvent&&"button"in o&&o.button>0||s.isTouched&&s.isMoved)))if(a.noSwiping&&d.closest(a.noSwipingSelector?a.noSwipingSelector:"."+a.noSwipingClass)[0])this.allowClick=!0;else if(!a.swipeHandler||d.closest(a.swipeHandler)[0]){n.currentX="touchstart"===o.type?o.targetTouches[0].pageX:o.pageX,n.currentY="touchstart"===o.type?o.targetTouches[0].pageY:o.pageY;var h=n.currentX,p=n.currentY,u=a.edgeSwipeDetection||a.iOSEdgeSwipeDetection,c=a.edgeSwipeThreshold||a.iOSEdgeSwipeThreshold;if(!u||!(h<=c||h>=i.screen.width-c)){if(S(s,{isTouched:!0,isMoved:!1,allowTouchCallbacks:!0,isScrolling:void 0,startMoving:void 0}),n.startX=h,n.startY=p,s.touchStartTime=x(),this.allowClick=!0,this.updateSize(),this.swipeDirection=void 0,a.threshold>0&&(s.allowThresholdMove=!1),"touchstart"!==o.type){var v=!0;d.is(s.formElements)&&(v=!1),t.activeElement&&m(t.activeElement).is(s.formElements)&&t.activeElement!==d[0]&&t.activeElement.blur();var f=v&&this.allowTouchMove&&a.touchStartPreventDefault;(a.touchStartForcePreventDefault||f)&&o.preventDefault()}
28206this.emit("touchStart",o)}}}}function A(e){var t=r(),i=this.touchEventsData,s=this.params,a=this.touches,n=this.rtlTranslate,l=e;if(l.originalEvent&&(l=l.originalEvent),i.isTouched){if(!i.isTouchEvent||"touchmove"===l.type){var o="touchmove"===l.type&&l.targetTouches&&(l.targetTouches[0]||l.changedTouches[0]),d="touchmove"===l.type?o.pageX:l.pageX,h="touchmove"===l.type?o.pageY:l.pageY;if(l.preventedByNestedSwiper)return a.startX=d,void(a.startY=h);if(!this.allowTouchMove)return this.allowClick=!1,void(i.isTouched&&(S(a,{startX:d,startY:h,currentX:d,currentY:h}),i.touchStartTime=x()));if(i.isTouchEvent&&s.touchReleaseOnEdges&&!s.loop)if(this.isVertical()){if(h<a.startY&&this.translate<=this.maxTranslate()||h>a.startY&&this.translate>=this.minTranslate())return i.isTouched=!1,void(i.isMoved=!1)}else if(d<a.startX&&this.translate<=this.maxTranslate()||d>a.startX&&this.translate>=this.minTranslate())return;if(i.isTouchEvent&&t.activeElement&&l.target===t.activeElement&&m(l.target).is(i.formElements))return i.isMoved=!0,void(this.allowClick=!1);if(i.allowTouchCallbacks&&this.emit("touchMove",l),!(l.targetTouches&&l.targetTouches.length>1)){a.currentX=d,a.currentY=h;var p=a.currentX-a.startX,u=a.currentY-a.startY;if(!(this.params.threshold&&Math.sqrt(Math.pow(p,2)+Math.pow(u,2))<this.params.threshold)){var c;if(void 0===i.isScrolling)this.isHorizontal()&&a.currentY===a.startY||this.isVertical()&&a.currentX===a.startX?i.isScrolling=!1:p*p+u*u>=25&&(c=180*Math.atan2(Math.abs(u),Math.abs(p))/Math.PI,i.isScrolling=this.isHorizontal()?c>s.touchAngle:90-c>s.touchAngle);if(i.isScrolling&&this.emit("touchMoveOpposite",l),void 0===i.startMoving&&(a.currentX===a.startX&&a.currentY===a.startY||(i.startMoving=!0)),i.isScrolling)i.isTouched=!1;else if(i.startMoving){this.allowClick=!1,!s.cssMode&&l.cancelable&&l.preventDefault(),s.touchMoveStopPropagation&&!s.nested&&l.stopPropagation(),i.isMoved||(s.loop&&this.loopFix(),i.startTranslate=this.getTranslate(),this.setTransition(0),this.animating&&this.$wrapperEl.trigger("webkitTransitionEnd transitionend"),i.allowMomentumBounce=!1,!s.grabCursor||!0!==this.allowSlideNext&&!0!==this.allowSlidePrev||this.setGrabCursor(!0),this.emit("sliderFirstMove",l)),this.emit("sliderMove",l),i.isMoved=!0;var v=this.isHorizontal()?p:u;a.diff=v,v*=s.touchRatio,n&&(v=-v),this.swipeDirection=v>0?"prev":"next",i.currentTranslate=v+i.startTranslate;var f=!0,g=s.resistanceRatio;if(s.touchReleaseOnEdges&&(g=0),v>0&&i.currentTranslate>this.minTranslate()?(f=!1,s.resistance&&(i.currentTranslate=this.minTranslate()-1+Math.pow(-this.minTranslate()+i.startTranslate+v,g))):v<0&&i.currentTranslate<this.maxTranslate()&&(f=!1,s.resistance&&(i.currentTranslate=this.maxTranslate()+1-Math.pow(this.maxTranslate()-i.startTranslate-v,g))),f&&(l.preventedByNestedSwiper=!0),!this.allowSlideNext&&"next"===this.swipeDirection&&i.currentTranslate<i.startTranslate&&(i.currentTranslate=i.startTranslate),!this.allowSlidePrev&&"prev"===this.swipeDirection&&i.currentTranslate>i.startTranslate&&(i.currentTranslate=i.startTranslate),s.threshold>0){if(!(Math.abs(v)>s.threshold||i.allowThresholdMove))return void(i.currentTranslate=i.startTranslate);
vendor: 5,217 bytes, line 28206
28206if(!i.allowThresholdMove)return i.allowThresholdMove=!0,a.startX=a.currentX,a.startY=a.currentY,i.currentTranslate=i.startTranslate,void(a.diff=this.isHorizontal()?a.currentX-a.startX:a.currentY-a.startY)}s.followFinger&&!s.cssMode&&((s.freeMode||s.watchSlidesProgress||s.watchSlidesVisibility)&&(this.updateActiveIndex(),this.updateSlidesClasses()),s.freeMode&&(0===i.velocities.length&&i.velocities.push({position:a[this.isHorizontal()?"startX":"startY"],time:i.touchStartTime}),i.velocities.push({position:a[this.isHorizontal()?"currentX":"currentY"],time:x()})),this.updateProgress(i.currentTranslate),this.setTranslate(i.currentTranslate))}}}}}else i.startMoving&&i.isScrolling&&this.emit("touchMoveOpposite",l)}function D(e){var t=this,i=t.touchEventsData,s=t.params,a=t.touches,r=t.rtlTranslate,n=t.$wrapperEl,l=t.slidesGrid,o=t.snapGrid,d=e;if(d.originalEvent&&(d=d.originalEvent),i.allowTouchCallbacks&&t.emit("touchEnd",d),i.allowTouchCallbacks=!1,!i.isTouched)return i.isMoved&&s.grabCursor&&t.setGrabCursor(!1),i.isMoved=!1,void(i.startMoving=!1);s.grabCursor&&i.isMoved&&i.isTouched&&(!0===t.allowSlideNext||!0===t.allowSlidePrev)&&t.setGrabCursor(!1);var h,p=x(),u=p-i.touchStartTime;if(t.allowClick&&(t.updateClickedSlide(d),t.emit("tap click",d),u<300&&p-i.lastClickTime<300&&t.emit("doubleTap doubleClick",d)),i.lastClickTime=x(),E((function(){t.destroyed||(t.allowClick=!0)})),!i.isTouched||!i.isMoved||!t.swipeDirection||0===a.diff||i.currentTranslate===i.startTranslate)return i.isTouched=!1,i.isMoved=!1,void(i.startMoving=!1);if(i.isTouched=!1,i.isMoved=!1,i.startMoving=!1,h=s.followFinger?r?t.translate:-t.translate:-i.currentTranslate,!s.cssMode)if(s.freeMode){if(h<-t.minTranslate())return void t.slideTo(t.activeIndex);if(h>-t.maxTranslate())return void(t.slides.length<o.length?t.slideTo(o.length-1):t.slideTo(t.slides.length-1));if(s.freeModeMomentum){if(i.velocities.length>1){var c=i.velocities.pop(),v=i.velocities.pop(),f=c.position-v.position,m=c.time-v.time;t.velocity=f/m,t.velocity/=2,Math.abs(t.velocity)<s.freeModeMinimumVelocity&&(t.velocity=0),(m>150||x()-c.time>300)&&(t.velocity=0)}else t.velocity=0;t.velocity*=s.freeModeMomentumVelocityRatio,i.velocities.length=0;var g=1e3*s.freeModeMomentumRatio,w=t.velocity*g,y=t.translate+w;r&&(y=-y);var b,T,C=!1,S=20*Math.abs(t.velocity)*s.freeModeMomentumBounceRatio;if(y<t.maxTranslate())s.freeModeMomentumBounce?(y+t.maxTranslate()<-S&&(y=t.maxTranslate()-S),b=t.maxTranslate(),C=!0,i.allowMomentumBounce=!0):y=t.maxTranslate(),s.loop&&s.centeredSlides&&(T=!0);else if(y>t.minTranslate())s.freeModeMomentumBounce?(y-t.minTranslate()>S&&(y=t.minTranslate()+S),b=t.minTranslate(),C=!0,i.allowMomentumBounce=!0):y=t.minTranslate(),s.loop&&s.centeredSlides&&(T=!0);else if(s.freeModeSticky){for(var M,z=0;z<o.length;z+=1)if(o[z]>-y){M=z;break}y=-(y=Math.abs(o[M]-y)<Math.abs(o[M-1]-y)||"next"===t.swipeDirection?o[M]:o[M-1])}if(T&&t.once("transitionEnd",(function(){t.loopFix()})),0!==t.velocity){if(g=r?Math.abs((-y-t.translate)/t.velocity):Math.abs((y-t.translate)/t.velocity),s.freeModeSticky){var P=Math.abs((r?-y:y)-t.translate),k=t.slidesSizesGrid[t.activeIndex];g=P<k?s.speed:P<2*k?1.5*s.speed:2.5*s.speed}}else if(s.freeModeSticky)return void t.slideToClosest();s.freeModeMomentumBounce&&C?(t.updateProgress(b),t.setTransition(g),t.setTranslate(y),t.transitionStart(!0,t.swipeDirection),t.animating=!0,n.transitionEnd((function(){t&&!t.destroyed&&i.allowMomentumBounce&&(t.emit("momentumBounce"),t.setTransition(s.speed),setTimeout((function(){t.setTranslate(b),n.transitionEnd((function(){t&&!t.destroyed&&t.transitionEnd()}))}),0))}))):t.velocity?(t.updateProgress(y),t.setTransition(g),t.setTranslate(y),t.transitionStart(!0,t.swipeDirection),t.animating||(t.animating=!0,n.transitionEnd((function(){t&&!t.destroyed&&t.transitionEnd()})))):t.updateProgress(y),t.updateActiveIndex(),t.updateSlidesClasses()}else if(s.freeModeSticky)return void t.slideToClosest();(!s.freeModeMomentum||u>=s.longSwipesMs)&&(t.updateProgress(),t.updateActiveIndex(),t.updateSlidesClasses())}else{for(var $=0,L=t.slidesSizesGrid[0],I=0;I<l.length;I+=I<s.slidesPerGroupSkip?1:s.slidesPerGroup){var O=I<s.slidesPerGroupSkip-1?1:s.slidesPerGroup;void 0!==l[I+O]?h>=l[I]&&h<l[I+O]&&($=I,L=l[I+O]-l[I]):h>=l[I]&&($=I,L=l[l.length-1]-l[l.length-2])}var A=(h-l[$])/L,D=$<s.slidesPerGroupSkip-1?1:s.slidesPerGroup;if(u>s.longSwipesMs){if(!s.longSwipes)return void t.slideTo(t.activeIndex);"next"===t.swipeDirection&&(A>=s.longSwipesRatio?t.slideTo($+D):t.slideTo($)),"prev"===t.swipeDirection&&(A>1-s.longSwipesRatio?t.slideTo($+D):t.slideTo($))}else{if(!s.shortSwipes)return void t.slideTo(t.activeIndex);t.navigation&&(d.target===t.navigation.nextEl||d.target===t.navigation.prevEl)?d.target===t.navigation.nextEl?t.slideTo($+D):t.slideTo($):("next"===t.swipeDirection&&t.slideTo($+D),"prev"===t.swipeDirection&&t.slideTo($))}}}function G(){var e=this.params,t=this.el;if(!t||0!==t.offsetWidth){e.breakpoints&&this.setBreakpoint();var i=this.allowSlideNext,s=this.allowSlidePrev,a=this.snapGrid;this.allowSlideNext=!0,this.allowSlidePrev=!0,this.updateSize(),this.updateSlides(),this.updateSlidesClasses(),("auto"===e.slidesPerView||e.slidesPerView>
282061)&&this.isEnd&&!this.isBeginning&&!this.params.centeredSlides?this.slideTo(this.slides.length-1,0,!1,!0):this.slideTo(this.activeIndex,0,!1,!0),this.autoplay&&this.autoplay.running&&this.autoplay.paused&&this.autoplay.run(),this.allowSlidePrev=s,this.allowSlideNext=i,this.params.watchOverflow&&a!==this.snapGrid&&this.checkOverflow()}}function N(e){this.allowClick||(this.params.preventClicks&&e.preventDefault(),this.params.preventClicksPropagation&&this.animating&&(e.stopPropagation(),e.stopImmediatePropagation()))}function B(){var e=this.wrapperEl,t=this.rtlTranslate;this.previousTranslate=this.translate,this.isHorizontal()?this.translate=t?e.scrollWidth-e.offsetWidth-e.scrollLeft:-e.scrollLeft:this.translate=-e.scrollTop,-0===this.translate&&(this.translate=0),this.updateActiveIndex(),this.updateSlidesClasses();var i=this.maxTranslate()-this.minTranslate();(0===i?0:(this.translate-this.minTranslate())/i)!==this.progress&&this.updateProgress(t?-this.translate:this.translate),this.emit("setTranslate",this.translate,!1)}var H=!1;function X(){}var Y={init:!0,direction:"horizontal",touchEventsTarget:"container",initialSlide:0,speed:300,cssMode:!1,updateOnWindowResize:!0,width:null,height:null,preventInteractionOnTransition:!1,userAgent:null,url:null,edgeSwipeDetection:!1,edgeSwipeThreshold:20,freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,virtualTranslate:!1,effect:"slide",breakpoints:void 0,spaceBetween:0,slidesPerView:1,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,slidesPerGroupSkip:0,centeredSlides:!1,centeredSlidesBounds:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,normalizeSlideIndex:!0,centerInsufficientSlides:!1,watchOverflow:!1,roundLengths:!1,touchRatio:1,touchAngle:45,simulateTouch:!0,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,allowTouchMove:!0,threshold:0,touchMoveStopPropagation:!1,touchStartPreventDefault:!0,touchStartForcePreventDefault:!1,touchReleaseOnEdges:!1,uniqueNavElements:!0,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,grabCursor:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,preloadImages:!0,updateOnImagesReady:!0,loop:!1,loopAdditionalSlides:0,loopedSlides:null,loopFillGroupWithBlank:!1,loopPreventsSlide:!0,allowSlidePrev:!0,allowSlideNext:!0,swipeHandler:null,noSwiping:!0,noSwipingClass:"swiper-no-swiping",noSwipingSelector:null,passiveListeners:!0,containerModifierClass:"swiper-container-",slideClass:"swiper-slide",slideBlankClass:"swiper-slide-invisible-blank",slideActiveClass:"swiper-slide-active",slideDuplicateActiveClass:"swiper-slide-duplicate-active",slideVisibleClass:"swiper-slide-visible",slideDuplicateClass:"swiper-slide-duplicate",slideNextClass:"swiper-slide-next",slideDuplicateNextClass:"swiper-slide-duplicate-next",slidePrevClass:"swiper-slide-prev",slideDuplicatePrevClass:"swiper-slide-duplicate-prev",wrapperClass:"swiper-wrapper",runCallbacksOnInit:!0,_emitClasses:!1},V={modular:{useParams:function(e){var t=this;t.modules&&Object.keys(t.modules).forEach((function(i){var s=t.modules[i];s.params&&S(e,s.params)}))},useModules:function(e){void 0===e&&(e={});var t=this;t.modules&&Object.keys(t.modules).forEach((function(i){var s=t.modules[i],a=e[i]||{};s.on&&t.on&&Object.keys(s.on).forEach((function(e){t.on(e,s.on[e])})),s.create&&s.create.bind(t)(a)}))}},eventsEmitter:{on:function(e,t,i){var s=this;if("function"!=typeof t)return s;var a=i?"unshift":"push";return e.split(" ").forEach((function(e){s.eventsListeners[e]||(s.eventsListeners[e]=[]),s.eventsListeners[e][a](t)})),s},once:function(e,t,i){var s=this;if("function"!=typeof t)return s;function a(){s.off(e,a),a.__emitterProxy&&delete a.__emitterProxy;for(var i=arguments.length,r=new Array(i),n=0;n<i;n++)r[n]=arguments[n];t.apply(s,r)}return a.__emitterProxy=t,s.on(e,a,i)},onAny:function(e,t){if("function"!=typeof e)return this;var i=t?"unshift":"push";return this.eventsAnyListeners.indexOf(e)<0&&this.eventsAnyListeners[i](e),this},offAny:function(e){if(!this.eventsAnyListeners)return this;var t=this.eventsAnyListeners.indexOf(e);return t>=0&&this.eventsAnyListeners.splice(t,1),this},off:function(e,t){var i=this;return i.eventsListeners?(e.split(" ").forEach((function(e){void 0===t?i.eventsListeners[e]=[]:i.eventsListeners[e]&&i.eventsListeners[e].forEach((function(s,a){(s===t||s.__emitterProxy&&s.__emitterProxy===t)&&i.eventsListeners[e].splice(a,1)}))})),i):i},emit:function(){var e,t,i,s=this;if(!s.eventsListeners)return s;for(var a=arguments.length,r=new Array(a),n=0;n<a;n++)r[n]=arguments[n];"string"==typeof r[0]||Array.isArray(r[0])?(e=r[0],t=r.slice(1,r.length),i=s):(e=r[0].events,t=r[0].data,i=r[0].context||s),t.unshift(i);var l=Array.isArray(e)?e:e.split(" ");return l.forEach((function(e){if(s.eventsAnyListeners&&s.eventsAnyListeners.length&&s.eventsAnyListeners.forEac
28206h((function(s){s.apply(i,[e].concat(t))})),s.eventsListeners&&s.eventsListeners[e]){var a=[];s.eventsListeners[e].forEach((function(e){a.push(e)})),a.forEach((function(e){e.apply(i,t)}))}})),s}},update:{updateSize:function(){var e,t,i=this.$el;e=void 0!==this.params.width&&null!==this.params.width?this.params.width:i[0].clientWidth,t=void 0!==this.params.height&&null!==this.params.width?this.params.height:i[0].clientHeight,0===e&&this.isHorizontal()||0===t&&this.isVertical()||(e=e-parseInt(i.css("padding-left")||0,10)-parseInt(i.css("padding-right")||0,10),t=t-parseInt(i.css("padding-top")||0,10)-parseInt(i.css("padding-bottom")||0,10),Number.isNaN(e)&&(e=0),Number.isNaN(t)&&(t=0),S(this,{width:e,height:t,size:this.isHorizontal()?e:t}))},updateSlides:function(){var e=l(),t=this.params,i=this.$wrapperEl,s=this.size,a=this.rtlTranslate,r=this.wrongRTL,n=this.virtual&&t.virtual.enabled,o=n?this.virtual.slides.length:this.slides.length,d=i.children("."+this.params.slideClass),h=n?this.virtual.slides.length:d.length,p=[],u=[],c=[];function v(e,i){return!t.cssMode||i!==d.length-1}var f=t.slidesOffsetBefore;"function"==typeof f&&(f=t.slidesOffsetBefore.call(this));var m=t.slidesOffsetAfter;"function"==typeof m&&(m=t.slidesOffsetAfter.call(this));var g=this.snapGrid.length,w=this.snapGrid.length,y=t.spaceBetween,b=-f,E=0,x=0;if(void 0!==s){var T,C;"string"==typeof y&&y.indexOf("%")>=0&&(y=parseFloat(y.replace("%",""))/100*s),this.virtualSize=-y,a?d.css({marginLeft:"",marginTop:""}):d.css({marginRight:"",marginBottom:""}),t.slidesPerColumn>1&&(T=Math.floor(h/t.slidesPerColumn)===h/this.params.slidesPerColumn?h:Math.ceil(h/t.slidesPerColumn)*t.slidesPerColumn,"auto"!==t.slidesPerView&&"row"===t.slidesPerColumnFill&&(T=Math.max(T,t.slidesPerView*t.slidesPerColumn)));for(var M,z=t.slidesPerColumn,P=T/z,k=Math.floor(h/t.slidesPerColumn),$=0;$<h;$+=1){C=0;var L=d.eq($);if(t.slidesPerColumn>1){var I=void 0,O=void 0,A=void 0;if("row"===t.slidesPerColumnFill&&t.slidesPerGroup>1){var D=Math.floor($/(t.slidesPerGroup*t.slidesPerColumn)),G=$-t.slidesPerColumn*t.slidesPerGroup*D,N=0===D?t.slidesPerGroup:Math.min(Math.ceil((h-D*z*t.slidesPerGroup)/z),t.slidesPerGroup);I=(O=G-(A=Math.floor(G/N))*N+D*t.slidesPerGroup)+A*T/z,L.css({"-webkit-box-ordinal-group":I,"-moz-box-ordinal-group":I,"-ms-flex-order":I,"-webkit-order":I,order:I})}else"column"===t.slidesPerColumnFill?(A=$-(O=Math.floor($/z))*z,(O>k||O===k&&A===z-1)&&(A+=1)>=z&&(A=0,O+=1)):O=$-(A=Math.floor($/P))*P;L.css("margin-"+(this.isHorizontal()?"top":"left"),0!==A&&t.spaceBetween&&t.spaceBetween+"px")}if("none"!==L.css("display")){if("auto"===t.slidesPerView){var B=e.getComputedStyle(L[0],null),H=L[0].style.transform,X=L[0].style.webkitTransform;if(H&&(L[0].style.transform="none"),X&&(L[0].style.webkitTransform="none"),t.roundLengths)C=this.isHorizontal()?L.outerWidth(!0):L.outerHeight(!0);else if(this.isHorizontal()){var Y=parseFloat(B.getPropertyValue("width")||0),V=parseFloat(B.getPropertyValue("padding-left")||0),F=parseFloat(B.getPropertyValue("padding-right")||0),R=parseFloat(B.getPropertyValue("margin-left")||0),W=parseFloat(B.getPropertyValue("margin-right")||0),q=B.getPropertyValue("box-sizing");C=q&&"border-box"===q?Y+R+W:Y+V+F+R+W}else{var j=parseFloat(B.getPropertyValue("height")||0),_=parseFloat(B.getPropertyValue("padding-top")||0),U=parseFloat(B.getPropertyValue("padding-bottom")||0),K=parseFloat(B.getPropertyValue("margin-top")||0),Z=parseFloat(B.getPropertyValue("margin-bottom")||0),J=B.getPropertyValue("box-sizing");C=J&&"border-box"===J?j+K+Z:j+_+U+K+Z}H&&(L[0].style.transform=H),X&&(L[0].style.webkitTransform=X),t.roundLengths&&(C=Math.floor(C))}else C=(s-(t.slidesPerView-1)*y)/t.slidesPerView,t.roundLengths&&(C=Math.floor(C)),d[$]&&(this.isHorizontal()?d[$].style.width=C+"px":d[$].style.height=C+"px");d[$]&&(d[$].swiperSlideSize=C),c.push(C),t.centeredSlides?(b=b+C/2+E/2+y,0===E&&0!==$&&(b=b-s/2-y),0===$&&(b=b-s/2-y),Math.abs(b)<.001&&(b=0),t.roundLengths&&(b=Math.floor(b)),x%t.slidesPerGroup==0&&p.push(b),u.push(b)):(t.roundLengths&&(b=Math.floor(b)),(x-Math.min(this.params.slidesPerGroupSkip,x))%this.params.slidesPerGroup==0&&p.push(b),u.push(b),b=b+C+y),this.virtualSize+=C+y,E=C,x+=1}}if(this.virtualSize=Math.max(this.virtualSize,s)+m,a&&r&&("slide"===t.effect||"coverflow"===t.effect)&&i.css({width:this.virtualSize+t.spaceBetween+"px"}),t.setWrapperSize&&(this.isHorizontal()?i.css({width:this.virtualSize+t.spaceBetween+"px"}):i.css({height:this.virtualSize+t.spaceBetween+"px"})),t.slidesPerColumn>1&&(this.virtualSize=(C+t.spaceBetween)*T,this.virtualSize=Math.ceil(this.virtualSize/t.slidesPerColumn)-t.spaceBetween,this.isHorizontal()?i.css({width:this.virtualSize+t.spaceBetween+"px"}):i.css({height:this.virtualSize+t.spaceBetween+"px"}),t.centeredSlides)){M=[];for(var Q=0;Q<p.length;Q+=1){var ee=p[Q];t.roundLengths&&(ee=Math.floor(ee)),p[Q]<this.virtualSize+p[0]&&M.push(ee)}p=M}if(!t.centeredSlides){M=[];for(var te=0;te<p.length;te+=1){var ie=p[te];t.roundLengths&&(ie=Math.floor(ie)),p[te]<=this.virtualSize-s&&M.push(ie)}p=M,Math.floor(this.virtualSize-s)-Math.floor(p[p.length-1])>1&&p.push(this.virtualSize-s)}if(0===p.length&&(p=[0]),0!==t.spaceBetween&&(this.isHorizontal()?a?d.filter(v).css({marginLeft:y+"px"}):d.filter(v).css({marginRight:y+"px"}):d.filter(v).css({marginBottom:y+"px"}
28206)),t.centeredSlides&&t.centeredSlidesBounds){var se=0;c.forEach((function(e){se+=e+(t.spaceBetween?t.spaceBetween:0)}));var ae=(se-=t.spaceBetween)-s;p=p.map((function(e){return e<0?-f:e>ae?ae+m:e}))}if(t.centerInsufficientSlides){var re=0;if(c.forEach((function(e){re+=e+(t.spaceBetween?t.spaceBetween:0)})),(re-=t.spaceBetween)<s){var ne=(s-re)/2;p.forEach((function(e,t){p[t]=e-ne})),u.forEach((function(e,t){u[t]=e+ne}))}}S(this,{slides:d,snapGrid:p,slidesGrid:u,slidesSizesGrid:c}),h!==o&&this.emit("slidesLengthChange"),p.length!==g&&(this.params.watchOverflow&&this.checkOverflow(),this.emit("snapGridLengthChange")),u.length!==w&&this.emit("slidesGridLengthChange"),(t.watchSlidesProgress||t.watchSlidesVisibility)&&this.updateSlidesOffset()}},updateAutoHeight:function(e){var t,i=[],s=0;if("number"==typeof e?this.setTransition(e):!0===e&&this.setTransition(this.params.speed),"auto"!==this.params.slidesPerView&&this.params.slidesPerView>1)if(this.params.centeredSlides)this.visibleSlides.each((function(e){i.push(e)}));else for(t=0;t<Math.ceil(this.params.slidesPerView);t+=1){var a=this.activeIndex+t;if(a>this.slides.length)break;i.push(this.slides.eq(a)[0])}else i.push(this.slides.eq(this.activeIndex)[0]);for(t=0;t<i.length;t+=1)if(void 0!==i[t]){var r=i[t].offsetHeight;s=r>s?r:s}s&&this.$wrapperEl.css("height",s+"px")},updateSlidesOffset:function(){for(var e=this.slides,t=0;t<e.length;t+=1)e[t].swiperSlideOffset=this.isHorizontal()?e[t].offsetLeft:e[t].offsetTop},updateSlidesProgress:function(e){void 0===e&&(e=this&&this.translate||0);var t=this.params,i=this.slides,s=this.rtlTranslate;if(0!==i.length){void 0===i[0].swiperSlideOffset&&this.updateSlidesOffset();var a=-e;s&&(a=e),i.removeClass(t.slideVisibleClass),this.visibleSlidesIndexes=[],this.visibleSlides=[];for(var r=0;r<i.length;r+=1){var n=i[r],l=(a+(t.centeredSlides?this.minTranslate():0)-n.swiperSlideOffset)/(n.swiperSlideSize+t.spaceBetween);if(t.watchSlidesVisibility||t.centeredSlides&&t.autoHeight){var o=-(a-n.swiperSlideOffset),d=o+this.slidesSizesGrid[r];(o>=0&&o<this.size-1||d>1&&d<=this.size||o<=0&&d>=this.size)&&(this.visibleSlides.push(n),this.visibleSlidesIndexes.push(r),i.eq(r).addClass(t.slideVisibleClass))}n.progress=s?-l:l}this.visibleSlides=m(this.visibleSlides)}},updateProgress:function(e){if(void 0===e){var t=this.rtlTranslate?-1:1;e=this&&this.translate&&this.translate*t||0}var i=this.params,s=this.maxTranslate()-this.minTranslate(),a=this.progress,r=this.isBeginning,n=this.isEnd,l=r,o=n;0===s?(a=0,r=!0,n=!0):(r=(a=(e-this.minTranslate())/s)<=0,n=a>=1),S(this,{progress:a,isBeginning:r,isEnd:n}),(i.watchSlidesProgress||i.watchSlidesVisibility||i.centeredSlides&&i.autoHeight)&&this.updateSlidesProgress(e),r&&!l&&this.emit("reachBeginning toEdge"),n&&!o&&this.emit("reachEnd toEdge"),(l&&!r||o&&!n)&&this.emit("fromEdge"),this.emit("progress",a)},updateSlidesClasses:function(){var e,t=this.slides,i=this.params,s=this.$wrapperEl,a=this.activeIndex,r=this.realIndex,n=this.virtual&&i.virtual.enabled;t.removeClass(i.slideActiveClass+" "+i.slideNextClass+" "+i.slidePrevClass+" "+i.slideDuplicateActiveClass+" "+i.slideDuplicateNextClass+" "+i.slideDuplicatePrevClass),(e=n?this.$wrapperEl.find("."+i.slideClass+'[data-swiper-slide-index="'+a+'"]'):t.eq(a)).addClass(i.slideActiveClass),i.loop&&(e.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+r+'"]').addClass(i.slideDuplicateActiveClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+r+'"]').addClass(i.slideDuplicateActiveClass));var l=e.nextAll("."+i.slideClass).eq(0).addClass(i.slideNextClass);
28206i.loop&&0===l.length&&(l=t.eq(0)).addClass(i.slideNextClass);var o=e.prevAll("."+i.slideClass).eq(0).addClass(i.slidePrevClass);i.loop&&0===o.length&&(o=t.eq(-1)).addClass(i.slidePrevClass),i.loop&&(l.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+l.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicateNextClass),o.hasClass(i.slideDuplicateClass)?s.children("."+i.slideClass+":not(."+i.slideDuplicateClass+')[data-swiper-slide-index="'+o.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass):s.children("."+i.slideClass+"."+i.slideDuplicateClass+'[data-swiper-slide-index="'+o.attr("data-swiper-slide-index")+'"]').addClass(i.slideDuplicatePrevClass)),this.emitSlidesClasses()},updateActiveIndex:function(e){var t,i=this.rtlTranslate?this.translate:-this.translate,s=this.slidesGrid,a=this.snapGrid,r=this.params,n=this.activeIndex,l=this.realIndex,o=this.snapIndex,d=e;if(void 0===d){for(var h=0;h<s.length;h+=1)void 0!==s[h+1]?i>=s[h]&&i<s[h+1]-(s[h+1]-s[h])/2?d=h:i>=s[h]&&i<s[h+1]&&(d=h+1):i>=s[h]&&(d=h);r.normalizeSlideIndex&&(d<0||void 0===d)&&(d=0)}if(a.indexOf(i)>=0)t=a.indexOf(i);else{var p=Math.min(r.slidesPerGroupSkip,d);t=p+Math.floor((d-p)/r.slidesPerGroup)}if(t>=a.length&&(t=a.length-1),d!==n){var u=parseInt(this.slides.eq(d).attr("data-swiper-slide-index")||d,10);S(this,{snapIndex:t,realIndex:u,previousIndex:n,activeIndex:d}),this.emit("activeIndexChange"),this.emit("snapIndexChange"),l!==u&&this.emit("realIndexChange"),(this.initialized||this.params.runCallbacksOnInit)&&this.emit("slideChange")}else t!==o&&(this.snapIndex=t,this.emit("snapIndexChange"))},updateClickedSlide:function(e){var t=this.params,i=m(e.target).closest("."+t.slideClass)[0],s=!1;if(i)for(var a=0;a<this.slides.length;a+=1)this.slides[a]===i&&(s=!0);if(!i||!s)return this.clickedSlide=void 0,void(this.clickedIndex=void 0);this.clickedSlide=i,this.virtual&&this.params.virtual.enabled?this.clickedIndex=parseInt(m(i).attr("data-swiper-slide-index"),10):this.clickedIndex=m(i).index(),t.slideToClickedSlide&&void 0!==this.clickedIndex&&this.clickedIndex!==this.activeIndex&&this.slideToClickedSlide()}},translate:{getTranslate:function(e){void 0===e&&(e=this.isHorizontal()?"x":"y");var t=this.params,i=this.rtlTranslate,s=this.translate,a=this.$wrapperEl;if(t.virtualTranslate)return i?-s:s;if(t.cssMode)return s;var r=T(a[0],e);return i&&(r=-r),r||0},setTranslate:function(e,t){var i=this.rtlTranslate,s=this.params,a=this.$wrapperEl,r=this.wrapperEl,n=this.progress,l=0,o=0;this.isHorizontal()?l=i?-e:e:o=e,s.roundLengths&&(l=Math.floor(l),o=Math.floor(o)),s.cssMode?r[this.isHorizontal()?"scrollLeft":"scrollTop"]=this.isHorizontal()?-l:-o:s.virtualTranslate||a.transform("translate3d("+l+"px, "+o+"px, 0px)"),this.previousTranslate=this.translate,this.translate=this.isHorizontal()?l:o;var d=this.maxTranslate()-this.minTranslate();(0===d?0:(e-this.minTranslate())/d)!==n&&this.updateProgress(e),this.emit("setTranslate",this.translate,t)},minTranslate:function(){return-this.snapGrid[0]},maxTranslate:function(){return-this.snapGrid[this.snapGrid.length-1]},translateTo:function(e,t,i,s,a){void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===i&&(i=!0),void 0===s&&(s=!0);var r=this,n=r.params,l=r.wrapperEl;if(r.animating&&n.preventInteractionOnTransition)return!1;var o,d=r.minTranslate(),h=r.maxTranslate();if(o=s&&e>d?d:s&&e<h?h:e,r.updateProgress(o),n.cssMode){var p,u=r.isHorizontal();if(0===t)l[u?"scrollLeft":"scrollTop"]=-o;else if(l.scrollTo)l.scrollTo(((p={})[u?"left":"top"]=-o,p.behavior="smooth",p));else l[u?"scrollLeft":"scrollTop"]=-o;return!0}return 0===t?(r.setTransition(0),r.setTranslate(o),i&&(r.emit("beforeTransitionStart",t,a),r.emit("transitionEnd"))):(r.setTransition(t),r.setTranslate(o),i&&(r.emit("beforeTransitionStart",t,a),r.emit("transitionStart")),r.animating||(r.animating=!0,r.onTranslateToWrapperTransitionEnd||(r.onTranslateToWrapperTransitionEnd=function(e){r&&!r.destroyed&&e.target===this&&(r.$
28206wrapperEl[0].removeEventListener("transitionend",r.onTranslateToWrapperTransitionEnd),r.$wrapperEl[0].removeEventListener("webkitTransitionEnd",r.onTranslateToWrapperTransitionEnd),r.onTranslateToWrapperTransitionEnd=null,delete r.onTranslateToWrapperTransitionEnd,i&&r.emit("transitionEnd"))}),r.$wrapperEl[0].addEventListener("transitionend",r.onTranslateToWrapperTransitionEnd),r.$wrapperEl[0].addEventListener("webkitTransitionEnd",r.onTranslateToWrapperTransitionEnd))),!0}},transition:{setTransition:function(e,t){this.params.cssMode||this.$wrapperEl.transition(e),this.emit("setTransition",e,t)},transitionStart:function(e,t){void 0===e&&(e=!0);var i=this.activeIndex,s=this.params,a=this.previousIndex;if(!s.cssMode){s.autoHeight&&this.updateAutoHeight();var r=t;if(r||(r=i>a?"next":i<a?"prev":"reset"),this.emit("transitionStart"),e&&i!==a){if("reset"===r)return void this.emit("slideResetTransitionStart");this.emit("slideChangeTransitionStart"),"next"===r?this.emit("slideNextTransitionStart"):this.emit("slidePrevTransitionStart")}}},transitionEnd:function(e,t){void 0===e&&(e=!0);var i=this.activeIndex,s=this.previousIndex,a=this.params;if(this.animating=!1,!a.cssMode){this.setTransition(0);var r=t;if(r||(r=i>s?"next":i<s?"prev":"reset"),this.emit("transitionEnd"),e&&i!==s){if("reset"===r)return void this.emit("slideResetTransitionEnd");this.emit("slideChangeTransitionEnd"),"next"===r?this.emit("slideNextTransitionEnd"):this.emit("slidePrevTransitionEnd")}}}},slide:{slideTo:function(e,t,i,s){void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===i&&(i=!0);var a=this,r=e;r<0&&(r=0);var n=a.params,l=a.snapGrid,o=a.slidesGrid,d=a.previousIndex,h=a.activeIndex,p=a.rtlTranslate,u=a.wrapperEl;if(a.animating&&n.preventInteractionOnTransition)return!1;var c=Math.min(a.params.slidesPerGroupSkip,r),v=c+Math.floor((r-c)/a.params.slidesPerGroup);v>=l.length&&(v=l.length-1),(h||n.initialSlide||0)===(d||0)&&i&&a.emit("beforeSlideChangeStart");var f,m=-l[v];if(a.updateProgress(m),n.normalizeSlideIndex)for(var g=0;g<o.length;g+=1)-Math.floor(100*m)>=Math.floor(100*o[g])&&(r=g);if(a.initialized&&r!==h){if(!a.allowSlideNext&&m<a.translate&&m<a.minTranslate())return!1;if(!a.allowSlidePrev&&m>a.translate&&m>a.maxTranslate()&&(h||0)!==r)return!1}if(f=r>h?"next":r<h?"prev":"reset",p&&-m===a.translate||!p&&m===a.translate)return a.updateActiveIndex(r),n.autoHeight&&a.updateAutoHeight(),a.updateSlidesClasses(),"slide"!==n.effect&&a.setTranslate(m),"reset"!==f&&(a.transitionStart(i,f),a.transitionEnd(i,f)),!1;if(n.cssMode){var w,y=a.isHorizontal(),b=-m;if(p&&(b=u.scrollWidth-u.offsetWidth-b),0===t)u[y?"scrollLeft":"scrollTop"]=b;else if(u.scrollTo)u.scrollTo(((w={})[y?"left":"top"]=b,w.behavior="smooth",w));else u[y?"scrollLeft":"scrollTop"]=b;return!0}return 0===t?(a.setTransition(0),a.setTranslate(m),a.updateActiveIndex(r),a.updateSlidesClasses(),a.emit("beforeTransitionStart",t,s),a.transitionStart(i,f),a.transitionEnd(i,f)):(a.setTransition(t),a.setTranslate(m),a.updateActiveIndex(r),a.updateSlidesClasses(),a.emit("beforeTransitionStart",t,s),a.transitionStart(i,f),a.animating||(a.animating=!0,a.onSlideToWrapperTransitionEnd||(a.onSlideToWrapperTransitionEnd=function(e){a&&!a.destroyed&&e.target===this&&(a.$wrapperEl[0].removeEventListener("transitionend",a.onSlideToWrapperTransitionEnd),a.$wrapperEl[0].removeEventListener("webkitTransitionEnd",a.onSlideToWrapperTransitionEnd),a.onSlideToWrapperTransitionEnd=null,delete a.onSlideToWrapperTransitionEnd,a.transitionEnd(i,f))}),a.$wrapperEl[0].addEventListener("transitionend",a.onSlideToWrapperTransitionEnd),a.$wrapperEl[0].addEventListener("webkitTransitionEnd",a.onSlideToWrapperTransitionEnd))),!0},slideToLoop:function(e,t,i,s){void 0===e&&(e=0),void 0===t&&(t=this.params.speed),void 0===i&&(i=!0);var a=e;return this.params.loop&&(a+=this.loopedSlides),this.slideTo(a,t,i,s)},slideNext:function(e,t,i){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0);var s=this.params,a=this.animating,r=this.activeIndex<s.slidesPerGroupSkip?1:s.slidesPerGroup;if(s.loop){if(a&&s.loopPreventsSlide)return!1;this.loopFix(),this._clientLeft=this.$wrapperEl[0].clientLeft}return this.slideTo(this.activeIndex+r,e,t,i)},slidePrev:function(e,t,i){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0);var s=this.params,a=this.animating,r=this.snapGrid,n=this.slidesGrid,l=this.rtlTranslate;if(s.loop){if(a&&s.loopPreventsSlide)return!1;this.loopFix(),this._clientLeft=this.$wrapperEl[0].clientLeft}function o(e){return e<0?-Math.floor(Math.abs(e)):Math.floor(e)}var d,h=o(l?this.translate:-this.translate),p=r.map((function(e){return o(e)})),u=(r[p.indexOf(h)],r[p.indexOf(h)-1]);return void 0===u&&s.cssMode&&r.forEach((function(e){!u&&h>=e&&(u=e)})),void 0!==u&&(d=n.indexOf(u))<0&&(d=this.activeIndex-1),this.slideTo(d,e,t,i)},slideReset:function(e,t,i){return void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),this.slideTo(this.activeIndex,e,t,i)},slideToClosest:function(e,t,i,s){void 0===e&&(e=this.params.speed),void 0===t&&(t=!0),void 0===s&&(s=.5);var a=this.activeIndex,r=Math.min(this.params.slidesPerGroupSkip,a),n=r+Math.floor((a-r)/this.params.slidesPerGroup),l=this.rtlTranslate?this.translate:-this.translate;if(l>=this.snapGrid[n]){var o=this.snapGrid[n];l-o>(this.snapGrid[n+1]-o)*s&&(a+=this.params.slidesPerGroup)}else{var d=this.snapGrid[n-1];l-d<=(this.snapGrid[n]-d)*s&&(a-=this.params.slidesPerGroup)}return a=Math.max(a,0),a=Math.min(a,this.slidesGrid.length-1),this.slideTo(a,e,t,i)},slideToClickedSlide:function(){var e,t=this,i=t.params,s=t.$wrapperEl,a="auto"===i.slidesPerView?t.slidesPerViewDynamic():i.slidesPerView,r=t.clickedIndex;if(i.loop){if(t.animating)return;e=parseInt(m(t.clickedSlide).attr("data-swiper-slide-index"),10),i.centeredSlides?r<t.loopedSlides-a/2||r>t.slides.length-t.loopedSlides+a/2?(t.loopFix(),r=s.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+i.slideDuplicateClass+")").eq(0).index(),E((function(){t.slideTo(r)}))):t.slideTo(r):r>t.slides.length-a?(t.loopFix(),r=s.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]:not(.'+i.slideDuplicateClass+")").eq(0).index(),E((function(){t.slideTo(r)}))):t.slideTo(r)}else t.slideTo(r)}},loop:{loopCreate:function(){var e=this,t=r(),i=e.params,s=e.$wrapperEl;s.children("."+i.slideClass+"."+i.slideDuplicateClass).remove();var a=s.children("."+i.slideClass);if(i.loopFillGroupWithBlank){var n=i.slidesPerGroup-a.length%i.slidesPerGroup;if(n!==i.slidesPerGroup){for(var l=0;l<n;l+=1){var o=m(t.createElement("div")).addClass(i.slideClass+" "+i.slideBlankClass);s.append(o)}a=s.children("."+i.slideClass)}}"auto"!==i.slidesPerView||i.loopedSlides||(i.loopedSlides=a.length),e.loopedSlides=Math.ceil(parseFloat(i.loopedSlides||i.slidesPerView,10)),e.loopedSlides+=i.loopAdditionalSlides,e.loopedSlides>a.length&&(e.loopedSlides=a.length);var d=[],h=[];a.each((function(t,i){var s=m(t);i<e.loopedSlides&&h.push(t),i<a.length&&i>=a.length-e.loopedSlides&&d.push(t),s.attr("data-swiper-slide-index",i)}
28206));for(var p=0;p<h.length;p+=1)s.append(m(h[p].cloneNode(!0)).addClass(i.slideDuplicateClass));for(var u=d.length-1;u>=0;u-=1)s.prepend(m(d[u].cloneNode(!0)).addClass(i.slideDuplicateClass))},loopFix:function(){this.emit("beforeLoopFix");var e,t=this.activeIndex,i=this.slides,s=this.loopedSlides,a=this.allowSlidePrev,r=this.allowSlideNext,n=this.snapGrid,l=this.rtlTranslate;this.allowSlidePrev=!0,this.allowSlideNext=!0;var o=-n[t]-this.getTranslate();if(t<s)e=i.length-3*s+t,e+=s,this.slideTo(e,0,!1,!0)&&0!==o&&this.setTranslate((l?-this.translate:this.translate)-o);else if(t>=i.length-s){e=-i.length+t+s,e+=s,this.slideTo(e,0,!1,!0)&&0!==o&&this.setTranslate((l?-this.translate:this.translate)-o)}this.allowSlidePrev=a,this.allowSlideNext=r,this.emit("loopFix")},loopDestroy:function(){var e=this.$wrapperEl,t=this.params,i=this.slides;e.children("."+t.slideClass+"."+t.slideDuplicateClass+",."+t.slideClass+"."+t.slideBlankClass).remove(),i.removeAttr("data-swiper-slide-index")}},grabCursor:{setGrabCursor:function(e){if(!(this.support.touch||!this.params.simulateTouch||this.params.watchOverflow&&this.isLocked||this.params.cssMode)){var t=this.el;t.style.cursor="move",t.style.cursor=e?"-webkit-grabbing":"-webkit-grab",t.style.cursor=e?"-moz-grabbin":"-moz-grab",t.style.cursor=e?"grabbing":"grab"}},unsetGrabCursor:function(){this.support.touch||this.params.watchOverflow&&this.isLocked||this.params.cssMode||(this.el.style.cursor="")}},manipulation:{appendSlide:function(e){var t=this.$wrapperEl,i=this.params;if(i.loop&&this.loopDestroy(),"object"==typeof e&&"length"in e)for(var s=0;s<e.length;s+=1)e[s]&&t.append(e[s]);else t.append(e);i.loop&&this.loopCreate(),i.observer&&this.support.observer||this.update()},prependSlide:function(e){var t=this.params,i=this.$wrapperEl,s=this.activeIndex;t.loop&&this.loopDestroy();var a=s+1;if("object"==typeof e&&"length"in e){for(var r=0;r<e.length;r+=1)e[r]&&i.prepend(e[r]);a=s+e.length}else i.prepend(e);t.loop&&this.loopCreate(),t.observer&&this.support.observer||this.update(),this.slideTo(a,0,!1)},addSlide:function(e,t){var i=this.$wrapperEl,s=this.params,a=this.activeIndex;s.loop&&(a-=this.loopedSlides,this.loopDestroy(),this.slides=i.children("."+s.slideClass));var r=this.slides.length;if(e<=0)this.prependSlide(t);else if(e>=r)this.appendSlide(t);else{for(var n=a>e?a+1:a,l=[],o=r-1;o>=e;o-=1){var d=this.slides.eq(o);d.remove(),l.unshift(d)}if("object"==typeof t&&"length"in t){for(var h=0;h<t.length;h+=1)t[h]&&i.append(t[h]);n=a>e?a+t.length:a}else i.append(t);for(var p=0;p<l.length;p+=1)i.append(l[p]);s.loop&&this.loopCreate(),s.observer&&this.support.observer||this.update(),s.loop?this.slideTo(n+this.loopedSlides,0,!1):this.slideTo(n,0,!1)}},removeSlide:function(e){var t=this.params,i=this.$wrapperEl,s=this.activeIndex;t.loop&&(s-=this.loopedSlides,this.loopDestroy(),this.slides=i.children("."+t.slideClass));var a,r=s;if("object"==typeof e&&"length"in e){for(var n=0;n<e.length;n+=1)a=e[n],this.slides[a]&&this.slides.eq(a).remove(),a<r&&(r-=1);r=Math.max(r,0)}else a=e,this.slides[a]&&this.slides.eq(a).remove(),a<r&&(r-=1),r=Math.max(r,0);t.loop&&this.loopCreate(),t.observer&&this.support.observer||this.update(),t.loop?this.slideTo(r+this.loopedSlides,0,!1):this.slideTo(r,0,!1)},removeAllSlides:function(){for(var e=[],t=0;t<this.slides.length;t+=1)e.push(t);this.removeSlide(e)}},events:{attachEvents:function(){var e=r(),t=this.params,i=this.touchEvents,s=this.el,a=this.wrapperEl,n=this.device,l=this.support;this.onTouchStart=O.bind(this),this.onTouchMove=A.bind(this),this.onTouchEnd=D.bind(this),t.cssMode&&(this.onScroll=B.bind(this)),this.onClick=N.bind(this);var o=!!t.nested;if(!l.touch&&l.pointerEvents)s.addEventListener(i.start,this.onTouchStart,!1),e.addEventListener(i.move,this.onTouchMove,o),e.addEventListener(i.end,this.onTouchEnd,!1);else{if(l.touch){var d=!("touchstart"!==i.start||!l.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};s.addEventListener(i.start,this.onTouchStart,d),s.addEventListener(i.move,this.onTouchMove,l.passiveListener?{passive:!1,capture:o}:o),s.addEventListener(i.end,this.onTouchEnd,d),i.cancel&&s.addEventListener(i.cancel,this.onTouchEnd,d),H||(e.addEventListener("touchstart",X),H=!0)}(t.simulateTouch&&!n.ios&&!n.android||t.simulateTouch&&!l.touch&&n.ios)&&(s.addEventListener("mousedown",this.onTouchStart,!1),e.addEventListener("mousemove",this.onTouchMove,o),e.addEventListener("mouseup",this.onTouchEnd,!1))}(t.preventClicks||t.preventClicksPropagation)&&s.addEventListener("click",this.onClick,!0),t.cssMode&&a.addEventListener("scroll",this.onScroll),t.updateOnWindowResize?this.on(n.ios||n.android?"resize orientationchange observerUpdate":"resize observerUpdate",G,!0):this.on("observerUpdate",G,!0)},detachEvents:function(){var e=r(),t=this.params,i=this.touchEvents,s=this.el,a=this.wrapperEl,n=this.device,l=this.support,o=!!t.nested;
28206if(!l.touch&&l.pointerEvents)s.removeEventListener(i.start,this.onTouchStart,!1),e.removeEventListener(i.move,this.onTouchMove,o),e.removeEventListener(i.end,this.onTouchEnd,!1);else{if(l.touch){var d=!("onTouchStart"!==i.start||!l.passiveListener||!t.passiveListeners)&&{passive:!0,capture:!1};s.removeEventListener(i.start,this.onTouchStart,d),s.removeEventListener(i.move,this.onTouchMove,o),s.removeEventListener(i.end,this.onTouchEnd,d),i.cancel&&s.removeEventListener(i.cancel,this.onTouchEnd,d)}(t.simulateTouch&&!n.ios&&!n.android||t.simulateTouch&&!l.touch&&n.ios)&&(s.removeEventListener("mousedown",this.onTouchStart,!1),e.removeEventListener("mousemove",this.onTouchMove,o),e.removeEventListener("mouseup",this.onTouchEnd,!1))}(t.preventClicks||t.preventClicksPropagation)&&s.removeEventListener("click",this.onClick,!0),t.cssMode&&a.removeEventListener("scroll",this.onScroll),this.off(n.ios||n.android?"resize orientationchange observerUpdate":"resize observerUpdate",G)}},breakpoints:{setBreakpoint:function(){var e=this.activeIndex,t=this.initialized,i=this.loopedSlides,s=void 0===i?0:i,a=this.params,r=this.$el,n=a.breakpoints;if(n&&(!n||0!==Object.keys(n).length)){var l=this.getBreakpoint(n);if(l&&this.currentBreakpoint!==l){var o=l in n?n[l]:void 0;o&&["slidesPerView","spaceBetween","slidesPerGroup","slidesPerGroupSkip","slidesPerColumn"].forEach((function(e){var t=o[e];void 0!==t&&(o[e]="slidesPerView"!==e||"AUTO"!==t&&"auto"!==t?"slidesPerView"===e?parseFloat(t):parseInt(t,10):"auto")}));var d=o||this.originalParams,h=a.slidesPerColumn>1,p=d.slidesPerColumn>1;h&&!p?(r.removeClass(a.containerModifierClass+"multirow "+a.containerModifierClass+"multirow-column"),this.emitContainerClasses()):!h&&p&&(r.addClass(a.containerModifierClass+"multirow"),"column"===d.slidesPerColumnFill&&r.addClass(a.containerModifierClass+"multirow-column"),this.emitContainerClasses());var u=d.direction&&d.direction!==a.direction,c=a.loop&&(d.slidesPerView!==a.slidesPerView||u);u&&t&&this.changeDirection(),S(this.params,d),S(this,{allowTouchMove:this.params.allowTouchMove,allowSlideNext:this.params.allowSlideNext,allowSlidePrev:this.params.allowSlidePrev}),this.currentBreakpoint=l,this.emit("_beforeBreakpoint",d),c&&t&&(this.loopDestroy(),this.loopCreate(),this.updateSlides(),this.slideTo(e-s+this.loopedSlides,0,!1)),this.emit("breakpoint",d)}}},getBreakpoint:function(e){var t=l();if(e){var i=!1,s=Object.keys(e).map((function(e){if("string"==typeof e&&0===e.indexOf("@")){var i=parseFloat(e.substr(1));return{value:t.innerHeight*i,point:e}}return{value:e,point:e}}));s.sort((function(e,t){return parseInt(e.value,10)-parseInt(t.value,10)}));for(var a=0;a<s.length;a+=1){var r=s[a],n=r.point;r.value<=t.innerWidth&&(i=n)}return i||"max"}}},checkOverflow:{checkOverflow:function(){var e=this.params,t=this.isLocked,i=this.slides.length>0&&e.slidesOffsetBefore+e.spaceBetween*(this.slides.length-1)+this.slides[0].offsetWidth*this.slides.length;e.slidesOffsetBefore&&e.slidesOffsetAfter&&i?this.isLocked=i<=this.size:this.isLocked=1===this.snapGrid.length,this.allowSlideNext=!this.isLocked,this.allowSlidePrev=!this.isLocked,t!==this.isLocked&&this.emit(this.isLocked?"lock":"unlock"),t&&t!==this.isLocked&&(this.isEnd=!1,this.navigation&&this.navigation.update())}},classes:{addClasses:function(){var e=this.classNames,t=this.params,i=this.rtl,s=this.$el,a=this.device,r=[];r.push("initialized"),r.push(t.direction),t.freeMode&&r.push("free-mode"),t.autoHeight&&r.push("autoheight"),i&&r.push("rtl"),t.slidesPerColumn>1&&(r.push("multirow"),"column"===t.slidesPerColumnFill&&r.push("multirow-column")),a.android&&r.push("android"),a.ios&&r.push("ios"),t.cssMode&&r.push("css-mode"),r.forEach((function(i){e.push(t.containerModifierClass+i)})),s.addClass(e.join(" ")),this.emitContainerClasses()},removeClasses:function(){var e=this.$el,t=this.classNames;e.removeClass(t.join(" ")),this.emitContainerClasses()}},images:{loadImage:function(e,t,i,s,a,r){var n,o=l();function d(){r&&r()}m(e).parent("picture")[0]||e.complete&&a?d():t?((n=new o.Image).onload=d,n.onerror=d,s&&(n.sizes=s),i&&(n.srcset=i),t&&(n.src=t)):d()},preloadImages:function(){var e=this;function t(){null!=e&&e&&!e.destroyed&&(void 0!==e.imagesLoaded&&(e.imagesLoaded+=1),e.imagesLoaded===e.imagesToLoad.length&&(e.params.updateOnImagesReady&&e.update(
28206),e.emit("imagesReady")))}e.imagesToLoad=e.$el.find("img");for(var i=0;i<e.imagesToLoad.length;i+=1){var s=e.imagesToLoad[i];e.loadImage(s,s.currentSrc||s.getAttribute("src"),s.srcset||s.getAttribute("srcset"),s.sizes||s.getAttribute("sizes"),!0,t)}}}},F={},R=function(){function t(){for(var e,i,s=arguments.length,a=new Array(s),r=0;r<s;r++)a[r]=arguments[r];1===a.length&&a[0].constructor&&a[0].constructor===Object?i=a[0]:(e=a[0],i=a[1]),i||(i={}),i=S({},i),e&&!i.el&&(i.el=e);var n=this;n.support=z(),n.device=P({userAgent:i.userAgent}),n.browser=k(),n.eventsListeners={},n.eventsAnyListeners=[],void 0===n.modules&&(n.modules={}),Object.keys(n.modules).forEach((function(e){var t=n.modules[e];if(t.params){var s=Object.keys(t.params)[0],a=t.params[s];if("object"!=typeof a||null===a)return;if(!(s in i)||!("enabled"in a))return;!0===i[s]&&(i[s]={enabled:!0}),"object"!=typeof i[s]||"enabled"in i[s]||(i[s].enabled=!0),i[s]||(i[s]={enabled:!1})}}));var l=S({},Y);n.useParams(l),n.params=S({},l,F,i),n.originalParams=S({},n.params),n.passedParams=S({}
28206,i),n.params&&n.params.on&&Object.keys(n.params.on).forEach((function(e){n.on(e,n.params.on[e])})),n.params&&n.params.onAny&&n.onAny(n.params.onAny),n.$=m;var o=m(n.params.el);if(e=o[0]){if(o.length>1){var d=[];return o.each((function(e){var s=S({},i,{el:e});d.push(new t(s))})),d}var h,p,u;return e.swiper=n,e&&e.shadowRoot&&e.shadowRoot.querySelector?(h=m(e.shadowRoot.querySelector("."+n.params.wrapperClass))).children=function(e){return o.children(e)}:h=o.children("."+n.params.wrapperClass),S(n,{$el:o,el:e,$wrapperEl:h,wrapperEl:h[0],classNames:[],slides:m(),slidesGrid:[],snapGrid:[],slidesSizesGrid:[],isHorizontal:function(){return"horizontal"===n.params.direction},isVertical:function(){return"vertical"===n.params.direction},rtl:"rtl"===e.dir.toLowerCase()||"rtl"===o.css("direction"),rtlTranslate:"horizontal"===n.params.direction&&("rtl"===e.dir.toLowerCase()||"rtl"===o.css("direction")),wrongRTL:"-webkit-box"===h.css("display"),activeIndex:0,realIndex:0,isBeginning:!0,isEnd:!1,translate:0,previousTranslate:0,progress:0,velocity:0,animating:!1,allowSlideNext:n.params.allowSlideNext,allowSlidePrev:n.params.allowSlidePrev,touchEvents:(p=["touchstart","touchmove","touchend","touchcancel"],u=["mousedown","mousemove","mouseup"],n.support.pointerEvents&&(u=["pointerdown","pointermove","pointerup"]),n.touchEventsTouch={start:p[0],move:p[1],end:p[2],cancel:p[3]},n.touchEventsDesktop={start:u[0],move:u[1],end:u[2]},n.support.touch||!n.params.simulateTouch?n.touchEventsTouch:n.touchEventsDesktop),touchEventsData:{isTouched:void 0,isMoved:void 0,allowTouchCallbacks:void 0,touchStartTime:void 0,isScrolling:void 0,currentTranslate:void 0,startTranslate:void 0,allowThresholdMove:void 0,formElements:"input, select, option, textarea, button, video, label",lastClickTime:x(),clickTimeout:void 0,velocities:[],allowMomentumBounce:void 0,isTouchEvent:void 0,startMoving:void 0},allowClick:!0,allowTouchMove:n.params.allowTouchMove,touches:{startX:0,startY:0,currentX:0,currentY:0,diff:0},imagesToLoad:[],imagesLoaded:0}),n.useModules(),n.emit("_swiper"),n.params.init&&n.init(),n}}var i,s,a,r=t.prototype;return r.emitContainerClasses=function(){var e=this;if(e.params._emitClasses&&e.el){var t=e.el.className.split(" ").filter((function(t){return 0===t.indexOf("swiper-container")||0===t.indexOf(e.params.containerModifierClass)}));e.emit("_containerClasses",t.join(" "))}},r.emitSlidesClasses=function(){var e=this;e.params._emitClasses&&e.el&&e.slides.each((function(t){var i=t.className.split(" ").filter((function(t){return 0===t.indexOf("swiper-slide")||0===t.indexOf(e.params.slideClass)}));e.emit("_slideClass",t,i.join(" "))}))},r.slidesPerViewDynamic=function(){var e=this.params,t=this.slides,i=this.slidesGrid,s=this.size,a=this.activeIndex,r=1;if(e.centeredSlides){for(var n,l=t[a].swiperSlideSize,o=a+1;o<t.length;o+=1)t[o]&&!n&&(r+=1,(l+=t[o].swiperSlideSize)>s&&(n=!0));for(var d=a-1;d>=0;d-=1)t[d]&&!n&&(r+=1,(l+=t[d].swiperSlideSize)>s&&(n=!0))}else for(var h=a+1;h<t.length;h+=1)i[h]-i[a]<s&&(r+=1);return r},r.update=function(){var e=this;if(e&&!e.destroyed){var t=e.snapGrid,i=e.params;i.breakpoints&&e.setBreakpoint(),e.updateSize(),e.updateSlides(),e.updateProgress(),e.updateSlidesClasses(),e.params.freeMode?(s(),e.params.autoHeight&&e.updateAutoHeight()):(("auto"===e.params.slidesPerView||e.params.slidesPerView>1)&&e.isEnd&&!e.params.centeredSlides?e.slideTo(e.slides.length-1,0,!1,!0):e.slideTo(e.activeIndex,0,!1,!0))||s(),i.watchOverflow&&t!==e.snapGrid&&e.checkOverflow(),e.emit("update")}function s(){var t=e.rtlTranslate?-1*e.translate:e.translate,i=Math.min(Math.max(t,e.maxTranslate()),e.minTranslate());e.setTranslate(i),e.updateActiveIndex(),e.updateSlidesClasses()}},r.changeDirection=function(e,t){void 0===t&&(t=!0);var i=this.params.direction;return e||(e="horizontal"===i?"vertical":"horizontal"),e===i||"horizontal"!==e&&"vertical"!==e||(this.$el.removeClass(""+this.params.containerModifierClass+i).addClass(""+this.params.containerModifierClass+e),this.emitContainerClasses(),this.params.direction=e,this.slides.each((function(t){"vertical"===e?t.style.width="":t.style.height=""}
28206)),this.emit("changeDirection"),t&&this.update()),this},r.init=function(){this.initialized||(this.emit("beforeInit"),this.params.breakpoints&&this.setBreakpoint(),this.addClasses(),this.params.loop&&this.loopCreate(),this.updateSize(),this.updateSlides(),this.params.watchOverflow&&this.checkOverflow(),this.params.grabCursor&&this.setGrabCursor(),this.params.preloadImages&&this.preloadImages(),this.params.loop?this.slideTo(this.params.initialSlide+this.loopedSlides,0,this.params.runCallbacksOnInit):this.slideTo(this.params.initialSlide,0,this.params.runCallbacksOnInit),this.attachEvents(),this.initialized=!0,this.emit("init"),this.emit("afterInit"))},r.destroy=function(e,t){void 0===e&&(e=!0),void 0===t&&(t=!0);var i,s=this,a=s.params,r=s.$el,n=s.$wrapperEl,l=s.slides;return void 0===s.params||s.destroyed||(s.emit("beforeDestroy"),s.initialized=!1,s.detachEvents(),a.loop&&s.loopDestroy(),t&&(s.removeClasses(),r.removeAttr("style"),n.removeAttr("style"),l&&l.length&&l.removeClass([a.slideVisibleClass,a.slideActiveClass,a.slideNextClass,a.slidePrevClass].join(" ")).removeAttr("style").removeAttr("data-swiper-slide-index")),s.emit("destroy"),Object.keys(s.eventsListeners).forEach((function(e){s.off(e)}
28206)),!1!==e&&(s.$el[0].swiper=null,i=s,Object.keys(i).forEach((function(e){try{i[e]=null}catch(e){}try{delete i[e]}catch(e){}}))),s.destroyed=!0),null},t.extendDefaults=function(e){S(F,e)},t.installModule=function(e){t.prototype.modules||(t.prototype.modules={});var i=e.name||Object.keys(t.prototype.modules).length+"_"+x();t.prototype.modules[i]=e},t.use=function(e){return Array.isArray(e)?(e.forEach((function(e){return t.installModule(e)})),t):(t.installModule(e),t)},i=t,a=[{key:"extendedDefaults",get:function(){return F}},{key:"defaults",get:function(){return Y}}],(s=null)&&e(i.prototype,s),a&&e(i,a),t}();Object.keys(V).forEach((function(e){Object.keys(V[e]).forEach((function(t){R.prototype[t]=V[e][t]}))})),R.use([$,I]);var W={update:function(e){var t=this,i=t.params,s=i.slidesPerView,a=i.slidesPerGroup,r=i.centeredSlides,n=t.params.virtual,l=n.addSlidesBefore,o=n.addSlidesAfter,d=t.virtual,h=d.from,p=d.to,u=d.slides,c=d.slidesGrid,v=d.renderSlide,f=d.offset;t.updateActiveIndex();var m,g,w,y=t.activeIndex||0;m=t.rtlTranslate?"right":t.isHorizontal()?"left":"top",r?(g=Math.floor(s/2)+a+o,w=Math.floor(s/2)+a+l):(g=s+(a-1)+o,w=a+l);var b=Math.max((y||0)-w,0),E=Math.min((y||0)+g,u.length-1),x=(t.slidesGrid[b]||0)-(t.slidesGrid[0]||0);function T(){t.updateSlides(),t.updateProgress(),t.updateSlidesClasses(),t.lazy&&t.params.lazy.enabled&&t.lazy.load()}if(S(t.virtual,{from:b,to:E,offset:x,slidesGrid:t.slidesGrid}),h===b&&p===E&&!e)return t.slidesGrid!==c&&x!==f&&t.slides.css(m,x+"px"),void t.updateProgress();if(t.params.virtual.renderExternal)return t.params.virtual.renderExternal.call(t,{offset:x,from:b,to:E,slides:function(){for(var e=[],t=b;t<=E;t+=1)e.push(u[t]);return e}()}),void(t.params.virtual.renderExternalUpdate&&T());var C=[],M=[];if(e)t.$wrapperEl.find("."+t.params.slideClass).remove();else for(var z=h;z<=p;z+=1)(z<b||z>E)&&t.$wrapperEl.find("."+t.params.slideClass+'[data-swiper-slide-index="'+z+'"]').remove();for(var P=0;P<u.length;P+=1)P>=b&&P<=E&&(void 0===p||e?M.push(P):(P>p&&M.push(P),P<h&&C.push(P)));M.forEach((function(e){t.$wrapperEl.append(v(u[e],e))})),C.sort((function(e,t){return t-e})).forEach((function(e){t.$wrapperEl.prepend(v(u[e],e))})),t.$wrapperEl.children(".swiper-slide").css(m,x+"px"),T()},renderSlide:function(e,t){var i=this.params.virtual;if(i.cache&&this.virtual.cache[t])return this.virtual.cache[t];var s=i.renderSlide?m(i.renderSlide.call(this,e,t)):m('<div class="'+this.params.slideClass+'" data-swiper-slide-index="'+t+'">'+e+"</div>");return s.attr("data-swiper-slide-index")||s.attr("data-swiper-slide-index",t),i.cache&&(this.virtual.cache[t]=s),s},appendSlide:function(e){if("object"==typeof e&&"length"in e)for(var t=0;t<e.length;t+=1)e[t]&&this.virtual.slides.push(e[t]);else this.virtual.slides.push(e);this.virtual.update(!0)},prependSlide:function(e){var t=this.activeIndex,i=t+1,s=1;if(Array.isArray(e)){for(var a=0;a<e.length;a+=1)e[a]&&this.virtual.slides.unshift(e[a]);i=t+e.length,s=e.length}else this.virtual.slides.unshift(e);if(this.params.virtual.cache){var r=this.virtual.cache,n={};Object.keys(r).forEach((function(e){var t=r[e],i=t.attr("data-swiper-slide-index");i&&t.attr("data-swiper-slide-index",parseInt(i,10)+1),n[parseInt(e,10)+s]=t})),this.virtual.cache=n}this.virtual.update(!0),this.slideTo(i,0)},removeSlide:function(e){if(null!=e){var t=this.activeIndex;if(Array.isArray(e))for(var i=e.length-1;i>=0;i-=1)this.virtual.slides.splice(e[i],1),this.params.virtual.cache&&delete this.virtual.cache[e[i]],e[i]<t&&(t-=1),t=Math.max(t,0);else this.virtual.slides.splice(e,1),this.params.virtual.cache&&delete this.virtual.cache[e],e<t&&(t-=1),t=Math.max(t,0);this.virtual.update(!0),this.slideTo(t,0)}},removeAllSlides:function(){this.virtual.slides=[],this.params.virtual.cache&&(this.virtual.cache={}),this.virtual.update(!0),this.slideTo(0,0)}},q={name:"virtual",params:{virtual:{enabled:!1,slides:[],cache:!0,renderSlide:null,renderExternal:null,renderExternalUpdate:!0,addSlidesBefore:0,addSlidesAfter:0}},create:function(){M(this,{virtual:t(t({},W),{},{slides:this.params.virtual.slides,cache:{}})})},on:{beforeInit:function(e){if(e.params.virtual.enabled){e.classNames.push(e.params.containerModifierClass+"virtual");var t={watchSlidesProgress:!0};S(e.params,t),S(e.originalParams,t),e.params.initialSlide||e.virtual.update(
28206)}},setTranslate:function(e){e.params.virtual.enabled&&e.virtual.update()}}},j={handle:function(e){var t=l(),i=r(),s=this.rtlTranslate,a=e;a.originalEvent&&(a=a.originalEvent);var n=a.keyCode||a.charCode,o=this.params.keyboard.pageUpDown,d=o&&33===n,h=o&&34===n,p=37===n,u=39===n,c=38===n,v=40===n;if(!this.allowSlideNext&&(this.isHorizontal()&&u||this.isVertical()&&v||h))return!1;if(!this.allowSlidePrev&&(this.isHorizontal()&&p||this.isVertical()&&c||d))return!1;if(!(a.shiftKey||a.altKey||a.ctrlKey||a.metaKey||i.activeElement&&i.activeElement.nodeName&&("input"===i.activeElement.nodeName.toLowerCase()||"textarea"===i.activeElement.nodeName.toLowerCase()))){if(this.params.keyboard.onlyInViewport&&(d||h||p||u||c||v)){var f=!1;if(this.$el.parents("."+this.params.slideClass).length>0&&0===this.$el.parents("."+this.params.slideActiveClass).length)return;var m=t.innerWidth,g=t.innerHeight,w=this.$el.offset();s&&(w.left-=this.$el[0].scrollLeft);for(var y=[[w.left,w.top],[w.left+this.width,w.top],[w.left,w.top+this.height],[w.left+this.width,w.top+this.height]],b=0;b<y.length;b+=1){var E=y[b];E[0]>=0&&E[0]<=m&&E[1]>=0&&E[1]<=g&&(f=!0)}if(!f)return}this.isHorizontal()?((d||h||p||u)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),((h||u)&&!s||(d||p)&&s)&&this.slideNext(),((d||p)&&!s||(h||u)&&s)&&this.slidePrev()):((d||h||c||v)&&(a.preventDefault?a.preventDefault():a.returnValue=!1),(h||v)&&this.slideNext(),(d||c)&&this.slidePrev()),this.emit("keyPress",n)}},enable:function(){var e=r();this.keyboard.enabled||(m(e).on("keydown",this.keyboard.handle),this.keyboard.enabled=!0)},disable:function(){var e=r();this.keyboard.enabled&&(m(e).off("keydown",this.keyboard.handle),this.keyboard.enabled=!1)}},_={name:"keyboard",params:{keyboard:{enabled:!1,onlyInViewport:!0,pageUpDown:!0}},create:function(){M(this,{keyboard:t({enabled:!1},j)})},on:{init:function(e){e.params.keyboard.enabled&&e.keyboard.enable()},destroy:function(e){e.keyboard.enabled&&e.keyboard.disable()}}};var U={lastScrollTime:x(),lastEventBeforeSnap:void 0,recentWheelEvents:[],event:function(){return l().navigator.userAgent.indexOf("firefox")>-1?"DOMMouseScroll":function(){var e=r(),t="onwheel"in e;if(!t){var i=e.createElement("div");i.setAttribute("onwheel","return;"),t="function"==typeof i.onwheel}return!t&&e.implementation&&e.implementation.hasFeature&&!0!==e.implementation.hasFeature("","")&&(t=e.implementation.hasFeature("Events.wheel","3.0")),t}()?"wheel":"mousewheel"},normalize:function(e){var t=0,i=0,s=0,a=0;return"detail"in e&&(i=e.detail),"wheelDelta"in e&&(i=-e.wheelDelta/120),"wheelDeltaY"in e&&(i=-e.wheelDeltaY/120),"wheelDeltaX"in e&&(t=-e.wheelDeltaX/120),"axis"in e&&e.axis===e.HORIZONTAL_AXIS&&(t=i,i=0),s=10*t,a=10*i,"deltaY"in e&&(a=e.deltaY),"deltaX"in e&&(s=e.deltaX),e.shiftKey&&!s&&(s=a,a=0),(s||a)&&e.deltaMode&&(1===e.deltaMode?(s*=40,a*=40):(s*=800,a*=800)),s&&!t&&(t=s<1?-1:1),a&&!i&&(i=a<1?-1:1),{spinX:t,spinY:i,pixelX:s,pixelY:a}},handleMouseEnter:function(){this.mouseEntered=!0},handleMouseLeave:function(){this.mouseEntered=!1},handle:function(e){var t=e,i=this,s=i.params.mousewheel;i.params.cssMode&&t.preventDefault();var a=i.$el;if("container"!==i.params.mousewheel.eventsTarget&&(a=m(i.params.mousewheel.eventsTarget)),!i.mouseEntered&&!a[
282060].contains(t.target)&&!s.releaseOnEdges)return!0;t.originalEvent&&(t=t.originalEvent);var r=0,n=i.rtlTranslate?-1:1,l=U.normalize(t);if(s.forceToAxis)if(i.isHorizontal()){if(!(Math.abs(l.pixelX)>Math.abs(l.pixelY)))return!0;r=-l.pixelX*n}else{if(!(Math.abs(l.pixelY)>Math.abs(l.pixelX)))return!0;r=-l.pixelY}else r=Math.abs(l.pixelX)>Math.abs(l.pixelY)?-l.pixelX*n:-l.pixelY;if(0===r)return!0;if(s.invert&&(r=-r),i.params.freeMode){var o={time:x(),delta:Math.abs(r),direction:Math.sign(r)},d=i.mousewheel.lastEventBeforeSnap,h=d&&o.time<d.time+500&&o.delta<=d.delta&&o.direction===d.direction;if(!h){i.mousewheel.lastEventBeforeSnap=void 0,i.params.loop&&i.loopFix();var p=i.getTranslate()+r*s.sensitivity,u=i.isBeginning,c=i.isEnd;if(p>=i.minTranslate()&&(p=i.minTranslate()),p<=i.maxTranslate()&&(p=i.maxTranslate()),i.setTransition(0),i.setTranslate(p),i.updateProgress(),i.updateActiveIndex(),i.updateSlidesClasses(),(!u&&i.isBeginning||!c&&i.isEnd)&&i.updateSlidesClasses(),i.params.freeModeSticky){clearTimeout(i.mousewheel.timeout),i.mousewheel.timeout=void 0;var v=i.mousewheel.recentWheelEvents;v.length>=15&&v.shift();var f=v.length?v[v.length-1]:void 0,g=v[0];if(v.push(o),f&&(o.delta>f.delta||o.direction!==f.direction))v.splice(0);else if(v.length>=15&&o.time-g.time<500&&g.delta-o.delta>=1&&o.delta<=6){var w=r>0?.8:.2;i.mousewheel.lastEventBeforeSnap=o,v.splice(0),i.mousewheel.timeout=E((function(){i.slideToClosest(i.params.speed,!0,void 0,w)}),0)}i.mousewheel.timeout||(i.mousewheel.timeout=E((function(){i.mousewheel.lastEventBeforeSnap=o,v.splice(0),i.slideToClosest(i.params.speed,!0,void 0,.5)}),500))}if(h||i.emit("scroll",t),i.params.autoplay&&i.params.autoplayDisableOnInteraction&&i.autoplay.stop(),p===i.minTranslate()||p===i.maxTranslate())return!0}}else{var y={time:x(),delta:Math.abs(r),direction:Math.sign(r),raw:e},b=i.mousewheel.recentWheelEvents;b.length>=2&&b.shift();var T=b.length?b[b.length-1]:void 0;if(b.push(y),T?(y.direction!==T.direction||y.delta>T.delta||y.time>T.time+150)&&i.mousewheel.animateSlider(y):i.mousewheel.animateSlider(y),i.mousewheel.releaseScroll(y))return!0}return t.preventDefault?t.preventDefault():t.returnValue=!1,!1},animateSlider:function(e){var t=l();return!(this.params.mousewheel.thresholdDelta&&e.delta<this.params.mousewheel.thresholdDelta)&&(!(this.params.mousewheel.thresholdTime&&x()-this.mousewheel.lastScrollTime<this.params.mousewheel.thresholdTime)&&(e.delta>=6&&x()-this.mousewheel.lastScrollTime<60||(e.direction<0?this.isEnd&&!this.params.loop||this.animating||(this.slideNext(),this.emit("scroll",e.raw)):this.isBeginning&&!this.params.loop||this.animating||(this.slidePrev(),this.emit("scroll",e.raw)),this.mousewheel.lastScrollTime=(new t.Date).getTime(),!1)))},releaseScroll:function(e){var t=this.params.mousewheel;if(e.direction<0){if(this.isEnd&&!this.params.loop&&t.releaseOnEdges)return!0}else if(this.isBeginning&&!this.params.loop&&t.releaseOnEdges)return!0;return!1},enable:function(){var e=U.event();if(this.params.cssMode)return this.wrapperEl.removeEventListener(e,this.mousewheel.handle),!0;if(!e)return!1;if(this.mousewheel.enabled)return!1;var t=this.$el;return"container"!==this.params.mousewheel.eventsTarget&&(t=m(this.params.mousewheel.eventsTarget)),t.on("mouseenter",this.mousewheel.handleMouseEnter),t.on("mouseleave",this.mousewheel.handleMouseLeave),t.on(e,this.mousewheel.handle),this.mousewheel.enabled=!0,!0},disable:function(){var e=U.event();if(this.params.cssMode)return this.wrapperEl.addEventListener(e,this.mousewheel.handle),!0;if(!e)return!1;if(!this.mousewheel.enabled)return!1;var t=this.$el;return"container"!==this.params.mousewheel.eventsTarget&&(t=m(this.params.mousewheel.eventsTarget)),t.off(e,this.mousewheel.handle),this.mousewheel.enabled=!1,!0}},K={update:function(){var e=this.params.navigation;if(!this.params.loop){var t=this.navigation,i=t.$nextEl,s=t.$prevEl;s&&s.length>0&&(this.isBeginning?s.addClass(e.disabledClass):s.removeClass(e.disabledClass),s[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](e.lockClass)),i&&i.length>0&&(this.isEnd?i.addClass(e.disabledClass):i.removeClass(e.disabledClass),i[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](e.lockClass))}}
28206,onPrevClick:function(e){e.preventDefault(),this.isBeginning&&!this.params.loop||this.slidePrev()},onNextClick:function(e){e.preventDefault(),this.isEnd&&!this.params.loop||this.slideNext()},init:function(){var e,t,i=this.params.navigation;(i.nextEl||i.prevEl)&&(i.nextEl&&(e=m(i.nextEl),this.params.uniqueNavElements&&"string"==typeof i.nextEl&&e.length>1&&1===this.$el.find(i.nextEl).length&&(e=this.$el.find(i.nextEl))),i.prevEl&&(t=m(i.prevEl),this.params.uniqueNavElements&&"string"==typeof i.prevEl&&t.length>1&&1===this.$el.find(i.prevEl).length&&(t=this.$el.find(i.prevEl))),e&&e.length>0&&e.on("click",this.navigation.onNextClick),t&&t.length>0&&t.on("click",this.navigation.onPrevClick),S(this.navigation,{$nextEl:e,nextEl:e&&e[0],$prevEl:t,prevEl:t&&t[0]}))},destroy:function(){var e=this.navigation,t=e.$nextEl,i=e.$prevEl;t&&t.length&&(t.off("click",this.navigation.onNextClick),t.removeClass(this.params.navigation.disabledClass)),i&&i.length&&(i.off("click",this.navigation.onPrevClick),i.removeClass(this.params.navigation.disabledClass))}},Z={update:function(){var e=this.rtl,t=this.params.pagination;if(t.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var i,s=this.virtual&&this.params.virtual.enabled?this.virtual.slides.length:this.slides.length,a=this.pagination.$el,r=this.params.loop?Math.ceil((s-2*this.loopedSlides)/this.params.slidesPerGroup):this.snapGrid.length;if(this.params.loop?((i=Math.ceil((this.activeIndex-this.loopedSlides)/this.params.slidesPerGroup))>s-1-2*this.loopedSlides&&(i-=s-2*this.loopedSlides),i>r-1&&(i-=r),i<0&&"bullets"!==this.params.paginationType&&(i=r+i)):i=void 0!==this.snapIndex?this.snapIndex:this.activeIndex||0,"bullets"===t.type&&this.pagination.bullets&&this.pagination.bullets.length>0){var n,l,o,d=this.pagination.bullets;if(t.dynamicBullets&&(this.pagination.bulletSize=d.eq(0)[this.isHorizontal()?"outerWidth":"outerHeight"](!0),a.css(this.isHorizontal()?"width":"height",this.pagination.bulletSize*(t.dynamicMainBullets+4)+"px"),t.dynamicMainBullets>1&&void 0!==this.previousIndex&&(this.pagination.dynamicBulletIndex+=i-this.previousIndex,this.pagination.dynamicBulletIndex>t.dynamicMainBullets-1?this.pagination.dynamicBulletIndex=t.dynamicMainBullets-1:this.pagination.dynamicBulletIndex<0&&(this.pagination.dynamicBulletIndex=0)),n=i-this.pagination.dynamicBulletIndex,o=((l=n+(Math.min(d.length,t.dynamicMainBullets)-1))+n)/2),d.removeClass(t.bulletActiveClass+" "+t.bulletActiveClass+"-next "+t.bulletActiveClass+"-next-next "+t.bulletActiveClass+"-prev "+t.bulletActiveClass+"-prev-prev "+t.bulletActiveClass+"-main"),a.length>1)d.each((function(e){var s=m(e),a=s.index();a===i&&s.addClass(t.bulletActiveClass),t.dynamicBullets&&(a>=n&&a<=l&&s.addClass(t.bulletActiveClass+"-main"),a===n&&s.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),a===l&&s.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next"))}));else{var h=d.eq(i),p=h.index();if(h.addClass(t.bulletActiveClass),t.dynamicBullets){for(var u=d.eq(n),c=d.eq(l),v=n;v<=l;v+=1)d.eq(v).addClass(t.bulletActiveClass+"-main");if(this.params.loop)if(p>=d.length-t.dynamicMainBullets){for(var f=t.dynamicMainBullets;f>=0;f-=1)d.eq(d.length-f).addClass(t.bulletActiveClass+"-main");d.eq(d.length-t.dynamicMainBullets-1).addClass(t.bulletActiveClass+"-prev")}else u.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),c.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next");else u.prev().addClass(t.bulletActiveClass+"-prev").prev().addClass(t.bulletActiveClass+"-prev-prev"),c.next().addClass(t.bulletActiveClass+"-next").next().addClass(t.bulletActiveClass+"-next-next")}}if(t.dynamicBullets){var g=Math.min(d.length,t.dynamicMainBullets+4),w=(this.pagination.bulletSize*g-this.pagination.bulletSize)/2-o*this.pagination.bulletSize,y=e?"right":"left";d.css(this.isHorizontal()?y:"top",w+"px")}}if("fraction"===t.type&&(a.find("."+t.currentClass).text(t.formatFractionCurrent(i+1)),a.find("."+t.totalClass).text(t.formatFractionTotal(r))),"progressbar"===t.type){var b;b=t.progressbarOpposite?this.isHorizontal()?"vertical":"horizontal":this.isHorizontal()?"horizontal":"vertical";var E=(i+1)/r,x=1,T=1;"horizontal"===b?x=E:T=E,a.find("."+t.progressbarFillClass).transform("translate3d(0,
282060,0) scaleX("+x+") scaleY("+T+")").transition(this.params.speed)}"custom"===t.type&&t.renderCustom?(a.html(t.renderCustom(this,i+1,r)),this.emit("paginationRender",a[0])):this.emit("paginationUpdate",a[0]),a[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](t.lockClass)}},render:function(){var e=this.params.pagination;if(e.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var t=this.virtual&&this.params.virtual.enabled?this.virtual.slides.length:this.slides.length,i=this.pagination.$el,s="";if("bullets"===e.type){for(var a=this.params.loop?Math.ceil((t-2*this.loopedSlides)/this.params.slidesPerGroup):this.snapGrid.length,r=0;r<a;r+=1)e.renderBullet?s+=e.renderBullet.call(this,r,e.bulletClass):s+="<"+e.bulletElement+' class="'+e.bulletClass+'"></'+e.bulletElement+">";i.html(s),this.pagination.bullets=i.find("."+e.bulletClass)}"fraction"===e.type&&(s=e.renderFraction?e.renderFraction.call(this,e.currentClass,e.totalClass):'<span class="'+e.currentClass+'"></span> / <span class="'+e.totalClass+'"></span>',i.html(s)),"progressbar"===e.type&&(s=e.renderProgressbar?e.renderProgressbar.call(this,e.progressbarFillClass):'<span class="'+e.progressbarFillClass+'"></span>',i.html(s)),"custom"!==e.type&&this.emit("paginationRender",this.pagination.$el[0])}},init:function(){var e=this,t=e.params.pagination;if(t.el){var i=m(t.el);0!==i.length&&(e.params.uniqueNavElements&&"string"==typeof t.el&&i.length>1&&(i=e.$el.find(t.el)),"bullets"===t.type&&t.clickable&&i.addClass(t.clickableClass),i.addClass(t.modifierClass+t.type),"bullets"===t.type&&t.dynamicBullets&&(i.addClass(""+t.modifierClass+t.type+"-dynamic"),e.pagination.dynamicBulletIndex=0,t.dynamicMainBullets<1&&(t.dynamicMainBullets=1)),"progressbar"===t.type&&t.progressbarOpposite&&i.addClass(t.progressbarOppositeClass),t.clickable&&i.on("click","."+t.bulletClass,(function(t){t.preventDefault();var i=m(this).index()*e.params.slidesPerGroup;e.params.loop&&(i+=e.loopedSlides),e.slideTo(i)})),S(e.pagination,{$el:i,el:i[0]}))}},destroy:function(){var e=this.params.pagination;if(e.el&&this.pagination.el&&this.pagination.$el&&0!==this.pagination.$el.length){var t=this.pagination.$el;t.removeClass(e.hiddenClass),t.removeClass(e.modifierClass+e.type),this.pagination.bullets&&this.pagination.bullets.removeClass(e.bulletActiveClass),e.clickable&&t.off("click","."+e.bulletClass)}}},J={setTranslate:function(){if(this.params.scrollbar.el&&this.scrollbar.el){var e=this.scrollbar,t=this.rtlTranslate,i=this.progress,s=e.dragSize,a=e.trackSize,r=e.$dragEl,n=e.$el,l=this.params.scrollbar,o=s,d=(a-s)*i;t?(d=-d)>0?(o=s-d,d=0):-d+s>a&&(o=a+d):d<0?(o=s+d,d=0):d+s>
28206a&&(o=a-d),this.isHorizontal()?(r.transform("translate3d("+d+"px, 0, 0)"),r[0].style.width=o+"px"):(r.transform("translate3d(0px, "+d+"px, 0)"),r[0].style.height=o+"px"),l.hide&&(clearTimeout(this.scrollbar.timeout),n[0].style.opacity=1,this.scrollbar.timeout=setTimeout((function(){n[0].style.opacity=0,n.transition(400)}),1e3))}},setTransition:function(e){this.params.scrollbar.el&&this.scrollbar.el&&this.scrollbar.$dragEl.transition(e)},updateSize:function(){if(this.params.scrollbar.el&&this.scrollbar.el){var e=this.scrollbar,t=e.$dragEl,i=e.$el;t[0].style.width="",t[0].style.height="";var s,a=this.isHorizontal()?i[0].offsetWidth:i[0].offsetHeight,r=this.size/this.virtualSize,n=r*(a/this.size);s="auto"===this.params.scrollbar.dragSize?a*r:parseInt(this.params.scrollbar.dragSize,10),this.isHorizontal()?t[0].style.width=s+"px":t[0].style.height=s+"px",i[0].style.display=r>=1?"none":"",this.params.scrollbar.hide&&(i[0].style.opacity=0),S(e,{trackSize:a,divider:r,moveDivider:n,dragSize:s}),e.$el[this.params.watchOverflow&&this.isLocked?"addClass":"removeClass"](this.params.scrollbar.lockClass)}},getPointerPosition:function(e){return this.isHorizontal()?"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientX:e.clientX:"touchstart"===e.type||"touchmove"===e.type?e.targetTouches[0].clientY:e.clientY},setDragPosition:function(e){var t,i=this.scrollbar,s=this.rtlTranslate,a=i.$el,r=i.dragSize,n=i.trackSize,l=i.dragStartPos;t=(i.getPointerPosition(e)-a.offset()[this.isHorizontal()?"left":"top"]-(null!==l?l:r/2))/(n-r),t=Math.max(Math.min(t,1),0),s&&(t=1-t);var o=this.minTranslate()+(this.maxTranslate()-this.minTranslate())*t;this.updateProgress(o),this.setTranslate(o),this.updateActiveIndex(),this.updateSlidesClasses()},onDragStart:function(e){var t=this.params.scrollbar,i=this.scrollbar,s=this.$wrapperEl,a=i.$el,r=i.$dragEl;this.scrollbar.isTouched=!0,this.scrollbar.dragStartPos=e.target===r[0]||e.target===r?i.getPointerPosition(e)-e.target.getBoundingClientRect()[this.isHorizontal()?"left":"top"]:null,e.preventDefault(),e.stopPropagation(),s.transition(100),r.transition(100),i.setDragPosition(e),clearTimeout(this.scrollbar.dragTimeout),a.transition(0),t.hide&&a.css("opacity",1),this.params.cssMode&&this.$wrapperEl.css("scroll-snap-type","none"),this.emit("scrollbarDragStart",e)},onDragMove:function(e){var t=this.scrollbar,i=this.$wrapperEl,s=t.$el,a=t.$dragEl;this.scrollbar.isTouched&&(e.preventDefault?e.preventDefault():e.returnValue=!1,t.setDragPosition(e),i.transition(0),s.transition(0),a.transition(0),this.emit("scrollbarDragMove",e))},onDragEnd:function(e){var t=this.params.scrollbar,i=this.scrollbar,s=this.$wrapperEl,a=i.$el;this.scrollbar.isTouched&&(this.scrollbar.isTouched=!1,this.params.cssMode&&(this.$wrapperEl.css("scroll-snap-type",""),s.transition("")),t.hide&&(clearTimeout(this.scrollbar.dragTimeout),this.scrollbar.dragTimeout=E((function(){a.css("opacity",0),a.transition(400)}),1e3)),this.emit("scrollbarDragEnd",e),t.snapOnRelease&&this.slideToClosest())},enableDraggable:function(){if(this.params.scrollbar.el){var e=r(),t=this.scrollbar,i=this.touchEventsTouch,s=this.touchEventsDesktop,a=this.params,n=this.support,l=t.$el[0],o=!(!n.passiveListener||!a.passiveListeners)&&{passive:!1,capture:!1},d=!(!n.passiveListener||!a.passiveListeners)&&{passive:!0,capture:!1};n.touch?(l.addEventListener(i.start,this.scrollbar.onDragStart,o),l.addEventListener(i.move,this.scrollbar.onDragMove,o),l.addEventListener(i.end,this.scrollbar.onDragEnd,d)):(l.addEventListener(s.start,this.scrollbar.onDragStart,o),e.addEventListener(s.move,this.scrollbar.onDragMove,o),e.addEventListener(s.end,this.scrollbar.onDragEnd,d))}},disableDraggable:function(){if(this.params.scrollbar.el){var e=r(),t=this.scrollbar,i=this.touchEventsTouch,s=this.touchEventsDesktop,a=this.params,n=this.support,l=t.$el[0],o=!(!n.passiveListener||!a.passiveListeners)&&{passive:!1,capture:!1},d=!(!n.passiveListener||!a.passiveListeners)&&{passive:!0,capture:!1};n.touch?(l.removeEventListener(i.start,this.scrollbar.onDragStart,o),l.removeEventListener(i.move,this.scrollbar.onDragMove,o),l.removeEventListener(i.end,this.scrollbar.onDragEnd,d)):(l.removeEventListener(s.start,this.scrollbar.onDragStart,o),e.removeEventListener(s.move,this.scrollbar.onDragMove,o),e.removeEventListener(s.end,this.scrollbar.onDragEnd,d))}},init:function(){if(this.params.scrollbar.el){var e=this.scrollbar,t=this.$el,i=this.params.scrollbar,s=m(i.el);this.params.uniqueNavElements&&"string"==typeof i.el&&s.length>1&&1===t.find(i.el).length&&(s=t.find(i.el));var a=s.find("."+this.params.scrollbar.dragClass);
vendor: 7,599 bytes, line 28206
282060===a.length&&(a=m('<div class="'+this.params.scrollbar.dragClass+'"></div>'),s.append(a)),S(e,{$el:s,el:s[0],$dragEl:a,dragEl:a[0]}),i.draggable&&e.enableDraggable()}},destroy:function(){this.scrollbar.disableDraggable()}},Q={setTransform:function(e,t){var i=this.rtl,s=m(e),a=i?-1:1,r=s.attr("data-swiper-parallax")||"0",n=s.attr("data-swiper-parallax-x"),l=s.attr("data-swiper-parallax-y"),o=s.attr("data-swiper-parallax-scale"),d=s.attr("data-swiper-parallax-opacity");if(n||l?(n=n||"0",l=l||"0"):this.isHorizontal()?(n=r,l="0"):(l=r,n="0"),n=n.indexOf("%")>=0?parseInt(n,10)*t*a+"%":n*t*a+"px",l=l.indexOf("%")>=0?parseInt(l,10)*t+"%":l*t+"px",null!=d){var h=d-(d-1)*(1-Math.abs(t));s[0].style.opacity=h}if(null==o)s.transform("translate3d("+n+", "+l+", 0px)");else{var p=o-(o-1)*(1-Math.abs(t));s.transform("translate3d("+n+", "+l+", 0px) scale("+p+")")}},setTranslate:function(){var e=this,t=e.$el,i=e.slides,s=e.progress,a=e.snapGrid;t.children("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t){e.parallax.setTransform(t,s)})),i.each((function(t,i){var r=t.progress;e.params.slidesPerGroup>1&&"auto"!==e.params.slidesPerView&&(r+=Math.ceil(i/2)-s*(a.length-1)),r=Math.min(Math.max(r,-1),1),m(t).find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t){e.parallax.setTransform(t,r)}))}))},setTransition:function(e){void 0===e&&(e=this.params.speed);this.$el.find("[data-swiper-parallax], [data-swiper-parallax-x], [data-swiper-parallax-y], [data-swiper-parallax-opacity], [data-swiper-parallax-scale]").each((function(t){var i=m(t),s=parseInt(i.attr("data-swiper-parallax-duration"),10)||e;0===e&&(s=0),i.transition(s)}))}},ee={getDistanceBetweenTouches:function(e){if(e.targetTouches.length<2)return 1;var t=e.targetTouches[0].pageX,i=e.targetTouches[0].pageY,s=e.targetTouches[1].pageX,a=e.targetTouches[1].pageY;return Math.sqrt(Math.pow(s-t,2)+Math.pow(a-i,2))},onGestureStart:function(e){var t=this.support,i=this.params.zoom,s=this.zoom,a=s.gesture;if(s.fakeGestureTouched=!1,s.fakeGestureMoved=!1,!t.gestures){if("touchstart"!==e.type||"touchstart"===e.type&&e.targetTouches.length<2)return;s.fakeGestureTouched=!0,a.scaleStart=ee.getDistanceBetweenTouches(e)}a.$slideEl&&a.$slideEl.length||(a.$slideEl=m(e.target).closest("."+this.params.slideClass),0===a.$slideEl.length&&(a.$slideEl=this.slides.eq(this.activeIndex)),a.$imageEl=a.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),a.$imageWrapEl=a.$imageEl.parent("."+i.containerClass),a.maxRatio=a.$imageWrapEl.attr("data-swiper-zoom")||i.maxRatio,0!==a.$imageWrapEl.length)?(a.$imageEl&&a.$imageEl.transition(0),this.zoom.isScaling=!0):a.$imageEl=void 0},onGestureChange:function(e){var t=this.support,i=this.params.zoom,s=this.zoom,a=s.gesture;if(!t.gestures){if("touchmove"!==e.type||"touchmove"===e.type&&e.targetTouches.length<2)return;s.fakeGestureMoved=!0,a.scaleMove=ee.getDistanceBetweenTouches(e)}a.$imageEl&&0!==a.$imageEl.length?(t.gestures?s.scale=e.scale*s.currentScale:s.scale=a.scaleMove/a.scaleStart*s.currentScale,s.scale>a.maxRatio&&(s.scale=a.maxRatio-1+Math.pow(s.scale-a.maxRatio+1,.5)),s.scale<i.minRatio&&(s.scale=i.minRatio+1-Math.pow(i.minRatio-s.scale+1,.5)),a.$imageEl.transform("translate3d(0,0,0) scale("+s.scale+")")):"gesturechange"===e.type&&s.onGestureStart(e)},onGestureEnd:function(e){var t=this.device,i=this.support,s=this.params.zoom,a=this.zoom,r=a.gesture;if(!i.gestures){if(!a.fakeGestureTouched||!a.fakeGestureMoved)return;if("touchend"!==e.type||"touchend"===e.type&&e.changedTouches.length<2&&!t.android)return;a.fakeGestureTouched=!1,a.fakeGestureMoved=!1}r.$imageEl&&0!==r.$imageEl.length&&(a.scale=Math.max(Math.min(a.scale,r.maxRatio),s.minRatio),r.$imageEl.transition(this.params.speed).transform("translate3d(0,0,0) scale("+a.scale+")"),a.currentScale=a.scale,a.isScaling=!1,1===a.scale&&(r.$slideEl=void 0))},onTouchStart:function(e){var t=this.device,i=this.zoom,s=i.gesture,a=i.image;s.$imageEl&&0!==s.$imageEl.length&&(a.isTouched||(t.android&&e.cancelable&&e.preventDefault(),a.isTouched=!0,a.touchesStart.x="touchstart"===e.type?e.targetTouches[0].pageX:e.pageX,a.touchesStart.y="touchstart"===e.type?e.targetTouches[0].pageY:e.pageY))},onTouchMove:function(e){var t=this.zoom,i=t.gesture,s=t.image,a=t.velocity;if(i.$imageEl&&0!==i.$imageEl.length&&(this.allowClick=!1,s.isTouched&&i.$slideEl)){s.isMoved||(s.width=i.$imageEl[0].offsetWidth,s.height=i.$imageEl[0].offsetHeight,s.startX=T(i.$imageWrapEl[0],"x")||0,s.startY=T(i.$imageWrapEl[0],"y")||0,i.slideWidth=i.$slideEl[0].offsetWidth,i.slideHeight=i.$slideEl[0].offsetHeight,i.$imageWrapEl.transition(0),this.rtl&&(s.startX=-s.startX,s.startY=-s.startY));var r=s.width*t.scale,n=s.height*t.scale;if(!(r<i.slideWidth&&n<i.slideHeight)){if(s.minX=Math.min(i.slideWidth/2-r/2,0),s.maxX=-s.minX,s.minY=Math.min(i.slideHeight/2-n/2,0),s.maxY=-s.minY,s.touchesCurrent.x="touchmove"===e.type?e.targetTouches[0].pageX:e.pageX,s.touchesCurrent.y="touchmove"===e.type?e.targetTouches[0].pageY:e.pageY,!s.isMoved&&!t.isScaling){if(this.isHorizontal()&&(Math.floor(s.minX)===Math.floor(s.startX)&&s.touchesCurrent.x<s.touchesStart.x||Math.floor(s.maxX)===Math.floor(s.startX)&&s.touchesCurrent.x>s.touchesStart.x))return void(s.isTouched=!1);if(!this.isHorizontal()&&(Math.floor(s.minY)===Math.floor(s.startY)&&s.touchesCurrent.y<s.touchesStart.y||Math.floor(s.maxY)===Math.floor(s.startY)&&s.touchesCurrent.y>s.touchesStart.y))return void(s.isTouched=!1)}e.cancelable&&e.preventDefault(),e.stopPropagation(),s.isMoved=!0,s.currentX=s.touchesCurrent.x-s.touchesStart.x+s.startX,s.currentY=s.touchesCurrent.y-s.touchesStart.y+s.startY,s.currentX<s.minX&&(s.currentX=s.minX+1-Math.pow(s.minX-s.currentX+1,.8)),s.currentX>s.maxX&&(s.currentX=s.maxX-1+Math.pow(s.currentX-s.maxX+1,.8)),s.currentY<s.minY&&(s.currentY=s.minY+1-Math.pow(s.minY-s.currentY+1,.8)),s.currentY>s.maxY&&(s.currentY=s.maxY-1+Math.pow(s.currentY-s.maxY+1,.8)),a.prevPositionX||(a.prevPositionX=s.touchesCurrent.x),a.prevPositionY||(a.prevPositionY=s.touchesCurrent.y),a.prevTime||(a.prevTime=Date.now()),a.x=(s.touchesCurrent.x-a.prevPositionX)/(Date.now()-a.prevTime)/2,a.y=(s.touchesCurrent.y-a.prevPositionY)/(Date.now()-a.prevTime)/2,Math.abs(s.touchesCurrent.x-a.prevPositionX)<2&&(a.x=0),Math.abs(s.touchesCurrent.y-a.prevPositionY)<2&&(a.y=0),a.prevPositionX=s.touchesCurrent.x,a.prevPositionY=s.touchesCurrent.y,a.prevTime=Date.now(),i.$imageWrapEl.transform("translate3d("+s.currentX+"px, "+s.currentY+"px,0)")}}},onTouchEnd:function(){var e=this.zoom,t=e.gesture,i=e.image,s=e.velocity;if(t.$imageEl&&0!==t.$imageEl.length){if(!i.isTouched||!i.isMoved)return i.isTouched=!1,void(i.isMoved=!1);i.isTouched=!1,i.isMoved=!1;var a=300,r=300,n=s.x*a,l=i.currentX+n,o=s.y*r,d=i.currentY+o;0!==s.x&&(a=Math.abs((l-i.currentX)/s.x)),0!==s.y&&(r=Math.abs((d-i.currentY)/s.y));var h=Math.max(a,r);i.currentX=l,i.currentY=d;var p=i.width*e.scale,u=i.height*e.scale;i.minX=Math.min(t.slideWidth/2-p/2,0),i.maxX=-i.minX,i.minY=Math.min(t.slideHeight/2-u/2,0),i.maxY=-i.minY,i.currentX=Math.max(Math.min(i.currentX,i.maxX),i.minX),i.currentY=Math.max(Math.min(i.currentY,i.maxY),i.minY),t.$imageWrapEl.transition(h).transform("translate3d("+i.currentX+"px, "+i.currentY+"px,0)")}},onTransitionEnd:function(){var e=this.zoom,t=e.gesture;t.$slideEl&&this.previousIndex!==this.activeIndex&&(t.$imageEl&&t.$imageEl.transform("translate3d(0,
282060,0) scale(1)"),t.$imageWrapEl&&t.$imageWrapEl.transform("translate3d(0,0,0)"),e.scale=1,e.currentScale=1,t.$slideEl=void 0,t.$imageEl=void 0,t.$imageWrapEl=void 0)},toggle:function(e){var t=this.zoom;t.scale&&1!==t.scale?t.out():t.in(e)},in:function(e){var t,i,s,a,r,n,l,o,d,h,p,u,c,v,f,m,g=this.zoom,w=this.params.zoom,y=g.gesture,b=g.image;(y.$slideEl||(this.params.virtual&&this.params.virtual.enabled&&this.virtual?y.$slideEl=this.$wrapperEl.children("."+this.params.slideActiveClass):y.$slideEl=this.slides.eq(this.activeIndex),y.$imageEl=y.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),y.$imageWrapEl=y.$imageEl.parent("."+w.containerClass)),y.$imageEl&&0!==y.$imageEl.length)&&(y.$slideEl.addClass(""+w.zoomedSlideClass),void 0===b.touchesStart.x&&e?(t="touchend"===e.type?e.changedTouches[0].pageX:e.pageX,i="touchend"===e.type?e.changedTouches[0].pageY:e.pageY):(t=b.touchesStart.x,i=b.touchesStart.y),g.scale=y.$imageWrapEl.attr("data-swiper-zoom")||w.maxRatio,g.currentScale=y.$imageWrapEl.attr("data-swiper-zoom")||w.maxRatio,e?(f=y.$slideEl[0].offsetWidth,m=y.$slideEl[0].offsetHeight,s=y.$slideEl.offset().left+f/2-t,a=y.$slideEl.offset().top+m/2-i,l=y.$imageEl[0].offsetWidth,o=y.$imageEl[0].offsetHeight,d=l*g.scale,h=o*g.scale,c=-(p=Math.min(f/2-d/2,0)),v=-(u=Math.min(m/2-h/2,0)),(r=s*g.scale)<p&&(r=p),r>c&&(r=c),(n=a*g.scale)<u&&(n=u),n>v&&(n=v)):(r=0,n=0),y.$imageWrapEl.transition(300).transform("translate3d("+r+"px, "+n+"px,0)"),y.$imageEl.transition(300).transform("translate3d(0,0,0) scale("+g.scale+")"))},out:function(){var e=this.zoom,t=this.params.zoom,i=e.gesture;i.$slideEl||(this.params.virtual&&this.params.virtual.enabled&&this.virtual?i.$slideEl=this.$wrapperEl.children("."+this.params.slideActiveClass):i.$slideEl=this.slides.eq(this.activeIndex),i.$imageEl=i.$slideEl.find("img, svg, canvas, picture, .swiper-zoom-target"),i.$imageWrapEl=i.$imageEl.parent("."+t.containerClass)),i.$imageEl&&0!==i.$imageEl.length&&(e.scale=1,e.currentScale=1,i.$imageWrapEl.transition(300).transform("translate3d(0,0,0)"),i.$imageEl.transition(300).transform("translate3d(0,0,0) scale(1)"),i.$slideEl.removeClass(""+t.zoomedSlideClass),i.$slideEl=void 0)},toggleGestures:function(e){var t=this.zoom,i=t.slideSelector,s=t.passiveListener;this.$wrapperEl[e]("gesturestart",i,t.onGestureStart,s),this.$wrapperEl[e]("gesturechange",i,t.onGestureChange,s),this.$wrapperEl[e]("gestureend",i,t.onGestureEnd,s)},enableGestures:function(){this.zoom.gesturesEnabled||(this.zoom.gesturesEnabled=!0,this.zoom.toggleGestures("on"))},disableGestures:function(){this.zoom.gesturesEnabled&&(this.zoom.gesturesEnabled=!1,this.zoom.toggleGestures("off"))},enable:function(){var e=this.support,t=this.zoom;if(!t.enabled){t.enabled=!0;var i=!("touchstart"!==this.touchEvents.start||!e.passiveListener||!this.params.passiveListeners)&&{passive:!0,capture:!1},s=!e.passiveListener||{passive:!1,capture:!0},a="."+this.params.slideClass;this.zoom.passiveListener=i,this.zoom.slideSelector=a,e.gestures?(this.$wrapperEl.on(this.touchEvents.start,this.zoom.enableGestures,i),this.$wrapperEl.on(this.touchEvents.end,this.zoom.disableGestures,i)):"touchstart"===this.touchEvents.start&&(this.$wrapperEl.on(this.touchEvents.start,a,t.onGestureStart,i),this.$wrapperEl.on(this.touchEvents.move,a,t.onGestureChange,s),this.$wrapperEl.on(this.touchEvents.end,a,t.onGestureEnd,i),this.touchEvents.cancel&&this.$wrapperEl.on(this.touchEvents.cancel,a,t.onGestureEnd,i)),this.$wrapperEl.on(this.touchEvents.move,"."+this.params.zoom.containerClass,t.onTouchMove,s)}},disable:function(){var e=this.zoom;if(e.enabled){var t=this.support;this.zoom.enabled=!1;var i=!("touchstart"!==this.touchEvents.start||!t.passiveListener||!this.params.passiveListeners)&&{passive:!0,capture:!1},s=!t.passiveListener||{passive:!1,capture:!0},a="."+this.params.slideClass;t.gestures?(this.$wrapperEl.off(this.touchEvents.start,this.zoom.enableGestures,i),this.$wrapperEl.off(this.touchEvents.end,this.zoom.disableGestures,i)):"touchstart"===this.touchEvents.start&&(this.$wrapperEl.off(this.touchEvents.start,a,e.onGestureStart,i),this.$wrapperEl.off(this.touchEvents.move,a,e.onGestureChange,s),this.$wrapperEl.off(this.touchEvents.end,a,e.onGestureEnd,i),this.touchEvents.cancel&&this.$wrapperEl.off(this.touchEvents.cancel,a,e.onGestureEnd,i)),this.$wrapperEl.off(this.touchEvents.move,"."+this.params.zoom.containerClass,e.onTouchMove,s)}}},te={loadInSlide:function(e,t){void 0===t&&(t=!0);var i=this,s=i.params.lazy;if(void 0!==e&&0!==i.slides.length){var a=i.virtual&&i.params.virtual.enabled?i.$wrapperEl.children("."+i.params.slideClass+'[data-swiper-slide-index="'+e+'"]'):i.slides.eq(e),r=a.find("."+s.elementClass+":not(."+s.loadedClass+"):not(."+s.loadingClass+")");!a.hasClass(s.elementClass)||a.hasClass(s.loadedClass)||a.hasClass(s.loadingClass)||r.push(a[0]),0!==r.length&&r.each((function(e){var r=m(e);r.addClass(s.loadingClass);var n=r.attr("data-background"),l=r.attr("data-src"),o=r.attr("data-srcset"),d=r.attr("data-sizes"),h=r.parent("picture");i.loadImage(r[0],l||n,o,d,!1,(function(){if(null!=i&&i&&(!i||i.params)&&!i.destroyed){
vendor: 4,828 bytes, line 28206
28206if(n?(r.css("background-image",'url("'+n+'")'),r.removeAttr("data-background")):(o&&(r.attr("srcset",o),r.removeAttr("data-srcset")),d&&(r.attr("sizes",d),r.removeAttr("data-sizes")),h.length&&h.children("source").each((function(e){var t=m(e);t.attr("data-srcset")&&(t.attr("srcset",t.attr("data-srcset")),t.removeAttr("data-srcset"))})),l&&(r.attr("src",l),r.removeAttr("data-src"))),r.addClass(s.loadedClass).removeClass(s.loadingClass),a.find("."+s.preloaderClass).remove(),i.params.loop&&t){var e=a.attr("data-swiper-slide-index");if(a.hasClass(i.params.slideDuplicateClass)){var p=i.$wrapperEl.children('[data-swiper-slide-index="'+e+'"]:not(.'+i.params.slideDuplicateClass+")");i.lazy.loadInSlide(p.index(),!1)}else{var u=i.$wrapperEl.children("."+i.params.slideDuplicateClass+'[data-swiper-slide-index="'+e+'"]');i.lazy.loadInSlide(u.index(),!1)}}i.emit("lazyImageReady",a[0],r[0]),i.params.autoHeight&&i.updateAutoHeight()}})),i.emit("lazyImageLoad",a[0],r[0])}))}},load:function(){var e=this,t=e.$wrapperEl,i=e.params,s=e.slides,a=e.activeIndex,r=e.virtual&&i.virtual.enabled,n=i.lazy,l=i.slidesPerView;function o(e){if(r){if(t.children("."+i.slideClass+'[data-swiper-slide-index="'+e+'"]').length)return!0}else if(s[e])return!0;return!1}function d(e){return r?m(e).attr("data-swiper-slide-index"):m(e).index()}if("auto"===l&&(l=0),e.lazy.initialImageLoaded||(e.lazy.initialImageLoaded=!0),e.params.watchSlidesVisibility)t.children("."+i.slideVisibleClass).each((function(t){var i=r?m(t).attr("data-swiper-slide-index"):m(t).index();e.lazy.loadInSlide(i)}));else if(l>1)for(var h=a;h<a+l;h+=1)o(h)&&e.lazy.loadInSlide(h);else e.lazy.loadInSlide(a);if(n.loadPrevNext)if(l>1||n.loadPrevNextAmount&&n.loadPrevNextAmount>1){for(var p=n.loadPrevNextAmount,u=l,c=Math.min(a+u+Math.max(p,u),s.length),v=Math.max(a-Math.max(u,p),0),f=a+l;f<c;f+=1)o(f)&&e.lazy.loadInSlide(f);for(var g=v;g<a;g+=1)o(g)&&e.lazy.loadInSlide(g)}else{var w=t.children("."+i.slideNextClass);w.length>0&&e.lazy.loadInSlide(d(w));var y=t.children("."+i.slidePrevClass);y.length>0&&e.lazy.loadInSlide(d(y))}}},ie={LinearSpline:function(e,t){var i,s,a,r,n,l=function(e,t){for(s=-1,i=e.length;i-s>1;)e[a=i+s>>1]<=t?s=a:i=a;return i};return this.x=e,this.y=t,this.lastIndex=e.length-1,this.interpolate=function(e){return e?(n=l(this.x,e),r=n-1,(e-this.x[r])*(this.y[n]-this.y[r])/(this.x[n]-this.x[r])+this.y[r]):0},this},getInterpolateFunction:function(e){this.controller.spline||(this.controller.spline=this.params.loop?new ie.LinearSpline(this.slidesGrid,e.slidesGrid):new ie.LinearSpline(this.snapGrid,e.snapGrid))},setTranslate:function(e,t){var i,s,a=this,r=a.controller.control,n=a.constructor;function l(e){var t=a.rtlTranslate?-a.translate:a.translate;"slide"===a.params.controller.by&&(a.controller.getInterpolateFunction(e),s=-a.controller.spline.interpolate(-t)),s&&"container"!==a.params.controller.by||(i=(e.maxTranslate()-e.minTranslate())/(a.maxTranslate()-a.minTranslate()),s=(t-a.minTranslate())*i+e.minTranslate()),a.params.controller.inverse&&(s=e.maxTranslate()-s),e.updateProgress(s),e.setTranslate(s,a),e.updateActiveIndex(),e.updateSlidesClasses()}if(Array.isArray(r))for(var o=0;o<r.length;o+=1)r[o]!==t&&r[o]instanceof n&&l(r[o]);else r instanceof n&&t!==r&&l(r)},setTransition:function(e,t){var i,s=this,a=s.constructor,r=s.controller.control;function n(t){t.setTransition(e,s),0!==e&&(t.transitionStart(),t.params.autoHeight&&E((function(){t.updateAutoHeight()})),t.$wrapperEl.transitionEnd((function(){r&&(t.params.loop&&"slide"===s.params.controller.by&&t.loopFix(),t.transitionEnd())})))}if(Array.isArray(r))for(i=0;i<r.length;i+=1)r[i]!==t&&r[i]instanceof a&&n(r[i]);else r instanceof a&&t!==r&&n(r)}},se={getRandomNumber:function(e){void 0===e&&(e=16);return"x".repeat(e).replace(/x/g,(function(){return Math.round(16*Math.random()).toString(16)}))},makeElFocusable:function(e){return e.attr("tabIndex","0"),e},makeElNotFocusable:function(e){return e.attr("tabIndex","-1"),e},addElRole:function(e,t){return e.attr("role",t),e},addElRoleDescription:function(e,t){return e.attr("aria-role-description",t),e},addElControls:function(e,t){return e.attr("aria-controls",t),e},addElLabel:function(e,t){return e.attr("aria-label",t),e},addElId:function(e,t){return e.attr("id",t),e},addElLive:function(e,t){return e.attr("aria-live",t),e},disableEl:function(e){return e.attr("aria-disabled",!0),e},enableEl:function(e){return e.attr("aria-disabled",!1),e},onEnterKey:function(e){var t=this.params.a11y;if(13===e.keyCode){var i=m(e.target);this.navigation&&this.navigation.$nextEl&&i.is(this.navigation.$nextEl)&&(this.isEnd&&!this.params.loop||this.slideNext(),this.isEnd?this.a11y.notify(t.lastSlideMessage):this.a11y.notify(t.nextSlideMessage)),this.navigation&&this.navigation.$prevEl&&i.is(this.navigation.$prevEl)&&(this.isBeg
28206inning&&!this.params.loop||this.slidePrev(),this.isBeginning?this.a11y.notify(t.firstSlideMessage):this.a11y.notify(t.prevSlideMessage)),this.pagination&&i.is("."+this.params.pagination.bulletClass)&&i[0].click()}},notify:function(e){var t=this.a11y.liveRegion;0!==t.length&&(t.html(""),t.html(e))},updateNavigation:function(){if(!this.params.loop&&this.navigation){var e=this.navigation,t=e.$nextEl,i=e.$prevEl;i&&i.length>0&&(this.isBeginning?(this.a11y.disableEl(i),this.a11y.makeElNotFocusable(i)):(this.a11y.enableEl(i),this.a11y.makeElFocusable(i))),t&&t.length>0&&(this.isEnd?(this.a11y.disableEl(t),this.a11y.makeElNotFocusable(t)):(this.a11y.enableEl(t),this.a11y.makeElFocusable(t)))}},updatePagination:function(){var e=this,t=e.params.a11y;e.pagination&&e.params.pagination.clickable&&e.pagination.bullets&&e.pagination.bullets.length&&e.pagination.bullets.each((function(i){var s=m(i);e.a11y.makeElFocusable(s),e.params.pagination.renderBullet||(e.a11y.addElRole(s,"button"),e.a11y.addElLabel(s,t.paginationBulletMessage.replace(/\{\{index\}\}/,s.index()+1)))}))},init:function(){var e=this,t=e.params.a11y;e.$el.append(e.a11y.liveRegion);var i=e.$el;t.containerRoleDescriptionMessage&&e.a11y.addElRoleDescription(i,t.containerRoleDescriptionMessage),t.containerMessage&&e.a11y.addElLabel(i,t.containerMessage);var s,a,r,n=e.$wrapperEl,l=n.attr("id")||"swiper-wrapper-"+e.a11y.getRandomNumber(16);e.a11y.addElId(n,l),s=e.params.autoplay&&e.params.autoplay.enabled?"off":"polite",e.a11y.addElLive(n,s),t.itemRoleDescriptionMessage&&e.a11y.addElRoleDescription(m(e.slides),t.itemRoleDescriptionMessage),e.a11y.addElRole(m(e.slides),"group"),e.slides.each((function(t){var i=m(t);e.a11y.addElLabel(i,i.index()+1+" / "+e.slides.length)})),e.navigation&&e.navigation.$nextEl&&(a=e.navigation.$nextEl),e.navigation&&e.navigation.$prevEl&&(r=e.navigation.$prevEl),a&&a.length&&(e.a11y.makeElFocusable(a),"BUTTON"!==a[0].tagName&&(e.a11y.addElRole(a,"button"),a.on("keydown",e.a11y.onEnterKey)),e.a11y.addElLabel(a,t.nextSlideMessage),e.a11y.addElControls(a,l)),r&&r.length&&(e.a11y.makeElFocusable(r),"BUTTON"!==r[0].tagName&&(e.a11y.addElRole(r,"button"),r.on("keydown",e.a11y.onEnterKey)),e.a11y.addElLabel(r,t.prevSlideMessage),e.a11y.addElControls(r,l)),e.pagination&&e.params.pagination.clickable&&e.pagination.bullets&&e.pagination.bullets.length&&e.pagination.$el.on("keydown","."+e.params.pagination.bulletClass,e.a11y.onEnterKey)},destroy:function(){var e,t;this.a11y.liveRegion&&this.a11y.liveRegion.length>0&&this.a11y.liveRegion.remove(),this.navigation&&this.navigation.$nextEl&&(e=this.navigation.$nextEl),this.navigation&&this.navigation.$prevEl&&(t=this.navigation.$prevEl),e&&e.off("keydown",this.a11y.onEnterKey),t&&t.off("keydown",this.a11y.onEnterKey),this.pagination&&this.params.pagination.clickable&&this.pagination.bullets&&this.pagination.bullets.length&&this.pagination.$el.off("keydown","."+this.params.pagination.bulletClass,this.a11y.onEnterKey)}},ae={init:function(){var e=l();if(this.params.history){if(!e.history||!e.history.pushState)return this.params.history.enabled=!1,void(this.params.hashNavigation.enabled=!0);var t=this.history;t.initialized=!0,t.paths=ae.getPathValues(this.params.url),(t.paths.key||t.paths.value)&&(t.scrollToSlide(0,t.paths.value,this.params.runCallbacksOnInit),this.params.history.replaceState||e.addEventListener("popstate",this.history.setHistoryPopState))}},destroy:function(){var e=l();this.params.history.replaceState||e.removeEventListener("popstate",this.history.setHistoryPopState)},setHistoryPopState:function(){this.history.paths=ae.getPathValues(this.params.url),this.history.scrollToSlide(this.params.speed,this.history.paths.value,!1)},getPathValues:function(e){var t=l(),i=(e?new URL(e):t.location).pathname.slice(1).split("/").filter((function(e){return""!==e})),s=i.length;return{key:i[s-2],value:i[s-1]}},setHistory:function(e,t){var i=l();if(this.history.initialized&&this.params.history.enabled){var s;s=this.params.url?new URL(this.params.url):i.location;var a=this.slides.eq(t),r=ae.slugify(a.attr("data-history"));s.pathname.includes(e)||(r=e+"/"+r);var n=i.history.state;n&&n.value===r||(this.params.history.replaceState?i.history.replaceState({value:r},null,r):i.history.pushState({value:r},null,r))}},slugify:function(e){return e.toString().replace(/\s+/g,"-").replace(/[^\w-]+/g,"").replace(/--+/g,"-").replace(/^-+/,"").replace(/-+$/,"")},scrollToSlide:function(e,t,i){if(t)for(var s=0,a=this.slides.length;s<a;s+=1){var r=this.slides.eq(s);if(ae.slugify(r.attr("data-history"))===t&&!r.hasClass(this.params.slideDuplicateClass)){var n=r.index();this.slideTo(n,e,i)}}else this.slideTo(0,e,i)}},re={onHashCange:function(){var e=r();
28206this.emit("hashChange");var t=e.location.hash.replace("#","");if(t!==this.slides.eq(this.activeIndex).attr("data-hash")){var i=this.$wrapperEl.children("."+this.params.slideClass+'[data-hash="'+t+'"]').index();if(void 0===i)return;this.slideTo(i)}},setHash:function(){var e=l(),t=r();if(this.hashNavigation.initialized&&this.params.hashNavigation.enabled)if(this.params.hashNavigation.replaceState&&e.history&&e.history.replaceState)e.history.replaceState(null,null,"#"+this.slides.eq(this.activeIndex).attr("data-hash")||""),this.emit("hashSet");else{var i=this.slides.eq(this.activeIndex),s=i.attr("data-hash")||i.attr("data-history");t.location.hash=s||"",this.emit("hashSet")}},init:function(){var e=r(),t=l();if(!(!this.params.hashNavigation.enabled||this.params.history&&this.params.history.enabled)){this.hashNavigation.initialized=!0;var i=e.location.hash.replace("#","");if(i)for(var s=0,a=this.slides.length;s<a;s+=1){var n=this.slides.eq(s);if((n.attr("data-hash")||n.attr("data-history"))===i&&!n.hasClass(this.params.slideDuplicateClass)){var o=n.index();this.slideTo(o,0,this.params.runCallbacksOnInit,!0)}}this.params.hashNavigation.watchState&&m(t).on("hashchange",this.hashNavigation.onHashCange)}},destroy:function(){var e=l();this.params.hashNavigation.watchState&&m(e).off("hashchange",this.hashNavigation.onHashCange)}},ne={run:function(){var e=this,t=e.slides.eq(e.activeIndex),i=e.params.autoplay.delay;t.attr("data-swiper-autoplay")&&(i=t.attr("data-swiper-autoplay")||e.params.autoplay.delay),clearTimeout(e.autoplay.timeout),e.autoplay.timeout=E((function(){e.params.autoplay.reverseDirection?e.params.loop?(e.loopFix(),e.slidePrev(e.params.speed,!0,!0),e.emit("autoplay")):e.isBeginning?e.params.autoplay.stopOnLastSlide?e.autoplay.stop():(e.slideTo(e.slides.length-1,e.params.speed,!0,!0),e.emit("autoplay")):(e.slidePrev(e.params.speed,!0,!0),e.emit("autoplay")):e.params.loop?(e.loopFix(),e.slideNext(e.params.speed,!0,!0),e.emit("autoplay")):e.isEnd?e.params.autoplay.stopOnLastSlide?e.autoplay.stop():(e.slideTo(0,e.params.speed,!0,!0),e.emit("autoplay")):(e.slideNext(e.params.speed,!0,!0),e.emit("autoplay")),e.params.cssMode&&e.autoplay.running&&e.autoplay.run()}),i)},start:function(){return void 0===this.autoplay.timeout&&(!this.autoplay.running&&(this.autoplay.running=!0,this.emit("autoplayStart"),this.autoplay.run(),!0))},stop:function(){return!!this.autoplay.running&&(void 0!==this.autoplay.timeout&&(this.autoplay.timeout&&(clearTimeout(this.autoplay.timeout),this.autoplay.timeout=void 0),this.autoplay.running=!1,this.emit("autoplayStop"),!0))},pause:function(e){this.autoplay.running&&(this.autoplay.paused||(this.autoplay.timeout&&clearTimeout(this.autoplay.timeout),this.autoplay.paused=!0,0!==e&&this.params.autoplay.waitForTransition?(this.$wrapperEl[0].addEventListener("transitionend",this.autoplay.onTransitionEnd),this.$wrapperEl[0].addEventListener("webkitTransitionEnd",this.autoplay.onTransitionEnd)):(this.autoplay.paused=!1,this.autoplay.run())))},onVisibilityChange:function(){var e=r();"hidden"===e.visibilityState&&this.autoplay.running&&this.autoplay.pause(),"visible"===e.visibilityState&&this.autoplay.paused&&(this.autoplay.run(),this.autoplay.paused=!1)},onTransitionEnd:function(e){this&&!this.destroyed&&this.$wrapperEl&&e.target===this.$wrapperEl[0]&&(this.$wrapperEl[0].removeEventListener("transitionend",this.autoplay.onTransitionEnd),this.$wrapperEl[0].removeEventListener("webkitTransitionEnd",this.autoplay.onTransitionEnd),this.autoplay.paused=!1,this.autoplay.running?this.autoplay.run():this.autoplay.stop())}},le={setTranslate:function(){for(var e=this.slides,t=0;t<e.length;t+=1){var i=this.slides.eq(t),s=-i[0].swiperSlideOffset;this.params.virtualTranslate||(s-=this.translate);var a=0;this.isHorizontal()||(a=s,s=0);var r=this.params.fadeEffect.crossFade?Math.max(1-Math.abs(i[0].progress),0):1+Math.min(Math.max(i[0].progress,-1),0);i.css({opacity:r}).transform("translate3d("+s+"px, "+a+"px, 0px)")}},setTransition:function(e){var t=this,i=t.slides,s=t.$wrapperEl;if(i.transition(e),t.params.virtualTranslate&&0!==e){var a=!1;i.transitionEnd((function(){if(!a&&t&&!t.destroyed){a=!0,t.animating=!1;for(var e=["webkitTransitionEnd","transitionend"],i=0;i<e.length;i+=1)s.trigger(e[i])}}))}}},oe={setTranslate:function(){var e,t=this.$el,i=this.$wrapperEl,s=this.slides,a=this.width,r=this.height,n=this.rtlTranslate,l=this.size,o=this.browser,d=this.params.cubeEffect,h=this.isHorizontal(),p=this.virtual&&this.params.virtual.enabled,u=0;d.shadow&&(h?(0===(e=i.find(".swiper-cube-shadow")).length&&(e=m('<div class="swiper-cube-shadow"></div>'),i.append(e)),e.css({height:a+"px"})):0===(e=t.find(".swiper-cube-shadow")).length&&(e=m('<div class="swiper-cube-shadow"></div>'),t.append(e)));for(var c=0;c<s.length;c+=1){var v=s.eq(c),f=c;p&&(f=parseInt(v.attr("data-swiper-slide-index"),10));var g=90*f,w=Math.floor(g/360);n&&(g=-g,w=Math.floor(-g/360));
vendor: 16,384 bytes, line 28206
28206var y=Math.max(Math.min(v[0].progress,1),-1),b=0,E=0,x=0;f%4==0?(b=4*-w*l,x=0):(f-1)%4==0?(b=0,x=4*-w*l):(f-2)%4==0?(b=l+4*w*l,x=l):(f-3)%4==0&&(b=-l,x=3*l+4*l*w),n&&(b=-b),h||(E=b,b=0);var T="rotateX("+(h?0:-g)+"deg) rotateY("+(h?g:0)+"deg) translate3d("+b+"px, "+E+"px, "+x+"px)";if(y<=1&&y>-1&&(u=90*f+90*y,n&&(u=90*-f-90*y)),v.transform(T),d.slideShadows){var C=h?v.find(".swiper-slide-shadow-left"):v.find(".swiper-slide-shadow-top"),S=h?v.find(".swiper-slide-shadow-right"):v.find(".swiper-slide-shadow-bottom");0===C.length&&(C=m('<div class="swiper-slide-shadow-'+(h?"left":"top")+'"></div>'),v.append(C)),0===S.length&&(S=m('<div class="swiper-slide-shadow-'+(h?"right":"bottom")+'"></div>'),v.append(S)),C.length&&(C[0].style.opacity=Math.max(-y,0)),S.length&&(S[0].style.opacity=Math.max(y,0))}}if(i.css({"-webkit-transform-origin":"50% 50% -"+l/2+"px","-moz-transform-origin":"50% 50% -"+l/2+"px","-ms-transform-origin":"50% 50% -"+l/2+"px","transform-origin":"50% 50% -"+l/2+"px"}),d.shadow)if(h)e.transform("translate3d(0px, "+(a/2+d.shadowOffset)+"px, "+-a/2+"px) rotateX(90deg) rotateZ(0deg) scale("+d.shadowScale+")");else{var M=Math.abs(u)-90*Math.floor(Math.abs(u)/90),z=1.5-(Math.sin(2*M*Math.PI/360)/2+Math.cos(2*M*Math.PI/360)/2),P=d.shadowScale,k=d.shadowScale/z,$=d.shadowOffset;e.transform("scale3d("+P+", 1, "+k+") translate3d(0px, "+(r/2+$)+"px, "+-r/2/k+"px) rotateX(-90deg)")}var L=o.isSafari||o.isWebView?-l/2:0;i.transform("translate3d(0px,0,"+L+"px) rotateX("+(this.isHorizontal()?0:u)+"deg) rotateY("+(this.isHorizontal()?-u:0)+"deg)")},setTransition:function(e){var t=this.$el;this.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),this.params.cubeEffect.shadow&&!this.isHorizontal()&&t.find(".swiper-cube-shadow").transition(e)}},de={setTranslate:function(){for(var e=this.slides,t=this.rtlTranslate,i=0;i<e.length;i+=1){var s=e.eq(i),a=s[0].progress;this.params.flipEffect.limitRotation&&(a=Math.max(Math.min(s[0].progress,1),-1));var r=-180*a,n=0,l=-s[0].swiperSlideOffset,o=0;if(this.isHorizontal()?t&&(r=-r):(o=l,l=0,n=-r,r=0),s[0].style.zIndex=-Math.abs(Math.round(a))+e.length,this.params.flipEffect.slideShadows){var d=this.isHorizontal()?s.find(".swiper-slide-shadow-left"):s.find(".swiper-slide-shadow-top"),h=this.isHorizontal()?s.find(".swiper-slide-shadow-right"):s.find(".swiper-slide-shadow-bottom");0===d.length&&(d=m('<div class="swiper-slide-shadow-'+(this.isHorizontal()?"left":"top")+'"></div>'),s.append(d)),0===h.length&&(h=m('<div class="swiper-slide-shadow-'+(this.isHorizontal()?"right":"bottom")+'"></div>'),s.append(h)),d.length&&(d[0].style.opacity=Math.max(-a,0)),h.length&&(h[0].style.opacity=Math.max(a,0))}s.transform("translate3d("+l+"px, "+o+"px, 0px) rotateX("+n+"deg) rotateY("+r+"deg)")}},setTransition:function(e){var t=this,i=t.slides,s=t.activeIndex,a=t.$wrapperEl;if(i.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e),t.params.virtualTranslate&&0!==e){var r=!1;i.eq(s).transitionEnd((function(){if(!r&&t&&!t.destroyed){r=!0,t.animating=!1;for(var e=["webkitTransitionEnd","transitionend"],i=0;i<e.length;i+=1)a.trigger(e[i])}}))}}},he={setTranslate:function(){for(var e=this.width,t=this.height,i=this.slides,s=this.slidesSizesGrid,a=this.params.coverflowEffect,r=this.isHorizontal(),n=this.translate,l=r?e/2-n:t/2-n,o=r?a.rotate:-a.rotate,d=a.depth,h=0,p=i.length;h<p;h+=1){var u=i.eq(h),c=s[h],v=(l-u[0].swiperSlideOffset-c/2)/c*a.modifier,f=r?o*v:0,g=r?0:o*v,w=-d*Math.abs(v),y=a.stretch;"string"==typeof y&&-1!==y.indexOf("%")&&(y=parseFloat(a.stretch)/100*c);var b=r?0:y*v,E=r?y*v:0,x=1-(1-a.scale)*Math.abs(v);Math.abs(E)<.001&&(E=0),Math.abs(b)<.001&&(b=0),Math.abs(w)<.001&&(w=0),Math.abs(f)<.001&&(f=0),Math.abs(g)<.001&&(g=0),Math.abs(x)<.001&&(x=0);var T="translate3d("+E+"px,"+b+"px,"+w+"px)  rotateX("+g+"deg) rotateY("+f+"deg) scale("+x+")";if(u.transform(T),u[0].style.zIndex=1-Math.abs(Math.round(v)),a.slideShadows){var C=r?u.find(".swiper-slide-shadow-left"):u.find(".swiper-slide-shadow-top"),S=r?u.find(".swiper-slide-shadow-right"):u.find(".swiper-slide-shadow-bottom");0===C.length&&(C=m('<div class="swiper-slide-shadow-'+(r?"left":"top")+'"></div>'),u.append(C)),0===S.length&&(S=m('<div class="swiper-slide-shadow-'+(r?"right":"bottom")+'"></div>'),u.append(S)),C.length&&(C[0].style.opacity=v>0?v:0),S.length&&(S[0].style.opacity=-v>0?-v:0)}}},setTransition:function(e){this.slides.transition(e).find(".swiper-slide-shadow-top, .swiper-slide-shadow-right, .swiper-slide-shadow-bottom, .swiper-slide-shadow-left").transition(e)}},pe={init:function(){var e=this.params.thumbs;if(this.thumbs.initialized)return!1;this.thumbs.initialized=!0;var t=this.constructor;return e.swiper instanceof t?(this.thumbs.swiper=e.swiper,S(this.thumbs.swiper.originalParams,{watchSlidesProgress:!0,slideToClickedSlide:!1}),S(this.thumbs.swiper.params,{watchSlidesProgress:!0,slideToClickedSlide:!1})):C(e.swiper)&&(this.thumbs.swiper=new t(S({},e.swiper,{watchSlidesVisibility:!0,watchSlidesProgress:!0,slideToClickedSlide:!1})),this.thumbs.swiperCreated=!0),this.thumbs.swiper.$el.addClass(this.params.thumbs.thumbsContainerClass),this.thumbs.swiper.on("tap",this.thumbs.onThumbClick),!0},onThumbClick:function(){var e=this.thumbs.swiper;if(e){var t=e.clickedIndex,i=e.clickedSlide;if(!(i&&m(i).hasClass(this.params.thumbs.slideThumbActiveClass)||null==t)){var s;if(s=e.params.loop?parseInt(m(e.clickedSlide).attr("data-swiper-slide-index"),10):t,this.params.loop){var a=this.activeIndex;this.slides.eq(a).hasClass(this.params.slideDuplicateClass)&&(this.loopFix(),this._clientLeft=this.$wrapperEl[0].clientLeft,a=this.activeIndex);var r=this.slides.eq(a).prevAll('[data-swiper-slide-index="'+s+'"]').eq(0).index(),n=this.slides.eq(a).nextAll('[data-swiper-slide-index="'+s+'"]').eq(0).index();s=void 0===r?n:void 0===n?r:n-a<a-r?n:r}this.slideTo(s)}}},update:function(e){var t=this.thumbs.swiper;if(t){var i="auto"===t.params.slidesPerView?t.slidesPerViewDynamic():t.params.slidesPerView,s=this.params.thumbs.autoScrollOffset,a=s&&!t.params.loop;if(this.realIndex!==t.realIndex||a){var r,n,l=t.activeIndex;if(t.params.loop){t.slides.eq(l).hasClass(t.params.slideDuplicateClass)&&(t.loopFix(),t._clientLeft=t.$wrapperEl[0].clientLeft,l=t.activeIndex);var o=t.slides.eq(l).prevAll('[data-swiper-slide-index="'+this.realIndex+'"]').eq(0).index(),d=t.slides.eq(l).nextAll('[data-swiper-slide-index="'+this.realIndex+'"]').eq(0).index();r=void 0===o?d:void 0===d?o:d-l==l-o?l:d-l<l-o?d:o,n=this.activeIndex>this.previousIndex?"next":"prev"}else n=(r=this.realIndex)>this.previousIndex?"next":"prev";a&&(r+="next"===n?s:-1*s),t.visibleSlidesIndexes&&t.visibleSlidesIndexes.indexOf(r)<0&&(t.params.centeredSlides?r=r>l?r-Math.floor(i/2)+1:r+Math.floor(i/2)-1:r>l&&(r=r-i+1),t.slideTo(r,e?0:void 0))}var h=1,p=this.params.thumbs.slideThumbActiveClass;if(this.params.slidesPerView>1&&!this.params.centeredSlides&&(h=this.params.slidesPerView),this.params.thumbs.multipleActiveThumbs||(h=1),h=Math.floor(h),t.slides.removeClass(p),t.params.loop||t.params.virtual&&t.params.virtual.enabled)for(var u=0;u<h;u+=1)t.$wrapperEl.children('[data-swiper-slide-index="'+(this.realIndex+u)+'"]').addClass(p);else for(var c=0;c<h;c+=1)t.slides.eq(this.realIndex+c).addClass(p)}}},ue=[q,_,{name:"mousewheel",params:{mousewheel:{enabled:!1,releaseOnEdges:!1,invert:!1,forceToAxis:!1,sensitivity:1,eventsTarget:"container",thresholdDelta:null,thresholdTime:null}},create:function(){M(this,{mousewheel:{enabled:!1,lastScrollTime:x(),lastEventBeforeSnap:void 0,recentWheelEvents:[],enable:U.enable,disable:U.disable,handle:U.handle,handleMouseEnter:U.handleMouseEnter,handleMouseLeave:U.handleMouseLeave,animateSlider:U.animateSlider,releaseScroll:U.releaseScroll}})},on:{init:function(e){!e.params.mousewheel.enabled&&e.params.cssMode&&e.mousewheel.disable(),e.params.mousewheel.enabled&&e.mousewheel.enable()},destroy:function(e){e.params.cssMode&&e.mousewheel.enable(),e.mousewheel.enabled&&e.mousewheel.disable()}}},{name:"navigation",params:{navigation:{nextEl:null,prevEl:null,hideOnClick:!1,disabledClass:"swiper-button-disabled",hiddenClass:"swiper-button-hidden",lockClass:"swiper-button-lock"}},create:function(){M(this,{navigation:t({},K)})},on:{init:function(e){e.navigation.init(),e.navigation.update()},toEdge:function(e){e.navigation.update()},fromEdge:function(e){e.navigation.update()},destroy:function(e){e.navigation.destroy()},click:function(e,t){var i,s=e.navigation,a=s.$nextEl,r=s.$prevEl;!e.params.navigation.hideOnClick||m(t.target).is(r)||m(t.target).is(a)||(a?i=a.hasClass(e.params.navigation.hiddenClass):r&&(i=r.hasClass(e.params.navigation.hiddenClass)),!0===i?e.emit("navigationShow"):e.emit("navigationHide"),a&&a.toggleClass(e.params.navigation.hiddenClass),r&&r.toggleClass(e.params.navigation.hiddenClass))}}},{name:"pagination",params:{pagination:{el:null,bulletElement:"span",clickable:!1,hideOnClick:!1,renderBullet:null,renderProgressbar:null,renderFraction:null,renderCustom:null,progressbarOpposite:!1,type:"bullets",dynamicBullets:!1,dynamicMainBullets:1,formatFractionCurrent:function(e){return e},formatFractionTotal:function(e){return e},bulletClass:"swiper-pagination-bullet",bulletActiveClass:"swiper-pagination-bullet-active",modifierClass:"swiper-pagination-",currentClass:"swiper-pagination-current",totalClass:"swiper-pagination-total",hiddenClass:"swiper-pagination-hidden",progressbarFillClass:"swiper-pagination-progressbar-fill",progressbarOppositeClass:"swiper-pagination-progressbar-opposite",clickableClass:"swiper-pagination-clickable",lockClass:"swiper-pagination-lock"}},create:function(){M(this,{pagination:t({dynamicBulletIndex:0},Z)})},on:{init:function(e){e.pagination.init(),e.pagination.render(),e.pagination.update()},activeIndexChange:function(e){(e.params.loop||void 0===e.snapIndex)&&e.pagination.update()},snapIndexChange:function(e){e.params.loop||e.pagination.update()},slidesLengthChange:function(e){e.params.loop&&(e.pagination.render(),e.pagination.update())},snapGridLengthChange:function(e){e.params.loop||(e.pagination.render(),e.pagination.update())},destroy:function(e){e.pagination.destroy()},click:function(e,t){e.params.pagination.el&&e.params.pagination.hideOnClick&&e.pagination.$el.length>0&&!m(t.target).hasClass(e.params.pagination.bulletClass)&&(!0===e.pagination.$el.hasClass(e.params.pagination.hiddenClass)?e.emit("paginationShow"):e.emit("paginationHide"),e.pagination.$el.toggleClass(e.params.pagination.hiddenClass))}}},{name:"scrollbar",params:{scrollbar:{el:null,dragSize:"auto",hide:!1,draggable:!1,snapOnRelease:!0,lockClass:"swiper-scrollbar-lock",dragClass:"swiper-scrollbar-drag"}},create:function(){M(this,{scrollbar:t({isTouched:!1,timeout:null,dragTimeout:null},J)})},on:{init:function(e){e.scrollbar.init(),e.scrollbar.updateSize(),e.scrollbar.setTranslate()},update:function(e){e.scrollbar.updateSize()},resize:function(e){e.scrollbar.updateSize()},observerUpdate:function(e){e.scrollbar.updateSize()},setTranslate:function(e){e.scrollbar.setTranslate()},setTransition:function(e,t){e.scrollbar.setTransition(t)},destroy:function(e){e.scrollbar.destroy()}}},{name:"parallax",params:{parallax:{enabled:!1}},create:function(){M(this,{parallax:t({},Q)})},on:{beforeInit:function(e){e.params.parallax.enabled&&(e.params.watchSlidesProgress=!0,e.originalParams.watchSlidesProgress=!0)},init:function(e){e.params.parallax.enabled&&e.parallax.setTranslate()},setTranslate:function(e){e.params.parallax.enabled&&e.parallax.setTranslate()},setTransition:function(e,t){e.params.parallax.enabled&&e.parallax.setTransition(t)}}},{name:"zoom",params:{zoom:{enabled:!1,maxRatio:3,minRatio:1,toggle:!0,containerClass:"swiper-zoom-container",zoomedSlideClass:"swiper-slide-zoomed"}},create:function(){var e=this;M(e,{zoom:t({enabled:!1,scale:1,currentScale:1,isScaling:!1,gesture:{$slideEl:void 0,slideWidth:void 0,slideHeight:void 0,$imageEl:void 0,$imageWrapEl:void 0,maxRatio:3},image:{isTouched:void 0,isMoved:void 0,currentX:void 0,currentY:void 0,minX:void 0,minY:void 0,maxX:void 0,maxY:void 0,width:void 0,height:void 0,startX:void 0,startY:void 0,touchesStart:{},touchesCurrent:{}},velocity:{x:void 0,y:void 0,prevPositionX:void 0,prevPositionY:void 0,prevTime:void 0}},ee)});var i=1;Object.defineProperty(e.zoom,"scale",{get:function(){return i},set:function(t){if(i!==t){var s=e.zoom.gesture.$imageEl?e.zoom.gesture.$imageEl[0]:void 0,a=e.zoom.gesture.$slideEl?e.zoom.gesture.$slideEl[0]:void 0;e.emit("zoomChange",t,s,a)}i=t}})},on:{init:function(e){e.params.zoom.enabled&&e.zoom.enable()},destroy:function(e){e.zoom.disable()},touchStart:function(e,t){e.zoom.enabled&&e.zoom.onTouchStart(t)},touchEnd:function(e,t){e.zoom.enabled&&e.zoom.onTouchEnd(t)},doubleTap:function(e,t){e.params.zoom.enabled&&e.zoom.enabled&&e.params.zoom.toggle&&e.zoom.toggle(t)},transitionEnd:function(e){e.zoom.enabled&&e.params.zoom.enabled&&e.zoom.onTransitionEnd()},slideChange:function(e){e.zoom.enabled&&e.params.zoom.enabled&&e.params.cssMode&&e.zoom.onTransitionEnd()}}},{name:"lazy",params:{lazy:{enabled:!1,loadPrevNext:!1,loadPrevNextAmount:1,loadOnTransitionStart:!1,elementClass:"swiper-lazy",loadingClass:"swiper-lazy-loading",loadedClass:"swiper-lazy-loaded",preloaderClass:"swiper-lazy-preloader"}},create:function(){M(this,{lazy:t({initialImageLoaded:!1},te)})},on:{beforeInit:function(e){e.params.lazy.enabled&&e.params.preloadImages&&(e.params.preloadImages=!1)},init:function(e){e.params.lazy.enabled&&!e.params.loop&&0===e.params.initialSlide&&e.lazy.load()},scroll:function(e){e.params.freeMode&&!e.params.freeModeSticky&&e.lazy.load()},resize:function(e){e.params.lazy.enabled&&e.lazy.load()},scrollbarDragMove:function(e){e.params.lazy.enabled&&e.lazy.load()},transitionStart:function(e){e.params.lazy.enabled&&(e.params.lazy.loadOnTransitionStart||!e.params.lazy.loadOnTransitionStart&&!e.lazy.initialImageLoaded)&&e.lazy.load()},transitionEnd:function(e){e.params.lazy.enabled&&!e.params.lazy.loadOnTransitionStart&&e.lazy.load()},slideChange:function(e){e.params.lazy.enabled&&e.params.cssMode&&e.lazy.load()}}},{name:"controller",params:{controller:{control:void 0,inverse:!1,by:"slide"}},create:function(){M(this,{controller:t({control:this.params.controller.control},ie)})},on:{update:function(e){e.controller.control&&e.controller.spline&&(e.controller.spline=void 0,delete e.controller.spline)},resize:function(e){e.controller.control&&e.controller.spline&&(e.controller.spline=void 0,delete e.controller.spline)},observerUpdate:function(e){e.controller.control&&e.controller.spline&&(e.controller.spline=void 0,delete e.controller.spline)},setTranslate:function(e,t,i){e.controller.control&&e.controller.setTranslate(t,i)},setTransition:function(e,t,i){e.controller.control&&e.controller.setTransition(t,i)}}},{name:"a11y",params:{a11y:{enabled:!0,notificationClass:"swiper-notification",prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide",paginationBulletMessage:"Go to slide {{index}}",containerMessage:null,containerRoleDescriptionMessage:null,itemRoleDescriptionMessage:null}},create:function(){M(this,{a11y:t(t({},se),{},{liveRegion:m('<span class="'+this.params.a11y.notificationClass+'" aria-live="assertive" aria-atomic="true"></span>')})})},on:{afterInit:function(e){e.params.a11y.enabled&&(e.a11y.init(),e.a11y.updateNavigation())},toEdge:function(e){e.params.a11y.enabled&&e.a11y.updateNavigation()},fromEdge:function(e){e.params.a11y.enabled&&e.a11y.updateNavigation()},paginationUpdate:function(e){e.params.a11y.enabled&&e.a11y.updatePagination()},destroy:function(e){e.params.a11y.enabled&&e.a11y.destroy()}}},{name:"history",params:{history:{enabled:!1,replaceState:!1,key:"slides"}},create:function(){M(this,{history:t({},ae)})},on:{init:function(e){e.params.history.enabled&&e.history.init()},destroy:function(e){e.params.history.enabled&&e.history.destroy()},transitionEnd:function(e){e.history.initialized&&e.history.setHistory(e.params.history.key,e.activeIndex)},slideChange:function(e){e.history.initialized&&e.params.cssMode&&e.history.setHistory(e.params.history.key,e.activeIndex)}}},{name:
28206"hash-navigation",params:{hashNavigation:{enabled:!1,replaceState:!1,watchState:!1}},create:function(){M(this,{hashNavigation:t({initialized:!1},re)})},on:{init:function(e){e.params.hashNavigation.enabled&&e.hashNavigation.init()},destroy:function(e){e.params.hashNavigation.enabled&&e.hashNavigation.destroy()},transitionEnd:function(e){e.hashNavigation.initialized&&e.hashNavigation.setHash()},slideChange:function(e){e.hashNavigation.initialized&&e.params.cssMode&&e.hashNavigation.setHash()}}},{name:"autoplay",params:{autoplay:{enabled:!1,delay:3e3,waitForTransition:!0,disableOnInteraction:!0,stopOnLastSlide:!1,reverseDirection:!1}},create:function(){M(this,{autoplay:t(t({},ne),{},{running:!1,paused:!1})})},on:{init:function(e){e.params.autoplay.enabled&&(e.autoplay.start(),r().addEventListener("visibilitychange",e.autoplay.onVisibilityChange))},beforeTransitionStart:function(e,t,i){e.autoplay.running&&(i||!e.params.autoplay.disableOnInteraction?e.autoplay.pause(t):e.autoplay.stop())},sliderFirstMove:function(e){e.autoplay.running&&(e.params.autoplay.disableOnInteraction?e.autoplay.stop():e.autoplay.pause())},touchEnd:function(e){e.params.cssMode&&e.autoplay.paused&&!e.params.autoplay.disableOnInteraction&&e.autoplay.run()},destroy:function(e){e.autoplay.running&&e.autoplay.stop(),r().removeEventListener("visibilitychange",e.autoplay.onVisibilityChange)}}},{name:"effect-fade",params:{fadeEffect:{crossFade:!1}},create:function(){M(this,{fadeEffect:t({},le)})},on:{beforeInit:function(e){if("fade"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"fade");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};S(e.params,t),S(e.originalParams,t)}},setTranslate:function(e){"fade"===e.params.effect&&e.fadeEffect.setTranslate()},setTransition:function(e,t){"fade"===e.params.effect&&e.fadeEffect.setTransition(t)}}},{name:"effect-cube",params:{cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94}},create:function(){M(this,{cubeEffect:t({},oe)})},on:{beforeInit:function(e){if("cube"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"cube"),e.classNames.push(e.params.containerModifierClass+"3d");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,resistanceRatio:0,spaceBetween:0,centeredSlides:!1,virtualTranslate:!0};S(e.params,t),S(e.originalParams,t)}},setTranslate:function(e){"cube"===e.params.effect&&e.cubeEffect.setTranslate()},setTransition:function(e,t){"cube"===e.params.effect&&e.cubeEffect.setTransition(t)}}},{name:"effect-flip",params:{flipEffect:{slideShadows:!0,limitRotation:!0}},create:function(){M(this,{flipEffect:t({},de)})},on:{beforeInit:function(e){if("flip"===e.params.effect){e.classNames.push(e.params.containerModifierClass+"flip"),e.classNames.push(e.params.containerModifierClass+"3d");var t={slidesPerView:1,slidesPerColumn:1,slidesPerGroup:1,watchSlidesProgress:!0,spaceBetween:0,virtualTranslate:!0};S(e.params,t),S(e.originalParams,t)}},setTranslate:function(e){"flip"===e.params.effect&&e.flipEffect.setTranslate()},setTransition:function(e,t){"flip"===e.params.effect&&e.flipEffect.setTransition(t)}}},{name:"effect-coverflow",params:{coverflowEffect:{rotate:50,stretch:0,depth:100,scale:1,modifier:1,slideShadows:!0}},create:function(){M(this,{coverflowEffect:t({},he)})},on:{beforeInit:function(e){"coverflow"===e.params.effect&&(e.classNames.push(e.params.containerModifierClass+"coverflow"),e.classNames.push(e.params.containerModifierClass+"3d"),e.params.watchSlidesProgress=!0,e.originalParams.watchSlidesProgress=!0)},setTranslate:function(e){"coverflow"===e.params.effect&&e.coverflowEffect.setTranslate()},setTransition:function(e,t){"coverflow"===e.params.effect&&e.coverflowEffect.setTransition(t)}}},{name:"thumbs",params:{thumbs:{swiper:null,multipleActiveThumbs:!0,autoScrollOffset:0,slideThumbActiveClass:"swiper-slide-thumb-active",thumbsContainerClass:"swiper-container-thumbs"}},create:function(){M(this,{thumbs:t({swiper:null,initialized:!1},pe)})},on:{beforeInit:function(e){var t=e.params.thumbs;t&&t.swiper&&(e.thumbs.init(),e.thumbs.update(!0))},slideChange:function(e){e.thumbs.swiper&&e.thumbs.update()},update:function(e){e.thumbs.swiper&&e.thumbs.update()},resize:function(e){e.thumbs.swiper&&e.thumbs.update()},observerUpdate:function(e){e.thumbs.swiper&&e.thumbs.update()},setTransition:function(e,t){var i=e.thumbs.swiper;i&&i.setTransition(t)},beforeDestroy:function(e){var t=e.thumbs.swiper;t&&e.thumbs.swiperCreated&&t&&t.destroy()}}}];return R.use(ue),R}));
28207/* End */
28208;
28209; /* Start:"a:4:{s:4:"full";s:59:"/bitrix/tools/concept.stories/js/scripts.js?162744795633366";s:6:"source";s:43:"/bitrix/tools/concept.stories/js/scripts.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/
28210var 
28211layerPopup = 0, 
28212windowWidth = document.documentElement.clientWidth,
28213windowHeight = document.documentElement.clientHeight;
28214
28215
28216
28217function cptStoriesHideAdv()
28218{
28219	
28220	var hideAdv = document.querySelector(".js-cpt-stories-hide-adv"),
28221		siteID = document.querySelector('.cpt-stories-site_id');
28222
28223	if(hideAdv)
28224	{
28225		cptStoriesXMLrequest({
28226			'path':'/bitrix/tools/concept.stories/hide_adv.php',
28227			'data': {
28228				'siteID':siteID.value,
28229				'check':'Y',
28230				'USER_ID': hideAdv.getAttribute('data-user-id'),
28231			},
28232			'NODE':null,
28233			'HIDE_ADV':'Y'
28234		});
28235	}
28236}
28237
28238(function(window){
28239
28240	window.CptStories = function(arParams)
28241	{
28242		this.product = arParams;
28243		this.nodes = {};
28244		this.eventsCustom = {};
28245		this.intervalId = null;
28246		this.time = 5;
28247		this.start = 0;
28248		this.setForLocalStorage = {};
28249		this.error = 0;
28250
28251		this.initConfig();
28252
28253
28254		if(this.product.SLIDER.ITEMS_CNT === '0')
28255			this.error = -100;
28256
28257		if(this.error === 0)
28258			BX.ready(BX.delegate(this.init, this));
28259	};
28260
28261	window.CptStories.prototype = 
28262	{
28263		initConfig: function(){
28264
28265			/*this.product.SLIDER.SELECTED = parseInt(this.product.SLIDER.SELECTED,10);
28266
28267			if(this.product.SLIDER.ITEMS.length>0)
28268			{
28269				for (var i = 0; i < this.product.SLIDER.ITEMS.length; i++) {
28270					this.product.SLIDER.ITEMS[i].SELECTED = parseInt(this.product.SLIDER.ITEMS[i].SELECTED);
28271				}
28272			}*/
28273		},
28274
28275		initNodes: function(){
28276
28277			if(this.product.NODE)
28278			{
28279				this.nodes.obStories = document.querySelector("#"+this.product.NODE);
28280
28281				var clone = this.nodes.obStories.cloneNode(true);
28282
28283				this.nodes.obStories.remove();
28284
28285				document.body.appendChild(clone);
28286				
28287				this.nodes.obStories = clone;
28288
28289				this.nodes.obWindow = this.nodes.obStories.querySelector(".js-cpt-stories-modal-guts");
28290				this.nodes.obCloseBtn = this.nodes.obStories.querySelector(".js-cpt-stories-close-button");
28291				this.nodes.obPauseBtn = this.nodes.obStories.querySelector(".js-cpt-stories-pause-button");
28292
28293				this.nodes.obBtnNext = this.nodes.obStories.querySelectorAll(".js-cpt-stories-window-next");
28294				this.nodes.obBtnPrev = this.nodes.obStories.querySelectorAll(".js-cpt-stories-window-prev");
28295
28296				this.nodes.obWrSlides = this.nodes.obStories.querySelector(".js-cpt-stories-slides");
28297				this.nodes.obSlides = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-slide");
28298				
28299				this.nodes.obFrames = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-frame");
28300
28301				this.nodes.obOverlay = this.nodes.obStories.querySelector(".js-cpt-stories-modal-overlay");
28302				this.nodes.obOverlayUser = this.nodes.obStories.querySelector(".js-cpt-stories-modal-overlay-user");
28303				this.nodes.obShadow = this.nodes.obStories.querySelector(".js-cpt-stories-bg-shadow");
28304
28305
28306				this.nodes.obStoriesPreview = document.querySelector("#"+this.product.NODE_PREVIEW);
28307
28308				this.nodes.obWrSlidesPreview = this.nodes.obStoriesPreview.querySelectorAll(".js-cpt-stories-preview-slide");
28309
28310
28311				this.nodes.obBtns = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-frame-btn");
28312				this.nodes.obFrameTitles = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-frame-title");
28313				this.nodes.obFrameSubTitles = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-frame-subtitle");
28314				this.nodes.obFrameText = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-frame-text");
28315
28316				/*this.nodes.obVideos = this.nodes.obWrSlides.querySelectorAll(".js-cpt-stories-video");*/
28317
28318			}
28319
28320			if(this.product.IS_WG === 'Y')
28321			{
28322				this.nodes.obFixBlock = document.querySelector(".js-cpt-stories-fixblock");
28323				this.nodes.obHideFixBlockBtn = this.nodes.obFixBlock.querySelector(".js-cpt-stories-close-button");
28324			}
28325		},
28326
28327		setFontsSize: function()
28328		{
28329			var curFSize = null,
28330				result = 0,
28331				ratio = 100,
28332				windowWidth = document.documentElement.clientWidth;
28333
28334
28335			if(windowWidth >= 1200)
28336			{
28337				ratio = 0;
28338			}
28339			else if(windowWidth >= 992 && windowWidth <= 1199)
28340			{
28341				ratio = 0;
28342			}
28343			else if(windowWidth >= 768 && windowWidth <= 991)
28344			{
28345				ratio = 10;
28346			}
28347			else
28348			{
28349				ratio = 15;
28350			}
28351
28352
28353			if(this.nodes.obBtns)
28354				for (var i = 0; i < this.nodes.obBtns.length; i++)
28355				{
28356					this.nodes.obBtns[i].style.fontSize='';
28357					curFSize = parseInt(window.getComputedStyle(this.nodes.obBtns[i]).fontSize);
28358					result = curFSize - (curFSize * ratio / 100);
28359					this.nodes.obBtns[i].style.fontSize=result+'px';
28360					this.nodes.obBtns[i].style.lineHeight=(result+4)+'px';
28361				}
28362				
28363			if(this.nodes.obFrameTitles)
28364				for (var i = 0; i < this.nodes.obFrameTitles.length; i++)
28365				{
28366					this.nodes.obFrameTitles[i].style.fontSize='';
28367					curFSize = parseInt(window.getComputedStyle(this.nodes.obFrameTitles[i]).fontSize);
28368					result = curFSize - (curFSize * ratio / 100);
28369					this.nodes.obFrameTitles[i].style.fontSize=result+'px';
28370					this.nodes.obFrameTitles[i].style.lineHeight=(result+4)+'px';
28371				}
28372
28373			if(this.nodes.obFrameSubTitles)
28374				for (var i = 0; i < this.nodes.obFrameSubTitles.length; i++)
28375				{
28376					this.nodes.obFrameSubTitles[i].style.fontSize='';
28377					curFSize = parseInt(window.getComputedStyle(this.nodes.obFrameSubTitles[i]).fontSize);
28378					result = curFSize - (curFSize * ratio / 100);
28379					this.nodes.obFrameSubTitles[i].style.fontSize=result+'px';
28380					this.nodes.obFrameSubTitles[i].style.lineHeight=(result+6)+'px';
28381				}
28382
28383			if(this.nodes.obFrameText)
28384				for (var i = 0; i < this.nodes.obFrameText.length; i++)
28385				{
28386					this.nodes.obFrameText[i].style.fontSize='';
28387					curFSize = parseInt(window.getComputedStyle(this.nodes.obFrameText[i]).fontSize);
28388					result = curFSize - (curFSize * ratio / 100);
28389					this.nodes.obFrameText[i].style.fontSize=result+'px';
28390					this.nodes.obFrameText[i].style.lineHeight=(result+4)+'px';
28391				}
28392		},
28393
28394		bindAnaliticsBtns: function()
28395		{
28396			var that = this;
28397			for (var i = 0; i < this.nodes.obBtns.length; i++)
28398			{
28399
28400				var slideID = null,
28401					frameID = null,
28402					nodeFrame = null;
28403
28404
28405				this.nodes.obBtns[i].addEventListener('click', function()
28406				{
28407
28408					var target = event.target;
28409
28410					if(target.closest(".js-cpt-stories-frame"))
28411					{
28412						
28413						nodeFrame = target.closest(".js-cpt-stories-frame");
28414						slideID = nodeFrame.getAttribute('data-story');
28415						frameID = nodeFrame.getAttribute('data-frame');
28416
28417						if(that.product.SLIDER.ITEMS[slideID].ITEMS[frameID].ANALYTIC_BTN_CLICK)
28418							cptStoriesAddScript(that.product.SLIDER.ITEMS[slideID].ITEMS[frameID].ANALYTIC_BTN_CLICK);
28419					
28420					}
28421
28422				});
28423				
28424			}
28425		},
28426
28427		bindBtns: function()
28428		{
28429			var that = this;
28430
28431			for (var i = 0; i < this.nodes.obBtns.length; i++)
28432			{
28433				this.nodes.obBtns[i].addEventListener('click', that.hidePopupStories.bind(that));
28434			}
28435		},
28436
28437		bindPauseFromFrame: function()
28438		{
28439			var that = this;
28440
28441		
28442			for (var i = 0; i < this.nodes.obFrames.length; i++)
28443			{
28444				this.nodes.obFrames[i].addEventListener("mousedown", that.pauseFrame.bind(that));
28445				this.nodes.obFrames[i].addEventListener("mouseup", that.playFrame.bind(that));
28446				this.nodes.obFrames[i].addEventListener("touchstart", that.pauseFrame.bind(that));
28447				this.nodes.obFrames[i].addEventListener("touchend", that.playFrame.bind(that));
28448			}
28449			
28450			
28451		},
28452
28453		
28454
28455		bindPrevNextBtns: function()
28456		{
28457			var that = this;
28458
28459			if(this.nodes.obBtnNext)
28460			{
28461				for (var i = 0; i < this.nodes.obBtnNext.length; i++)
28462				{
28463					this.nodes.obBtnNext[i].addEventListener("click", function(e) 
28464					{
28465						e.preventDefault();
28466						that.next();
28467					});
28468					/*this.nodes.obBtnNext[i].addEventListener("mouseup", function(e) 
28469					{
28470						e.preventDefault();
28471						that.playFrame();
28472					});*/
28473					
28474				}
28475			}
28476
28477			if(this.nodes.obBtnPrev)
28478			{
28479
28480				for (var i = 0; i < this.nodes.obBtnPrev.length; i++)
28481				{
28482					this.nodes.obBtnPrev[i].addEventListener("click", function(e) 
28483					{
28484						e.preventDefault();
28485						that.prev();
28486					});
28487					/*this.nodes.obBtnPrev[i].addEventListener("mouseup", function(e) 
28488					{
28489						e.preventDefault();
28490						that.playFrame();
28491					});*/
28492				}
28493			}
28494		},
28495
28496		bindShowPopupStories: function()
28497		{
28498			var that = this;
28499
28500			if(this.nodes.obWrSlidesPreview)
28501			{
28502				for (var i = 0; i < this.nodes.obWrSlidesPreview.length; i++)
28503				{
28504					this.nodes.obWrSlidesPreview[i].addEventListener("click", that.showPopupStories.bind(that));
28505				}
28506
28507			}
28508		},
28509
28510		bindHidePopupStories: function()
28511		{
28512			var that = this;
28513			if(this.nodes.obCloseBtn)
28514				this.nodes.obCloseBtn.addEventListener('click', that.hidePopupStories.bind(that));
28515
28516			if(this.nodes.obShadow)
28517				this.nodes.obShadow.addEventListener('click', that.hidePopupStories.bind(that));
28518		},
28519
28520		bindTooglePlayPause: function()
28521		{
28522			var target = event.target;
28523			event.preventDefault();
28524
28525
28526			if(target.closest(".cpt-stories-pause"))
28527			{
28528				this.pauseFrame();
28529			}
28530			else if(target.closest(".cpt-stories-play"))
28531			{
28532				this.playFrame();
28533			}
28534		},
28535
28536		showPopupStories: function()
28537		{
28538			var target = event.target, slide = null;
28539
28540			if(slide = target.closest(".js-cpt-stories-preview-slide"))
28541		    {
28542				event.preventDefault();
28543
28544				setBodyOverflowHidden();
28545
28546
28547				if(document.documentElement.clientWidth <= 576)
28548				{
28549					if(document.documentElement.requestFullScreen) {
28550					    document.documentElement.requestFullScreen();
28551					  } else if(document.documentElement.mozRequestFullScreen) {
28552					    document.documentElement.mozRequestFullScreen();
28553					  } else if(document.documentElement.webkitRequestFullScreen) {
28554					    document.documentElement.webkitRequestFullScreen();
28555					  }
28556				}
28557				
28558
28559
28560				this.product.SLIDER.SELECTED = slide.getAttribute('data-story');
28561
28562				this.changeSlide();
28563				this.changeFrame();
28564
28565				this.getCurrentStory();
28566				this.ComplitedFramesNav();
28567				this.startFrameNav();
28568
28569				this.nodes.obStories.classList.remove('cpt-stories-d-none');
28570
28571
28572
28573				if(this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ANALYTICS_START_WATCH)
28574					cptStoriesAddScript(this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ANALYTICS_START_WATCH);
28575
28576
28577
28578
28579			}
28580
28581		},
28582
28583		hidePopupStories: function()
28584		{
28585
28586			if(document.documentElement.clientWidth <= 576)
28587			{
28588				if(document.cancelFullScreen)
28589					document.cancelFullScreen();
28590
28591				else if(document.mozCancelFullScreen)
28592				    document.mozCancelFullScreen();
28593
28594				else if(document.webkitCancelFullScreen)
28595					document.webkitCancelFullScreen();
28596			}
28597
28598
28599			this.setBtnPlay();
28600			this.nodes.obStories.classList.add('cpt-stories-d-none');
28601			clearInterval(this.intervalId);
28602			deleteBodyOverflowHidden();
28603
28604		},
28605
28606		bindEvents: function()
28607		{
28608			this.bindShowPopupStories();
28609			this.bindHidePopupStories();
28610			this.bindPrevNextBtns();
28611			this.bindPauseFromFrame();
28612			this.bindBtns();
28613			this.bindAnaliticsBtns();
28614
28615			if(this.product.IS_WG === 'Y')
28616				this.bindHideFixBlockBtn();
28617
28618			var that = this;
28619			if(this.nodes.obPauseBtn)
28620				this.nodes.obPauseBtn.addEventListener('click', that.bindTooglePlayPause.bind(that));
28621		},
28622
28623
28624		preViewSlides: function()
28625		{
28626			var data = JSON.parse(localStorage.getItem('cpt-stories-'+this.product.ID)),
28627				newDate = {};
28628			
28629			if(data)
28630			{
28631
28632				if(Object.keys(data).length > 30)
28633				{
28634					localStorage.removeItem('cpt-stories-'+this.product.ID);
28635				}
28636				else
28637				{
28638
28639					if(this.product.SLIDER.ITEMS)
28640					{
28641						for (var pair in this.product.SLIDER.ITEMS){
28642
28643							if(this.product.SLIDER.ITEMS[pair].ITEMS_CNT === data[pair])
28644							{
28645								newDate[pair] = data[pair];
28646							}
28647						}
28648					}
28649
28650					if(Object.keys(newDate).length > 0)
28651					{
28652
28653						this.setForLocalStorage = newDate;
28654
28655						for (var i = 0; i < this.nodes.obWrSlidesPreview.length; i++)
28656						{
28657							var dataStory = this.nodes.obWrSlidesPreview[i].getAttribute('data-story');
28658
28659							for (var pair in this.setForLocalStorage){
28660								if(dataStory == pair)
28661									this.nodes.obWrSlidesPreview[i].classList.remove('cpt-stories-preview-slide-active');
28662
28663							}
28664							// this.nodes.obWrSlidesPreview[data[i]].classList.remove('cpt-stories-preview-slide-active');
28665						}
28666					}
28667				}
28668			}
28669		},
28670
28671		startWg: function(){
28672			this.product.WG_START_TIMER = parseFloat(this.product.WG_START_TIMER);
28673			var that = this,
28674				now = Date.now(),
28675				data = JSON.parse(localStorage.getItem('cpt-stories-timer'));
28676			
28677			if(data)
28678			{
28679				if(now>=data[0])
28680				{
28681					localStorage.removeItem('cpt-stories-timer');
28682				}
28683				else
28684				{
28685					that.product.WG_START_TIMER = data[0] - now;
28686				}
28687			}
28688
28689
28690			setTimeout(
28691				function()
28692				{
28693					that.nodes.obFixBlock.classList.add('cpt-stories-show');
28694
28695					setTimeout(
28696					function()
28697					{
28698						var previmg = that.nodes.obFixBlock.querySelector('.js-cpt-stories-fixblock-img');
28699						if(previmg)
28700							previmg.classList.add('cpt-stories-animate-rotate');
28701					},1000
28702				);
28703
28704
28705				},that.product.WG_START_TIMER
28706			);
28707			
28708		},
28709
28710		hideFixBlock: function()
28711		{
28712			this.nodes.obFixBlock.classList.remove('cpt-stories-show');
28713
28714			this.product.WG_HIDDEN_TIMER = parseInt(this.product.WG_HIDDEN_TIMER);
28715
28716			if(this.product.WG_HIDDEN_TIMER > 0)
28717			{
28718				var now = Date.now();
28719				localStorage.setItem('cpt-stories-timer', JSON.stringify([this.product.WG_HIDDEN_TIMER + now]));
28720			}
28721		},
28722
28723		bindHideFixBlockBtn: function(){
28724
28725			if(this.nodes.obHideFixBlockBtn)
28726			{
28727				var that = this;
28728				this.nodes.obHideFixBlockBtn.addEventListener('click', that.hideFixBlock.bind(that));
28729			}
28730			
28731		},
28732
28733		init: function()
28734		{
28735			
28736			this.initNodes();
28737			this.preViewSlides();
28738			this.setupFrameParams();
28739			window.addEventListener("resize", {handleEvent: this.setupFrameParams, context: this});
28740
28741
28742			if(this.product.IS_WG === 'Y')
28743				this.startWg();
28744
28745			this.changeSlide();
28746			this.changeFrame();
28747
28748			this.bindEvents();
28749
28750			this.getCurrentStory();
28751
28752		},
28753
28754		getCurrentStory: function(){
28755			this.getCurrentSlide();
28756			this.getCurrentFrame();
28757		},
28758
28759		resetFrames: function(){
28760			var obFrameNavs = this.nodes.obStories.querySelectorAll(".js-cpt-stories-slide-progress-item[data-story='"+this.product.SLIDER_SELECTED+"']");
28761
28762			for (var i = 0; i < obFrameNavs.length; i++)
28763			{
28764				obFrameNavs[i].style.width = '0%';
28765			}
28766		},
28767
28768
28769		ComplitedFramesNav: function(){
28770
28771			this.resetFrames();
28772
28773			var obFrameNavs = this.nodes.obStories.querySelectorAll(".js-cpt-stories-slide-progress-item[data-story='"+this.product.SLIDER_SELECTED+"']");
28774
28775			for (var i = 0; i < obFrameNavs.length; i++)
28776			{
28777				if(parseInt(this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].ITEMS[this.product.FRAME_SELECTED].INDEX) === i)
28778					break;
28779
28780				obFrameNavs[i].style.width = '100%';
28781			}
28782		
28783		},
28784
28785		setBtnPlay: function()
28786		{
28787			this.nodes.obPauseBtn.classList.add("cpt-stories-pause");
28788			this.nodes.obPauseBtn.classList.remove("cpt-stories-play");
28789		},
28790
28791		setBtnPause: function()
28792		{
28793			this.nodes.obPauseBtn.classList.add("cpt-stories-play");
28794			this.nodes.obPauseBtn.classList.remove("cpt-stories-pause");
28795		},
28796
28797		playFrame: function(){
28798			this.moveFrameNav();
28799			this.setBtnPlay();
28800		},
28801
28802		pauseFrame: function(){
28803
28804			if(this.intervalId)
28805			{
28806				clearInterval(this.intervalId);
28807				this.setBtnPause();
28808			}
28809
28810		},
28811
28812		moveFrameNav: function(){
28813			var that = this;
28814			var obFrameNav = this.nodes.obStories.querySelector(".js-cpt-stories-slide-progress-item[data-story='"+this.product.SLIDER_SELECTED+"'][data-frame='"+this.product.FRAME_SELECTED+"']");
28815
28816			this.intervalId = setInterval(function(){
28817				obFrameNav.style.width = that.start+'%';
28818				that.start++;
28819
28820				if(that.start > 100)
28821				{
28822					that.next();
28823				}
28824				
28825			}, that.time);
28826		},
28827
28828		startFrameNav: function(){
28829			
28830			this.time = (parseFloat(this.product.CURRENT_FRAME.TIMER) * 1000) / 100;
28831			this.start = 0;
28832
28833			if(this.intervalId)
28834				clearInterval(this.intervalId);
28835
28836			this.moveFrameNav();
28837		},
28838
28839		complitedFrameNav: function(){
28840			this.setBtnPlay();
28841			var obFrameNav = this.nodes.obStories.querySelector(".js-cpt-stories-slide-progress-item[data-story='"+this.product.SLIDER.SELECTED+"'][data-frame='"+this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].SELECTED+"']");
28842			obFrameNav.style.width = '100%';
28843		},
28844		prevFrameNav: function(){
28845			this.setBtnPlay();
28846			var obFrameNav = this.nodes.obStories.querySelector(".js-cpt-stories-slide-progress-item[data-story='"+this.product.SLIDER.SELECTED+"'][data-frame='"+this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].SELECTED+"']");
28847			obFrameNav.style.width = '0%';
28848		},
28849
28850		setupSlideParams: function()
28851		{
28852			var that = this, prepareHeight = -65;
28853			this.nodes.obSlides.forEach(function(item) {
28854				item.style.width = that.product.frameWidth+'px';
28855				item.style.height = that.product.frameHeigth+'px';
28856			});
28857
28858			if(document.documentElement.clientWidth < 576)
28859				prepareHeight = 0
28860			
28861
28862
28863			this.nodes.obFrames.forEach(function(item) {
28864				item.style.width = that.product.frameWidth+'px';
28865				item.style.height = (that.product.frameHeigth + prepareHeight)+'px';
28866			});
28867
28868
28869			this.changeSlide();
28870			this.cptStoriesResponsive();
28871			this.setFontSize();
28872		},
28873		setFontSize: function ()
28874		{
28875			/*var titles = this.nodes.obStories.querySelectorAll('.cpt-stories-frame-title'),
28876			subtitles = this.nodes.obStories.querySelectorAll('.cpt-stories-frame-subtitle'),
28877			texts = this.nodes.obStories.querySelectorAll('.cpt-stories-frame-text'),
28878			btns = this.nodes.obStories.querySelectorAll('.cpt-stories-frame-btn');
28879
28880			if(titles)
28881			{
28882				for (var i = 0; i < titles.length; i++) {
28883					console.log(titles[i]);
28884				}
28885			}
28886			if(subtitles)
28887			{
28888				for (var i = 0; i < subtitles.length; i++) {
28889				
28890				}
28891			}
28892			if(texts)
28893			{
28894				for (var i = 0; i < texts.length; i++) {
28895				
28896				}
28897			}
28898			if(btns)
28899			{
28900				for (var i = 0; i < btns.length; i++) {
28901				
28902				}
28903			}*/
28904			
28905		},
28906
28907		cptStoriesResponsive: function ()
28908		{
28909			
28910			if(this.product.frameWidth >= 750)
28911			{
28912				cssClass='cpt-stories-frame-xl';
28913			}
28914			else if(this.product.frameWidth >= 600 && this.product.frameWidth <= 749)
28915			{
28916				cssClass='cpt-stories-frame-lg';
28917			}
28918			else if(this.product.frameWidth >= 400 && this.product.frameWidth <= 599)
28919			{
28920				cssClass='cpt-stories-frame-md';
28921			}
28922			else
28923			{
28924				cssClass='cpt-stories-frame-sm';
28925			}
28926
28927			this.nodes.obStories.classList.remove('cpt-stories-frame-xl', 'cpt-stories-frame-lg', 'cpt-stories-frame-md', 'cpt-stories-frame-sm');
28928			this.nodes.obStories.classList.add(cssClass);
28929
28930		
28931		},
28932
28933		setupFrameParams: function()
28934		{
28935			windowWidth = document.documentElement.clientWidth,
28936			windowHeight = document.documentElement.clientHeight;
28937			
28938
28939			if(windowHeight>900)
28940				windowHeight = 900;
28941			
28942				var that = this;
28943
28944				if(this.context)
28945					that = this.context;
28946
28947				if(windowWidth<576)
28948				{
28949					that.product.frameWidth = parseInt(windowWidth, 10);
28950				}
28951				else
28952				{
28953					that.product.frameWidth = parseInt(windowHeight * that.product.CONFIG.RATIO, 10);
28954				}
28955
28956				that.product.frameHeigth = parseInt(windowHeight, 10);
28957
28958				that.nodes.obWindow.style.width = that.product.frameWidth+'px';
28959				that.nodes.obWindow.style.height = that.product.frameHeigth+'px';
28960
28961				that.changeFrame();
28962				that.setupSlideParams();
28963				that.setFontsSize();
28964
28965		},
28966
28967		changeSlide: function()
28968		{
28969
28970			var translateX = this.product.frameWidth * parseInt(this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].INDEX);
28971			this.nodes.obWrSlides.style.transform = "translate3d(-" + translateX + "px, 0px, 0px)";
28972
28973		},
28974
28975		changeFrame: function()
28976		{
28977			var obWrFrames = this.nodes.obStories.querySelector(".js-cpt-stories-slide[data-story='"+this.product.SLIDER.SELECTED+"'] .js-cpt-stories-frames");
28978
28979			var translateX = this.product.frameWidth * parseInt(this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED].INDEX);
28980			obWrFrames.style.transform = "translate3d(-" + translateX + "px, 0px, 0px)";
28981
28982
28983			this.setBg();
28984
28985		},
28986
28987		hasNextSlide: function()
28988		{
28989			return (this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].NEXT_ID)?true:false;
28990		},
28991
28992		hasPrevSlide: function()
28993		{
28994			return (this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].PREV_ID && this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].PREV_ID != this.product.SLIDER.SELECTED)?true:false;
28995		},
28996
28997		hasNextFrame: function()
28998		{
28999			var curFrameSelected = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED;
29000			return (this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[curFrameSelected].NEXT_ID)?true:false;
29001		},
29002
29003		hasPrevFrame: function()
29004		{
29005			var curFrameSelected = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED;
29006			return (this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[curFrameSelected].PREV_ID && this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[curFrameSelected].PREV_ID != curFrameSelected)?true:false;
29007		},
29008
29009		resetStories:function()
29010		{
29011			this.product.SLIDER.SELECTED = this.product.SLIDER.FIRST_SELECTED;
29012
29013			if(this.product.SLIDER.ITEMS.length>0)
29014			{
29015				for (var i = 0; i < this.product.SLIDER.ITEMS.length; i++) {
29016					this.product.SLIDER.ITEMS[i].SELECTED = this.product.SLIDER.ITEMS[i].FIRST_SELECTED;
29017				}
29018				
29019			}
29020		},
29021		
29022		complitedSlide: function()
29023		{
29024			this.resetSlide();
29025
29026			this.nodes.obWrSlidesPreview[this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].INDEX].classList.remove('cpt-stories-preview-slide-active');
29027
29028			this.setForLocalStorage[this.product.SLIDER.SELECTED]=this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS_CNT;
29029
29030			/*if(!this.setForLocalStorage.includes(this.product.SLIDER.SELECTED))
29031				this.setForLocalStorage.push(this.product.SLIDER.SELECTED);*/
29032
29033			localStorage.setItem('cpt-stories-'+this.product.ID, JSON.stringify(this.setForLocalStorage));
29034		},
29035
29036		resetSlide: function()
29037		{
29038			this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].FIRST_SELECTED;
29039			this.resetFrames();
29040		},
29041
29042		next: function()
29043		{
29044			var finish = false;
29045
29046			if(this.hasNextFrame())
29047			{
29048				this.complitedFrameNav();
29049				this.nextFrame();
29050				this.changeFrame();
29051
29052				if(this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].ITEMS[this.product.FRAME_SELECTED].ANALYTIC_FINISH_WATCH)
29053					cptStoriesAddScript(this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].ITEMS[this.product.FRAME_SELECTED].ANALYTIC_FINISH_WATCH);
29054
29055			}
29056			else if (this.hasNextSlide())
29057			{
29058				this.complitedSlide();
29059				this.nextSlide();
29060				this.changeSlide();
29061				this.changeFrame();
29062			}
29063			else
29064			{
29065				finish = true;
29066				this.complitedSlide();
29067				this.hidePopupStories();
29068			}
29069
29070			if(finish)
29071			{
29072				this.resetStories();
29073			}
29074			else
29075			{
29076				this.getCurrentStory();
29077				this.startFrameNav();
29078			}
29079			
29080
29081		},
29082
29083
29084		prev: function()
29085		{
29086			var finish = false;
29087
29088			if(this.hasPrevFrame())
29089			{
29090				this.prevFrameNav();
29091				this.prevFrame();
29092				this.changeFrame();
29093			}
29094			else if (this.hasPrevSlide())
29095			{
29096				this.prevSlide();
29097				this.changeSlide();
29098
29099
29100				this.changeFrame();
29101			}
29102			else
29103			{
29104				finish = true;
29105				this.hidePopupStories();
29106			}
29107
29108			if(finish)
29109			{
29110
29111			}
29112			else
29113			{
29114				this.getCurrentStory();
29115				this.startFrameNav();
29116			}
29117
29118		},
29119
29120		nextFrame: function()
29121		{
29122			var curFrameSelected = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED;
29123			this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[curFrameSelected].NEXT_ID;
29124		},
29125		prevFrame: function()
29126		{
29127			var curFrameSelected = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED;
29128			this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[curFrameSelected].PREV_ID;
29129		},
29130
29131		nextSlide: function()
29132		{
29133			this.product.SLIDER.SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].NEXT_ID;
29134		},
29135		prevSlide: function()
29136		{
29137			this.product.SLIDER.SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].PREV_ID;
29138		},
29139
29140		setBg: function()
29141		{
29142			this.nodes.obOverlay.style.backgroundImage = "url('"+this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED].BG+"')";
29143
29144
29145			if(this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED].BG_USER.length>0)
29146			{
29147				this.nodes.obOverlayUser.classList.remove('cpt-stories-d-none');
29148				this.nodes.obOverlayUser.style.backgroundImage = "url('"+this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].ITEMS[this.product.SLIDER.ITEMS[this.product.SLIDER.SELECTED].SELECTED].BG_USER+"')";
29149			}
29150			else
29151			{
29152				this.nodes.obOverlayUser.classList.add('cpt-stories-d-none');
29153			}
29154		},
29155
29156		getCurrentSlide: function()
29157		{
29158			this.product.SLIDER_SELECTED = this.product.SLIDER.SELECTED;
29159
29160
29161			if(this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED])
29162				this.product.CURRENT_SLIDE = this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED];
29163			else
29164			{
29165
29166			}
29167		},
29168
29169		getCurrentFrame: function()
29170		{
29171			this.product.FRAME_SELECTED = this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].SELECTED;
29172
29173			if(this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].ITEMS[this.product.FRAME_SELECTED])
29174				this.product.CURRENT_FRAME = this.product.SLIDER.ITEMS[this.product.SLIDER_SELECTED].ITEMS[this.product.FRAME_SELECTED];
29175			else
29176			{
29177
29178			}
29179		},
29180
29181	};
29182
29183})(window);
29184
29185
29186function initCptStartParams()
29187{
29188	windowWidth = document.documentElement.clientWidth;
29189	windowHeight = document.documentElement.clientHeight;
29190}
29191
29192/*initCptStartParams();
29193cptStoriesHideAdv();
29194buildStories();*/
29195
29196function initCptdocReady()
29197{
29198	cptAddHTML();
29199	cptStoriesResponsive();
29200	initCptStartParams();
29201	buildStories();
29202	cptStoriesHideAdv();
29203
29204
29205}
29206
29207function cptAddHTML()
29208{
29209	var html = '',
29210		adminMode = document.querySelector('.cpt-stories-admin-mode'),
29211		hideAdvMode = document.querySelector('.cpt-stories-hide-adv-mode'),
29212		urlTrue = document.querySelector('.cpt-stories-url-true'),
29213		urlFalse = document.querySelector('.cpt-stories-url-false');
29214
29215	html = "<div class=\"js-cpt-stories-ajax-wg\" data-url-true=\""+urlTrue.value+"\" data-url-false=\""+urlFalse.value+"\"></div>";
29216
29217
29218	if(adminMode)
29219		html += "<div class=\"js-cpt-stories-ajax-public-admin\"></div>";
29220
29221
29222	if(hideAdvMode)
29223		html += "<div class='js-cpt-stories-hide-adv' data-user-id='"+hideAdvMode.value+"'></div>";
29224
29225	document.body.insertAdjacentHTML("beforeEnd", html);
29226}
29227
29228function cptStoriesResponsive()
29229{
29230	
29231	windowWidth = document.documentElement.clientWidth;
29232
29233	var cptStories = document.querySelectorAll(".cpt-stories"),
29234		cssClass='';
29235
29236	if(cptStories.length>0)
29237	{
29238		if(windowWidth >= 1200)
29239		{
29240			cssClass='cpt-stories-xl';
29241		}
29242		else if(windowWidth >= 992 && windowWidth <= 1199)
29243		{
29244			cssClass='cpt-stories-lg';
29245		}
29246		else if(windowWidth >= 768 && windowWidth <= 991)
29247		{
29248			cssClass='cpt-stories-md';
29249		}
29250		else
29251		{
29252			cssClass='cpt-stories-sm';
29253		}
29254
29255		for (var i = 0; i < cptStories.length; i++) {
29256			cptStories[i].classList.remove('cpt-stories-xl', 'cpt-stories-lg', 'cpt-stories-md', 'cpt-stories-sm');
29257		}
29258
29259		for (var i = 0; i < cptStories.length; i++) {
29260			cptStories[i].classList.add(cssClass);
29261		}
29262
29263	}
29264}
29265
29266window.addEventListener("resize", cptStoriesResponsive);
29267document.addEventListener("DOMContentLoaded", initCptdocReady);
29268
29269
29270function buildStoriesBlocks(){
29271	var blocks = document.querySelectorAll('.js-cpt-stories-ajax'),
29272		siteID = document.querySelector('.cpt-stories-site_id'),
29273		params = [];
29274
29275	if(blocks)
29276	{
29277		for (var i = 0; i < blocks.length; i++)
29278		{
29279			params[i]={
29280				'path':'/bitrix/tools/concept.stories/init.php',
29281				'data': {
29282					'siteID':siteID.value,
29283					'ID':blocks[i].getAttribute('data-id'),
29284					'IS_WG':''
29285				},
29286				'NODE':blocks[i]
29287			};
29288
29289			blocks[i].classList.remove('js-cpt-stories-ajax');
29290
29291		}
29292
29293		if(params)
29294		{
29295			for (var i = 0; i < params.length; i++)
29296			{
29297				cptStoriesXMLrequest(params[i]);
29298			}
29299		}
29300	}
29301
29302}
29303
29304function buildStoriesBlock(node, data){
29305	var siteID = document.querySelector('.cpt-stories-site_id');
29306
29307	data = data || {};
29308	data.ID = node.getAttribute('data-id');
29309	data.siteID = siteID.value;
29310	data.IS_WG = '';
29311
29312
29313	params = {
29314		'path':'/bitrix/tools/concept.stories/init.php',
29315		'data':data,
29316		'NODE':node
29317	};
29318
29319	if(node)
29320	{
29321		node.classList.remove('js-cpt-stories-ajax');
29322		cptStoriesXMLrequest(params);
29323	}
29324
29325}
29326
29327function buildStoriesWG(){
29328	var siteID = document.querySelector('.cpt-stories-site_id'),
29329	wg = document.querySelector('.js-cpt-stories-ajax-wg');
29330
29331
29332	cptStoriesXMLrequest({
29333		'path':'/bitrix/tools/concept.stories/init.php',
29334		'data': {
29335			'siteID':siteID.value,
29336			'IS_WG':'Y',
29337			'URL_TRUE':wg.getAttribute('data-url-true'),
29338			'URL_FALSE':wg.getAttribute('data-url-false')
29339		},
29340		'NODE':wg
29341	});
29342}
29343
29344function buildStoriesAdmin(){
29345
29346	var admin = document.querySelector('.js-cpt-stories-ajax-public-admin'),
29347		siteID = document.querySelector('.cpt-stories-site_id');
29348	
29349
29350	if(admin)
29351	{
29352		cptStoriesXMLrequest({
29353			'path':'/bitrix/tools/concept.stories/public_admin.php',
29354			'data': {
29355				'siteID':siteID.value,
29356				'admin':'Y'
29357			},
29358			'NODE':admin
29359		});
29360	}
29361}
29362
29363function buildStories(){
29364	buildStoriesWG();
29365	buildStoriesBlocks();
29366	buildStoriesAdmin();
29367}
29368function cptStoriesAddScript(code)
29369{
29370
29371	if(code)
29372	{
29373		var script = document.createElement('script');
29374		script.text = code;
29375		document.body.appendChild(script);
29376	}
29377}
29378
29379function cptStoriesXMLrequest(arParams){
29380
29381	arParams = arParams || false;
29382	var path = arParams.path || false,
29383		emptySend = arParams.emptySend || false,
29384		formData = arParams.data || false;
29385
29386    var request = new XMLHttpRequest();
29387
29388    request.open('POST',path,true);
29389   
29390    request.addEventListener('readystatechange', function()
29391    {
29392		if ((request.readyState==4) && (request.status==200)){
29393
29394
29395			if(!emptySend)
29396			{
29397				/*cptStoriesXMLrequest({
29398		    		'path':'/',
29399		    		'emptySend':true
29400		    	});*/
29401
29402		    	//arParams.NODE.insertAdjacentHTML("beforeEnd", request.responseText);
29403		    	if(arParams.NODE)
29404		    	{
29405		    		arParams.NODE.innerHTML = request.responseText;
29406
29407			    	var scripts = arParams.NODE.querySelectorAll('script'), script = null;
29408
29409			    	if(scripts)
29410			    	{
29411			    		for (var i = 0; i < scripts.length; i++)
29412						{
29413			    			script = document.createElement('script');
29414			    			script.text = scripts[i].text;
29415			    			document.body.appendChild(script);
29416			    		}
29417
29418			    	}
29419
29420			    	if(formData.admin === 'Y')
29421			    	{
29422			    		script = document.createElement('script');
29423				        script.src = '/bitrix/tools/concept.stories/js/public_admin.js';
29424				        document.body.appendChild(script);
29425			    	}
29426
29427		    		cptStoriesResponsive();
29428		    	}
29429
29430		    	if(arParams.HIDE_ADV)
29431		    	{
29432		    		var resJson = JSON.parse(request.responseText);
29433		    		
29434		    		if(resJson.OK === 'Y')
29435		    			setAdvHideScript();
29436		    		
29437		    		
29438		    	}
29439
29440		    	
29441			}
29442
29443			
29444		}
29445    });
29446
29447    var params = "",
29448    	i = 0;
29449
29450
29451    for (var pair in formData) {
29452	  	if(i!==0)
29453    		params += "&";
29454
29455
29456    	params += pair+ '='+formData[pair];
29457    	i++;
29458	}
29459 
29460    
29461    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
29462    
29463    request.send(params);
29464}
29465function setAdvHideScript()
29466{
29467	var script;
29468	script = document.createElement('script');
29469    script.text = '
vendor: 286 bytes, line 29469
29469(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(
2946954591493
vendor: 75 bytes, line 29469
29469, "init", { clickmap:false, trackLinks:false, accurateTrackBounce:false });
29469';
29470    document.body.appendChild(script);
29471
29472    script = document.createElement('noscript');
29473    script.innerHTML = "<div><img src='https://mc.yandex.ru/watch/54591493' style='position:absolute; left:-9999px;'' alt='' /></div>";
29474    document.body.appendChild(script);
29475
29476    setTimeout(
29477		function()
29478		{
29479			script = document.createElement('script');
29480	        script.text = 'ym(54591493, \'reachGoal\', \'hide_stories\');';
29481	        document.body.appendChild(script);
29482		},2000);
29483}
29484function setBodyOverflowHidden()
29485{
29486	document.body.classList.add('cpt-stories-overflow-hidden');
29487	layerPopup++;
29488}
29489
29490function deleteBodyOverflowHidden()
29491{
29492	layerPopup--;
29493
29494	if(layerPopup === 0)
29495		document.body.classList.remove('cpt-stories-overflow-hidden');
29496}
29497/* End */
29498;; /* /bitrix/templates/universe_s5/plugins/jquery/jquery-2.2.4.js?1676870894257601*/
29499; /* /bitrix/resources/intec.core/js/core.js?177790467632505*/
29500; /* /bitrix/resources/intec.core/js/controls.js?177790467610327*/
29501; /* /bitrix/templates/universe_s5/plugins/bootstrap/js/bootstrap.js?167687089469707*/
29502; /* /bitrix/templates/universe_s5/plugins/jquery.colorpicker/jquery.colorpicker.js?167687089416692*/
29503; /* /bitrix/templates/universe_s5/plugins/jquery.mousewheel/jquery.mousewheel.js?16768708948267*/
29504; /* /bitrix/templates/universe_s5/plugins/jquery.zoom/jquery.zoom.js?16768708945948*/
29505; /* /bitrix/templates/universe_s5/plugins/jquery.scrollTo/jquery.scrollTo.js?16768708945707*/
29506; /* /bitrix/templates/universe_s5/plugins/sly/sly.js?167687089460427*/
29507; /* /bitrix/templates/universe_s5/plugins/jquery.stellar/jquery.stellar.js?167687089423077*/
29508; /* /bitrix/templates/universe_s5/plugins/jquery.lazyLoad/jquery.lazyLoad.js?16768708946571*/
29509; /* /bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.js?167687089489992*/
29510; /* /bitrix/templates/universe_s5/plugins/jquery.owlCarousel/jquery.owlCarousel.navigation.js?16768708944401*/
29511; /* /bitrix/templates/universe_s5/plugins/jquery.animateNumber/jquery.animateNumber.js?16768708945301*/
29512; /* /bitrix/templates/universe_s5/plugins/picturefill/picturefill.js?167687089423302*/
29513; /* /bitrix/templates/universe_s5/plugins/jquery.lightGallery/jquery.lightGallery.js?1676870894110674*/
29514; /* /bitrix/templates/universe_s5/plugins/jquery.scrollbar/jquery.scrollbar.js?167687089432171*/
29515; /* /bitrix/templates/universe_s5/plugins/jquery.printThis/jquery.printThis.js?167687089413950*/
29516; /* /bitrix/templates/universe_s5/js/universe.js?16768708901570*/
29517; /* /bitrix/templates/universe_s5/js/basket.js?16768708902039*/
29518; /* /bitrix/templates/universe_s5/js/compare.js?16768708901830*/
29519; /* /bitrix/templates/universe_s5/js/catalog.js?16768708905846*/
29520; /* /bitrix/templates/universe_s5/js/common.js?16768708902044*/
29521; /* /bitrix/templates/universe_s5/js/forms.js?16768708903217*/
29522; /* /bitrix/templates/universe_s5/js/components.js?16768708903044*/
29523; /* /bitrix/templates/universe_s5/js/custom.js?17714050017616*/
29524; /* /bitrix/templates/universe_s5/js/jquery.maskedinput.min.js?16768708903574*/
29525; /* /bitrix/components/bitrix/search.title/script.js?174583535710542*/
29526; /* /bitrix/tools/concept.stories/js/swipe.min.js?1627447956140791*/
29527; /* /bitrix/tools/concept.stories/js/scripts.js?162744795633366*/
29528
29529//# sourceMappingURL=template_9ef20b67aa1f0d9a6df0a6d3340dac56.map.js

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.