PageSourceSearch

https://www.studiomedicosangiuseppe.it/js/ct-ultimate-gdpr.js

js studiomedicosangiuseppe.it collected 2026-09-27 14:18:48 UTC 454,564 bytes, 13,988 lines download raw bytes

vendor: 42,881 bytes, lines 1-1589
1/*!
2 * jQuery JavaScript Library v3.3.1
3 * https://jquery.com/
4 *
5 * Includes Sizzle.js
6 * https://sizzlejs.com/
7 *
8 * Copyright JS Foundation and other contributors
9 * Released under the MIT license
10 * https://jquery.org/license
11 *
12 * Date: 2018-01-20T17:24Z
13 */
14( function( global, factory ) {
15
16	"use strict";
17
18	if ( typeof module === "object" && typeof module.exports === "object" ) {
19
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// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
43// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
44// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
45// enough that all such attempts are guarded in a try block.
46"use strict";
47
48var arr = [];
49
50var document = window.document;
51
52var getProto = Object.getPrototypeOf;
53
54var slice = arr.slice;
55
56var concat = arr.concat;
57
58var push = arr.push;
59
60var indexOf = arr.indexOf;
61
62var class2type = {};
63
64var toString = class2type.toString;
65
66var hasOwn = class2type.hasOwnProperty;
67
68var fnToString = hasOwn.toString;
69
70var ObjectFunctionString = fnToString.call( Object );
71
72var support = {};
73
74var isFunction = function isFunction( obj ) {
75
76      // Support: Chrome <=57, Firefox <=52
77      // In some browsers, typeof returns "function" for HTML <object> elements
78      // (i.e., `typeof document.createElement( "object" ) === "function"`).
79      // We don't want to classify *any* DOM node as a function.
80      return typeof obj === "function" && typeof obj.nodeType !== "number";
81  };
82
83
84var isWindow = function isWindow( obj ) {
85		return obj != null && obj === obj.window;
86	};
87
88
89
90
91	var preservedScriptAttributes = {
92		type: true,
93		src: true,
94		noModule: true
95	};
96
97	function DOMEval( code, doc, node ) {
98		doc = doc || document;
99
100		var i,
101			script = doc.createElement( "script" );
102
103		script.text = code;
104		if ( node ) {
105			for ( i in preservedScriptAttributes ) {
106				if ( node[ i ] ) {
107					script[ i ] = node[ i ];
108				}
109			}
110		}
111		doc.head.appendChild( script ).parentNode.removeChild( script );
112	}
113
114
115function toType( obj ) {
116	if ( obj == null ) {
117		return obj + "";
118	}
119
120	// Support: Android <=2.3 only (functionish RegExp)
121	return typeof obj === "object" || typeof obj === "function" ?
122		class2type[ toString.call( obj ) ] || "object" :
123		typeof obj;
124}
125/* global Symbol */
126// Defining this global in .eslintrc.json would create a danger of using the global
127// unguarded in another place, it seems safer to define global only for this module
128
129
130
131var
132	version = "3.3.1",
133
134	// Define a local copy of jQuery
135	jQuery = function( selector, context ) {
136
137		// The jQuery object is actually just the init constructor 'enhanced'
138		// Need init if jQuery is called (just allow error to be thrown if not included)
139		return new jQuery.fn.init( selector, context );
140	},
141
142	// Support: Android <=4.0 only
143	// Make sure we trim BOM and NBSP
144	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
145
146jQuery.fn = jQuery.prototype = {
147
148	// The current version of jQuery being used
149	jquery: version,
150
151	constructor: jQuery,
152
153	// The default length of a jQuery object is 0
154	length: 0,
155
156	toArray: function() {
157		return slice.call( this );
158	},
159
160	// Get the Nth element in the matched element set OR
161	// Get the whole matched element set as a clean array
162	get: function( num ) {
163
164		// Return all the elements in a clean array
165		if ( num == null ) {
166			return slice.call( this );
167		}
168
169		// Return just the one element from the set
170		return num < 0 ? this[ num + this.length ] : this[ num ];
171	},
172
173	// Take an array of elements and push it onto the stack
174	// (returning the new matched element set)
175	pushStack: function( elems ) {
176
177		// Build a new jQuery matched element set
178		var ret = jQuery.merge( this.constructor(), elems );
179
180		// Add the old object onto the stack (as a reference)
181		ret.prevObject = this;
182
183		// Return the newly-formed element set
184		return ret;
185	},
186
187	// Execute a callback for every element in the matched set.
188	each: function( callback ) {
189		return jQuery.each( this, callback );
190	},
191
192	map: function( callback ) {
193		return this.pushStack( jQuery.map( this, function( elem, i ) {
194			return callback.call( elem, i, elem );
195		} ) );
196	},
197
198	slice: function() {
199		return this.pushStack( slice.apply( this, arguments ) );
200	},
201
202	first: function() {
203		return this.eq( 0 );
204	},
205
206	last: function() {
207		return this.eq( -1 );
208	},
209
210	eq: function( i ) {
211		var len = this.length,
212			j = +i + ( i < 0 ? len : 0 );
213		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
214	},
215
216	end: function() {
217		return this.prevObject || this.constructor();
218	},
219
220	// For internal use only.
221	// Behaves like an Array's method, not like a jQuery method.
222	push: push,
223	sort: arr.sort,
224	splice: arr.splice
225};
226
227jQuery.extend = jQuery.fn.extend = function() {
228	var options, name, src, copy, copyIsArray, clone,
229		target = arguments[ 0 ] || {},
230		i = 1,
231		length = arguments.length,
232		deep = false;
233
234	// Handle a deep copy situation
235	if ( typeof target === "boolean" ) {
236		deep = target;
237
238		// Skip the boolean and the target
239		target = arguments[ i ] || {};
240		i++;
241	}
242
243	// Handle case when target is a string or something (possible in deep copy)
244	if ( typeof target !== "object" && !isFunction( target ) ) {
245		target = {};
246	}
247
248	// Extend jQuery itself if only one argument is passed
249	if ( i === length ) {
250		target = this;
251		i--;
252	}
253
254	for ( ; i < length; i++ ) {
255
256		// Only deal with non-null/undefined values
257		if ( ( options = arguments[ i ] ) != null ) {
258
259			// Extend the base object
260			for ( name in options ) {
261				src = target[ name ];
262				copy = options[ name ];
263
264				// Prevent never-ending loop
265				if ( target === copy ) {
266					continue;
267				}
268
269				// Recurse if we're merging plain objects or arrays
270				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
271					( copyIsArray = Array.isArray( copy ) ) ) ) {
272
273					if ( copyIsArray ) {
274						copyIsArray = false;
275						clone = src && Array.isArray( src ) ? src : [];
276
277					} else {
278						clone = src && jQuery.isPlainObject( src ) ? src : {};
279					}
280
281					// Never move original objects, clone them
282					target[ name ] = jQuery.extend( deep, clone, copy );
283
284				// Don't bring in undefined values
285				} else if ( copy !== undefined ) {
286					target[ name ] = copy;
287				}
288			}
289		}
290	}
291
292	// Return the modified object
293	return target;
294};
295
296jQuery.extend( {
297
298	// Unique for each copy of jQuery on the page
299	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
300
301	// Assume jQuery is ready without the ready module
302	isReady: true,
303
304	error: function( msg ) {
305		throw new Error( msg );
306	},
307
308	noop: function() {},
309
310	isPlainObject: function( obj ) {
311		var proto, Ctor;
312
313		// Detect obvious negatives
314		// Use toString instead of jQuery.type to catch host objects
315		if ( !obj || toString.call( obj ) !== "[object Object]" ) {
316			return false;
317		}
318
319		proto = getProto( obj );
320
321		// Objects with no prototype (e.g., `Object.create( null )`) are plain
322		if ( !proto ) {
323			return true;
324		}
325
326		// Objects with prototype are plain iff they were constructed by a global Object function
327		Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
328		return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
329	},
330
331	isEmptyObject: function( obj ) {
332
333		/* eslint-disable no-unused-vars */
334		// See https://github.com/eslint/eslint/issues/6125
335		var name;
336
337		for ( name in obj ) {
338			return false;
339		}
340		return true;
341	},
342
343	// Evaluates a script in a global context
344	globalEval: function( code ) {
345		DOMEval( code );
346	},
347
348	each: function( obj, callback ) {
349		var length, i = 0;
350
351		if ( isArrayLike( obj ) ) {
352			length = obj.length;
353			for ( ; i < length; i++ ) {
354				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
355					break;
356				}
357			}
358		} else {
359			for ( i in obj ) {
360				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
361					break;
362				}
363			}
364		}
365
366		return obj;
367	},
368
369	// Support: Android <=4.0 only
370	trim: function( text ) {
371		return text == null ?
372			"" :
373			( text + "" ).replace( rtrim, "" );
374	},
375
376	// results is for internal usage only
377	makeArray: function( arr, results ) {
378		var ret = results || [];
379
380		if ( arr != null ) {
381			if ( isArrayLike( Object( arr ) ) ) {
382				jQuery.merge( ret,
383					typeof arr === "string" ?
384					[ arr ] : arr
385				);
386			} else {
387				push.call( ret, arr );
388			}
389		}
390
391		return ret;
392	},
393
394	inArray: function( elem, arr, i ) {
395		return arr == null ? -1 : indexOf.call( arr, elem, i );
396	},
397
398	// Support: Android <=4.0 only, PhantomJS 1 only
399	// push.apply(_, arraylike) throws on ancient WebKit
400	merge: function( first, second ) {
401		var len = +second.length,
402			j = 0,
403			i = first.length;
404
405		for ( ; j < len; j++ ) {
406			first[ i++ ] = second[ j ];
407		}
408
409		first.length = i;
410
411		return first;
412	},
413
414	grep: function( elems, callback, invert ) {
415		var callbackInverse,
416			matches = [],
417			i = 0,
418			length = elems.length,
419			callbackExpect = !invert;
420
421		// Go through the array, only saving the items
422		// that pass the validator function
423		for ( ; i < length; i++ ) {
424			callbackInverse = !callback( elems[ i ], i );
425			if ( callbackInverse !== callbackExpect ) {
426				matches.push( elems[ i ] );
427			}
428		}
429
430		return matches;
431	},
432
433	// arg is for internal usage only
434	map: function( elems, callback, arg ) {
435		var length, value,
436			i = 0,
437			ret = [];
438
439		// Go through the array, translating each of the items to their new values
440		if ( isArrayLike( elems ) ) {
441			length = elems.length;
442			for ( ; i < length; i++ ) {
443				value = callback( elems[ i ], i, arg );
444
445				if ( value != null ) {
446					ret.push( value );
447				}
448			}
449
450		// Go through every key on the object,
451		} else {
452			for ( i in elems ) {
453				value = callback( elems[ i ], i, arg );
454
455				if ( value != null ) {
456					ret.push( value );
457				}
458			}
459		}
460
461		// Flatten any nested arrays
462		return concat.apply( [], ret );
463	},
464
465	// A global GUID counter for objects
466	guid: 1,
467
468	// jQuery.support is not used in Core but other projects attach their
469	// properties to it so it needs to exist.
470	support: support
471} );
472
473if ( typeof Symbol === "function" ) {
474	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
475}
476
477// Populate the class2type map
478jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
479function( i, name ) {
480	class2type[ "[object " + name + "]" ] = name.toLowerCase();
481} );
482
483function isArrayLike( obj ) {
484
485	// Support: real iOS 8.2 only (not reproducible in simulator)
486	// `in` check used to prevent JIT error (gh-2145)
487	// hasOwn isn't used here due to false negatives
488	// regarding Nodelist length in IE
489	var length = !!obj && "length" in obj && obj.length,
490		type = toType( obj );
491
492	if ( isFunction( obj ) || isWindow( obj ) ) {
493		return false;
494	}
495
496	return type === "array" || length === 0 ||
497		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
498}
499var Sizzle =
500/*!
501 * Sizzle CSS Selector Engine v2.3.3
502 * https://sizzlejs.com/
503 *
504 * Copyright jQuery Foundation and other contributors
505 * Released under the MIT license
506 * http://jquery.org/license
507 *
508 * Date: 2016-08-08
509 */
510(function( window ) {
511
512var i,
513	support,
514	Expr,
515	getText,
516	isXML,
517	tokenize,
518	compile,
519	select,
520	outermostContext,
521	sortInput,
522	hasDuplicate,
523
524	// Local document vars
525	setDocument,
526	document,
527	docElem,
528	documentIsHTML,
529	rbuggyQSA,
530	rbuggyMatches,
531	matches,
532	contains,
533
534	// Instance-specific data
535	expando = "sizzle" + 1 * new Date(),
536	preferredDoc = window.document,
537	dirruns = 0,
538	done = 0,
539	classCache = createCache(),
540	tokenCache = createCache(),
541	compilerCache = createCache(),
542	sortOrder = function( a, b ) {
543		if ( a === b ) {
544			hasDuplicate = true;
545		}
546		return 0;
547	},
548
549	// Instance methods
550	hasOwn = ({}).hasOwnProperty,
551	arr = [],
552	pop = arr.pop,
553	push_native = arr.push,
554	push = arr.push,
555	slice = arr.slice,
556	// Use a stripped-down indexOf as it's faster than native
557	// https://jsperf.com/thor-indexof-vs-for/5
558	indexOf = function( list, elem ) {
559		var i = 0,
560			len = list.length;
561		for ( ; i < len; i++ ) {
562			if ( list[i] === elem ) {
563				return i;
564			}
565		}
566		return -1;
567	},
568
569	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
570
571	// Regular expressions
572
573	// http://www.w3.org/TR/css3-selectors/#whitespace
574	whitespace = "[\\x20\\t\\r\\n\\f]",
575
576	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
577	identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
578
579	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
580	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
581		// Operator (capture 2)
582		"*([*^$|!~]?=)" + whitespace +
583		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
584		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
585		"*\\]",
586
587	pseudos = ":(" + identifier + ")(?:\\((" +
588		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
589		// 1. quoted (capture 3; capture 4 or capture 5)
590		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
591		// 2. simple (capture 6)
592		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
593		// 3. anything else (capture 2)
594		".*" +
595		")\\)|)",
596
597	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
598	rwhitespace = new RegExp( whitespace + "+", "g" ),
599	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
600
601	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
602	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
603
604	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
605
606	rpseudo = new RegExp( pseudos ),
607	ridentifier = new RegExp( "^" + identifier + "$" ),
608
609	matchExpr = {
610		"ID": new RegExp( "^#(" + identifier + ")" ),
611		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
612		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
613		"ATTR": new RegExp( "^" + attributes ),
614		"PSEUDO": new RegExp( "^" + pseudos ),
615		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
616			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
617			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
618		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
619		// For use in libraries implementing .is()
620		// We use this for POS matching in `select`
621		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
622			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
623	},
624
625	rinputs = /^(?:input|select|textarea|button)$/i,
626	rheader = /^h\d$/i,
627
628	rnative = /^[^{]+\{\s*\[native \w/,
629
630	// Easily-parseable/retrievable ID or TAG or CLASS selectors
631	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
632
633	rsibling = /[+~]/,
634
635	// CSS escapes
636	// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
637	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
638	funescape = function( _, escaped, escapedWhitespace ) {
639		var high = "0x" + escaped - 0x10000;
640		// NaN means non-codepoint
641		// Support: Firefox<24
642		// Workaround erroneous numeric interpretation of +"0x"
643		return high !== high || escapedWhitespace ?
644			escaped :
645			high < 0 ?
646				// BMP codepoint
647				String.fromCharCode( high + 0x10000 ) :
648				// Supplemental Plane codepoint (surrogate pair)
649				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
650	},
651
652	// CSS string/identifier serialization
653	// https://drafts.csswg.org/cssom/#common-serializing-idioms
654	rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
655	fcssescape = function( ch, asCodePoint ) {
656		if ( asCodePoint ) {
657
658			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
659			if ( ch === "\0" ) {
660				return "\uFFFD";
661			}
662
663			// Control characters and (dependent upon position) numbers get escaped as code points
664			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
665		}
666
667		// Other potentially-special ASCII characters get backslash-escaped
668		return "\\" + ch;
669	},
670
671	// Used for iframes
672	// See setDocument()
673	// Removing the function wrapper causes a "Permission Denied"
674	// error in IE
675	unloadHandler = function() {
676		setDocument();
677	},
678
679	disabledAncestor = addCombinator(
680		function( elem ) {
681			return elem.disabled === true && ("form" in elem || "label" in elem);
682		},
683		{ dir: "parentNode", next: "legend" }
684	);
685
686// Optimize for push.apply( _, NodeList )
687try {
688	push.apply(
689		(arr = slice.call( preferredDoc.childNodes )),
690		preferredDoc.childNodes
691	);
692	// Support: Android<4.0
693	// Detect silently failing push.apply
694	arr[ preferredDoc.childNodes.length ].nodeType;
695} catch ( e ) {
696	push = { apply: arr.length ?
697
698		// Leverage slice if possible
699		function( target, els ) {
700			push_native.apply( target, slice.call(els) );
701		} :
702
703		// Support: IE<9
704		// Otherwise append directly
705		function( target, els ) {
706			var j = target.length,
707				i = 0;
708			// Can't trust NodeList.length
709			while ( (target[j++] = els[i++]) ) {}
710			target.length = j - 1;
711		}
712	};
713}
714
715function Sizzle( selector, context, results, seed ) {
716	var m, i, elem, nid, match, groups, newSelector,
717		newContext = context && context.ownerDocument,
718
719		// nodeType defaults to 9, since context defaults to document
720		nodeType = context ? context.nodeType : 9;
721
722	results = results || [];
723
724	// Return early from calls with invalid selector or context
725	if ( typeof selector !== "string" || !selector ||
726		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
727
728		return results;
729	}
730
731	// Try to shortcut find operations (as opposed to filters) in HTML documents
732	if ( !seed ) {
733
734		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
735			setDocument( context );
736		}
737		context = context || document;
738
739		if ( documentIsHTML ) {
740
741			// If the selector is sufficiently simple, try using a "get*By*" DOM method
742			// (excepting DocumentFragment context, where the methods don't exist)
743			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
744
745				// ID selector
746				if ( (m = match[1]) ) {
747
748					// Document context
749					if ( nodeType === 9 ) {
750						if ( (elem = context.getElementById( m )) ) {
751
752							// Support: IE, Opera, Webkit
753							// TODO: identify versions
754							// getElementById can match elements by name instead of ID
755							if ( elem.id === m ) {
756								results.push( elem );
757								return results;
758							}
759						} else {
760							return results;
761						}
762
763					// Element context
764					} else {
765
766						// Support: IE, Opera, Webkit
767						// TODO: identify versions
768						// getElementById can match elements by name instead of ID
769						if ( newContext && (elem = newContext.getElementById( m )) &&
770							contains( context, elem ) &&
771							elem.id === m ) {
772
773							results.push( elem );
774							return results;
775						}
776					}
777
778				// Type selector
779				} else if ( match[2] ) {
780					push.apply( results, context.getElementsByTagName( selector ) );
781					return results;
782
783				// Class selector
784				} else if ( (m = match[3]) && support.getElementsByClassName &&
785					context.getElementsByClassName ) {
786
787					push.apply( results, context.getElementsByClassName( m ) );
788					return results;
789				}
790			}
791
792			// Take advantage of querySelectorAll
793			if ( support.qsa &&
794				!compilerCache[ selector + " " ] &&
795				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
796
797				if ( nodeType !== 1 ) {
798					newContext = context;
799					newSelector = selector;
800
801				// qSA looks outside Element context, which is not what we want
802				// Thanks to Andrew Dupont for this workaround technique
803				// Support: IE <=8
804				// Exclude object elements
805				} else if ( context.nodeName.toLowerCase() !== "object" ) {
806
807					// Capture the context ID, setting it first if necessary
808					if ( (nid = context.getAttribute( "id" )) ) {
809						nid = nid.replace( rcssescape, fcssescape );
810					} else {
811						context.setAttribute( "id", (nid = expando) );
812					}
813
814					// Prefix every selector in the list
815					groups = tokenize( selector );
816					i = groups.length;
817					while ( i-- ) {
818						groups[i] = "#" + nid + " " + toSelector( groups[i] );
819					}
820					newSelector = groups.join( "," );
821
822					// Expand context for sibling selectors
823					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
824						context;
825				}
826
827				if ( newSelector ) {
828					try {
829						push.apply( results,
830							newContext.querySelectorAll( newSelector )
831						);
832						return results;
833					} catch ( qsaError ) {
834					} finally {
835						if ( nid === expando ) {
836							context.removeAttribute( "id" );
837						}
838					}
839				}
840			}
841		}
842	}
843
844	// All others
845	return select( selector.replace( rtrim, "$1" ), context, results, seed );
846}
847
848/**
849 * Create key-value caches of limited size
850 * @returns {function(string, object)} Returns the Object data after storing it on itself with
851 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
852 *	deleting the oldest entry
853 */
854function createCache() {
855	var keys = [];
856
857	function cache( key, value ) {
858		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
859		if ( keys.push( key + " " ) > Expr.cacheLength ) {
860			// Only keep the most recent entries
861			delete cache[ keys.shift() ];
862		}
863		return (cache[ key + " " ] = value);
864	}
865	return cache;
866}
867
868/**
869 * Mark a function for special use by Sizzle
870 * @param {Function} fn The function to mark
871 */
872function markFunction( fn ) {
873	fn[ expando ] = true;
874	return fn;
875}
876
877/**
878 * Support testing using an element
879 * @param {Function} fn Passed the created element and returns a boolean result
880 */
881function assert( fn ) {
882	var el = document.createElement("fieldset");
883
884	try {
885		return !!fn( el );
886	} catch (e) {
887		return false;
888	} finally {
889		// Remove from its parent by default
890		if ( el.parentNode ) {
891			el.parentNode.removeChild( el );
892		}
893		// release memory in IE
894		el = null;
895	}
896}
897
898/**
899 * Adds the same handler for all of the specified attrs
900 * @param {String} attrs Pipe-separated list of attributes
901 * @param {Function} handler The method that will be applied
902 */
903function addHandle( attrs, handler ) {
904	var arr = attrs.split("|"),
905		i = arr.length;
906
907	while ( i-- ) {
908		Expr.attrHandle[ arr[i] ] = handler;
909	}
910}
911
912/**
913 * Checks document order of two siblings
914 * @param {Element} a
915 * @param {Element} b
916 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
917 */
918function siblingCheck( a, b ) {
919	var cur = b && a,
920		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
921			a.sourceIndex - b.sourceIndex;
922
923	// Use IE sourceIndex if available on both nodes
924	if ( diff ) {
925		return diff;
926	}
927
928	// Check if b follows a
929	if ( cur ) {
930		while ( (cur = cur.nextSibling) ) {
931			if ( cur === b ) {
932				return -1;
933			}
934		}
935	}
936
937	return a ? 1 : -1;
938}
939
940/**
941 * Returns a function to use in pseudos for input types
942 * @param {String} type
943 */
944function createInputPseudo( type ) {
945	return function( elem ) {
946		var name = elem.nodeName.toLowerCase();
947		return name === "input" && elem.type === type;
948	};
949}
950
951/**
952 * Returns a function to use in pseudos for buttons
953 * @param {String} type
954 */
955function createButtonPseudo( type ) {
956	return function( elem ) {
957		var name = elem.nodeName.toLowerCase();
958		return (name === "input" || name === "button") && elem.type === type;
959	};
960}
961
962/**
963 * Returns a function to use in pseudos for :enabled/:disabled
964 * @param {Boolean} disabled true for :disabled; false for :enabled
965 */
966function createDisabledPseudo( disabled ) {
967
968	// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
969	return function( elem ) {
970
971		// Only certain elements can match :enabled or :disabled
972		// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
973		// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
974		if ( "form" in elem ) {
975
976			// Check for inherited disabledness on relevant non-disabled elements:
977			// * listed form-associated elements in a disabled fieldset
978			//   https://html.spec.whatwg.org/multipage/forms.html#category-listed
979			//   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
980			// * option elements in a disabled optgroup
981			//   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
982			// All such elements have a "form" property.
983			if ( elem.parentNode && elem.disabled === false ) {
984
985				// Option elements defer to a parent optgroup if present
986				if ( "label" in elem ) {
987					if ( "label" in elem.parentNode ) {
988						return elem.parentNode.disabled === disabled;
989					} else {
990						return elem.disabled === disabled;
991					}
992				}
993
994				// Support: IE 6 - 11
995				// Use the isDisabled shortcut property to check for disabled fieldset ancestors
996				return elem.isDisabled === disabled ||
997
998					// Where there is no isDisabled, check manually
999					/* jshint -W018 */
1000					elem.isDisabled !== !disabled &&
1001						disabledAncestor( elem ) === disabled;
1002			}
1003
1004			return elem.disabled === disabled;
1005
1006		// Try to winnow out elements that can't be disabled before trusting the disabled property.
1007		// Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1008		// even exist on them, let alone have a boolean value.
1009		} else if ( "label" in elem ) {
1010			return elem.disabled === disabled;
1011		}
1012
1013		// Remaining elements are neither :enabled nor :disabled
1014		return false;
1015	};
1016}
1017
1018/**
1019 * Returns a function to use in pseudos for positionals
1020 * @param {Function} fn
1021 */
1022function createPositionalPseudo( fn ) {
1023	return markFunction(function( argument ) {
1024		argument = +argument;
1025		return markFunction(function( seed, matches ) {
1026			var j,
1027				matchIndexes = fn( [], seed.length, argument ),
1028				i = matchIndexes.length;
1029
1030			// Match elements found at the specified indexes
1031			while ( i-- ) {
1032				if ( seed[ (j = matchIndexes[i]) ] ) {
1033					seed[j] = !(matches[j] = seed[j]);
1034				}
1035			}
1036		});
1037	});
1038}
1039
1040/**
1041 * Checks a node for validity as a Sizzle context
1042 * @param {Element|Object=} context
1043 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1044 */
1045function testContext( context ) {
1046	return context && typeof context.getElementsByTagName !== "undefined" && context;
1047}
1048
1049// Expose support vars for convenience
1050support = Sizzle.support = {};
1051
1052/**
1053 * Detects XML nodes
1054 * @param {Element|Object} elem An element or a document
1055 * @returns {Boolean} True iff elem is a non-HTML XML node
1056 */
1057isXML = Sizzle.isXML = function( elem ) {
1058	// documentElement is verified for cases where it doesn't yet exist
1059	// (such as loading iframes in IE - #4833)
1060	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1061	return documentElement ? documentElement.nodeName !== "HTML" : false;
1062};
1063
1064/**
1065 * Sets document-related variables once based on the current document
1066 * @param {Element|Object} [doc] An element or document object to use to set the document
1067 * @returns {Object} Returns the current document
1068 */
1069setDocument = Sizzle.setDocument = function( node ) {
1070	var hasCompare, subWindow,
1071		doc = node ? node.ownerDocument || node : preferredDoc;
1072
1073	// Return early if doc is invalid or already selected
1074	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1075		return document;
1076	}
1077
1078	// Update global variables
1079	document = doc;
1080	docElem = document.documentElement;
1081	documentIsHTML = !isXML( document );
1082
1083	// Support: IE 9-11, Edge
1084	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1085	if ( preferredDoc !== document &&
1086		(subWindow = document.defaultView) && subWindow.top !== subWindow ) {
1087
1088		// Support: IE 11, Edge
1089		if ( subWindow.addEventListener ) {
1090			subWindow.addEventListener( "unload", unloadHandler, false );
1091
1092		// Support: IE 9 - 10 only
1093		} else if ( subWindow.attachEvent ) {
1094			subWindow.attachEvent( "onunload", unloadHandler );
1095		}
1096	}
1097
1098	/* Attributes
1099	---------------------------------------------------------------------- */
1100
1101	// Support: IE<8
1102	// Verify that getAttribute really returns attributes and not properties
1103	// (excepting IE8 booleans)
1104	support.attributes = assert(function( el ) {
1105		el.className = "i";
1106		return !el.getAttribute("className");
1107	});
1108
1109	/* getElement(s)By*
1110	---------------------------------------------------------------------- */
1111
1112	// Check if getElementsByTagName("*") returns only elements
1113	support.getElementsByTagName = assert(function( el ) {
1114		el.appendChild( document.createComment("") );
1115		return !el.getElementsByTagName("*").length;
1116	});
1117
1118	// Support: IE<9
1119	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1120
1121	// Support: IE<10
1122	// Check if getElementById returns elements by name
1123	// The broken getElementById methods don't pick up programmatically-set names,
1124	// so use a roundabout getElementsByName test
1125	support.getById = assert(function( el ) {
1126		docElem.appendChild( el ).id = expando;
1127		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1128	});
1129
1130	// ID filter and find
1131	if ( support.getById ) {
1132		Expr.filter["ID"] = function( id ) {
1133			var attrId = id.replace( runescape, funescape );
1134			return function( elem ) {
1135				return elem.getAttribute("id") === attrId;
1136			};
1137		};
1138		Expr.find["ID"] = function( id, context ) {
1139			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1140				var elem = context.getElementById( id );
1141				return elem ? [ elem ] : [];
1142			}
1143		};
1144	} else {
1145		Expr.filter["ID"] =  function( id ) {
1146			var attrId = id.replace( runescape, funescape );
1147			return function( elem ) {
1148				var node = typeof elem.getAttributeNode !== "undefined" &&
1149					elem.getAttributeNode("id");
1150				return node && node.value === attrId;
1151			};
1152		};
1153
1154		// Support: IE 6 - 7 only
1155		// getElementById is not reliable as a find shortcut
1156		Expr.find["ID"] = function( id, context ) {
1157			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1158				var node, i, elems,
1159					elem = context.getElementById( id );
1160
1161				if ( elem ) {
1162
1163					// Verify the id attribute
1164					node = elem.getAttributeNode("id");
1165					if ( node && node.value === id ) {
1166						return [ elem ];
1167					}
1168
1169					// Fall back on getElementsByName
1170					elems = context.getElementsByName( id );
1171					i = 0;
1172					while ( (elem = elems[i++]) ) {
1173						node = elem.getAttributeNode("id");
1174						if ( node && node.value === id ) {
1175							return [ elem ];
1176						}
1177					}
1178				}
1179
1180				return [];
1181			}
1182		};
1183	}
1184
1185	// Tag
1186	Expr.find["TAG"] = support.getElementsByTagName ?
1187		function( tag, context ) {
1188			if ( typeof context.getElementsByTagName !== "undefined" ) {
1189				return context.getElementsByTagName( tag );
1190
1191			// DocumentFragment nodes don't have gEBTN
1192			} else if ( support.qsa ) {
1193				return context.querySelectorAll( tag );
1194			}
1195		} :
1196
1197		function( tag, context ) {
1198			var elem,
1199				tmp = [],
1200				i = 0,
1201				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1202				results = context.getElementsByTagName( tag );
1203
1204			// Filter out possible comments
1205			if ( tag === "*" ) {
1206				while ( (elem = results[i++]) ) {
1207					if ( elem.nodeType === 1 ) {
1208						tmp.push( elem );
1209					}
1210				}
1211
1212				return tmp;
1213			}
1214			return results;
1215		};
1216
1217	// Class
1218	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1219		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1220			return context.getElementsByClassName( className );
1221		}
1222	};
1223
1224	/* QSA/matchesSelector
1225	---------------------------------------------------------------------- */
1226
1227	// QSA and matchesSelector support
1228
1229	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1230	rbuggyMatches = [];
1231
1232	// qSa(:focus) reports false when true (Chrome 21)
1233	// We allow this because of a bug in IE8/9 that throws an error
1234	// whenever `document.activeElement` is accessed on an iframe
1235	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1236	// See https://bugs.jquery.com/ticket/13378
1237	rbuggyQSA = [];
1238
1239	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1240		// Build QSA regex
1241		// Regex strategy adopted from Diego Perini
1242		assert(function( el ) {
1243			// Select is set to empty string on purpose
1244			// This is to test IE's treatment of not explicitly
1245			// setting a boolean content attribute,
1246			// since its presence should be enough
1247			// https://bugs.jquery.com/ticket/12359
1248			docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1249				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1250				"<option selected=''></option></select>";
1251
1252			// Support: IE8, Opera 11-12.16
1253			// Nothing should be selected when empty strings follow ^= or $= or *=
1254			// The test attribute must be unknown in Opera but "safe" for WinRT
1255			// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1256			if ( el.querySelectorAll("[msallowcapture^='']").length ) {
1257				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1258			}
1259
1260			// Support: IE8
1261			// Boolean attributes and "value" are not treated correctly
1262			if ( !el.querySelectorAll("[selected]").length ) {
1263				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1264			}
1265
1266			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1267			if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1268				rbuggyQSA.push("~=");
1269			}
1270
1271			// Webkit/Opera - :checked should return selected option elements
1272			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1273			// IE8 throws error here and will not see later tests
1274			if ( !el.querySelectorAll(":checked").length ) {
1275				rbuggyQSA.push(":checked");
1276			}
1277
1278			// Support: Safari 8+, iOS 8+
1279			// https://bugs.webkit.org/show_bug.cgi?id=136851
1280			// In-page `selector#id sibling-combinator selector` fails
1281			if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1282				rbuggyQSA.push(".#.+[+~]");
1283			}
1284		});
1285
1286		assert(function( el ) {
1287			el.innerHTML = "<a href='' disabled='disabled'></a>" +
1288				"<select disabled='disabled'><option/></select>";
1289
1290			// Support: Windows 8 Native Apps
1291			// The type and name attributes are restricted during .innerHTML assignment
1292			var input = document.createElement("input");
1293			input.setAttribute( "type", "hidden" );
1294			el.appendChild( input ).setAttribute( "name", "D" );
1295
1296			// Support: IE8
1297			// Enforce case-sensitivity of name attribute
1298			if ( el.querySelectorAll("[name=d]").length ) {
1299				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1300			}
1301
1302			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1303			// IE8 throws error here and will not see later tests
1304			if ( el.querySelectorAll(":enabled").length !== 2 ) {
1305				rbuggyQSA.push( ":enabled", ":disabled" );
1306			}
1307
1308			// Support: IE9-11+
1309			// IE's :disabled selector does not pick up the children of disabled fieldsets
1310			docElem.appendChild( el ).disabled = true;
1311			if ( el.querySelectorAll(":disabled").length !== 2 ) {
1312				rbuggyQSA.push( ":enabled", ":disabled" );
1313			}
1314
1315			// Opera 10-11 does not throw on post-comma invalid pseudos
1316			el.querySelectorAll("*,:x");
1317			rbuggyQSA.push(",.*:");
1318		});
1319	}
1320
1321	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1322		docElem.webkitMatchesSelector ||
1323		docElem.mozMatchesSelector ||
1324		docElem.oMatchesSelector ||
1325		docElem.msMatchesSelector) )) ) {
1326
1327		assert(function( el ) {
1328			// Check to see if it's possible to do matchesSelector
1329			// on a disconnected node (IE 9)
1330			support.disconnectedMatch = matches.call( el, "*" );
1331
1332			// This should fail with an exception
1333			// Gecko does not error, returns false instead
1334			matches.call( el, "[s!='']:x" );
1335			rbuggyMatches.push( "!=", pseudos );
1336		});
1337	}
1338
1339	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1340	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1341
1342	/* Contains
1343	---------------------------------------------------------------------- */
1344	hasCompare = rnative.test( docElem.compareDocumentPosition );
1345
1346	// Element contains another
1347	// Purposefully self-exclusive
1348	// As in, an element does not contain itself
1349	contains = hasCompare || rnative.test( docElem.contains ) ?
1350		function( a, b ) {
1351			var adown = a.nodeType === 9 ? a.documentElement : a,
1352				bup = b && b.parentNode;
1353			return a === bup || !!( bup && bup.nodeType === 1 && (
1354				adown.contains ?
1355					adown.contains( bup ) :
1356					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1357			));
1358		} :
1359		function( a, b ) {
1360			if ( b ) {
1361				while ( (b = b.parentNode) ) {
1362					if ( b === a ) {
1363						return true;
1364					}
1365				}
1366			}
1367			return false;
1368		};
1369
1370	/* Sorting
1371	---------------------------------------------------------------------- */
1372
1373	// Document order sorting
1374	sortOrder = hasCompare ?
1375	function( a, b ) {
1376
1377		// Flag for duplicate removal
1378		if ( a === b ) {
1379			hasDuplicate = true;
1380			return 0;
1381		}
1382
1383		// Sort on method existence if only one input has compareDocumentPosition
1384		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1385		if ( compare ) {
1386			return compare;
1387		}
1388
1389		// Calculate position if both inputs belong to the same document
1390		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1391			a.compareDocumentPosition( b ) :
1392
1393			// Otherwise we know they are disconnected
1394			1;
1395
1396		// Disconnected nodes
1397		if ( compare & 1 ||
1398			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1399
1400			// Choose the first element that is related to our preferred document
1401			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1402				return -1;
1403			}
1404			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1405				return 1;
1406			}
1407
1408			// Maintain original order
1409			return sortInput ?
1410				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1411				0;
1412		}
1413
1414		return compare & 4 ? -1 : 1;
1415	} :
1416	function( a, b ) {
1417		// Exit early if the nodes are identical
1418		if ( a === b ) {
1419			hasDuplicate = true;
1420			return 0;
1421		}
1422
1423		var cur,
1424			i = 0,
1425			aup = a.parentNode,
1426			bup = b.parentNode,
1427			ap = [ a ],
1428			bp = [ b ];
1429
1430		// Parentless nodes are either documents or disconnected
1431		if ( !aup || !bup ) {
1432			return a === document ? -1 :
1433				b === document ? 1 :
1434				aup ? -1 :
1435				bup ? 1 :
1436				sortInput ?
1437				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1438				0;
1439
1440		// If the nodes are siblings, we can do a quick check
1441		} else if ( aup === bup ) {
1442			return siblingCheck( a, b );
1443		}
1444
1445		// Otherwise we need full lists of their ancestors for comparison
1446		cur = a;
1447		while ( (cur = cur.parentNode) ) {
1448			ap.unshift( cur );
1449		}
1450		cur = b;
1451		while ( (cur = cur.parentNode) ) {
1452			bp.unshift( cur );
1453		}
1454
1455		// Walk down the tree looking for a discrepancy
1456		while ( ap[i] === bp[i] ) {
1457			i++;
1458		}
1459
1460		return i ?
1461			// Do a sibling check if the nodes have a common ancestor
1462			siblingCheck( ap[i], bp[i] ) :
1463
1464			// Otherwise nodes in our document sort first
1465			ap[i] === preferredDoc ? -1 :
1466			bp[i] === preferredDoc ? 1 :
1467			0;
1468	};
1469
1470	return document;
1471};
1472
1473Sizzle.matches = function( expr, elements ) {
1474	return Sizzle( expr, null, null, elements );
1475};
1476
1477Sizzle.matchesSelector = function( elem, expr ) {
1478	// Set document vars if needed
1479	if ( ( elem.ownerDocument || elem ) !== document ) {
1480		setDocument( elem );
1481	}
1482
1483	// Make sure that attribute selectors are quoted
1484	expr = expr.replace( rattributeQuotes, "='$1']" );
1485
1486	if ( support.matchesSelector && documentIsHTML &&
1487		!compilerCache[ expr + " " ] &&
1488		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1489		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1490
1491		try {
1492			var ret = matches.call( elem, expr );
1493
1494			// IE 9's matchesSelector returns false on disconnected nodes
1495			if ( ret || support.disconnectedMatch ||
1496					// As well, disconnected nodes are said to be in a document
1497					// fragment in IE 9
1498					elem.document && elem.document.nodeType !== 11 ) {
1499				return ret;
1500			}
1501		} catch (e) {}
1502	}
1503
1504	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1505};
1506
1507Sizzle.contains = function( context, elem ) {
1508	// Set document vars if needed
1509	if ( ( context.ownerDocument || context ) !== document ) {
1510		setDocument( context );
1511	}
1512	return contains( context, elem );
1513};
1514
1515Sizzle.attr = function( elem, name ) {
1516	// Set document vars if needed
1517	if ( ( elem.ownerDocument || elem ) !== document ) {
1518		setDocument( elem );
1519	}
1520
1521	var fn = Expr.attrHandle[ name.toLowerCase() ],
1522		// Don't get fooled by Object.prototype properties (jQuery #13807)
1523		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1524			fn( elem, name, !documentIsHTML ) :
1525			undefined;
1526
1527	return val !== undefined ?
1528		val :
1529		support.attributes || !documentIsHTML ?
1530			elem.getAttribute( name ) :
1531			(val = elem.getAttributeNode(name)) && val.specified ?
1532				val.value :
1533				null;
1534};
1535
1536Sizzle.escape = function( sel ) {
1537	return (sel + "").replace( rcssescape, fcssescape );
1538};
1539
1540Sizzle.error = function( msg ) {
1541	throw new Error( "Syntax error, unrecognized expression: " + msg );
1542};
1543
1544/**
1545 * Document sorting and removing duplicates
1546 * @param {ArrayLike} results
1547 */
1548Sizzle.uniqueSort = function( results ) {
1549	var elem,
1550		duplicates = [],
1551		j = 0,
1552		i = 0;
1553
1554	// Unless we *know* we can detect duplicates, assume their presence
1555	hasDuplicate = !support.detectDuplicates;
1556	sortInput = !support.sortStable && results.slice( 0 );
1557	results.sort( sortOrder );
1558
1559	if ( hasDuplicate ) {
1560		while ( (elem = results[i++]) ) {
1561			if ( elem === results[ i ] ) {
1562				j = duplicates.push( i );
1563			}
1564		}
1565		while ( j-- ) {
1566			results.splice( duplicates[ j ], 1 );
1567		}
1568	}
1569
1570	// Clear input after sorting to release objects
1571	// See https://github.com/jquery/sizzle/pull/225
1572	sortInput = null;
1573
1574	return results;
1575};
1576
1577/**
1578 * Utility function for retrieving the text value of an array of DOM nodes
1579 * @param {Array|Element} elem
1580 */
1581getText = Sizzle.getText = function( elem ) {
1582	var node,
1583		ret = "",
1584		i = 0,
1585		nodeType = elem.nodeType;
1586
1587	if ( !nodeType ) {
1588		// If no nodeType, this is expected to be an array
1589		while ( (node = elem[i++]) ) {
vendor: 11,976 bytes, lines 1590-1988
1590			// Do not traverse comment nodes
1591			ret += getText( node );
1592		}
1593	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1594		// Use textContent for elements
1595		// innerText usage removed for consistency of new lines (jQuery #11153)
1596		if ( typeof elem.textContent === "string" ) {
1597			return elem.textContent;
1598		} else {
1599			// Traverse its children
1600			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1601				ret += getText( elem );
1602			}
1603		}
1604	} else if ( nodeType === 3 || nodeType === 4 ) {
1605		return elem.nodeValue;
1606	}
1607	// Do not include comment or processing instruction nodes
1608
1609	return ret;
1610};
1611
1612Expr = Sizzle.selectors = {
1613
1614	// Can be adjusted by the user
1615	cacheLength: 50,
1616
1617	createPseudo: markFunction,
1618
1619	match: matchExpr,
1620
1621	attrHandle: {},
1622
1623	find: {},
1624
1625	relative: {
1626		">": { dir: "parentNode", first: true },
1627		" ": { dir: "parentNode" },
1628		"+": { dir: "previousSibling", first: true },
1629		"~": { dir: "previousSibling" }
1630	},
1631
1632	preFilter: {
1633		"ATTR": function( match ) {
1634			match[1] = match[1].replace( runescape, funescape );
1635
1636			// Move the given value to match[3] whether quoted or unquoted
1637			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1638
1639			if ( match[2] === "~=" ) {
1640				match[3] = " " + match[3] + " ";
1641			}
1642
1643			return match.slice( 0, 4 );
1644		},
1645
1646		"CHILD": function( match ) {
1647			/* matches from matchExpr["CHILD"]
1648				1 type (only|nth|...)
1649				2 what (child|of-type)
1650				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1651				4 xn-component of xn+y argument ([+-]?\d*n|)
1652				5 sign of xn-component
1653				6 x of xn-component
1654				7 sign of y-component
1655				8 y of y-component
1656			*/
1657			match[1] = match[1].toLowerCase();
1658
1659			if ( match[1].slice( 0, 3 ) === "nth" ) {
1660				// nth-* requires argument
1661				if ( !match[3] ) {
1662					Sizzle.error( match[0] );
1663				}
1664
1665				// numeric x and y parameters for Expr.filter.CHILD
1666				// remember that false/true cast respectively to 0/1
1667				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1668				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1669
1670			// other types prohibit arguments
1671			} else if ( match[3] ) {
1672				Sizzle.error( match[0] );
1673			}
1674
1675			return match;
1676		},
1677
1678		"PSEUDO": function( match ) {
1679			var excess,
1680				unquoted = !match[6] && match[2];
1681
1682			if ( matchExpr["CHILD"].test( match[0] ) ) {
1683				return null;
1684			}
1685
1686			// Accept quoted arguments as-is
1687			if ( match[3] ) {
1688				match[2] = match[4] || match[5] || "";
1689
1690			// Strip excess characters from unquoted arguments
1691			} else if ( unquoted && rpseudo.test( unquoted ) &&
1692				// Get excess from tokenize (recursively)
1693				(excess = tokenize( unquoted, true )) &&
1694				// advance to the next closing parenthesis
1695				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1696
1697				// excess is a negative index
1698				match[0] = match[0].slice( 0, excess );
1699				match[2] = unquoted.slice( 0, excess );
1700			}
1701
1702			// Return only captures needed by the pseudo filter method (type and argument)
1703			return match.slice( 0, 3 );
1704		}
1705	},
1706
1707	filter: {
1708
1709		"TAG": function( nodeNameSelector ) {
1710			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1711			return nodeNameSelector === "*" ?
1712				function() { return true; } :
1713				function( elem ) {
1714					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1715				};
1716		},
1717
1718		"CLASS": function( className ) {
1719			var pattern = classCache[ className + " " ];
1720
1721			return pattern ||
1722				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1723				classCache( className, function( elem ) {
1724					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1725				});
1726		},
1727
1728		"ATTR": function( name, operator, check ) {
1729			return function( elem ) {
1730				var result = Sizzle.attr( elem, name );
1731
1732				if ( result == null ) {
1733					return operator === "!=";
1734				}
1735				if ( !operator ) {
1736					return true;
1737				}
1738
1739				result += "";
1740
1741				return operator === "=" ? result === check :
1742					operator === "!=" ? result !== check :
1743					operator === "^=" ? check && result.indexOf( check ) === 0 :
1744					operator === "*=" ? check && result.indexOf( check ) > -1 :
1745					operator === "$=" ? check && result.slice( -check.length ) === check :
1746					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1747					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1748					false;
1749			};
1750		},
1751
1752		"CHILD": function( type, what, argument, first, last ) {
1753			var simple = type.slice( 0, 3 ) !== "nth",
1754				forward = type.slice( -4 ) !== "last",
1755				ofType = what === "of-type";
1756
1757			return first === 1 && last === 0 ?
1758
1759				// Shortcut for :nth-*(n)
1760				function( elem ) {
1761					return !!elem.parentNode;
1762				} :
1763
1764				function( elem, context, xml ) {
1765					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1766						dir = simple !== forward ? "nextSibling" : "previousSibling",
1767						parent = elem.parentNode,
1768						name = ofType && elem.nodeName.toLowerCase(),
1769						useCache = !xml && !ofType,
1770						diff = false;
1771
1772					if ( parent ) {
1773
1774						// :(first|last|only)-(child|of-type)
1775						if ( simple ) {
1776							while ( dir ) {
1777								node = elem;
1778								while ( (node = node[ dir ]) ) {
1779									if ( ofType ?
1780										node.nodeName.toLowerCase() === name :
1781										node.nodeType === 1 ) {
1782
1783										return false;
1784									}
1785								}
1786								// Reverse direction for :only-* (if we haven't yet done so)
1787								start = dir = type === "only" && !start && "nextSibling";
1788							}
1789							return true;
1790						}
1791
1792						start = [ forward ? parent.firstChild : parent.lastChild ];
1793
1794						// non-xml :nth-child(...) stores cache data on `parent`
1795						if ( forward && useCache ) {
1796
1797							// Seek `elem` from a previously-cached index
1798
1799							// ...in a gzip-friendly way
1800							node = parent;
1801							outerCache = node[ expando ] || (node[ expando ] = {});
1802
1803							// Support: IE <9 only
1804							// Defend against cloned attroperties (jQuery gh-1709)
1805							uniqueCache = outerCache[ node.uniqueID ] ||
1806								(outerCache[ node.uniqueID ] = {});
1807
1808							cache = uniqueCache[ type ] || [];
1809							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1810							diff = nodeIndex && cache[ 2 ];
1811							node = nodeIndex && parent.childNodes[ nodeIndex ];
1812
1813							while ( (node = ++nodeIndex && node && node[ dir ] ||
1814
1815								// Fallback to seeking `elem` from the start
1816								(diff = nodeIndex = 0) || start.pop()) ) {
1817
1818								// When found, cache indexes on `parent` and break
1819								if ( node.nodeType === 1 && ++diff && node === elem ) {
1820									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1821									break;
1822								}
1823							}
1824
1825						} else {
1826							// Use previously-cached element index if available
1827							if ( useCache ) {
1828								// ...in a gzip-friendly way
1829								node = elem;
1830								outerCache = node[ expando ] || (node[ expando ] = {});
1831
1832								// Support: IE <9 only
1833								// Defend against cloned attroperties (jQuery gh-1709)
1834								uniqueCache = outerCache[ node.uniqueID ] ||
1835									(outerCache[ node.uniqueID ] = {});
1836
1837								cache = uniqueCache[ type ] || [];
1838								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1839								diff = nodeIndex;
1840							}
1841
1842							// xml :nth-child(...)
1843							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1844							if ( diff === false ) {
1845								// Use the same loop as above to seek `elem` from the start
1846								while ( (node = ++nodeIndex && node && node[ dir ] ||
1847									(diff = nodeIndex = 0) || start.pop()) ) {
1848
1849									if ( ( ofType ?
1850										node.nodeName.toLowerCase() === name :
1851										node.nodeType === 1 ) &&
1852										++diff ) {
1853
1854										// Cache the index of each encountered element
1855										if ( useCache ) {
1856											outerCache = node[ expando ] || (node[ expando ] = {});
1857
1858											// Support: IE <9 only
1859											// Defend against cloned attroperties (jQuery gh-1709)
1860											uniqueCache = outerCache[ node.uniqueID ] ||
1861												(outerCache[ node.uniqueID ] = {});
1862
1863											uniqueCache[ type ] = [ dirruns, diff ];
1864										}
1865
1866										if ( node === elem ) {
1867											break;
1868										}
1869									}
1870								}
1871							}
1872						}
1873
1874						// Incorporate the offset, then check against cycle size
1875						diff -= last;
1876						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1877					}
1878				};
1879		},
1880
1881		"PSEUDO": function( pseudo, argument ) {
1882			// pseudo-class names are case-insensitive
1883			// http://www.w3.org/TR/selectors/#pseudo-classes
1884			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1885			// Remember that setFilters inherits from pseudos
1886			var args,
1887				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1888					Sizzle.error( "unsupported pseudo: " + pseudo );
1889
1890			// The user may use createPseudo to indicate that
1891			// arguments are needed to create the filter function
1892			// just as Sizzle does
1893			if ( fn[ expando ] ) {
1894				return fn( argument );
1895			}
1896
1897			// But maintain support for old signatures
1898			if ( fn.length > 1 ) {
1899				args = [ pseudo, pseudo, "", argument ];
1900				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1901					markFunction(function( seed, matches ) {
1902						var idx,
1903							matched = fn( seed, argument ),
1904							i = matched.length;
1905						while ( i-- ) {
1906							idx = indexOf( seed, matched[i] );
1907							seed[ idx ] = !( matches[ idx ] = matched[i] );
1908						}
1909					}) :
1910					function( elem ) {
1911						return fn( elem, 0, args );
1912					};
1913			}
1914
1915			return fn;
1916		}
1917	},
1918
1919	pseudos: {
1920		// Potentially complex pseudos
1921		"not": markFunction(function( selector ) {
1922			// Trim the selector passed to compile
1923			// to avoid treating leading and trailing
1924			// spaces as combinators
1925			var input = [],
1926				results = [],
1927				matcher = compile( selector.replace( rtrim, "$1" ) );
1928
1929			return matcher[ expando ] ?
1930				markFunction(function( seed, matches, context, xml ) {
1931					var elem,
1932						unmatched = matcher( seed, null, xml, [] ),
1933						i = seed.length;
1934
1935					// Match elements unmatched by `matcher`
1936					while ( i-- ) {
1937						if ( (elem = unmatched[i]) ) {
1938							seed[i] = !(matches[i] = elem);
1939						}
1940					}
1941				}) :
1942				function( elem, context, xml ) {
1943					input[0] = elem;
1944					matcher( input, null, xml, results );
1945					// Don't keep the element (issue #299)
1946					input[0] = null;
1947					return !results.pop();
1948				};
1949		}),
1950
1951		"has": markFunction(function( selector ) {
1952			return function( elem ) {
1953				return Sizzle( selector, elem ).length > 0;
1954			};
1955		}),
1956
1957		"contains": markFunction(function( text ) {
1958			text = text.replace( runescape, funescape );
1959			return function( elem ) {
1960				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1961			};
1962		}),
1963
1964		// "Whether an element is represented by a :lang() selector
1965		// is based solely on the element's language value
1966		// being equal to the identifier C,
1967		// or beginning with the identifier C immediately followed by "-".
1968		// The matching of C against the element's language value is performed case-insensitively.
1969		// The identifier C does not have to be a valid language name."
1970		// http://www.w3.org/TR/selectors/#lang-pseudo
1971		"lang": markFunction( function( lang ) {
1972			// lang value must be a valid identifier
1973			if ( !ridentifier.test(lang || "") ) {
1974				Sizzle.error( "unsupported lang: " + lang );
1975			}
1976			lang = lang.replace( runescape, funescape ).toLowerCase();
1977			return function( elem ) {
1978				var elemLang;
1979				do {
1980					if ( (elemLang = documentIsHTML ?
1981						elem.lang :
1982						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1983
1984						elemLang = elemLang.toLowerCase();
1985						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1986					}
1987				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1988				return false;
vendor: 23,967 bytes, lines 1989-2860
1989			};
1990		}),
1991
1992		// Miscellaneous
1993		"target": function( elem ) {
1994			var hash = window.location && window.location.hash;
1995			return hash && hash.slice( 1 ) === elem.id;
1996		},
1997
1998		"root": function( elem ) {
1999			return elem === docElem;
2000		},
2001
2002		"focus": function( elem ) {
2003			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2004		},
2005
2006		// Boolean properties
2007		"enabled": createDisabledPseudo( false ),
2008		"disabled": createDisabledPseudo( true ),
2009
2010		"checked": function( elem ) {
2011			// In CSS3, :checked should return both checked and selected elements
2012			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2013			var nodeName = elem.nodeName.toLowerCase();
2014			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2015		},
2016
2017		"selected": function( elem ) {
2018			// Accessing this property makes selected-by-default
2019			// options in Safari work properly
2020			if ( elem.parentNode ) {
2021				elem.parentNode.selectedIndex;
2022			}
2023
2024			return elem.selected === true;
2025		},
2026
2027		// Contents
2028		"empty": function( elem ) {
2029			// http://www.w3.org/TR/selectors/#empty-pseudo
2030			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2031			//   but not by others (comment: 8; processing instruction: 7; etc.)
2032			// nodeType < 6 works because attributes (2) do not appear as children
2033			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2034				if ( elem.nodeType < 6 ) {
2035					return false;
2036				}
2037			}
2038			return true;
2039		},
2040
2041		"parent": function( elem ) {
2042			return !Expr.pseudos["empty"]( elem );
2043		},
2044
2045		// Element/input types
2046		"header": function( elem ) {
2047			return rheader.test( elem.nodeName );
2048		},
2049
2050		"input": function( elem ) {
2051			return rinputs.test( elem.nodeName );
2052		},
2053
2054		"button": function( elem ) {
2055			var name = elem.nodeName.toLowerCase();
2056			return name === "input" && elem.type === "button" || name === "button";
2057		},
2058
2059		"text": function( elem ) {
2060			var attr;
2061			return elem.nodeName.toLowerCase() === "input" &&
2062				elem.type === "text" &&
2063
2064				// Support: IE<8
2065				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2066				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2067		},
2068
2069		// Position-in-collection
2070		"first": createPositionalPseudo(function() {
2071			return [ 0 ];
2072		}),
2073
2074		"last": createPositionalPseudo(function( matchIndexes, length ) {
2075			return [ length - 1 ];
2076		}),
2077
2078		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2079			return [ argument < 0 ? argument + length : argument ];
2080		}),
2081
2082		"even": createPositionalPseudo(function( matchIndexes, length ) {
2083			var i = 0;
2084			for ( ; i < length; i += 2 ) {
2085				matchIndexes.push( i );
2086			}
2087			return matchIndexes;
2088		}),
2089
2090		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2091			var i = 1;
2092			for ( ; i < length; i += 2 ) {
2093				matchIndexes.push( i );
2094			}
2095			return matchIndexes;
2096		}),
2097
2098		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2099			var i = argument < 0 ? argument + length : argument;
2100			for ( ; --i >= 0; ) {
2101				matchIndexes.push( i );
2102			}
2103			return matchIndexes;
2104		}),
2105
2106		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2107			var i = argument < 0 ? argument + length : argument;
2108			for ( ; ++i < length; ) {
2109				matchIndexes.push( i );
2110			}
2111			return matchIndexes;
2112		})
2113	}
2114};
2115
2116Expr.pseudos["nth"] = Expr.pseudos["eq"];
2117
2118// Add button/input type pseudos
2119for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2120	Expr.pseudos[ i ] = createInputPseudo( i );
2121}
2122for ( i in { submit: true, reset: true } ) {
2123	Expr.pseudos[ i ] = createButtonPseudo( i );
2124}
2125
2126// Easy API for creating new setFilters
2127function setFilters() {}
2128setFilters.prototype = Expr.filters = Expr.pseudos;
2129Expr.setFilters = new setFilters();
2130
2131tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2132	var matched, match, tokens, type,
2133		soFar, groups, preFilters,
2134		cached = tokenCache[ selector + " " ];
2135
2136	if ( cached ) {
2137		return parseOnly ? 0 : cached.slice( 0 );
2138	}
2139
2140	soFar = selector;
2141	groups = [];
2142	preFilters = Expr.preFilter;
2143
2144	while ( soFar ) {
2145
2146		// Comma and first run
2147		if ( !matched || (match = rcomma.exec( soFar )) ) {
2148			if ( match ) {
2149				// Don't consume trailing commas as valid
2150				soFar = soFar.slice( match[0].length ) || soFar;
2151			}
2152			groups.push( (tokens = []) );
2153		}
2154
2155		matched = false;
2156
2157		// Combinators
2158		if ( (match = rcombinators.exec( soFar )) ) {
2159			matched = match.shift();
2160			tokens.push({
2161				value: matched,
2162				// Cast descendant combinators to space
2163				type: match[0].replace( rtrim, " " )
2164			});
2165			soFar = soFar.slice( matched.length );
2166		}
2167
2168		// Filters
2169		for ( type in Expr.filter ) {
2170			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2171				(match = preFilters[ type ]( match ))) ) {
2172				matched = match.shift();
2173				tokens.push({
2174					value: matched,
2175					type: type,
2176					matches: match
2177				});
2178				soFar = soFar.slice( matched.length );
2179			}
2180		}
2181
2182		if ( !matched ) {
2183			break;
2184		}
2185	}
2186
2187	// Return the length of the invalid excess
2188	// if we're just parsing
2189	// Otherwise, throw an error or return tokens
2190	return parseOnly ?
2191		soFar.length :
2192		soFar ?
2193			Sizzle.error( selector ) :
2194			// Cache the tokens
2195			tokenCache( selector, groups ).slice( 0 );
2196};
2197
2198function toSelector( tokens ) {
2199	var i = 0,
2200		len = tokens.length,
2201		selector = "";
2202	for ( ; i < len; i++ ) {
2203		selector += tokens[i].value;
2204	}
2205	return selector;
2206}
2207
2208function addCombinator( matcher, combinator, base ) {
2209	var dir = combinator.dir,
2210		skip = combinator.next,
2211		key = skip || dir,
2212		checkNonElements = base && key === "parentNode",
2213		doneName = done++;
2214
2215	return combinator.first ?
2216		// Check against closest ancestor/preceding element
2217		function( elem, context, xml ) {
2218			while ( (elem = elem[ dir ]) ) {
2219				if ( elem.nodeType === 1 || checkNonElements ) {
2220					return matcher( elem, context, xml );
2221				}
2222			}
2223			return false;
2224		} :
2225
2226		// Check against all ancestor/preceding elements
2227		function( elem, context, xml ) {
2228			var oldCache, uniqueCache, outerCache,
2229				newCache = [ dirruns, doneName ];
2230
2231			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2232			if ( xml ) {
2233				while ( (elem = elem[ dir ]) ) {
2234					if ( elem.nodeType === 1 || checkNonElements ) {
2235						if ( matcher( elem, context, xml ) ) {
2236							return true;
2237						}
2238					}
2239				}
2240			} else {
2241				while ( (elem = elem[ dir ]) ) {
2242					if ( elem.nodeType === 1 || checkNonElements ) {
2243						outerCache = elem[ expando ] || (elem[ expando ] = {});
2244
2245						// Support: IE <9 only
2246						// Defend against cloned attroperties (jQuery gh-1709)
2247						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2248
2249						if ( skip && skip === elem.nodeName.toLowerCase() ) {
2250							elem = elem[ dir ] || elem;
2251						} else if ( (oldCache = uniqueCache[ key ]) &&
2252							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2253
2254							// Assign to newCache so results back-propagate to previous elements
2255							return (newCache[ 2 ] = oldCache[ 2 ]);
2256						} else {
2257							// Reuse newcache so results back-propagate to previous elements
2258							uniqueCache[ key ] = newCache;
2259
2260							// A match means we're done; a fail means we have to keep checking
2261							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2262								return true;
2263							}
2264						}
2265					}
2266				}
2267			}
2268			return false;
2269		};
2270}
2271
2272function elementMatcher( matchers ) {
2273	return matchers.length > 1 ?
2274		function( elem, context, xml ) {
2275			var i = matchers.length;
2276			while ( i-- ) {
2277				if ( !matchers[i]( elem, context, xml ) ) {
2278					return false;
2279				}
2280			}
2281			return true;
2282		} :
2283		matchers[0];
2284}
2285
2286function multipleContexts( selector, contexts, results ) {
2287	var i = 0,
2288		len = contexts.length;
2289	for ( ; i < len; i++ ) {
2290		Sizzle( selector, contexts[i], results );
2291	}
2292	return results;
2293}
2294
2295function condense( unmatched, map, filter, context, xml ) {
2296	var elem,
2297		newUnmatched = [],
2298		i = 0,
2299		len = unmatched.length,
2300		mapped = map != null;
2301
2302	for ( ; i < len; i++ ) {
2303		if ( (elem = unmatched[i]) ) {
2304			if ( !filter || filter( elem, context, xml ) ) {
2305				newUnmatched.push( elem );
2306				if ( mapped ) {
2307					map.push( i );
2308				}
2309			}
2310		}
2311	}
2312
2313	return newUnmatched;
2314}
2315
2316function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2317	if ( postFilter && !postFilter[ expando ] ) {
2318		postFilter = setMatcher( postFilter );
2319	}
2320	if ( postFinder && !postFinder[ expando ] ) {
2321		postFinder = setMatcher( postFinder, postSelector );
2322	}
2323	return markFunction(function( seed, results, context, xml ) {
2324		var temp, i, elem,
2325			preMap = [],
2326			postMap = [],
2327			preexisting = results.length,
2328
2329			// Get initial elements from seed or context
2330			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2331
2332			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2333			matcherIn = preFilter && ( seed || !selector ) ?
2334				condense( elems, preMap, preFilter, context, xml ) :
2335				elems,
2336
2337			matcherOut = matcher ?
2338				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2339				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2340
2341					// ...intermediate processing is necessary
2342					[] :
2343
2344					// ...otherwise use results directly
2345					results :
2346				matcherIn;
2347
2348		// Find primary matches
2349		if ( matcher ) {
2350			matcher( matcherIn, matcherOut, context, xml );
2351		}
2352
2353		// Apply postFilter
2354		if ( postFilter ) {
2355			temp = condense( matcherOut, postMap );
2356			postFilter( temp, [], context, xml );
2357
2358			// Un-match failing elements by moving them back to matcherIn
2359			i = temp.length;
2360			while ( i-- ) {
2361				if ( (elem = temp[i]) ) {
2362					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2363				}
2364			}
2365		}
2366
2367		if ( seed ) {
2368			if ( postFinder || preFilter ) {
2369				if ( postFinder ) {
2370					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2371					temp = [];
2372					i = matcherOut.length;
2373					while ( i-- ) {
2374						if ( (elem = matcherOut[i]) ) {
2375							// Restore matcherIn since elem is not yet a final match
2376							temp.push( (matcherIn[i] = elem) );
2377						}
2378					}
2379					postFinder( null, (matcherOut = []), temp, xml );
2380				}
2381
2382				// Move matched elements from seed to results to keep them synchronized
2383				i = matcherOut.length;
2384				while ( i-- ) {
2385					if ( (elem = matcherOut[i]) &&
2386						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2387
2388						seed[temp] = !(results[temp] = elem);
2389					}
2390				}
2391			}
2392
2393		// Add elements to results, through postFinder if defined
2394		} else {
2395			matcherOut = condense(
2396				matcherOut === results ?
2397					matcherOut.splice( preexisting, matcherOut.length ) :
2398					matcherOut
2399			);
2400			if ( postFinder ) {
2401				postFinder( null, results, matcherOut, xml );
2402			} else {
2403				push.apply( results, matcherOut );
2404			}
2405		}
2406	});
2407}
2408
2409function matcherFromTokens( tokens ) {
2410	var checkContext, matcher, j,
2411		len = tokens.length,
2412		leadingRelative = Expr.relative[ tokens[0].type ],
2413		implicitRelative = leadingRelative || Expr.relative[" "],
2414		i = leadingRelative ? 1 : 0,
2415
2416		// The foundational matcher ensures that elements are reachable from top-level context(s)
2417		matchContext = addCombinator( function( elem ) {
2418			return elem === checkContext;
2419		}, implicitRelative, true ),
2420		matchAnyContext = addCombinator( function( elem ) {
2421			return indexOf( checkContext, elem ) > -1;
2422		}, implicitRelative, true ),
2423		matchers = [ function( elem, context, xml ) {
2424			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2425				(checkContext = context).nodeType ?
2426					matchContext( elem, context, xml ) :
2427					matchAnyContext( elem, context, xml ) );
2428			// Avoid hanging onto element (issue #299)
2429			checkContext = null;
2430			return ret;
2431		} ];
2432
2433	for ( ; i < len; i++ ) {
2434		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2435			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2436		} else {
2437			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2438
2439			// Return special upon seeing a positional matcher
2440			if ( matcher[ expando ] ) {
2441				// Find the next relative operator (if any) for proper handling
2442				j = ++i;
2443				for ( ; j < len; j++ ) {
2444					if ( Expr.relative[ tokens[j].type ] ) {
2445						break;
2446					}
2447				}
2448				return setMatcher(
2449					i > 1 && elementMatcher( matchers ),
2450					i > 1 && toSelector(
2451						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2452						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2453					).replace( rtrim, "$1" ),
2454					matcher,
2455					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2456					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2457					j < len && toSelector( tokens )
2458				);
2459			}
2460			matchers.push( matcher );
2461		}
2462	}
2463
2464	return elementMatcher( matchers );
2465}
2466
2467function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2468	var bySet = setMatchers.length > 0,
2469		byElement = elementMatchers.length > 0,
2470		superMatcher = function( seed, context, xml, results, outermost ) {
2471			var elem, j, matcher,
2472				matchedCount = 0,
2473				i = "0",
2474				unmatched = seed && [],
2475				setMatched = [],
2476				contextBackup = outermostContext,
2477				// We must always have either seed elements or outermost context
2478				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2479				// Use integer dirruns iff this is the outermost matcher
2480				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2481				len = elems.length;
2482
2483			if ( outermost ) {
2484				outermostContext = context === document || context || outermost;
2485			}
2486
2487			// Add elements passing elementMatchers directly to results
2488			// Support: IE<9, Safari
2489			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2490			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2491				if ( byElement && elem ) {
2492					j = 0;
2493					if ( !context && elem.ownerDocument !== document ) {
2494						setDocument( elem );
2495						xml = !documentIsHTML;
2496					}
2497					while ( (matcher = elementMatchers[j++]) ) {
2498						if ( matcher( elem, context || document, xml) ) {
2499							results.push( elem );
2500							break;
2501						}
2502					}
2503					if ( outermost ) {
2504						dirruns = dirrunsUnique;
2505					}
2506				}
2507
2508				// Track unmatched elements for set filters
2509				if ( bySet ) {
2510					// They will have gone through all possible matchers
2511					if ( (elem = !matcher && elem) ) {
2512						matchedCount--;
2513					}
2514
2515					// Lengthen the array for every element, matched or not
2516					if ( seed ) {
2517						unmatched.push( elem );
2518					}
2519				}
2520			}
2521
2522			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2523			// makes the latter nonnegative.
2524			matchedCount += i;
2525
2526			// Apply set filters to unmatched elements
2527			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2528			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2529			// no element matchers and no seed.
2530			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2531			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2532			// numerically zero.
2533			if ( bySet && i !== matchedCount ) {
2534				j = 0;
2535				while ( (matcher = setMatchers[j++]) ) {
2536					matcher( unmatched, setMatched, context, xml );
2537				}
2538
2539				if ( seed ) {
2540					// Reintegrate element matches to eliminate the need for sorting
2541					if ( matchedCount > 0 ) {
2542						while ( i-- ) {
2543							if ( !(unmatched[i] || setMatched[i]) ) {
2544								setMatched[i] = pop.call( results );
2545							}
2546						}
2547					}
2548
2549					// Discard index placeholder values to get only actual matches
2550					setMatched = condense( setMatched );
2551				}
2552
2553				// Add matches to results
2554				push.apply( results, setMatched );
2555
2556				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2557				if ( outermost && !seed && setMatched.length > 0 &&
2558					( matchedCount + setMatchers.length ) > 1 ) {
2559
2560					Sizzle.uniqueSort( results );
2561				}
2562			}
2563
2564			// Override manipulation of globals by nested matchers
2565			if ( outermost ) {
2566				dirruns = dirrunsUnique;
2567				outermostContext = contextBackup;
2568			}
2569
2570			return unmatched;
2571		};
2572
2573	return bySet ?
2574		markFunction( superMatcher ) :
2575		superMatcher;
2576}
2577
2578compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2579	var i,
2580		setMatchers = [],
2581		elementMatchers = [],
2582		cached = compilerCache[ selector + " " ];
2583
2584	if ( !cached ) {
2585		// Generate a function of recursive functions that can be used to check each element
2586		if ( !match ) {
2587			match = tokenize( selector );
2588		}
2589		i = match.length;
2590		while ( i-- ) {
2591			cached = matcherFromTokens( match[i] );
2592			if ( cached[ expando ] ) {
2593				setMatchers.push( cached );
2594			} else {
2595				elementMatchers.push( cached );
2596			}
2597		}
2598
2599		// Cache the compiled function
2600		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2601
2602		// Save selector and tokenization
2603		cached.selector = selector;
2604	}
2605	return cached;
2606};
2607
2608/**
2609 * A low-level selection function that works with Sizzle's compiled
2610 *  selector functions
2611 * @param {String|Function} selector A selector or a pre-compiled
2612 *  selector function built with Sizzle.compile
2613 * @param {Element} context
2614 * @param {Array} [results]
2615 * @param {Array} [seed] A set of elements to match against
2616 */
2617select = Sizzle.select = function( selector, context, results, seed ) {
2618	var i, tokens, token, type, find,
2619		compiled = typeof selector === "function" && selector,
2620		match = !seed && tokenize( (selector = compiled.selector || selector) );
2621
2622	results = results || [];
2623
2624	// Try to minimize operations if there is only one selector in the list and no seed
2625	// (the latter of which guarantees us context)
2626	if ( match.length === 1 ) {
2627
2628		// Reduce context if the leading compound selector is an ID
2629		tokens = match[0] = match[0].slice( 0 );
2630		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2631				context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) {
2632
2633			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2634			if ( !context ) {
2635				return results;
2636
2637			// Precompiled matchers will still verify ancestry, so step up a level
2638			} else if ( compiled ) {
2639				context = context.parentNode;
2640			}
2641
2642			selector = selector.slice( tokens.shift().value.length );
2643		}
2644
2645		// Fetch a seed set for right-to-left matching
2646		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2647		while ( i-- ) {
2648			token = tokens[i];
2649
2650			// Abort if we hit a combinator
2651			if ( Expr.relative[ (type = token.type) ] ) {
2652				break;
2653			}
2654			if ( (find = Expr.find[ type ]) ) {
2655				// Search, expanding context for leading sibling combinators
2656				if ( (seed = find(
2657					token.matches[0].replace( runescape, funescape ),
2658					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2659				)) ) {
2660
2661					// If seed is empty or no tokens remain, we can return early
2662					tokens.splice( i, 1 );
2663					selector = seed.length && toSelector( tokens );
2664					if ( !selector ) {
2665						push.apply( results, seed );
2666						return results;
2667					}
2668
2669					break;
2670				}
2671			}
2672		}
2673	}
2674
2675	// Compile and execute a filtering function if one is not provided
2676	// Provide `match` to avoid retokenization if we modified the selector above
2677	( compiled || compile( selector, match ) )(
2678		seed,
2679		context,
2680		!documentIsHTML,
2681		results,
2682		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2683	);
2684	return results;
2685};
2686
2687// One-time assignments
2688
2689// Sort stability
2690support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2691
2692// Support: Chrome 14-35+
2693// Always assume duplicates if they aren't passed to the comparison function
2694support.detectDuplicates = !!hasDuplicate;
2695
2696// Initialize against the default document
2697setDocument();
2698
2699// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2700// Detached nodes confoundingly follow *each other*
2701support.sortDetached = assert(function( el ) {
2702	// Should return 1, but returns 4 (following)
2703	return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
2704});
2705
2706// Support: IE<8
2707// Prevent attribute/property "interpolation"
2708// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2709if ( !assert(function( el ) {
2710	el.innerHTML = "<a href='#'></a>";
2711	return el.firstChild.getAttribute("href") === "#" ;
2712}) ) {
2713	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2714		if ( !isXML ) {
2715			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2716		}
2717	});
2718}
2719
2720// Support: IE<9
2721// Use defaultValue in place of getAttribute("value")
2722if ( !support.attributes || !assert(function( el ) {
2723	el.innerHTML = "<input/>";
2724	el.firstChild.setAttribute( "value", "" );
2725	return el.firstChild.getAttribute( "value" ) === "";
2726}) ) {
2727	addHandle( "value", function( elem, name, isXML ) {
2728		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2729			return elem.defaultValue;
2730		}
2731	});
2732}
2733
2734// Support: IE<9
2735// Use getAttributeNode to fetch booleans when getAttribute lies
2736if ( !assert(function( el ) {
2737	return el.getAttribute("disabled") == null;
2738}) ) {
2739	addHandle( booleans, function( elem, name, isXML ) {
2740		var val;
2741		if ( !isXML ) {
2742			return elem[ name ] === true ? name.toLowerCase() :
2743					(val = elem.getAttributeNode( name )) && val.specified ?
2744					val.value :
2745				null;
2746		}
2747	});
2748}
2749
2750return Sizzle;
2751
2752})( window );
2753
2754
2755
2756jQuery.find = Sizzle;
2757jQuery.expr = Sizzle.selectors;
2758
2759// Deprecated
2760jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2761jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2762jQuery.text = Sizzle.getText;
2763jQuery.isXMLDoc = Sizzle.isXML;
2764jQuery.contains = Sizzle.contains;
2765jQuery.escapeSelector = Sizzle.escape;
2766
2767
2768
2769
2770var dir = function( elem, dir, until ) {
2771	var matched = [],
2772		truncate = until !== undefined;
2773
2774	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2775		if ( elem.nodeType === 1 ) {
2776			if ( truncate && jQuery( elem ).is( until ) ) {
2777				break;
2778			}
2779			matched.push( elem );
2780		}
2781	}
2782	return matched;
2783};
2784
2785
2786var siblings = function( n, elem ) {
2787	var matched = [];
2788
2789	for ( ; n; n = n.nextSibling ) {
2790		if ( n.nodeType === 1 && n !== elem ) {
2791			matched.push( n );
2792		}
2793	}
2794
2795	return matched;
2796};
2797
2798
2799var rneedsContext = jQuery.expr.match.needsContext;
2800
2801
2802
2803function nodeName( elem, name ) {
2804
2805  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
2806
2807};
2808var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
2809
2810
2811
2812// Implement the identical functionality for filter and not
2813function winnow( elements, qualifier, not ) {
2814	if ( isFunction( qualifier ) ) {
2815		return jQuery.grep( elements, function( elem, i ) {
2816			return !!qualifier.call( elem, i, elem ) !== not;
2817		} );
2818	}
2819
2820	// Single element
2821	if ( qualifier.nodeType ) {
2822		return jQuery.grep( elements, function( elem ) {
2823			return ( elem === qualifier ) !== not;
2824		} );
2825	}
2826
2827	// Arraylike of elements (jQuery, arguments, Array)
2828	if ( typeof qualifier !== "string" ) {
2829		return jQuery.grep( elements, function( elem ) {
2830			return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2831		} );
2832	}
2833
2834	// Filtered directly for both simple and complex selectors
2835	return jQuery.filter( qualifier, elements, not );
2836}
2837
2838jQuery.filter = function( expr, elems, not ) {
2839	var elem = elems[ 0 ];
2840
2841	if ( not ) {
2842		expr = ":not(" + expr + ")";
2843	}
2844
2845	if ( elems.length === 1 && elem.nodeType === 1 ) {
2846		return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
2847	}
2848
2849	return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2850		return elem.nodeType === 1;
2851	} ) );
2852};
2853
2854jQuery.fn.extend( {
2855	find: function( selector ) {
2856		var i, ret,
2857			len = this.length,
2858			self = this;
2859
2860		if ( typeof selector !== "string" ) {
vendor: 4,662 bytes, lines 2861-3046
2861			return this.pushStack( jQuery( selector ).filter( function() {
2862				for ( i = 0; i < len; i++ ) {
2863					if ( jQuery.contains( self[ i ], this ) ) {
2864						return true;
2865					}
2866				}
2867			} ) );
2868		}
2869
2870		ret = this.pushStack( [] );
2871
2872		for ( i = 0; i < len; i++ ) {
2873			jQuery.find( selector, self[ i ], ret );
2874		}
2875
2876		return len > 1 ? jQuery.uniqueSort( ret ) : ret;
2877	},
2878	filter: function( selector ) {
2879		return this.pushStack( winnow( this, selector || [], false ) );
2880	},
2881	not: function( selector ) {
2882		return this.pushStack( winnow( this, selector || [], true ) );
2883	},
2884	is: function( selector ) {
2885		return !!winnow(
2886			this,
2887
2888			// If this is a positional/relative selector, check membership in the returned set
2889			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2890			typeof selector === "string" && rneedsContext.test( selector ) ?
2891				jQuery( selector ) :
2892				selector || [],
2893			false
2894		).length;
2895	}
2896} );
2897
2898
2899// Initialize a jQuery object
2900
2901
2902// A central reference to the root jQuery(document)
2903var rootjQuery,
2904
2905	// A simple way to check for HTML strings
2906	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2907	// Strict HTML recognition (#11290: must start with <)
2908	// Shortcut simple #id case for speed
2909	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
2910
2911	init = jQuery.fn.init = function( selector, context, root ) {
2912		var match, elem;
2913
2914		// HANDLE: $(""), $(null), $(undefined), $(false)
2915		if ( !selector ) {
2916			return this;
2917		}
2918
2919		// Method init() accepts an alternate rootjQuery
2920		// so migrate can support jQuery.sub (gh-2101)
2921		root = root || rootjQuery;
2922
2923		// Handle HTML strings
2924		if ( typeof selector === "string" ) {
2925			if ( selector[ 0 ] === "<" &&
2926				selector[ selector.length - 1 ] === ">" &&
2927				selector.length >= 3 ) {
2928
2929				// Assume that strings that start and end with <> are HTML and skip the regex check
2930				match = [ null, selector, null ];
2931
2932			} else {
2933				match = rquickExpr.exec( selector );
2934			}
2935
2936			// Match html or make sure no context is specified for #id
2937			if ( match && ( match[ 1 ] || !context ) ) {
2938
2939				// HANDLE: $(html) -> $(array)
2940				if ( match[ 1 ] ) {
2941					context = context instanceof jQuery ? context[ 0 ] : context;
2942
2943					// Option to run scripts is true for back-compat
2944					// Intentionally let the error be thrown if parseHTML is not present
2945					jQuery.merge( this, jQuery.parseHTML(
2946						match[ 1 ],
2947						context && context.nodeType ? context.ownerDocument || context : document,
2948						true
2949					) );
2950
2951					// HANDLE: $(html, props)
2952					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2953						for ( match in context ) {
2954
2955							// Properties of context are called as methods if possible
2956							if ( isFunction( this[ match ] ) ) {
2957								this[ match ]( context[ match ] );
2958
2959							// ...and otherwise set as attributes
2960							} else {
2961								this.attr( match, context[ match ] );
2962							}
2963						}
2964					}
2965
2966					return this;
2967
2968				// HANDLE: $(#id)
2969				} else {
2970					elem = document.getElementById( match[ 2 ] );
2971
2972					if ( elem ) {
2973
2974						// Inject the element directly into the jQuery object
2975						this[ 0 ] = elem;
2976						this.length = 1;
2977					}
2978					return this;
2979				}
2980
2981			// HANDLE: $(expr, $(...))
2982			} else if ( !context || context.jquery ) {
2983				return ( context || root ).find( selector );
2984
2985			// HANDLE: $(expr, context)
2986			// (which is just equivalent to: $(context).find(expr)
2987			} else {
2988				return this.constructor( context ).find( selector );
2989			}
2990
2991		// HANDLE: $(DOMElement)
2992		} else if ( selector.nodeType ) {
2993			this[ 0 ] = selector;
2994			this.length = 1;
2995			return this;
2996
2997		// HANDLE: $(function)
2998		// Shortcut for document ready
2999		} else if ( isFunction( selector ) ) {
3000			return root.ready !== undefined ?
3001				root.ready( selector ) :
3002
3003				// Execute immediately if ready is not present
3004				selector( jQuery );
3005		}
3006
3007		return jQuery.makeArray( selector, this );
3008	};
3009
3010// Give the init function the jQuery prototype for later instantiation
3011init.prototype = jQuery.fn;
3012
3013// Initialize central reference
3014rootjQuery = jQuery( document );
3015
3016
3017var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3018
3019	// Methods guaranteed to produce a unique set when starting from a unique set
3020	guaranteedUnique = {
3021		children: true,
3022		contents: true,
3023		next: true,
3024		prev: true
3025	};
3026
3027jQuery.fn.extend( {
3028	has: function( target ) {
3029		var targets = jQuery( target, this ),
3030			l = targets.length;
3031
3032		return this.filter( function() {
3033			var i = 0;
3034			for ( ; i < l; i++ ) {
3035				if ( jQuery.contains( this, targets[ i ] ) ) {
3036					return true;
3037				}
3038			}
3039		} );
3040	},
3041
3042	closest: function( selectors, context ) {
3043		var cur,
3044			i = 0,
3045			l = this.length,
3046			matched = [],
vendor: 6,003 bytes, lines 3047-3273
3047			targets = typeof selectors !== "string" && jQuery( selectors );
3048
3049		// Positional selectors never match, since there's no _selection_ context
3050		if ( !rneedsContext.test( selectors ) ) {
3051			for ( ; i < l; i++ ) {
3052				for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3053
3054					// Always skip document fragments
3055					if ( cur.nodeType < 11 && ( targets ?
3056						targets.index( cur ) > -1 :
3057
3058						// Don't pass non-elements to Sizzle
3059						cur.nodeType === 1 &&
3060							jQuery.find.matchesSelector( cur, selectors ) ) ) {
3061
3062						matched.push( cur );
3063						break;
3064					}
3065				}
3066			}
3067		}
3068
3069		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3070	},
3071
3072	// Determine the position of an element within the set
3073	index: function( elem ) {
3074
3075		// No argument, return index in parent
3076		if ( !elem ) {
3077			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3078		}
3079
3080		// Index in selector
3081		if ( typeof elem === "string" ) {
3082			return indexOf.call( jQuery( elem ), this[ 0 ] );
3083		}
3084
3085		// Locate the position of the desired element
3086		return indexOf.call( this,
3087
3088			// If it receives a jQuery object, the first element is used
3089			elem.jquery ? elem[ 0 ] : elem
3090		);
3091	},
3092
3093	add: function( selector, context ) {
3094		return this.pushStack(
3095			jQuery.uniqueSort(
3096				jQuery.merge( this.get(), jQuery( selector, context ) )
3097			)
3098		);
3099	},
3100
3101	addBack: function( selector ) {
3102		return this.add( selector == null ?
3103			this.prevObject : this.prevObject.filter( selector )
3104		);
3105	}
3106} );
3107
3108function sibling( cur, dir ) {
3109	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3110	return cur;
3111}
3112
3113jQuery.each( {
3114	parent: function( elem ) {
3115		var parent = elem.parentNode;
3116		return parent && parent.nodeType !== 11 ? parent : null;
3117	},
3118	parents: function( elem ) {
3119		return dir( elem, "parentNode" );
3120	},
3121	parentsUntil: function( elem, i, until ) {
3122		return dir( elem, "parentNode", until );
3123	},
3124	next: function( elem ) {
3125		return sibling( elem, "nextSibling" );
3126	},
3127	prev: function( elem ) {
3128		return sibling( elem, "previousSibling" );
3129	},
3130	nextAll: function( elem ) {
3131		return dir( elem, "nextSibling" );
3132	},
3133	prevAll: function( elem ) {
3134		return dir( elem, "previousSibling" );
3135	},
3136	nextUntil: function( elem, i, until ) {
3137		return dir( elem, "nextSibling", until );
3138	},
3139	prevUntil: function( elem, i, until ) {
3140		return dir( elem, "previousSibling", until );
3141	},
3142	siblings: function( elem ) {
3143		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3144	},
3145	children: function( elem ) {
3146		return siblings( elem.firstChild );
3147	},
3148	contents: function( elem ) {
3149        if ( nodeName( elem, "iframe" ) ) {
3150            return elem.contentDocument;
3151        }
3152
3153        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3154        // Treat the template element as a regular one in browsers that
3155        // don't support it.
3156        if ( nodeName( elem, "template" ) ) {
3157            elem = elem.content || elem;
3158        }
3159
3160        return jQuery.merge( [], elem.childNodes );
3161	}
3162}, function( name, fn ) {
3163	jQuery.fn[ name ] = function( until, selector ) {
3164		var matched = jQuery.map( this, fn, until );
3165
3166		if ( name.slice( -5 ) !== "Until" ) {
3167			selector = until;
3168		}
3169
3170		if ( selector && typeof selector === "string" ) {
3171			matched = jQuery.filter( selector, matched );
3172		}
3173
3174		if ( this.length > 1 ) {
3175
3176			// Remove duplicates
3177			if ( !guaranteedUnique[ name ] ) {
3178				jQuery.uniqueSort( matched );
3179			}
3180
3181			// Reverse order for parents* and prev-derivatives
3182			if ( rparentsprev.test( name ) ) {
3183				matched.reverse();
3184			}
3185		}
3186
3187		return this.pushStack( matched );
3188	};
3189} );
3190var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3191
3192
3193
3194// Convert String-formatted options into Object-formatted ones
3195function createOptions( options ) {
3196	var object = {};
3197	jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3198		object[ flag ] = true;
3199	} );
3200	return object;
3201}
3202
3203/*
3204 * Create a callback list using the following parameters:
3205 *
3206 *	options: an optional list of space-separated options that will change how
3207 *			the callback list behaves or a more traditional option object
3208 *
3209 * By default a callback list will act like an event callback list and can be
3210 * "fired" multiple times.
3211 *
3212 * Possible options:
3213 *
3214 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3215 *
3216 *	memory:			will keep track of previous values and will call any callback added
3217 *					after the list has been fired right away with the latest "memorized"
3218 *					values (like a Deferred)
3219 *
3220 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3221 *
3222 *	stopOnFalse:	interrupt callings when a callback returns false
3223 *
3224 */
3225jQuery.Callbacks = function( options ) {
3226
3227	// Convert options from String-formatted to Object-formatted if needed
3228	// (we check in cache first)
3229	options = typeof options === "string" ?
3230		createOptions( options ) :
3231		jQuery.extend( {}, options );
3232
3233	var // Flag to know if list is currently firing
3234		firing,
3235
3236		// Last fire value for non-forgettable lists
3237		memory,
3238
3239		// Flag to know if list was already fired
3240		fired,
3241
3242		// Flag to prevent firing
3243		locked,
3244
3245		// Actual callback list
3246		list = [],
3247
3248		// Queue of execution data for repeatable lists
3249		queue = [],
3250
3251		// Index of currently firing callback (modified by add/remove as needed)
3252		firingIndex = -1,
3253
3254		// Fire callbacks
3255		fire = function() {
3256
3257			// Enforce single-firing
3258			locked = locked || options.once;
3259
3260			// Execute callbacks for all pending executions,
3261			// respecting firingIndex overrides and runtime changes
3262			fired = firing = true;
3263			for ( ; queue.length; firingIndex = -1 ) {
3264				memory = queue.shift();
3265				while ( ++firingIndex < list.length ) {
3266
3267					// Run callback and check for early termination
3268					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3269						options.stopOnFalse ) {
3270
3271						// Jump to end and forget the data so .add doesn't re-fire
3272						firingIndex = list.length;
3273						memory = false;
vendor: 4,918 bytes, lines 3274-3483
3274					}
3275				}
3276			}
3277
3278			// Forget the data if we're done with it
3279			if ( !options.memory ) {
3280				memory = false;
3281			}
3282
3283			firing = false;
3284
3285			// Clean up if we're done firing for good
3286			if ( locked ) {
3287
3288				// Keep an empty list if we have data for future add calls
3289				if ( memory ) {
3290					list = [];
3291
3292				// Otherwise, this object is spent
3293				} else {
3294					list = "";
3295				}
3296			}
3297		},
3298
3299		// Actual Callbacks object
3300		self = {
3301
3302			// Add a callback or a collection of callbacks to the list
3303			add: function() {
3304				if ( list ) {
3305
3306					// If we have memory from a past run, we should fire after adding
3307					if ( memory && !firing ) {
3308						firingIndex = list.length - 1;
3309						queue.push( memory );
3310					}
3311
3312					( function add( args ) {
3313						jQuery.each( args, function( _, arg ) {
3314							if ( isFunction( arg ) ) {
3315								if ( !options.unique || !self.has( arg ) ) {
3316									list.push( arg );
3317								}
3318							} else if ( arg && arg.length && toType( arg ) !== "string" ) {
3319
3320								// Inspect recursively
3321								add( arg );
3322							}
3323						} );
3324					} )( arguments );
3325
3326					if ( memory && !firing ) {
3327						fire();
3328					}
3329				}
3330				return this;
3331			},
3332
3333			// Remove a callback from the list
3334			remove: function() {
3335				jQuery.each( arguments, function( _, arg ) {
3336					var index;
3337					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3338						list.splice( index, 1 );
3339
3340						// Handle firing indexes
3341						if ( index <= firingIndex ) {
3342							firingIndex--;
3343						}
3344					}
3345				} );
3346				return this;
3347			},
3348
3349			// Check if a given callback is in the list.
3350			// If no argument is given, return whether or not list has callbacks attached.
3351			has: function( fn ) {
3352				return fn ?
3353					jQuery.inArray( fn, list ) > -1 :
3354					list.length > 0;
3355			},
3356
3357			// Remove all callbacks from the list
3358			empty: function() {
3359				if ( list ) {
3360					list = [];
3361				}
3362				return this;
3363			},
3364
3365			// Disable .fire and .add
3366			// Abort any current/pending executions
3367			// Clear all callbacks and values
3368			disable: function() {
3369				locked = queue = [];
3370				list = memory = "";
3371				return this;
3372			},
3373			disabled: function() {
3374				return !list;
3375			},
3376
3377			// Disable .fire
3378			// Also disable .add unless we have memory (since it would have no effect)
3379			// Abort any pending executions
3380			lock: function() {
3381				locked = queue = [];
3382				if ( !memory && !firing ) {
3383					list = memory = "";
3384				}
3385				return this;
3386			},
3387			locked: function() {
3388				return !!locked;
3389			},
3390
3391			// Call all callbacks with the given context and arguments
3392			fireWith: function( context, args ) {
3393				if ( !locked ) {
3394					args = args || [];
3395					args = [ context, args.slice ? args.slice() : args ];
3396					queue.push( args );
3397					if ( !firing ) {
3398						fire();
3399					}
3400				}
3401				return this;
3402			},
3403
3404			// Call all the callbacks with the given arguments
3405			fire: function() {
3406				self.fireWith( this, arguments );
3407				return this;
3408			},
3409
3410			// To know if the callbacks have already been called at least once
3411			fired: function() {
3412				return !!fired;
3413			}
3414		};
3415
3416	return self;
3417};
3418
3419
3420function Identity( v ) {
3421	return v;
3422}
3423function Thrower( ex ) {
3424	throw ex;
3425}
3426
3427function adoptValue( value, resolve, reject, noValue ) {
3428	var method;
3429
3430	try {
3431
3432		// Check for promise aspect first to privilege synchronous behavior
3433		if ( value && isFunction( ( method = value.promise ) ) ) {
3434			method.call( value ).done( resolve ).fail( reject );
3435
3436		// Other thenables
3437		} else if ( value && isFunction( ( method = value.then ) ) ) {
3438			method.call( value, resolve, reject );
3439
3440		// Other non-thenables
3441		} else {
3442
3443			// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
3444			// * false: [ value ].slice( 0 ) => resolve( value )
3445			// * true: [ value ].slice( 1 ) => resolve()
3446			resolve.apply( undefined, [ value ].slice( noValue ) );
3447		}
3448
3449	// For Promises/A+, convert exceptions into rejections
3450	// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
3451	// Deferred#then to conditionally suppress rejection.
3452	} catch ( value ) {
3453
3454		// Support: Android 4.0 only
3455		// Strict mode functions invoked without .call/.apply get global-object context
3456		reject.apply( undefined, [ value ] );
3457	}
3458}
3459
3460jQuery.extend( {
3461
3462	Deferred: function( func ) {
3463		var tuples = [
3464
3465				// action, add listener, callbacks,
3466				// ... .then handlers, argument index, [final state]
3467				[ "notify", "progress", jQuery.Callbacks( "memory" ),
3468					jQuery.Callbacks( "memory" ), 2 ],
3469				[ "resolve", "done", jQuery.Callbacks( "once memory" ),
3470					jQuery.Callbacks( "once memory" ), 0, "resolved" ],
3471				[ "reject", "fail", jQuery.Callbacks( "once memory" ),
3472					jQuery.Callbacks( "once memory" ), 1, "rejected" ]
3473			],
3474			state = "pending",
3475			promise = {
3476				state: function() {
3477					return state;
3478				},
3479				always: function() {
3480					deferred.done( arguments ).fail( arguments );
3481					return this;
3482				},
3483				"catch": function( fn ) {
vendor: 15,167 bytes, lines 3484-4075
3484					return promise.then( null, fn );
3485				},
3486
3487				// Keep pipe for back-compat
3488				pipe: function( /* fnDone, fnFail, fnProgress */ ) {
3489					var fns = arguments;
3490
3491					return jQuery.Deferred( function( newDefer ) {
3492						jQuery.each( tuples, function( i, tuple ) {
3493
3494							// Map tuples (progress, done, fail) to arguments (done, fail, progress)
3495							var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
3496
3497							// deferred.progress(function() { bind to newDefer or newDefer.notify })
3498							// deferred.done(function() { bind to newDefer or newDefer.resolve })
3499							// deferred.fail(function() { bind to newDefer or newDefer.reject })
3500							deferred[ tuple[ 1 ] ]( function() {
3501								var returned = fn && fn.apply( this, arguments );
3502								if ( returned && isFunction( returned.promise ) ) {
3503									returned.promise()
3504										.progress( newDefer.notify )
3505										.done( newDefer.resolve )
3506										.fail( newDefer.reject );
3507								} else {
3508									newDefer[ tuple[ 0 ] + "With" ](
3509										this,
3510										fn ? [ returned ] : arguments
3511									);
3512								}
3513							} );
3514						} );
3515						fns = null;
3516					} ).promise();
3517				},
3518				then: function( onFulfilled, onRejected, onProgress ) {
3519					var maxDepth = 0;
3520					function resolve( depth, deferred, handler, special ) {
3521						return function() {
3522							var that = this,
3523								args = arguments,
3524								mightThrow = function() {
3525									var returned, then;
3526
3527									// Support: Promises/A+ section 2.3.3.3.3
3528									// https://promisesaplus.com/#point-59
3529									// Ignore double-resolution attempts
3530									if ( depth < maxDepth ) {
3531										return;
3532									}
3533
3534									returned = handler.apply( that, args );
3535
3536									// Support: Promises/A+ section 2.3.1
3537									// https://promisesaplus.com/#point-48
3538									if ( returned === deferred.promise() ) {
3539										throw new TypeError( "Thenable self-resolution" );
3540									}
3541
3542									// Support: Promises/A+ sections 2.3.3.1, 3.5
3543									// https://promisesaplus.com/#point-54
3544									// https://promisesaplus.com/#point-75
3545									// Retrieve `then` only once
3546									then = returned &&
3547
3548										// Support: Promises/A+ section 2.3.4
3549										// https://promisesaplus.com/#point-64
3550										// Only check objects and functions for thenability
3551										( typeof returned === "object" ||
3552											typeof returned === "function" ) &&
3553										returned.then;
3554
3555									// Handle a returned thenable
3556									if ( isFunction( then ) ) {
3557
3558										// Special processors (notify) just wait for resolution
3559										if ( special ) {
3560											then.call(
3561												returned,
3562												resolve( maxDepth, deferred, Identity, special ),
3563												resolve( maxDepth, deferred, Thrower, special )
3564											);
3565
3566										// Normal processors (resolve) also hook into progress
3567										} else {
3568
3569											// ...and disregard older resolution values
3570											maxDepth++;
3571
3572											then.call(
3573												returned,
3574												resolve( maxDepth, deferred, Identity, special ),
3575												resolve( maxDepth, deferred, Thrower, special ),
3576												resolve( maxDepth, deferred, Identity,
3577													deferred.notifyWith )
3578											);
3579										}
3580
3581									// Handle all other returned values
3582									} else {
3583
3584										// Only substitute handlers pass on context
3585										// and multiple values (non-spec behavior)
3586										if ( handler !== Identity ) {
3587											that = undefined;
3588											args = [ returned ];
3589										}
3590
3591										// Process the value(s)
3592										// Default process is resolve
3593										( special || deferred.resolveWith )( that, args );
3594									}
3595								},
3596
3597								// Only normal processors (resolve) catch and reject exceptions
3598								process = special ?
3599									mightThrow :
3600									function() {
3601										try {
3602											mightThrow();
3603										} catch ( e ) {
3604
3605											if ( jQuery.Deferred.exceptionHook ) {
3606												jQuery.Deferred.exceptionHook( e,
3607													process.stackTrace );
3608											}
3609
3610											// Support: Promises/A+ section 2.3.3.3.4.1
3611											// https://promisesaplus.com/#point-61
3612											// Ignore post-resolution exceptions
3613											if ( depth + 1 >= maxDepth ) {
3614
3615												// Only substitute handlers pass on context
3616												// and multiple values (non-spec behavior)
3617												if ( handler !== Thrower ) {
3618													that = undefined;
3619													args = [ e ];
3620												}
3621
3622												deferred.rejectWith( that, args );
3623											}
3624										}
3625									};
3626
3627							// Support: Promises/A+ section 2.3.3.3.1
3628							// https://promisesaplus.com/#point-57
3629							// Re-resolve promises immediately to dodge false rejection from
3630							// subsequent errors
3631							if ( depth ) {
3632								process();
3633							} else {
3634
3635								// Call an optional hook to record the stack, in case of exception
3636								// since it's otherwise lost when execution goes async
3637								if ( jQuery.Deferred.getStackHook ) {
3638									process.stackTrace = jQuery.Deferred.getStackHook();
3639								}
3640								window.setTimeout( process );
3641							}
3642						};
3643					}
3644
3645					return jQuery.Deferred( function( newDefer ) {
3646
3647						// progress_handlers.add( ... )
3648						tuples[ 0 ][ 3 ].add(
3649							resolve(
3650								0,
3651								newDefer,
3652								isFunction( onProgress ) ?
3653									onProgress :
3654									Identity,
3655								newDefer.notifyWith
3656							)
3657						);
3658
3659						// fulfilled_handlers.add( ... )
3660						tuples[ 1 ][ 3 ].add(
3661							resolve(
3662								0,
3663								newDefer,
3664								isFunction( onFulfilled ) ?
3665									onFulfilled :
3666									Identity
3667							)
3668						);
3669
3670						// rejected_handlers.add( ... )
3671						tuples[ 2 ][ 3 ].add(
3672							resolve(
3673								0,
3674								newDefer,
3675								isFunction( onRejected ) ?
3676									onRejected :
3677									Thrower
3678							)
3679						);
3680					} ).promise();
3681				},
3682
3683				// Get a promise for this deferred
3684				// If obj is provided, the promise aspect is added to the object
3685				promise: function( obj ) {
3686					return obj != null ? jQuery.extend( obj, promise ) : promise;
3687				}
3688			},
3689			deferred = {};
3690
3691		// Add list-specific methods
3692		jQuery.each( tuples, function( i, tuple ) {
3693			var list = tuple[ 2 ],
3694				stateString = tuple[ 5 ];
3695
3696			// promise.progress = list.add
3697			// promise.done = list.add
3698			// promise.fail = list.add
3699			promise[ tuple[ 1 ] ] = list.add;
3700
3701			// Handle state
3702			if ( stateString ) {
3703				list.add(
3704					function() {
3705
3706						// state = "resolved" (i.e., fulfilled)
3707						// state = "rejected"
3708						state = stateString;
3709					},
3710
3711					// rejected_callbacks.disable
3712					// fulfilled_callbacks.disable
3713					tuples[ 3 - i ][ 2 ].disable,
3714
3715					// rejected_handlers.disable
3716					// fulfilled_handlers.disable
3717					tuples[ 3 - i ][ 3 ].disable,
3718
3719					// progress_callbacks.lock
3720					tuples[ 0 ][ 2 ].lock,
3721
3722					// progress_handlers.lock
3723					tuples[ 0 ][ 3 ].lock
3724				);
3725			}
3726
3727			// progress_handlers.fire
3728			// fulfilled_handlers.fire
3729			// rejected_handlers.fire
3730			list.add( tuple[ 3 ].fire );
3731
3732			// deferred.notify = function() { deferred.notifyWith(...) }
3733			// deferred.resolve = function() { deferred.resolveWith(...) }
3734			// deferred.reject = function() { deferred.rejectWith(...) }
3735			deferred[ tuple[ 0 ] ] = function() {
3736				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
3737				return this;
3738			};
3739
3740			// deferred.notifyWith = list.fireWith
3741			// deferred.resolveWith = list.fireWith
3742			// deferred.rejectWith = list.fireWith
3743			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3744		} );
3745
3746		// Make the deferred a promise
3747		promise.promise( deferred );
3748
3749		// Call given func if any
3750		if ( func ) {
3751			func.call( deferred, deferred );
3752		}
3753
3754		// All done!
3755		return deferred;
3756	},
3757
3758	// Deferred helper
3759	when: function( singleValue ) {
3760		var
3761
3762			// count of uncompleted subordinates
3763			remaining = arguments.length,
3764
3765			// count of unprocessed arguments
3766			i = remaining,
3767
3768			// subordinate fulfillment data
3769			resolveContexts = Array( i ),
3770			resolveValues = slice.call( arguments ),
3771
3772			// the master Deferred
3773			master = jQuery.Deferred(),
3774
3775			// subordinate callback factory
3776			updateFunc = function( i ) {
3777				return function( value ) {
3778					resolveContexts[ i ] = this;
3779					resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3780					if ( !( --remaining ) ) {
3781						master.resolveWith( resolveContexts, resolveValues );
3782					}
3783				};
3784			};
3785
3786		// Single- and empty arguments are adopted like Promise.resolve
3787		if ( remaining <= 1 ) {
3788			adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
3789				!remaining );
3790
3791			// Use .then() to unwrap secondary thenables (cf. gh-3000)
3792			if ( master.state() === "pending" ||
3793				isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
3794
3795				return master.then();
3796			}
3797		}
3798
3799		// Multiple arguments are aggregated like Promise.all array elements
3800		while ( i-- ) {
3801			adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
3802		}
3803
3804		return master.promise();
3805	}
3806} );
3807
3808
3809// These usually indicate a programmer mistake during development,
3810// warn about them ASAP rather than swallowing them by default.
3811var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
3812
3813jQuery.Deferred.exceptionHook = function( error, stack ) {
3814
3815	// Support: IE 8 - 9 only
3816	// Console exists when dev tools are open, which can happen at any time
3817	if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
3818		window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
3819	}
3820};
3821
3822
3823
3824
3825jQuery.readyException = function( error ) {
3826	window.setTimeout( function() {
3827		throw error;
3828	} );
3829};
3830
3831
3832
3833
3834// The deferred used on DOM ready
3835var readyList = jQuery.Deferred();
3836
3837jQuery.fn.ready = function( fn ) {
3838
3839	readyList
3840		.then( fn )
3841
3842		// Wrap jQuery.readyException in a function so that the lookup
3843		// happens at the time of error handling instead of callback
3844		// registration.
3845		.catch( function( error ) {
3846			jQuery.readyException( error );
3847		} );
3848
3849	return this;
3850};
3851
3852jQuery.extend( {
3853
3854	// Is the DOM ready to be used? Set to true once it occurs.
3855	isReady: false,
3856
3857	// A counter to track how many items to wait for before
3858	// the ready event fires. See #6781
3859	readyWait: 1,
3860
3861	// Handle when the DOM is ready
3862	ready: function( wait ) {
3863
3864		// Abort if there are pending holds or we're already ready
3865		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3866			return;
3867		}
3868
3869		// Remember that the DOM is ready
3870		jQuery.isReady = true;
3871
3872		// If a normal DOM Ready event fired, decrement, and wait if need be
3873		if ( wait !== true && --jQuery.readyWait > 0 ) {
3874			return;
3875		}
3876
3877		// If there are functions bound, to execute
3878		readyList.resolveWith( document, [ jQuery ] );
3879	}
3880} );
3881
3882jQuery.ready.then = readyList.then;
3883
3884// The ready event handler and self cleanup method
3885function completed() {
3886	document.removeEventListener( "DOMContentLoaded", completed );
3887	window.removeEventListener( "load", completed );
3888	jQuery.ready();
3889}
3890
3891// Catch cases where $(document).ready() is called
3892// after the browser event has already occurred.
3893// Support: IE <=9 - 10 only
3894// Older IE sometimes signals "interactive" too soon
3895if ( document.readyState === "complete" ||
3896	( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3897
3898	// Handle it asynchronously to allow scripts the opportunity to delay ready
3899	window.setTimeout( jQuery.ready );
3900
3901} else {
3902
3903	// Use the handy event callback
3904	document.addEventListener( "DOMContentLoaded", completed );
3905
3906	// A fallback to window.onload, that will always work
3907	window.addEventListener( "load", completed );
3908}
3909
3910
3911
3912
3913// Multifunctional method to get and set values of a collection
3914// The value/s can optionally be executed if it's a function
3915var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3916	var i = 0,
3917		len = elems.length,
3918		bulk = key == null;
3919
3920	// Sets many values
3921	if ( toType( key ) === "object" ) {
3922		chainable = true;
3923		for ( i in key ) {
3924			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3925		}
3926
3927	// Sets one value
3928	} else if ( value !== undefined ) {
3929		chainable = true;
3930
3931		if ( !isFunction( value ) ) {
3932			raw = true;
3933		}
3934
3935		if ( bulk ) {
3936
3937			// Bulk operations run against the entire set
3938			if ( raw ) {
3939				fn.call( elems, value );
3940				fn = null;
3941
3942			// ...except when executing function values
3943			} else {
3944				bulk = fn;
3945				fn = function( elem, key, value ) {
3946					return bulk.call( jQuery( elem ), value );
3947				};
3948			}
3949		}
3950
3951		if ( fn ) {
3952			for ( ; i < len; i++ ) {
3953				fn(
3954					elems[ i ], key, raw ?
3955					value :
3956					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3957				);
3958			}
3959		}
3960	}
3961
3962	if ( chainable ) {
3963		return elems;
3964	}
3965
3966	// Gets
3967	if ( bulk ) {
3968		return fn.call( elems );
3969	}
3970
3971	return len ? fn( elems[ 0 ], key ) : emptyGet;
3972};
3973
3974
3975// Matches dashed string for camelizing
3976var rmsPrefix = /^-ms-/,
3977	rdashAlpha = /-([a-z])/g;
3978
3979// Used by camelCase as callback to replace()
3980function fcamelCase( all, letter ) {
3981	return letter.toUpperCase();
3982}
3983
3984// Convert dashed to camelCase; used by the css and data modules
3985// Support: IE <=9 - 11, Edge 12 - 15
3986// Microsoft forgot to hump their vendor prefix (#9572)
3987function camelCase( string ) {
3988	return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
3989}
3990var acceptData = function( owner ) {
3991
3992	// Accepts only:
3993	//  - Node
3994	//    - Node.ELEMENT_NODE
3995	//    - Node.DOCUMENT_NODE
3996	//  - Object
3997	//    - Any
3998	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3999};
4000
4001
4002
4003
4004function Data() {
4005	this.expando = jQuery.expando + Data.uid++;
4006}
4007
4008Data.uid = 1;
4009
4010Data.prototype = {
4011
4012	cache: function( owner ) {
4013
4014		// Check if the owner object already has a cache
4015		var value = owner[ this.expando ];
4016
4017		// If not, create one
4018		if ( !value ) {
4019			value = {};
4020
4021			// We can accept data for non-element nodes in modern browsers,
4022			// but we should not, see #8335.
4023			// Always return an empty object.
4024			if ( acceptData( owner ) ) {
4025
4026				// If it is a node unlikely to be stringify-ed or looped over
4027				// use plain assignment
4028				if ( owner.nodeType ) {
4029					owner[ this.expando ] = value;
4030
4031				// Otherwise secure it in a non-enumerable property
4032				// configurable must be true to allow the property to be
4033				// deleted when data is removed
4034				} else {
4035					Object.defineProperty( owner, this.expando, {
4036						value: value,
4037						configurable: true
4038					} );
4039				}
4040			}
4041		}
4042
4043		return value;
4044	},
4045	set: function( owner, data, value ) {
4046		var prop,
4047			cache = this.cache( owner );
4048
4049		// Handle: [ owner, key, value ] args
4050		// Always use camelCase key (gh-2257)
4051		if ( typeof data === "string" ) {
4052			cache[ camelCase( data ) ] = value;
4053
4054		// Handle: [ owner, { properties } ] args
4055		} else {
4056
4057			// Copy the properties one-by-one to the cache object
4058			for ( prop in data ) {
4059				cache[ camelCase( prop ) ] = data[ prop ];
4060			}
4061		}
4062		return cache;
4063	},
4064	get: function( owner, key ) {
4065		return key === undefined ?
4066			this.cache( owner ) :
4067
4068			// Always use camelCase key (gh-2257)
4069			owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4070	},
4071	access: function( owner, key, value ) {
4072
4073		// In cases where either:
4074		//
4075		//   1. No key was specified
vendor: 8,694 bytes, lines 4076-4434
4076		//   2. A string key was specified, but no value provided
4077		//
4078		// Take the "read" path and allow the get method to determine
4079		// which value to return, respectively either:
4080		//
4081		//   1. The entire cache object
4082		//   2. The data stored at the key
4083		//
4084		if ( key === undefined ||
4085				( ( key && typeof key === "string" ) && value === undefined ) ) {
4086
4087			return this.get( owner, key );
4088		}
4089
4090		// When the key is not a string, or both a key and value
4091		// are specified, set or extend (existing objects) with either:
4092		//
4093		//   1. An object of properties
4094		//   2. A key and value
4095		//
4096		this.set( owner, key, value );
4097
4098		// Since the "set" path can have two possible entry points
4099		// return the expected data based on which path was taken[*]
4100		return value !== undefined ? value : key;
4101	},
4102	remove: function( owner, key ) {
4103		var i,
4104			cache = owner[ this.expando ];
4105
4106		if ( cache === undefined ) {
4107			return;
4108		}
4109
4110		if ( key !== undefined ) {
4111
4112			// Support array or space separated string of keys
4113			if ( Array.isArray( key ) ) {
4114
4115				// If key is an array of keys...
4116				// We always set camelCase keys, so remove that.
4117				key = key.map( camelCase );
4118			} else {
4119				key = camelCase( key );
4120
4121				// If a key with the spaces exists, use it.
4122				// Otherwise, create an array by matching non-whitespace
4123				key = key in cache ?
4124					[ key ] :
4125					( key.match( rnothtmlwhite ) || [] );
4126			}
4127
4128			i = key.length;
4129
4130			while ( i-- ) {
4131				delete cache[ key[ i ] ];
4132			}
4133		}
4134
4135		// Remove the expando if there's no more data
4136		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4137
4138			// Support: Chrome <=35 - 45
4139			// Webkit & Blink performance suffers when deleting properties
4140			// from DOM nodes, so set to undefined instead
4141			// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4142			if ( owner.nodeType ) {
4143				owner[ this.expando ] = undefined;
4144			} else {
4145				delete owner[ this.expando ];
4146			}
4147		}
4148	},
4149	hasData: function( owner ) {
4150		var cache = owner[ this.expando ];
4151		return cache !== undefined && !jQuery.isEmptyObject( cache );
4152	}
4153};
4154var dataPriv = new Data();
4155
4156var dataUser = new Data();
4157
4158
4159
4160//	Implementation Summary
4161//
4162//	1. Enforce API surface and semantic compatibility with 1.9.x branch
4163//	2. Improve the module's maintainability by reducing the storage
4164//		paths to a single mechanism.
4165//	3. Use the same single mechanism to support "private" and "user" data.
4166//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4167//	5. Avoid exposing implementation details on user objects (eg. expando properties)
4168//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
4169
4170var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4171	rmultiDash = /[A-Z]/g;
4172
4173function getData( data ) {
4174	if ( data === "true" ) {
4175		return true;
4176	}
4177
4178	if ( data === "false" ) {
4179		return false;
4180	}
4181
4182	if ( data === "null" ) {
4183		return null;
4184	}
4185
4186	// Only convert to a number if it doesn't change the string
4187	if ( data === +data + "" ) {
4188		return +data;
4189	}
4190
4191	if ( rbrace.test( data ) ) {
4192		return JSON.parse( data );
4193	}
4194
4195	return data;
4196}
4197
4198function dataAttr( elem, key, data ) {
4199	var name;
4200
4201	// If nothing was found internally, try to fetch any
4202	// data from the HTML5 data-* attribute
4203	if ( data === undefined && elem.nodeType === 1 ) {
4204		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4205		data = elem.getAttribute( name );
4206
4207		if ( typeof data === "string" ) {
4208			try {
4209				data = getData( data );
4210			} catch ( e ) {}
4211
4212			// Make sure we set the data so it isn't changed later
4213			dataUser.set( elem, key, data );
4214		} else {
4215			data = undefined;
4216		}
4217	}
4218	return data;
4219}
4220
4221jQuery.extend( {
4222	hasData: function( elem ) {
4223		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4224	},
4225
4226	data: function( elem, name, data ) {
4227		return dataUser.access( elem, name, data );
4228	},
4229
4230	removeData: function( elem, name ) {
4231		dataUser.remove( elem, name );
4232	},
4233
4234	// TODO: Now that all calls to _data and _removeData have been replaced
4235	// with direct calls to dataPriv methods, these can be deprecated.
4236	_data: function( elem, name, data ) {
4237		return dataPriv.access( elem, name, data );
4238	},
4239
4240	_removeData: function( elem, name ) {
4241		dataPriv.remove( elem, name );
4242	}
4243} );
4244
4245jQuery.fn.extend( {
4246	data: function( key, value ) {
4247		var i, name, data,
4248			elem = this[ 0 ],
4249			attrs = elem && elem.attributes;
4250
4251		// Gets all values
4252		if ( key === undefined ) {
4253			if ( this.length ) {
4254				data = dataUser.get( elem );
4255
4256				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4257					i = attrs.length;
4258					while ( i-- ) {
4259
4260						// Support: IE 11 only
4261						// The attrs elements can be null (#14894)
4262						if ( attrs[ i ] ) {
4263							name = attrs[ i ].name;
4264							if ( name.indexOf( "data-" ) === 0 ) {
4265								name = camelCase( name.slice( 5 ) );
4266								dataAttr( elem, name, data[ name ] );
4267							}
4268						}
4269					}
4270					dataPriv.set( elem, "hasDataAttrs", true );
4271				}
4272			}
4273
4274			return data;
4275		}
4276
4277		// Sets multiple values
4278		if ( typeof key === "object" ) {
4279			return this.each( function() {
4280				dataUser.set( this, key );
4281			} );
4282		}
4283
4284		return access( this, function( value ) {
4285			var data;
4286
4287			// The calling jQuery object (element matches) is not empty
4288			// (and therefore has an element appears at this[ 0 ]) and the
4289			// `value` parameter was not undefined. An empty jQuery object
4290			// will result in `undefined` for elem = this[ 0 ] which will
4291			// throw an exception if an attempt to read a data cache is made.
4292			if ( elem && value === undefined ) {
4293
4294				// Attempt to get data from the cache
4295				// The key will always be camelCased in Data
4296				data = dataUser.get( elem, key );
4297				if ( data !== undefined ) {
4298					return data;
4299				}
4300
4301				// Attempt to "discover" the data in
4302				// HTML5 custom data-* attrs
4303				data = dataAttr( elem, key );
4304				if ( data !== undefined ) {
4305					return data;
4306				}
4307
4308				// We tried really hard, but the data doesn't exist.
4309				return;
4310			}
4311
4312			// Set the data...
4313			this.each( function() {
4314
4315				// We always store the camelCased key
4316				dataUser.set( this, key, value );
4317			} );
4318		}, null, value, arguments.length > 1, null, true );
4319	},
4320
4321	removeData: function( key ) {
4322		return this.each( function() {
4323			dataUser.remove( this, key );
4324		} );
4325	}
4326} );
4327
4328
4329jQuery.extend( {
4330	queue: function( elem, type, data ) {
4331		var queue;
4332
4333		if ( elem ) {
4334			type = ( type || "fx" ) + "queue";
4335			queue = dataPriv.get( elem, type );
4336
4337			// Speed up dequeue by getting out quickly if this is just a lookup
4338			if ( data ) {
4339				if ( !queue || Array.isArray( data ) ) {
4340					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4341				} else {
4342					queue.push( data );
4343				}
4344			}
4345			return queue || [];
4346		}
4347	},
4348
4349	dequeue: function( elem, type ) {
4350		type = type || "fx";
4351
4352		var queue = jQuery.queue( elem, type ),
4353			startLength = queue.length,
4354			fn = queue.shift(),
4355			hooks = jQuery._queueHooks( elem, type ),
4356			next = function() {
4357				jQuery.dequeue( elem, type );
4358			};
4359
4360		// If the fx queue is dequeued, always remove the progress sentinel
4361		if ( fn === "inprogress" ) {
4362			fn = queue.shift();
4363			startLength--;
4364		}
4365
4366		if ( fn ) {
4367
4368			// Add a progress sentinel to prevent the fx queue from being
4369			// automatically dequeued
4370			if ( type === "fx" ) {
4371				queue.unshift( "inprogress" );
4372			}
4373
4374			// Clear up the last queue stop function
4375			delete hooks.stop;
4376			fn.call( elem, next, hooks );
4377		}
4378
4379		if ( !startLength && hooks ) {
4380			hooks.empty.fire();
4381		}
4382	},
4383
4384	// Not public - generate a queueHooks object, or return the current one
4385	_queueHooks: function( elem, type ) {
4386		var key = type + "queueHooks";
4387		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4388			empty: jQuery.Callbacks( "once memory" ).add( function() {
4389				dataPriv.remove( elem, [ type + "queue", key ] );
4390			} )
4391		} );
4392	}
4393} );
4394
4395jQuery.fn.extend( {
4396	queue: function( type, data ) {
4397		var setter = 2;
4398
4399		if ( typeof type !== "string" ) {
4400			data = type;
4401			type = "fx";
4402			setter--;
4403		}
4404
4405		if ( arguments.length < setter ) {
4406			return jQuery.queue( this[ 0 ], type );
4407		}
4408
4409		return data === undefined ?
4410			this :
4411			this.each( function() {
4412				var queue = jQuery.queue( this, type, data );
4413
4414				// Ensure a hooks for this queue
4415				jQuery._queueHooks( this, type );
4416
4417				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4418					jQuery.dequeue( this, type );
4419				}
4420			} );
4421	},
4422	dequeue: function( type ) {
4423		return this.each( function() {
4424			jQuery.dequeue( this, type );
4425		} );
4426	},
4427	clearQueue: function( type ) {
4428		return this.queue( type || "fx", [] );
4429	},
4430
4431	// Get a promise resolved when queues of a certain type
4432	// are emptied (fx is the type by default)
4433	promise: function( type, obj ) {
4434		var tmp,
vendor: 37,137 bytes, lines 4435-5860
4435			count = 1,
4436			defer = jQuery.Deferred(),
4437			elements = this,
4438			i = this.length,
4439			resolve = function() {
4440				if ( !( --count ) ) {
4441					defer.resolveWith( elements, [ elements ] );
4442				}
4443			};
4444
4445		if ( typeof type !== "string" ) {
4446			obj = type;
4447			type = undefined;
4448		}
4449		type = type || "fx";
4450
4451		while ( i-- ) {
4452			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4453			if ( tmp && tmp.empty ) {
4454				count++;
4455				tmp.empty.add( resolve );
4456			}
4457		}
4458		resolve();
4459		return defer.promise( obj );
4460	}
4461} );
4462var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4463
4464var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4465
4466
4467var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4468
4469var isHiddenWithinTree = function( elem, el ) {
4470
4471		// isHiddenWithinTree might be called from jQuery#filter function;
4472		// in that case, element will be second argument
4473		elem = el || elem;
4474
4475		// Inline style trumps all
4476		return elem.style.display === "none" ||
4477			elem.style.display === "" &&
4478
4479			// Otherwise, check computed style
4480			// Support: Firefox <=43 - 45
4481			// Disconnected elements can have computed display: none, so first confirm that elem is
4482			// in the document.
4483			jQuery.contains( elem.ownerDocument, elem ) &&
4484
4485			jQuery.css( elem, "display" ) === "none";
4486	};
4487
4488var swap = function( elem, options, callback, args ) {
4489	var ret, name,
4490		old = {};
4491
4492	// Remember the old values, and insert the new ones
4493	for ( name in options ) {
4494		old[ name ] = elem.style[ name ];
4495		elem.style[ name ] = options[ name ];
4496	}
4497
4498	ret = callback.apply( elem, args || [] );
4499
4500	// Revert the old values
4501	for ( name in options ) {
4502		elem.style[ name ] = old[ name ];
4503	}
4504
4505	return ret;
4506};
4507
4508
4509
4510
4511function adjustCSS( elem, prop, valueParts, tween ) {
4512	var adjusted, scale,
4513		maxIterations = 20,
4514		currentValue = tween ?
4515			function() {
4516				return tween.cur();
4517			} :
4518			function() {
4519				return jQuery.css( elem, prop, "" );
4520			},
4521		initial = currentValue(),
4522		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4523
4524		// Starting value computation is required for potential unit mismatches
4525		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4526			rcssNum.exec( jQuery.css( elem, prop ) );
4527
4528	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4529
4530		// Support: Firefox <=54
4531		// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
4532		initial = initial / 2;
4533
4534		// Trust units reported by jQuery.css
4535		unit = unit || initialInUnit[ 3 ];
4536
4537		// Iteratively approximate from a nonzero starting point
4538		initialInUnit = +initial || 1;
4539
4540		while ( maxIterations-- ) {
4541
4542			// Evaluate and update our best guess (doubling guesses that zero out).
4543			// Finish if the scale equals or crosses 1 (making the old*new product non-positive).
4544			jQuery.style( elem, prop, initialInUnit + unit );
4545			if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
4546				maxIterations = 0;
4547			}
4548			initialInUnit = initialInUnit / scale;
4549
4550		}
4551
4552		initialInUnit = initialInUnit * 2;
4553		jQuery.style( elem, prop, initialInUnit + unit );
4554
4555		// Make sure we update the tween properties later on
4556		valueParts = valueParts || [];
4557	}
4558
4559	if ( valueParts ) {
4560		initialInUnit = +initialInUnit || +initial || 0;
4561
4562		// Apply relative offset (+=/-=) if specified
4563		adjusted = valueParts[ 1 ] ?
4564			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4565			+valueParts[ 2 ];
4566		if ( tween ) {
4567			tween.unit = unit;
4568			tween.start = initialInUnit;
4569			tween.end = adjusted;
4570		}
4571	}
4572	return adjusted;
4573}
4574
4575
4576var defaultDisplayMap = {};
4577
4578function getDefaultDisplay( elem ) {
4579	var temp,
4580		doc = elem.ownerDocument,
4581		nodeName = elem.nodeName,
4582		display = defaultDisplayMap[ nodeName ];
4583
4584	if ( display ) {
4585		return display;
4586	}
4587
4588	temp = doc.body.appendChild( doc.createElement( nodeName ) );
4589	display = jQuery.css( temp, "display" );
4590
4591	temp.parentNode.removeChild( temp );
4592
4593	if ( display === "none" ) {
4594		display = "block";
4595	}
4596	defaultDisplayMap[ nodeName ] = display;
4597
4598	return display;
4599}
4600
4601function showHide( elements, show ) {
4602	var display, elem,
4603		values = [],
4604		index = 0,
4605		length = elements.length;
4606
4607	// Determine new display value for elements that need to change
4608	for ( ; index < length; index++ ) {
4609		elem = elements[ index ];
4610		if ( !elem.style ) {
4611			continue;
4612		}
4613
4614		display = elem.style.display;
4615		if ( show ) {
4616
4617			// Since we force visibility upon cascade-hidden elements, an immediate (and slow)
4618			// check is required in this first loop unless we have a nonempty display value (either
4619			// inline or about-to-be-restored)
4620			if ( display === "none" ) {
4621				values[ index ] = dataPriv.get( elem, "display" ) || null;
4622				if ( !values[ index ] ) {
4623					elem.style.display = "";
4624				}
4625			}
4626			if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
4627				values[ index ] = getDefaultDisplay( elem );
4628			}
4629		} else {
4630			if ( display !== "none" ) {
4631				values[ index ] = "none";
4632
4633				// Remember what we're overwriting
4634				dataPriv.set( elem, "display", display );
4635			}
4636		}
4637	}
4638
4639	// Set the display of the elements in a second loop to avoid constant reflow
4640	for ( index = 0; index < length; index++ ) {
4641		if ( values[ index ] != null ) {
4642			elements[ index ].style.display = values[ index ];
4643		}
4644	}
4645
4646	return elements;
4647}
4648
4649jQuery.fn.extend( {
4650	show: function() {
4651		return showHide( this, true );
4652	},
4653	hide: function() {
4654		return showHide( this );
4655	},
4656	toggle: function( state ) {
4657		if ( typeof state === "boolean" ) {
4658			return state ? this.show() : this.hide();
4659		}
4660
4661		return this.each( function() {
4662			if ( isHiddenWithinTree( this ) ) {
4663				jQuery( this ).show();
4664			} else {
4665				jQuery( this ).hide();
4666			}
4667		} );
4668	}
4669} );
4670var rcheckableType = ( /^(?:checkbox|radio)$/i );
4671
4672var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
4673
4674var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
4675
4676
4677
4678// We have to close these tags to support XHTML (#13200)
4679var wrapMap = {
4680
4681	// Support: IE <=9 only
4682	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4683
4684	// XHTML parsers do not magically insert elements in the
4685	// same way that tag soup parsers do. So we cannot shorten
4686	// this by omitting <tbody> or other required elements.
4687	thead: [ 1, "<table>", "</table>" ],
4688	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4689	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4690	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4691
4692	_default: [ 0, "", "" ]
4693};
4694
4695// Support: IE <=9 only
4696wrapMap.optgroup = wrapMap.option;
4697
4698wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4699wrapMap.th = wrapMap.td;
4700
4701
4702function getAll( context, tag ) {
4703
4704	// Support: IE <=9 - 11 only
4705	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4706	var ret;
4707
4708	if ( typeof context.getElementsByTagName !== "undefined" ) {
4709		ret = context.getElementsByTagName( tag || "*" );
4710
4711	} else if ( typeof context.querySelectorAll !== "undefined" ) {
4712		ret = context.querySelectorAll( tag || "*" );
4713
4714	} else {
4715		ret = [];
4716	}
4717
4718	if ( tag === undefined || tag && nodeName( context, tag ) ) {
4719		return jQuery.merge( [ context ], ret );
4720	}
4721
4722	return ret;
4723}
4724
4725
4726// Mark scripts as having already been evaluated
4727function setGlobalEval( elems, refElements ) {
4728	var i = 0,
4729		l = elems.length;
4730
4731	for ( ; i < l; i++ ) {
4732		dataPriv.set(
4733			elems[ i ],
4734			"globalEval",
4735			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4736		);
4737	}
4738}
4739
4740
4741var rhtml = /<|&#?\w+;/;
4742
4743function buildFragment( elems, context, scripts, selection, ignored ) {
4744	var elem, tmp, tag, wrap, contains, j,
4745		fragment = context.createDocumentFragment(),
4746		nodes = [],
4747		i = 0,
4748		l = elems.length;
4749
4750	for ( ; i < l; i++ ) {
4751		elem = elems[ i ];
4752
4753		if ( elem || elem === 0 ) {
4754
4755			// Add nodes directly
4756			if ( toType( elem ) === "object" ) {
4757
4758				// Support: Android <=4.0 only, PhantomJS 1 only
4759				// push.apply(_, arraylike) throws on ancient WebKit
4760				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4761
4762			// Convert non-html into a text node
4763			} else if ( !rhtml.test( elem ) ) {
4764				nodes.push( context.createTextNode( elem ) );
4765
4766			// Convert html into DOM nodes
4767			} else {
4768				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4769
4770				// Deserialize a standard representation
4771				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4772				wrap = wrapMap[ tag ] || wrapMap._default;
4773				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4774
4775				// Descend through wrappers to the right content
4776				j = wrap[ 0 ];
4777				while ( j-- ) {
4778					tmp = tmp.lastChild;
4779				}
4780
4781				// Support: Android <=4.0 only, PhantomJS 1 only
4782				// push.apply(_, arraylike) throws on ancient WebKit
4783				jQuery.merge( nodes, tmp.childNodes );
4784
4785				// Remember the top-level container
4786				tmp = fragment.firstChild;
4787
4788				// Ensure the created nodes are orphaned (#12392)
4789				tmp.textContent = "";
4790			}
4791		}
4792	}
4793
4794	// Remove wrapper from fragment
4795	fragment.textContent = "";
4796
4797	i = 0;
4798	while ( ( elem = nodes[ i++ ] ) ) {
4799
4800		// Skip elements already in the context collection (trac-4087)
4801		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4802			if ( ignored ) {
4803				ignored.push( elem );
4804			}
4805			continue;
4806		}
4807
4808		contains = jQuery.contains( elem.ownerDocument, elem );
4809
4810		// Append to fragment
4811		tmp = getAll( fragment.appendChild( elem ), "script" );
4812
4813		// Preserve script evaluation history
4814		if ( contains ) {
4815			setGlobalEval( tmp );
4816		}
4817
4818		// Capture executables
4819		if ( scripts ) {
4820			j = 0;
4821			while ( ( elem = tmp[ j++ ] ) ) {
4822				if ( rscriptType.test( elem.type || "" ) ) {
4823					scripts.push( elem );
4824				}
4825			}
4826		}
4827	}
4828
4829	return fragment;
4830}
4831
4832
4833( function() {
4834	var fragment = document.createDocumentFragment(),
4835		div = fragment.appendChild( document.createElement( "div" ) ),
4836		input = document.createElement( "input" );
4837
4838	// Support: Android 4.0 - 4.3 only
4839	// Check state lost if the name is set (#11217)
4840	// Support: Windows Web Apps (WWA)
4841	// `name` and `type` must use .setAttribute for WWA (#14901)
4842	input.setAttribute( "type", "radio" );
4843	input.setAttribute( "checked", "checked" );
4844	input.setAttribute( "name", "t" );
4845
4846	div.appendChild( input );
4847
4848	// Support: Android <=4.1 only
4849	// Older WebKit doesn't clone checked state correctly in fragments
4850	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4851
4852	// Support: IE <=11 only
4853	// Make sure textarea (and checkbox) defaultValue is properly cloned
4854	div.innerHTML = "<textarea>x</textarea>";
4855	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4856} )();
4857var documentElement = document.documentElement;
4858
4859
4860
4861var
4862	rkeyEvent = /^key/,
4863	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4864	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4865
4866function returnTrue() {
4867	return true;
4868}
4869
4870function returnFalse() {
4871	return false;
4872}
4873
4874// Support: IE <=9 only
4875// See #13393 for more info
4876function safeActiveElement() {
4877	try {
4878		return document.activeElement;
4879	} catch ( err ) { }
4880}
4881
4882function on( elem, types, selector, data, fn, one ) {
4883	var origFn, type;
4884
4885	// Types can be a map of types/handlers
4886	if ( typeof types === "object" ) {
4887
4888		// ( types-Object, selector, data )
4889		if ( typeof selector !== "string" ) {
4890
4891			// ( types-Object, data )
4892			data = data || selector;
4893			selector = undefined;
4894		}
4895		for ( type in types ) {
4896			on( elem, type, selector, data, types[ type ], one );
4897		}
4898		return elem;
4899	}
4900
4901	if ( data == null && fn == null ) {
4902
4903		// ( types, fn )
4904		fn = selector;
4905		data = selector = undefined;
4906	} else if ( fn == null ) {
4907		if ( typeof selector === "string" ) {
4908
4909			// ( types, selector, fn )
4910			fn = data;
4911			data = undefined;
4912		} else {
4913
4914			// ( types, data, fn )
4915			fn = data;
4916			data = selector;
4917			selector = undefined;
4918		}
4919	}
4920	if ( fn === false ) {
4921		fn = returnFalse;
4922	} else if ( !fn ) {
4923		return elem;
4924	}
4925
4926	if ( one === 1 ) {
4927		origFn = fn;
4928		fn = function( event ) {
4929
4930			// Can use an empty set, since event contains the info
4931			jQuery().off( event );
4932			return origFn.apply( this, arguments );
4933		};
4934
4935		// Use same guid so caller can remove using origFn
4936		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4937	}
4938	return elem.each( function() {
4939		jQuery.event.add( this, types, fn, data, selector );
4940	} );
4941}
4942
4943/*
4944 * Helper functions for managing events -- not part of the public interface.
4945 * Props to Dean Edwards' addEvent library for many of the ideas.
4946 */
4947jQuery.event = {
4948
4949	global: {},
4950
4951	add: function( elem, types, handler, data, selector ) {
4952
4953		var handleObjIn, eventHandle, tmp,
4954			events, t, handleObj,
4955			special, handlers, type, namespaces, origType,
4956			elemData = dataPriv.get( elem );
4957
4958		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4959		if ( !elemData ) {
4960			return;
4961		}
4962
4963		// Caller can pass in an object of custom data in lieu of the handler
4964		if ( handler.handler ) {
4965			handleObjIn = handler;
4966			handler = handleObjIn.handler;
4967			selector = handleObjIn.selector;
4968		}
4969
4970		// Ensure that invalid selectors throw exceptions at attach time
4971		// Evaluate against documentElement in case elem is a non-element node (e.g., document)
4972		if ( selector ) {
4973			jQuery.find.matchesSelector( documentElement, selector );
4974		}
4975
4976		// Make sure that the handler has a unique ID, used to find/remove it later
4977		if ( !handler.guid ) {
4978			handler.guid = jQuery.guid++;
4979		}
4980
4981		// Init the element's event structure and main handler, if this is the first
4982		if ( !( events = elemData.events ) ) {
4983			events = elemData.events = {};
4984		}
4985		if ( !( eventHandle = elemData.handle ) ) {
4986			eventHandle = elemData.handle = function( e ) {
4987
4988				// Discard the second event of a jQuery.event.trigger() and
4989				// when an event is called after a page has unloaded
4990				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4991					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4992			};
4993		}
4994
4995		// Handle multiple events separated by a space
4996		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
4997		t = types.length;
4998		while ( t-- ) {
4999			tmp = rtypenamespace.exec( types[ t ] ) || [];
5000			type = origType = tmp[ 1 ];
5001			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5002
5003			// There *must* be a type, no attaching namespace-only handlers
5004			if ( !type ) {
5005				continue;
5006			}
5007
5008			// If event changes its type, use the special event handlers for the changed type
5009			special = jQuery.event.special[ type ] || {};
5010
5011			// If selector defined, determine special event api type, otherwise given type
5012			type = ( selector ? special.delegateType : special.bindType ) || type;
5013
5014			// Update special based on newly reset type
5015			special = jQuery.event.special[ type ] || {};
5016
5017			// handleObj is passed to all event handlers
5018			handleObj = jQuery.extend( {
5019				type: type,
5020				origType: origType,
5021				data: data,
5022				handler: handler,
5023				guid: handler.guid,
5024				selector: selector,
5025				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5026				namespace: namespaces.join( "." )
5027			}, handleObjIn );
5028
5029			// Init the event handler queue if we're the first
5030			if ( !( handlers = events[ type ] ) ) {
5031				handlers = events[ type ] = [];
5032				handlers.delegateCount = 0;
5033
5034				// Only use addEventListener if the special events handler returns false
5035				if ( !special.setup ||
5036					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5037
5038					if ( elem.addEventListener ) {
5039						elem.addEventListener( type, eventHandle );
5040					}
5041				}
5042			}
5043
5044			if ( special.add ) {
5045				special.add.call( elem, handleObj );
5046
5047				if ( !handleObj.handler.guid ) {
5048					handleObj.handler.guid = handler.guid;
5049				}
5050			}
5051
5052			// Add to the element's handler list, delegates in front
5053			if ( selector ) {
5054				handlers.splice( handlers.delegateCount++, 0, handleObj );
5055			} else {
5056				handlers.push( handleObj );
5057			}
5058
5059			// Keep track of which events have ever been used, for event optimization
5060			jQuery.event.global[ type ] = true;
5061		}
5062
5063	},
5064
5065	// Detach an event or set of events from an element
5066	remove: function( elem, types, handler, selector, mappedTypes ) {
5067
5068		var j, origCount, tmp,
5069			events, t, handleObj,
5070			special, handlers, type, namespaces, origType,
5071			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5072
5073		if ( !elemData || !( events = elemData.events ) ) {
5074			return;
5075		}
5076
5077		// Once for each type.namespace in types; type may be omitted
5078		types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5079		t = types.length;
5080		while ( t-- ) {
5081			tmp = rtypenamespace.exec( types[ t ] ) || [];
5082			type = origType = tmp[ 1 ];
5083			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5084
5085			// Unbind all events (on this namespace, if provided) for the element
5086			if ( !type ) {
5087				for ( type in events ) {
5088					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5089				}
5090				continue;
5091			}
5092
5093			special = jQuery.event.special[ type ] || {};
5094			type = ( selector ? special.delegateType : special.bindType ) || type;
5095			handlers = events[ type ] || [];
5096			tmp = tmp[ 2 ] &&
5097				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5098
5099			// Remove matching events
5100			origCount = j = handlers.length;
5101			while ( j-- ) {
5102				handleObj = handlers[ j ];
5103
5104				if ( ( mappedTypes || origType === handleObj.origType ) &&
5105					( !handler || handler.guid === handleObj.guid ) &&
5106					( !tmp || tmp.test( handleObj.namespace ) ) &&
5107					( !selector || selector === handleObj.selector ||
5108						selector === "**" && handleObj.selector ) ) {
5109					handlers.splice( j, 1 );
5110
5111					if ( handleObj.selector ) {
5112						handlers.delegateCount--;
5113					}
5114					if ( special.remove ) {
5115						special.remove.call( elem, handleObj );
5116					}
5117				}
5118			}
5119
5120			// Remove generic event handler if we removed something and no more handlers exist
5121			// (avoids potential for endless recursion during removal of special event handlers)
5122			if ( origCount && !handlers.length ) {
5123				if ( !special.teardown ||
5124					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5125
5126					jQuery.removeEvent( elem, type, elemData.handle );
5127				}
5128
5129				delete events[ type ];
5130			}
5131		}
5132
5133		// Remove data and the expando if it's no longer used
5134		if ( jQuery.isEmptyObject( events ) ) {
5135			dataPriv.remove( elem, "handle events" );
5136		}
5137	},
5138
5139	dispatch: function( nativeEvent ) {
5140
5141		// Make a writable jQuery.Event from the native event object
5142		var event = jQuery.event.fix( nativeEvent );
5143
5144		var i, j, ret, matched, handleObj, handlerQueue,
5145			args = new Array( arguments.length ),
5146			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
5147			special = jQuery.event.special[ event.type ] || {};
5148
5149		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5150		args[ 0 ] = event;
5151
5152		for ( i = 1; i < arguments.length; i++ ) {
5153			args[ i ] = arguments[ i ];
5154		}
5155
5156		event.delegateTarget = this;
5157
5158		// Call the preDispatch hook for the mapped type, and let it bail if desired
5159		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5160			return;
5161		}
5162
5163		// Determine handlers
5164		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5165
5166		// Run delegates first; they may want to stop propagation beneath us
5167		i = 0;
5168		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5169			event.currentTarget = matched.elem;
5170
5171			j = 0;
5172			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5173				!event.isImmediatePropagationStopped() ) {
5174
5175				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5176				// a subset or equal to those in the bound event (both can have no namespace).
5177				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5178
5179					event.handleObj = handleObj;
5180					event.data = handleObj.data;
5181
5182					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5183						handleObj.handler ).apply( matched.elem, args );
5184
5185					if ( ret !== undefined ) {
5186						if ( ( event.result = ret ) === false ) {
5187							event.preventDefault();
5188							event.stopPropagation();
5189						}
5190					}
5191				}
5192			}
5193		}
5194
5195		// Call the postDispatch hook for the mapped type
5196		if ( special.postDispatch ) {
5197			special.postDispatch.call( this, event );
5198		}
5199
5200		return event.result;
5201	},
5202
5203	handlers: function( event, handlers ) {
5204		var i, handleObj, sel, matchedHandlers, matchedSelectors,
5205			handlerQueue = [],
5206			delegateCount = handlers.delegateCount,
5207			cur = event.target;
5208
5209		// Find delegate handlers
5210		if ( delegateCount &&
5211
5212			// Support: IE <=9
5213			// Black-hole SVG <use> instance trees (trac-13180)
5214			cur.nodeType &&
5215
5216			// Support: Firefox <=42
5217			// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5218			// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5219			// Support: IE 11 only
5220			// ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5221			!( event.type === "click" && event.button >= 1 ) ) {
5222
5223			for ( ; cur !== this; cur = cur.parentNode || this ) {
5224
5225				// Don't check non-elements (#13208)
5226				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5227				if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5228					matchedHandlers = [];
5229					matchedSelectors = {};
5230					for ( i = 0; i < delegateCount; i++ ) {
5231						handleObj = handlers[ i ];
5232
5233						// Don't conflict with Object.prototype properties (#13203)
5234						sel = handleObj.selector + " ";
5235
5236						if ( matchedSelectors[ sel ] === undefined ) {
5237							matchedSelectors[ sel ] = handleObj.needsContext ?
5238								jQuery( sel, this ).index( cur ) > -1 :
5239								jQuery.find( sel, this, null, [ cur ] ).length;
5240						}
5241						if ( matchedSelectors[ sel ] ) {
5242							matchedHandlers.push( handleObj );
5243						}
5244					}
5245					if ( matchedHandlers.length ) {
5246						handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5247					}
5248				}
5249			}
5250		}
5251
5252		// Add the remaining (directly-bound) handlers
5253		cur = this;
5254		if ( delegateCount < handlers.length ) {
5255			handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5256		}
5257
5258		return handlerQueue;
5259	},
5260
5261	addProp: function( name, hook ) {
5262		Object.defineProperty( jQuery.Event.prototype, name, {
5263			enumerable: true,
5264			configurable: true,
5265
5266			get: isFunction( hook ) ?
5267				function() {
5268					if ( this.originalEvent ) {
5269							return hook( this.originalEvent );
5270					}
5271				} :
5272				function() {
5273					if ( this.originalEvent ) {
5274							return this.originalEvent[ name ];
5275					}
5276				},
5277
5278			set: function( value ) {
5279				Object.defineProperty( this, name, {
5280					enumerable: true,
5281					configurable: true,
5282					writable: true,
5283					value: value
5284				} );
5285			}
5286		} );
5287	},
5288
5289	fix: function( originalEvent ) {
5290		return originalEvent[ jQuery.expando ] ?
5291			originalEvent :
5292			new jQuery.Event( originalEvent );
5293	},
5294
5295	special: {
5296		load: {
5297
5298			// Prevent triggered image.load events from bubbling to window.load
5299			noBubble: true
5300		},
5301		focus: {
5302
5303			// Fire native event if possible so blur/focus sequence is correct
5304			trigger: function() {
5305				if ( this !== safeActiveElement() && this.focus ) {
5306					this.focus();
5307					return false;
5308				}
5309			},
5310			delegateType: "focusin"
5311		},
5312		blur: {
5313			trigger: function() {
5314				if ( this === safeActiveElement() && this.blur ) {
5315					this.blur();
5316					return false;
5317				}
5318			},
5319			delegateType: "focusout"
5320		},
5321		click: {
5322
5323			// For checkbox, fire native event so checked state will be right
5324			trigger: function() {
5325				if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
5326					this.click();
5327					return false;
5328				}
5329			},
5330
5331			// For cross-browser consistency, don't fire native .click() on links
5332			_default: function( event ) {
5333				return nodeName( event.target, "a" );
5334			}
5335		},
5336
5337		beforeunload: {
5338			postDispatch: function( event ) {
5339
5340				// Support: Firefox 20+
5341				// Firefox doesn't alert if the returnValue field is not set.
5342				if ( event.result !== undefined && event.originalEvent ) {
5343					event.originalEvent.returnValue = event.result;
5344				}
5345			}
5346		}
5347	}
5348};
5349
5350jQuery.removeEvent = function( elem, type, handle ) {
5351
5352	// This "if" is needed for plain objects
5353	if ( elem.removeEventListener ) {
5354		elem.removeEventListener( type, handle );
5355	}
5356};
5357
5358jQuery.Event = function( src, props ) {
5359
5360	// Allow instantiation without the 'new' keyword
5361	if ( !( this instanceof jQuery.Event ) ) {
5362		return new jQuery.Event( src, props );
5363	}
5364
5365	// Event object
5366	if ( src && src.type ) {
5367		this.originalEvent = src;
5368		this.type = src.type;
5369
5370		// Events bubbling up the document may have been marked as prevented
5371		// by a handler lower down the tree; reflect the correct value.
5372		this.isDefaultPrevented = src.defaultPrevented ||
5373				src.defaultPrevented === undefined &&
5374
5375				// Support: Android <=2.3 only
5376				src.returnValue === false ?
5377			returnTrue :
5378			returnFalse;
5379
5380		// Create target properties
5381		// Support: Safari <=6 - 7 only
5382		// Target should not be a text node (#504, #13143)
5383		this.target = ( src.target && src.target.nodeType === 3 ) ?
5384			src.target.parentNode :
5385			src.target;
5386
5387		this.currentTarget = src.currentTarget;
5388		this.relatedTarget = src.relatedTarget;
5389
5390	// Event type
5391	} else {
5392		this.type = src;
5393	}
5394
5395	// Put explicitly provided properties onto the event object
5396	if ( props ) {
5397		jQuery.extend( this, props );
5398	}
5399
5400	// Create a timestamp if incoming event doesn't have one
5401	this.timeStamp = src && src.timeStamp || Date.now();
5402
5403	// Mark it as fixed
5404	this[ jQuery.expando ] = true;
5405};
5406
5407// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5408// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5409jQuery.Event.prototype = {
5410	constructor: jQuery.Event,
5411	isDefaultPrevented: returnFalse,
5412	isPropagationStopped: returnFalse,
5413	isImmediatePropagationStopped: returnFalse,
5414	isSimulated: false,
5415
5416	preventDefault: function() {
5417		var e = this.originalEvent;
5418
5419		this.isDefaultPrevented = returnTrue;
5420
5421		if ( e && !this.isSimulated ) {
5422			e.preventDefault();
5423		}
5424	},
5425	stopPropagation: function() {
5426		var e = this.originalEvent;
5427
5428		this.isPropagationStopped = returnTrue;
5429
5430		if ( e && !this.isSimulated ) {
5431			e.stopPropagation();
5432		}
5433	},
5434	stopImmediatePropagation: function() {
5435		var e = this.originalEvent;
5436
5437		this.isImmediatePropagationStopped = returnTrue;
5438
5439		if ( e && !this.isSimulated ) {
5440			e.stopImmediatePropagation();
5441		}
5442
5443		this.stopPropagation();
5444	}
5445};
5446
5447// Includes all common event props including KeyEvent and MouseEvent specific props
5448jQuery.each( {
5449	altKey: true,
5450	bubbles: true,
5451	cancelable: true,
5452	changedTouches: true,
5453	ctrlKey: true,
5454	detail: true,
5455	eventPhase: true,
5456	metaKey: true,
5457	pageX: true,
5458	pageY: true,
5459	shiftKey: true,
5460	view: true,
5461	"char": true,
5462	charCode: true,
5463	key: true,
5464	keyCode: true,
5465	button: true,
5466	buttons: true,
5467	clientX: true,
5468	clientY: true,
5469	offsetX: true,
5470	offsetY: true,
5471	pointerId: true,
5472	pointerType: true,
5473	screenX: true,
5474	screenY: true,
5475	targetTouches: true,
5476	toElement: true,
5477	touches: true,
5478
5479	which: function( event ) {
5480		var button = event.button;
5481
5482		// Add which for key events
5483		if ( event.which == null && rkeyEvent.test( event.type ) ) {
5484			return event.charCode != null ? event.charCode : event.keyCode;
5485		}
5486
5487		// Add which for click: 1 === left; 2 === middle; 3 === right
5488		if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
5489			if ( button & 1 ) {
5490				return 1;
5491			}
5492
5493			if ( button & 2 ) {
5494				return 3;
5495			}
5496
5497			if ( button & 4 ) {
5498				return 2;
5499			}
5500
5501			return 0;
5502		}
5503
5504		return event.which;
5505	}
5506}, jQuery.event.addProp );
5507
5508// Create mouseenter/leave events using mouseover/out and event-time checks
5509// so that event delegation works in jQuery.
5510// Do the same for pointerenter/pointerleave and pointerover/pointerout
5511//
5512// Support: Safari 7 only
5513// Safari sends mouseenter too often; see:
5514// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
5515// for the description of the bug (it existed in older Chrome versions as well).
5516jQuery.each( {
5517	mouseenter: "mouseover",
5518	mouseleave: "mouseout",
5519	pointerenter: "pointerover",
5520	pointerleave: "pointerout"
5521}, function( orig, fix ) {
5522	jQuery.event.special[ orig ] = {
5523		delegateType: fix,
5524		bindType: fix,
5525
5526		handle: function( event ) {
5527			var ret,
5528				target = this,
5529				related = event.relatedTarget,
5530				handleObj = event.handleObj;
5531
5532			// For mouseenter/leave call the handler if related is outside the target.
5533			// NB: No relatedTarget if the mouse left/entered the browser window
5534			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5535				event.type = handleObj.origType;
5536				ret = handleObj.handler.apply( this, arguments );
5537				event.type = fix;
5538			}
5539			return ret;
5540		}
5541	};
5542} );
5543
5544jQuery.fn.extend( {
5545
5546	on: function( types, selector, data, fn ) {
5547		return on( this, types, selector, data, fn );
5548	},
5549	one: function( types, selector, data, fn ) {
5550		return on( this, types, selector, data, fn, 1 );
5551	},
5552	off: function( types, selector, fn ) {
5553		var handleObj, type;
5554		if ( types && types.preventDefault && types.handleObj ) {
5555
5556			// ( event )  dispatched jQuery.Event
5557			handleObj = types.handleObj;
5558			jQuery( types.delegateTarget ).off(
5559				handleObj.namespace ?
5560					handleObj.origType + "." + handleObj.namespace :
5561					handleObj.origType,
5562				handleObj.selector,
5563				handleObj.handler
5564			);
5565			return this;
5566		}
5567		if ( typeof types === "object" ) {
5568
5569			// ( types-object [, selector] )
5570			for ( type in types ) {
5571				this.off( type, selector, types[ type ] );
5572			}
5573			return this;
5574		}
5575		if ( selector === false || typeof selector === "function" ) {
5576
5577			// ( types [, fn] )
5578			fn = selector;
5579			selector = undefined;
5580		}
5581		if ( fn === false ) {
5582			fn = returnFalse;
5583		}
5584		return this.each( function() {
5585			jQuery.event.remove( this, types, fn, selector );
5586		} );
5587	}
5588} );
5589
5590
5591var
5592
5593	/* eslint-disable max-len */
5594
5595	// See https://github.com/eslint/eslint/issues/3229
5596	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
5597
5598	/* eslint-enable */
5599
5600	// Support: IE <=10 - 11, Edge 12 - 13 only
5601	// In IE/Edge using regex groups here causes severe slowdowns.
5602	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5603	rnoInnerhtml = /<script|<style|<link/i,
5604
5605	// checked="checked" or checked
5606	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5607	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5608
5609// Prefer a tbody over its parent table for containing new rows
5610function manipulationTarget( elem, content ) {
5611	if ( nodeName( elem, "table" ) &&
5612		nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5613
5614		return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
5615	}
5616
5617	return elem;
5618}
5619
5620// Replace/restore the type attribute of script elements for safe DOM manipulation
5621function disableScript( elem ) {
5622	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5623	return elem;
5624}
5625function restoreScript( elem ) {
5626	if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
5627		elem.type = elem.type.slice( 5 );
5628	} else {
5629		elem.removeAttribute( "type" );
5630	}
5631
5632	return elem;
5633}
5634
5635function cloneCopyEvent( src, dest ) {
5636	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5637
5638	if ( dest.nodeType !== 1 ) {
5639		return;
5640	}
5641
5642	// 1. Copy private data: events, handlers, etc.
5643	if ( dataPriv.hasData( src ) ) {
5644		pdataOld = dataPriv.access( src );
5645		pdataCur = dataPriv.set( dest, pdataOld );
5646		events = pdataOld.events;
5647
5648		if ( events ) {
5649			delete pdataCur.handle;
5650			pdataCur.events = {};
5651
5652			for ( type in events ) {
5653				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5654					jQuery.event.add( dest, type, events[ type ][ i ] );
5655				}
5656			}
5657		}
5658	}
5659
5660	// 2. Copy user data
5661	if ( dataUser.hasData( src ) ) {
5662		udataOld = dataUser.access( src );
5663		udataCur = jQuery.extend( {}, udataOld );
5664
5665		dataUser.set( dest, udataCur );
5666	}
5667}
5668
5669// Fix IE bugs, see support tests
5670function fixInput( src, dest ) {
5671	var nodeName = dest.nodeName.toLowerCase();
5672
5673	// Fails to persist the checked state of a cloned checkbox or radio button.
5674	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5675		dest.checked = src.checked;
5676
5677	// Fails to return the selected option to the default selected state when cloning options
5678	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5679		dest.defaultValue = src.defaultValue;
5680	}
5681}
5682
5683function domManip( collection, args, callback, ignored ) {
5684
5685	// Flatten any nested arrays
5686	args = concat.apply( [], args );
5687
5688	var fragment, first, scripts, hasScripts, node, doc,
5689		i = 0,
5690		l = collection.length,
5691		iNoClone = l - 1,
5692		value = args[ 0 ],
5693		valueIsFunction = isFunction( value );
5694
5695	// We can't cloneNode fragments that contain checked, in WebKit
5696	if ( valueIsFunction ||
5697			( l > 1 && typeof value === "string" &&
5698				!support.checkClone && rchecked.test( value ) ) ) {
5699		return collection.each( function( index ) {
5700			var self = collection.eq( index );
5701			if ( valueIsFunction ) {
5702				args[ 0 ] = value.call( this, index, self.html() );
5703			}
5704			domManip( self, args, callback, ignored );
5705		} );
5706	}
5707
5708	if ( l ) {
5709		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5710		first = fragment.firstChild;
5711
5712		if ( fragment.childNodes.length === 1 ) {
5713			fragment = first;
5714		}
5715
5716		// Require either new content or an interest in ignored elements to invoke the callback
5717		if ( first || ignored ) {
5718			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5719			hasScripts = scripts.length;
5720
5721			// Use the original fragment for the last item
5722			// instead of the first because it can end up
5723			// being emptied incorrectly in certain situations (#8070).
5724			for ( ; i < l; i++ ) {
5725				node = fragment;
5726
5727				if ( i !== iNoClone ) {
5728					node = jQuery.clone( node, true, true );
5729
5730					// Keep references to cloned scripts for later restoration
5731					if ( hasScripts ) {
5732
5733						// Support: Android <=4.0 only, PhantomJS 1 only
5734						// push.apply(_, arraylike) throws on ancient WebKit
5735						jQuery.merge( scripts, getAll( node, "script" ) );
5736					}
5737				}
5738
5739				callback.call( collection[ i ], node, i );
5740			}
5741
5742			if ( hasScripts ) {
5743				doc = scripts[ scripts.length - 1 ].ownerDocument;
5744
5745				// Reenable scripts
5746				jQuery.map( scripts, restoreScript );
5747
5748				// Evaluate executable scripts on first document insertion
5749				for ( i = 0; i < hasScripts; i++ ) {
5750					node = scripts[ i ];
5751					if ( rscriptType.test( node.type || "" ) &&
5752						!dataPriv.access( node, "globalEval" ) &&
5753						jQuery.contains( doc, node ) ) {
5754
5755						if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
5756
5757							// Optional AJAX dependency, but won't run scripts if not present
5758							if ( jQuery._evalUrl ) {
5759								jQuery._evalUrl( node.src );
5760							}
5761						} else {
5762							DOMEval( node.textContent.replace( rcleanScript, "" ), doc, node );
5763						}
5764					}
5765				}
5766			}
5767		}
5768	}
5769
5770	return collection;
5771}
5772
5773function remove( elem, selector, keepData ) {
5774	var node,
5775		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5776		i = 0;
5777
5778	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5779		if ( !keepData && node.nodeType === 1 ) {
5780			jQuery.cleanData( getAll( node ) );
5781		}
5782
5783		if ( node.parentNode ) {
5784			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5785				setGlobalEval( getAll( node, "script" ) );
5786			}
5787			node.parentNode.removeChild( node );
5788		}
5789	}
5790
5791	return elem;
5792}
5793
5794jQuery.extend( {
5795	htmlPrefilter: function( html ) {
5796		return html.replace( rxhtmlTag, "<$1></$2>" );
5797	},
5798
5799	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5800		var i, l, srcElements, destElements,
5801			clone = elem.cloneNode( true ),
5802			inPage = jQuery.contains( elem.ownerDocument, elem );
5803
5804		// Fix IE cloning issues
5805		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5806				!jQuery.isXMLDoc( elem ) ) {
5807
5808			// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
5809			destElements = getAll( clone );
5810			srcElements = getAll( elem );
5811
5812			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5813				fixInput( srcElements[ i ], destElements[ i ] );
5814			}
5815		}
5816
5817		// Copy the events from the original to the clone
5818		if ( dataAndEvents ) {
5819			if ( deepDataAndEvents ) {
5820				srcElements = srcElements || getAll( elem );
5821				destElements = destElements || getAll( clone );
5822
5823				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5824					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5825				}
5826			} else {
5827				cloneCopyEvent( elem, clone );
5828			}
5829		}
5830
5831		// Preserve script evaluation history
5832		destElements = getAll( clone, "script" );
5833		if ( destElements.length > 0 ) {
5834			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5835		}
5836
5837		// Return the cloned set
5838		return clone;
5839	},
5840
5841	cleanData: function( elems ) {
5842		var data, elem, type,
5843			special = jQuery.event.special,
5844			i = 0;
5845
5846		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5847			if ( acceptData( elem ) ) {
5848				if ( ( data = elem[ dataPriv.expando ] ) ) {
5849					if ( data.events ) {
5850						for ( type in data.events ) {
5851							if ( special[ type ] ) {
5852								jQuery.event.remove( elem, type );
5853
5854							// This is a shortcut to avoid jQuery.event.remove's overhead
5855							} else {
5856								jQuery.removeEvent( elem, type, data.handle );
5857							}
5858						}
5859					}
5860
vendor: 1,119 bytes, lines 5861-5905
5861					// Support: Chrome <=35 - 45+
5862					// Assign undefined instead of using delete, see Data#remove
5863					elem[ dataPriv.expando ] = undefined;
5864				}
5865				if ( elem[ dataUser.expando ] ) {
5866
5867					// Support: Chrome <=35 - 45+
5868					// Assign undefined instead of using delete, see Data#remove
5869					elem[ dataUser.expando ] = undefined;
5870				}
5871			}
5872		}
5873	}
5874} );
5875
5876jQuery.fn.extend( {
5877	detach: function( selector ) {
5878		return remove( this, selector, true );
5879	},
5880
5881	remove: function( selector ) {
5882		return remove( this, selector );
5883	},
5884
5885	text: function( value ) {
5886		return access( this, function( value ) {
5887			return value === undefined ?
5888				jQuery.text( this ) :
5889				this.empty().each( function() {
5890					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5891						this.textContent = value;
5892					}
5893				} );
5894		}, null, value, arguments.length );
5895	},
5896
5897	append: function() {
5898		return domManip( this, arguments, function( elem ) {
5899			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5900				var target = manipulationTarget( this, elem );
5901				target.appendChild( elem );
5902			}
5903		} );
5904	},
5905
vendor: 52,786 bytes, lines 5906-7960
5906	prepend: function() {
5907		return domManip( this, arguments, function( elem ) {
5908			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5909				var target = manipulationTarget( this, elem );
5910				target.insertBefore( elem, target.firstChild );
5911			}
5912		} );
5913	},
5914
5915	before: function() {
5916		return domManip( this, arguments, function( elem ) {
5917			if ( this.parentNode ) {
5918				this.parentNode.insertBefore( elem, this );
5919			}
5920		} );
5921	},
5922
5923	after: function() {
5924		return domManip( this, arguments, function( elem ) {
5925			if ( this.parentNode ) {
5926				this.parentNode.insertBefore( elem, this.nextSibling );
5927			}
5928		} );
5929	},
5930
5931	empty: function() {
5932		var elem,
5933			i = 0;
5934
5935		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5936			if ( elem.nodeType === 1 ) {
5937
5938				// Prevent memory leaks
5939				jQuery.cleanData( getAll( elem, false ) );
5940
5941				// Remove any remaining nodes
5942				elem.textContent = "";
5943			}
5944		}
5945
5946		return this;
5947	},
5948
5949	clone: function( dataAndEvents, deepDataAndEvents ) {
5950		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5951		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5952
5953		return this.map( function() {
5954			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5955		} );
5956	},
5957
5958	html: function( value ) {
5959		return access( this, function( value ) {
5960			var elem = this[ 0 ] || {},
5961				i = 0,
5962				l = this.length;
5963
5964			if ( value === undefined && elem.nodeType === 1 ) {
5965				return elem.innerHTML;
5966			}
5967
5968			// See if we can take a shortcut and just use innerHTML
5969			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5970				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5971
5972				value = jQuery.htmlPrefilter( value );
5973
5974				try {
5975					for ( ; i < l; i++ ) {
5976						elem = this[ i ] || {};
5977
5978						// Remove element nodes and prevent memory leaks
5979						if ( elem.nodeType === 1 ) {
5980							jQuery.cleanData( getAll( elem, false ) );
5981							elem.innerHTML = value;
5982						}
5983					}
5984
5985					elem = 0;
5986
5987				// If using innerHTML throws an exception, use the fallback method
5988				} catch ( e ) {}
5989			}
5990
5991			if ( elem ) {
5992				this.empty().append( value );
5993			}
5994		}, null, value, arguments.length );
5995	},
5996
5997	replaceWith: function() {
5998		var ignored = [];
5999
6000		// Make the changes, replacing each non-ignored context element with the new content
6001		return domManip( this, arguments, function( elem ) {
6002			var parent = this.parentNode;
6003
6004			if ( jQuery.inArray( this, ignored ) < 0 ) {
6005				jQuery.cleanData( getAll( this ) );
6006				if ( parent ) {
6007					parent.replaceChild( elem, this );
6008				}
6009			}
6010
6011		// Force callback invocation
6012		}, ignored );
6013	}
6014} );
6015
6016jQuery.each( {
6017	appendTo: "append",
6018	prependTo: "prepend",
6019	insertBefore: "before",
6020	insertAfter: "after",
6021	replaceAll: "replaceWith"
6022}, function( name, original ) {
6023	jQuery.fn[ name ] = function( selector ) {
6024		var elems,
6025			ret = [],
6026			insert = jQuery( selector ),
6027			last = insert.length - 1,
6028			i = 0;
6029
6030		for ( ; i <= last; i++ ) {
6031			elems = i === last ? this : this.clone( true );
6032			jQuery( insert[ i ] )[ original ]( elems );
6033
6034			// Support: Android <=4.0 only, PhantomJS 1 only
6035			// .get() because push.apply(_, arraylike) throws on ancient WebKit
6036			push.apply( ret, elems.get() );
6037		}
6038
6039		return this.pushStack( ret );
6040	};
6041} );
6042var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6043
6044var getStyles = function( elem ) {
6045
6046		// Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6047		// IE throws on elements created in popups
6048		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6049		var view = elem.ownerDocument.defaultView;
6050
6051		if ( !view || !view.opener ) {
6052			view = window;
6053		}
6054
6055		return view.getComputedStyle( elem );
6056	};
6057
6058var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6059
6060
6061
6062( function() {
6063
6064	// Executing both pixelPosition & boxSizingReliable tests require only one layout
6065	// so they're executed at the same time to save the second computation.
6066	function computeStyleTests() {
6067
6068		// This is a singleton, we need to execute it only once
6069		if ( !div ) {
6070			return;
6071		}
6072
6073		container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6074			"margin-top:1px;padding:0;border:0";
6075		div.style.cssText =
6076			"position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6077			"margin:auto;border:1px;padding:1px;" +
6078			"width:60%;top:1%";
6079		documentElement.appendChild( container ).appendChild( div );
6080
6081		var divStyle = window.getComputedStyle( div );
6082		pixelPositionVal = divStyle.top !== "1%";
6083
6084		// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6085		reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6086
6087		// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6088		// Some styles come back with percentage values, even though they shouldn't
6089		div.style.right = "60%";
6090		pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6091
6092		// Support: IE 9 - 11 only
6093		// Detect misreporting of content dimensions for box-sizing:border-box elements
6094		boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6095
6096		// Support: IE 9 only
6097		// Detect overflow:scroll screwiness (gh-3699)
6098		div.style.position = "absolute";
6099		scrollboxSizeVal = div.offsetWidth === 36 || "absolute";
6100
6101		documentElement.removeChild( container );
6102
6103		// Nullify the div so it wouldn't be stored in the memory and
6104		// it will also be a sign that checks already performed
6105		div = null;
6106	}
6107
6108	function roundPixelMeasures( measure ) {
6109		return Math.round( parseFloat( measure ) );
6110	}
6111
6112	var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6113		reliableMarginLeftVal,
6114		container = document.createElement( "div" ),
6115		div = document.createElement( "div" );
6116
6117	// Finish early in limited (non-browser) environments
6118	if ( !div.style ) {
6119		return;
6120	}
6121
6122	// Support: IE <=9 - 11 only
6123	// Style of cloned element affects source element cloned (#8908)
6124	div.style.backgroundClip = "content-box";
6125	div.cloneNode( true ).style.backgroundClip = "";
6126	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6127
6128	jQuery.extend( support, {
6129		boxSizingReliable: function() {
6130			computeStyleTests();
6131			return boxSizingReliableVal;
6132		},
6133		pixelBoxStyles: function() {
6134			computeStyleTests();
6135			return pixelBoxStylesVal;
6136		},
6137		pixelPosition: function() {
6138			computeStyleTests();
6139			return pixelPositionVal;
6140		},
6141		reliableMarginLeft: function() {
6142			computeStyleTests();
6143			return reliableMarginLeftVal;
6144		},
6145		scrollboxSize: function() {
6146			computeStyleTests();
6147			return scrollboxSizeVal;
6148		}
6149	} );
6150} )();
6151
6152
6153function curCSS( elem, name, computed ) {
6154	var width, minWidth, maxWidth, ret,
6155
6156		// Support: Firefox 51+
6157		// Retrieving style before computed somehow
6158		// fixes an issue with getting wrong values
6159		// on detached elements
6160		style = elem.style;
6161
6162	computed = computed || getStyles( elem );
6163
6164	// getPropertyValue is needed for:
6165	//   .css('filter') (IE 9 only, #12537)
6166	//   .css('--customProperty) (#3144)
6167	if ( computed ) {
6168		ret = computed.getPropertyValue( name ) || computed[ name ];
6169
6170		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6171			ret = jQuery.style( elem, name );
6172		}
6173
6174		// A tribute to the "awesome hack by Dean Edwards"
6175		// Android Browser returns percentage for some values,
6176		// but width seems to be reliably pixels.
6177		// This is against the CSSOM draft spec:
6178		// https://drafts.csswg.org/cssom/#resolved-values
6179		if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
6180
6181			// Remember the original values
6182			width = style.width;
6183			minWidth = style.minWidth;
6184			maxWidth = style.maxWidth;
6185
6186			// Put in the new values to get a computed value out
6187			style.minWidth = style.maxWidth = style.width = ret;
6188			ret = computed.width;
6189
6190			// Revert the changed values
6191			style.width = width;
6192			style.minWidth = minWidth;
6193			style.maxWidth = maxWidth;
6194		}
6195	}
6196
6197	return ret !== undefined ?
6198
6199		// Support: IE <=9 - 11 only
6200		// IE returns zIndex value as an integer.
6201		ret + "" :
6202		ret;
6203}
6204
6205
6206function addGetHookIf( conditionFn, hookFn ) {
6207
6208	// Define the hook, we'll check on the first run if it's really needed.
6209	return {
6210		get: function() {
6211			if ( conditionFn() ) {
6212
6213				// Hook not needed (or it's not possible to use it due
6214				// to missing dependency), remove it.
6215				delete this.get;
6216				return;
6217			}
6218
6219			// Hook needed; redefine it so that the support test is not executed again.
6220			return ( this.get = hookFn ).apply( this, arguments );
6221		}
6222	};
6223}
6224
6225
6226var
6227
6228	// Swappable if display is none or starts with table
6229	// except "table", "table-cell", or "table-caption"
6230	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6231	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6232	rcustomProp = /^--/,
6233	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6234	cssNormalTransform = {
6235		letterSpacing: "0",
6236		fontWeight: "400"
6237	},
6238
6239	cssPrefixes = [ "Webkit", "Moz", "ms" ],
6240	emptyStyle = document.createElement( "div" ).style;
6241
6242// Return a css property mapped to a potentially vendor prefixed property
6243function vendorPropName( name ) {
6244
6245	// Shortcut for names that are not vendor prefixed
6246	if ( name in emptyStyle ) {
6247		return name;
6248	}
6249
6250	// Check for vendor prefixed names
6251	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
6252		i = cssPrefixes.length;
6253
6254	while ( i-- ) {
6255		name = cssPrefixes[ i ] + capName;
6256		if ( name in emptyStyle ) {
6257			return name;
6258		}
6259	}
6260}
6261
6262// Return a property mapped along what jQuery.cssProps suggests or to
6263// a vendor prefixed property.
6264function finalPropName( name ) {
6265	var ret = jQuery.cssProps[ name ];
6266	if ( !ret ) {
6267		ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
6268	}
6269	return ret;
6270}
6271
6272function setPositiveNumber( elem, value, subtract ) {
6273
6274	// Any relative (+/-) values have already been
6275	// normalized at this point
6276	var matches = rcssNum.exec( value );
6277	return matches ?
6278
6279		// Guard against undefined "subtract", e.g., when used as in cssHooks
6280		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
6281		value;
6282}
6283
6284function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
6285	var i = dimension === "width" ? 1 : 0,
6286		extra = 0,
6287		delta = 0;
6288
6289	// Adjustment may not be necessary
6290	if ( box === ( isBorderBox ? "border" : "content" ) ) {
6291		return 0;
6292	}
6293
6294	for ( ; i < 4; i += 2 ) {
6295
6296		// Both box models exclude margin
6297		if ( box === "margin" ) {
6298			delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
6299		}
6300
6301		// If we get here with a content-box, we're seeking "padding" or "border" or "margin"
6302		if ( !isBorderBox ) {
6303
6304			// Add padding
6305			delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6306
6307			// For "border" or "margin", add border
6308			if ( box !== "padding" ) {
6309				delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6310
6311			// But still keep track of it otherwise
6312			} else {
6313				extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6314			}
6315
6316		// If we get here with a border-box (content + padding + border), we're seeking "content" or
6317		// "padding" or "margin"
6318		} else {
6319
6320			// For "content", subtract padding
6321			if ( box === "content" ) {
6322				delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6323			}
6324
6325			// For "content" or "padding", subtract border
6326			if ( box !== "margin" ) {
6327				delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6328			}
6329		}
6330	}
6331
6332	// Account for positive content-box scroll gutter when requested by providing computedVal
6333	if ( !isBorderBox && computedVal >= 0 ) {
6334
6335		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
6336		// Assuming integer scroll gutter, subtract the rest and round down
6337		delta += Math.max( 0, Math.ceil(
6338			elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6339			computedVal -
6340			delta -
6341			extra -
6342			0.5
6343		) );
6344	}
6345
6346	return delta;
6347}
6348
6349function getWidthOrHeight( elem, dimension, extra ) {
6350
6351	// Start with computed style
6352	var styles = getStyles( elem ),
6353		val = curCSS( elem, dimension, styles ),
6354		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6355		valueIsBorderBox = isBorderBox;
6356
6357	// Support: Firefox <=54
6358	// Return a confounding non-pixel value or feign ignorance, as appropriate.
6359	if ( rnumnonpx.test( val ) ) {
6360		if ( !extra ) {
6361			return val;
6362		}
6363		val = "auto";
6364	}
6365
6366	// Check for style in case a browser which returns unreliable values
6367	// for getComputedStyle silently falls back to the reliable elem.style
6368	valueIsBorderBox = valueIsBorderBox &&
6369		( support.boxSizingReliable() || val === elem.style[ dimension ] );
6370
6371	// Fall back to offsetWidth/offsetHeight when value is "auto"
6372	// This happens for inline elements with no explicit setting (gh-3571)
6373	// Support: Android <=4.1 - 4.3 only
6374	// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
6375	if ( val === "auto" ||
6376		!parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) {
6377
6378		val = elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ];
6379
6380		// offsetWidth/offsetHeight provide border-box values
6381		valueIsBorderBox = true;
6382	}
6383
6384	// Normalize "" and auto
6385	val = parseFloat( val ) || 0;
6386
6387	// Adjust for the element's box model
6388	return ( val +
6389		boxModelAdjustment(
6390			elem,
6391			dimension,
6392			extra || ( isBorderBox ? "border" : "content" ),
6393			valueIsBorderBox,
6394			styles,
6395
6396			// Provide the current computed size to request scroll gutter calculation (gh-3589)
6397			val
6398		)
6399	) + "px";
6400}
6401
6402jQuery.extend( {
6403
6404	// Add in style property hooks for overriding the default
6405	// behavior of getting and setting a style property
6406	cssHooks: {
6407		opacity: {
6408			get: function( elem, computed ) {
6409				if ( computed ) {
6410
6411					// We should always get a number back from opacity
6412					var ret = curCSS( elem, "opacity" );
6413					return ret === "" ? "1" : ret;
6414				}
6415			}
6416		}
6417	},
6418
6419	// Don't automatically add "px" to these possibly-unitless properties
6420	cssNumber: {
6421		"animationIterationCount": true,
6422		"columnCount": true,
6423		"fillOpacity": true,
6424		"flexGrow": true,
6425		"flexShrink": true,
6426		"fontWeight": true,
6427		"lineHeight": true,
6428		"opacity": true,
6429		"order": true,
6430		"orphans": true,
6431		"widows": true,
6432		"zIndex": true,
6433		"zoom": true
6434	},
6435
6436	// Add in properties whose names you wish to fix before
6437	// setting or getting the value
6438	cssProps: {},
6439
6440	// Get and set the style property on a DOM Node
6441	style: function( elem, name, value, extra ) {
6442
6443		// Don't set styles on text and comment nodes
6444		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6445			return;
6446		}
6447
6448		// Make sure that we're working with the right name
6449		var ret, type, hooks,
6450			origName = camelCase( name ),
6451			isCustomProp = rcustomProp.test( name ),
6452			style = elem.style;
6453
6454		// Make sure that we're working with the right name. We don't
6455		// want to query the value if it is a CSS custom property
6456		// since they are user-defined.
6457		if ( !isCustomProp ) {
6458			name = finalPropName( origName );
6459		}
6460
6461		// Gets hook for the prefixed version, then unprefixed version
6462		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6463
6464		// Check if we're setting a value
6465		if ( value !== undefined ) {
6466			type = typeof value;
6467
6468			// Convert "+=" or "-=" to relative numbers (#7345)
6469			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6470				value = adjustCSS( elem, name, ret );
6471
6472				// Fixes bug #9237
6473				type = "number";
6474			}
6475
6476			// Make sure that null and NaN values aren't set (#7116)
6477			if ( value == null || value !== value ) {
6478				return;
6479			}
6480
6481			// If a number was passed in, add the unit (except for certain CSS properties)
6482			if ( type === "number" ) {
6483				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6484			}
6485
6486			// background-* props affect original clone's values
6487			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6488				style[ name ] = "inherit";
6489			}
6490
6491			// If a hook was provided, use that value, otherwise just set the specified value
6492			if ( !hooks || !( "set" in hooks ) ||
6493				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6494
6495				if ( isCustomProp ) {
6496					style.setProperty( name, value );
6497				} else {
6498					style[ name ] = value;
6499				}
6500			}
6501
6502		} else {
6503
6504			// If a hook was provided get the non-computed value from there
6505			if ( hooks && "get" in hooks &&
6506				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6507
6508				return ret;
6509			}
6510
6511			// Otherwise just get the value from the style object
6512			return style[ name ];
6513		}
6514	},
6515
6516	css: function( elem, name, extra, styles ) {
6517		var val, num, hooks,
6518			origName = camelCase( name ),
6519			isCustomProp = rcustomProp.test( name );
6520
6521		// Make sure that we're working with the right name. We don't
6522		// want to modify the value if it is a CSS custom property
6523		// since they are user-defined.
6524		if ( !isCustomProp ) {
6525			name = finalPropName( origName );
6526		}
6527
6528		// Try prefixed name followed by the unprefixed name
6529		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6530
6531		// If a hook was provided get the computed value from there
6532		if ( hooks && "get" in hooks ) {
6533			val = hooks.get( elem, true, extra );
6534		}
6535
6536		// Otherwise, if a way to get the computed value exists, use that
6537		if ( val === undefined ) {
6538			val = curCSS( elem, name, styles );
6539		}
6540
6541		// Convert "normal" to computed value
6542		if ( val === "normal" && name in cssNormalTransform ) {
6543			val = cssNormalTransform[ name ];
6544		}
6545
6546		// Make numeric if forced or a qualifier was provided and val looks numeric
6547		if ( extra === "" || extra ) {
6548			num = parseFloat( val );
6549			return extra === true || isFinite( num ) ? num || 0 : val;
6550		}
6551
6552		return val;
6553	}
6554} );
6555
6556jQuery.each( [ "height", "width" ], function( i, dimension ) {
6557	jQuery.cssHooks[ dimension ] = {
6558		get: function( elem, computed, extra ) {
6559			if ( computed ) {
6560
6561				// Certain elements can have dimension info if we invisibly show them
6562				// but it must have a current display style that would benefit
6563				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6564
6565					// Support: Safari 8+
6566					// Table columns in Safari have non-zero offsetWidth & zero
6567					// getBoundingClientRect().width unless display is changed.
6568					// Support: IE <=11 only
6569					// Running getBoundingClientRect on a disconnected node
6570					// in IE throws an error.
6571					( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
6572						swap( elem, cssShow, function() {
6573							return getWidthOrHeight( elem, dimension, extra );
6574						} ) :
6575						getWidthOrHeight( elem, dimension, extra );
6576			}
6577		},
6578
6579		set: function( elem, value, extra ) {
6580			var matches,
6581				styles = getStyles( elem ),
6582				isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6583				subtract = extra && boxModelAdjustment(
6584					elem,
6585					dimension,
6586					extra,
6587					isBorderBox,
6588					styles
6589				);
6590
6591			// Account for unreliable border-box dimensions by comparing offset* to computed and
6592			// faking a content-box to get border and padding (gh-3699)
6593			if ( isBorderBox && support.scrollboxSize() === styles.position ) {
6594				subtract -= Math.ceil(
6595					elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
6596					parseFloat( styles[ dimension ] ) -
6597					boxModelAdjustment( elem, dimension, "border", false, styles ) -
6598					0.5
6599				);
6600			}
6601
6602			// Convert to pixels if value adjustment is needed
6603			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6604				( matches[ 3 ] || "px" ) !== "px" ) {
6605
6606				elem.style[ dimension ] = value;
6607				value = jQuery.css( elem, dimension );
6608			}
6609
6610			return setPositiveNumber( elem, value, subtract );
6611		}
6612	};
6613} );
6614
6615jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6616	function( elem, computed ) {
6617		if ( computed ) {
6618			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6619				elem.getBoundingClientRect().left -
6620					swap( elem, { marginLeft: 0 }, function() {
6621						return elem.getBoundingClientRect().left;
6622					} )
6623				) + "px";
6624		}
6625	}
6626);
6627
6628// These hooks are used by animate to expand properties
6629jQuery.each( {
6630	margin: "",
6631	padding: "",
6632	border: "Width"
6633}, function( prefix, suffix ) {
6634	jQuery.cssHooks[ prefix + suffix ] = {
6635		expand: function( value ) {
6636			var i = 0,
6637				expanded = {},
6638
6639				// Assumes a single number if not a string
6640				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6641
6642			for ( ; i < 4; i++ ) {
6643				expanded[ prefix + cssExpand[ i ] + suffix ] =
6644					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6645			}
6646
6647			return expanded;
6648		}
6649	};
6650
6651	if ( prefix !== "margin" ) {
6652		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6653	}
6654} );
6655
6656jQuery.fn.extend( {
6657	css: function( name, value ) {
6658		return access( this, function( elem, name, value ) {
6659			var styles, len,
6660				map = {},
6661				i = 0;
6662
6663			if ( Array.isArray( name ) ) {
6664				styles = getStyles( elem );
6665				len = name.length;
6666
6667				for ( ; i < len; i++ ) {
6668					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6669				}
6670
6671				return map;
6672			}
6673
6674			return value !== undefined ?
6675				jQuery.style( elem, name, value ) :
6676				jQuery.css( elem, name );
6677		}, name, value, arguments.length > 1 );
6678	}
6679} );
6680
6681
6682function Tween( elem, options, prop, end, easing ) {
6683	return new Tween.prototype.init( elem, options, prop, end, easing );
6684}
6685jQuery.Tween = Tween;
6686
6687Tween.prototype = {
6688	constructor: Tween,
6689	init: function( elem, options, prop, end, easing, unit ) {
6690		this.elem = elem;
6691		this.prop = prop;
6692		this.easing = easing || jQuery.easing._default;
6693		this.options = options;
6694		this.start = this.now = this.cur();
6695		this.end = end;
6696		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6697	},
6698	cur: function() {
6699		var hooks = Tween.propHooks[ this.prop ];
6700
6701		return hooks && hooks.get ?
6702			hooks.get( this ) :
6703			Tween.propHooks._default.get( this );
6704	},
6705	run: function( percent ) {
6706		var eased,
6707			hooks = Tween.propHooks[ this.prop ];
6708
6709		if ( this.options.duration ) {
6710			this.pos = eased = jQuery.easing[ this.easing ](
6711				percent, this.options.duration * percent, 0, 1, this.options.duration
6712			);
6713		} else {
6714			this.pos = eased = percent;
6715		}
6716		this.now = ( this.end - this.start ) * eased + this.start;
6717
6718		if ( this.options.step ) {
6719			this.options.step.call( this.elem, this.now, this );
6720		}
6721
6722		if ( hooks && hooks.set ) {
6723			hooks.set( this );
6724		} else {
6725			Tween.propHooks._default.set( this );
6726		}
6727		return this;
6728	}
6729};
6730
6731Tween.prototype.init.prototype = Tween.prototype;
6732
6733Tween.propHooks = {
6734	_default: {
6735		get: function( tween ) {
6736			var result;
6737
6738			// Use a property on the element directly when it is not a DOM element,
6739			// or when there is no matching style property that exists.
6740			if ( tween.elem.nodeType !== 1 ||
6741				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6742				return tween.elem[ tween.prop ];
6743			}
6744
6745			// Passing an empty string as a 3rd parameter to .css will automatically
6746			// attempt a parseFloat and fallback to a string if the parse fails.
6747			// Simple values such as "10px" are parsed to Float;
6748			// complex values such as "rotate(1rad)" are returned as-is.
6749			result = jQuery.css( tween.elem, tween.prop, "" );
6750
6751			// Empty strings, null, undefined and "auto" are converted to 0.
6752			return !result || result === "auto" ? 0 : result;
6753		},
6754		set: function( tween ) {
6755
6756			// Use step hook for back compat.
6757			// Use cssHook if its there.
6758			// Use .style if available and use plain properties where available.
6759			if ( jQuery.fx.step[ tween.prop ] ) {
6760				jQuery.fx.step[ tween.prop ]( tween );
6761			} else if ( tween.elem.nodeType === 1 &&
6762				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6763					jQuery.cssHooks[ tween.prop ] ) ) {
6764				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6765			} else {
6766				tween.elem[ tween.prop ] = tween.now;
6767			}
6768		}
6769	}
6770};
6771
6772// Support: IE <=9 only
6773// Panic based approach to setting things on disconnected nodes
6774Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6775	set: function( tween ) {
6776		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6777			tween.elem[ tween.prop ] = tween.now;
6778		}
6779	}
6780};
6781
6782jQuery.easing = {
6783	linear: function( p ) {
6784		return p;
6785	},
6786	swing: function( p ) {
6787		return 0.5 - Math.cos( p * Math.PI ) / 2;
6788	},
6789	_default: "swing"
6790};
6791
6792jQuery.fx = Tween.prototype.init;
6793
6794// Back compat <1.8 extension point
6795jQuery.fx.step = {};
6796
6797
6798
6799
6800var
6801	fxNow, inProgress,
6802	rfxtypes = /^(?:toggle|show|hide)$/,
6803	rrun = /queueHooks$/;
6804
6805function schedule() {
6806	if ( inProgress ) {
6807		if ( document.hidden === false && window.requestAnimationFrame ) {
6808			window.requestAnimationFrame( schedule );
6809		} else {
6810			window.setTimeout( schedule, jQuery.fx.interval );
6811		}
6812
6813		jQuery.fx.tick();
6814	}
6815}
6816
6817// Animations created synchronously will run synchronously
6818function createFxNow() {
6819	window.setTimeout( function() {
6820		fxNow = undefined;
6821	} );
6822	return ( fxNow = Date.now() );
6823}
6824
6825// Generate parameters to create a standard animation
6826function genFx( type, includeWidth ) {
6827	var which,
6828		i = 0,
6829		attrs = { height: type };
6830
6831	// If we include width, step value is 1 to do all cssExpand values,
6832	// otherwise step value is 2 to skip over Left and Right
6833	includeWidth = includeWidth ? 1 : 0;
6834	for ( ; i < 4; i += 2 - includeWidth ) {
6835		which = cssExpand[ i ];
6836		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6837	}
6838
6839	if ( includeWidth ) {
6840		attrs.opacity = attrs.width = type;
6841	}
6842
6843	return attrs;
6844}
6845
6846function createTween( value, prop, animation ) {
6847	var tween,
6848		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6849		index = 0,
6850		length = collection.length;
6851	for ( ; index < length; index++ ) {
6852		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6853
6854			// We're done with this property
6855			return tween;
6856		}
6857	}
6858}
6859
6860function defaultPrefilter( elem, props, opts ) {
6861	var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
6862		isBox = "width" in props || "height" in props,
6863		anim = this,
6864		orig = {},
6865		style = elem.style,
6866		hidden = elem.nodeType && isHiddenWithinTree( elem ),
6867		dataShow = dataPriv.get( elem, "fxshow" );
6868
6869	// Queue-skipping animations hijack the fx hooks
6870	if ( !opts.queue ) {
6871		hooks = jQuery._queueHooks( elem, "fx" );
6872		if ( hooks.unqueued == null ) {
6873			hooks.unqueued = 0;
6874			oldfire = hooks.empty.fire;
6875			hooks.empty.fire = function() {
6876				if ( !hooks.unqueued ) {
6877					oldfire();
6878				}
6879			};
6880		}
6881		hooks.unqueued++;
6882
6883		anim.always( function() {
6884
6885			// Ensure the complete handler is called before this completes
6886			anim.always( function() {
6887				hooks.unqueued--;
6888				if ( !jQuery.queue( elem, "fx" ).length ) {
6889					hooks.empty.fire();
6890				}
6891			} );
6892		} );
6893	}
6894
6895	// Detect show/hide animations
6896	for ( prop in props ) {
6897		value = props[ prop ];
6898		if ( rfxtypes.test( value ) ) {
6899			delete props[ prop ];
6900			toggle = toggle || value === "toggle";
6901			if ( value === ( hidden ? "hide" : "show" ) ) {
6902
6903				// Pretend to be hidden if this is a "show" and
6904				// there is still data from a stopped show/hide
6905				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6906					hidden = true;
6907
6908				// Ignore all other no-op show/hide data
6909				} else {
6910					continue;
6911				}
6912			}
6913			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6914		}
6915	}
6916
6917	// Bail out if this is a no-op like .hide().hide()
6918	propTween = !jQuery.isEmptyObject( props );
6919	if ( !propTween && jQuery.isEmptyObject( orig ) ) {
6920		return;
6921	}
6922
6923	// Restrict "overflow" and "display" styles during box animations
6924	if ( isBox && elem.nodeType === 1 ) {
6925
6926		// Support: IE <=9 - 11, Edge 12 - 15
6927		// Record all 3 overflow attributes because IE does not infer the shorthand
6928		// from identically-valued overflowX and overflowY and Edge just mirrors
6929		// the overflowX value there.
6930		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6931
6932		// Identify a display type, preferring old show/hide data over the CSS cascade
6933		restoreDisplay = dataShow && dataShow.display;
6934		if ( restoreDisplay == null ) {
6935			restoreDisplay = dataPriv.get( elem, "display" );
6936		}
6937		display = jQuery.css( elem, "display" );
6938		if ( display === "none" ) {
6939			if ( restoreDisplay ) {
6940				display = restoreDisplay;
6941			} else {
6942
6943				// Get nonempty value(s) by temporarily forcing visibility
6944				showHide( [ elem ], true );
6945				restoreDisplay = elem.style.display || restoreDisplay;
6946				display = jQuery.css( elem, "display" );
6947				showHide( [ elem ] );
6948			}
6949		}
6950
6951		// Animate inline elements as inline-block
6952		if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
6953			if ( jQuery.css( elem, "float" ) === "none" ) {
6954
6955				// Restore the original display value at the end of pure show/hide animations
6956				if ( !propTween ) {
6957					anim.done( function() {
6958						style.display = restoreDisplay;
6959					} );
6960					if ( restoreDisplay == null ) {
6961						display = style.display;
6962						restoreDisplay = display === "none" ? "" : display;
6963					}
6964				}
6965				style.display = "inline-block";
6966			}
6967		}
6968	}
6969
6970	if ( opts.overflow ) {
6971		style.overflow = "hidden";
6972		anim.always( function() {
6973			style.overflow = opts.overflow[ 0 ];
6974			style.overflowX = opts.overflow[ 1 ];
6975			style.overflowY = opts.overflow[ 2 ];
6976		} );
6977	}
6978
6979	// Implement show/hide animations
6980	propTween = false;
6981	for ( prop in orig ) {
6982
6983		// General show/hide setup for this element animation
6984		if ( !propTween ) {
6985			if ( dataShow ) {
6986				if ( "hidden" in dataShow ) {
6987					hidden = dataShow.hidden;
6988				}
6989			} else {
6990				dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
6991			}
6992
6993			// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
6994			if ( toggle ) {
6995				dataShow.hidden = !hidden;
6996			}
6997
6998			// Show elements before animating them
6999			if ( hidden ) {
7000				showHide( [ elem ], true );
7001			}
7002
7003			/* eslint-disable no-loop-func */
7004
7005			anim.done( function() {
7006
7007			/* eslint-enable no-loop-func */
7008
7009				// The final step of a "hide" animation is actually hiding the element
7010				if ( !hidden ) {
7011					showHide( [ elem ] );
7012				}
7013				dataPriv.remove( elem, "fxshow" );
7014				for ( prop in orig ) {
7015					jQuery.style( elem, prop, orig[ prop ] );
7016				}
7017			} );
7018		}
7019
7020		// Per-property setup
7021		propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7022		if ( !( prop in dataShow ) ) {
7023			dataShow[ prop ] = propTween.start;
7024			if ( hidden ) {
7025				propTween.end = propTween.start;
7026				propTween.start = 0;
7027			}
7028		}
7029	}
7030}
7031
7032function propFilter( props, specialEasing ) {
7033	var index, name, easing, value, hooks;
7034
7035	// camelCase, specialEasing and expand cssHook pass
7036	for ( index in props ) {
7037		name = camelCase( index );
7038		easing = specialEasing[ name ];
7039		value = props[ index ];
7040		if ( Array.isArray( value ) ) {
7041			easing = value[ 1 ];
7042			value = props[ index ] = value[ 0 ];
7043		}
7044
7045		if ( index !== name ) {
7046			props[ name ] = value;
7047			delete props[ index ];
7048		}
7049
7050		hooks = jQuery.cssHooks[ name ];
7051		if ( hooks && "expand" in hooks ) {
7052			value = hooks.expand( value );
7053			delete props[ name ];
7054
7055			// Not quite $.extend, this won't overwrite existing keys.
7056			// Reusing 'index' because we have the correct "name"
7057			for ( index in value ) {
7058				if ( !( index in props ) ) {
7059					props[ index ] = value[ index ];
7060					specialEasing[ index ] = easing;
7061				}
7062			}
7063		} else {
7064			specialEasing[ name ] = easing;
7065		}
7066	}
7067}
7068
7069function Animation( elem, properties, options ) {
7070	var result,
7071		stopped,
7072		index = 0,
7073		length = Animation.prefilters.length,
7074		deferred = jQuery.Deferred().always( function() {
7075
7076			// Don't match elem in the :animated selector
7077			delete tick.elem;
7078		} ),
7079		tick = function() {
7080			if ( stopped ) {
7081				return false;
7082			}
7083			var currentTime = fxNow || createFxNow(),
7084				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7085
7086				// Support: Android 2.3 only
7087				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7088				temp = remaining / animation.duration || 0,
7089				percent = 1 - temp,
7090				index = 0,
7091				length = animation.tweens.length;
7092
7093			for ( ; index < length; index++ ) {
7094				animation.tweens[ index ].run( percent );
7095			}
7096
7097			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7098
7099			// If there's more to do, yield
7100			if ( percent < 1 && length ) {
7101				return remaining;
7102			}
7103
7104			// If this was an empty animation, synthesize a final progress notification
7105			if ( !length ) {
7106				deferred.notifyWith( elem, [ animation, 1, 0 ] );
7107			}
7108
7109			// Resolve the animation and report its conclusion
7110			deferred.resolveWith( elem, [ animation ] );
7111			return false;
7112		},
7113		animation = deferred.promise( {
7114			elem: elem,
7115			props: jQuery.extend( {}, properties ),
7116			opts: jQuery.extend( true, {
7117				specialEasing: {},
7118				easing: jQuery.easing._default
7119			}, options ),
7120			originalProperties: properties,
7121			originalOptions: options,
7122			startTime: fxNow || createFxNow(),
7123			duration: options.duration,
7124			tweens: [],
7125			createTween: function( prop, end ) {
7126				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7127						animation.opts.specialEasing[ prop ] || animation.opts.easing );
7128				animation.tweens.push( tween );
7129				return tween;
7130			},
7131			stop: function( gotoEnd ) {
7132				var index = 0,
7133
7134					// If we are going to the end, we want to run all the tweens
7135					// otherwise we skip this part
7136					length = gotoEnd ? animation.tweens.length : 0;
7137				if ( stopped ) {
7138					return this;
7139				}
7140				stopped = true;
7141				for ( ; index < length; index++ ) {
7142					animation.tweens[ index ].run( 1 );
7143				}
7144
7145				// Resolve when we played the last frame; otherwise, reject
7146				if ( gotoEnd ) {
7147					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7148					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7149				} else {
7150					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7151				}
7152				return this;
7153			}
7154		} ),
7155		props = animation.props;
7156
7157	propFilter( props, animation.opts.specialEasing );
7158
7159	for ( ; index < length; index++ ) {
7160		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7161		if ( result ) {
7162			if ( isFunction( result.stop ) ) {
7163				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7164					result.stop.bind( result );
7165			}
7166			return result;
7167		}
7168	}
7169
7170	jQuery.map( props, createTween, animation );
7171
7172	if ( isFunction( animation.opts.start ) ) {
7173		animation.opts.start.call( elem, animation );
7174	}
7175
7176	// Attach callbacks from options
7177	animation
7178		.progress( animation.opts.progress )
7179		.done( animation.opts.done, animation.opts.complete )
7180		.fail( animation.opts.fail )
7181		.always( animation.opts.always );
7182
7183	jQuery.fx.timer(
7184		jQuery.extend( tick, {
7185			elem: elem,
7186			anim: animation,
7187			queue: animation.opts.queue
7188		} )
7189	);
7190
7191	return animation;
7192}
7193
7194jQuery.Animation = jQuery.extend( Animation, {
7195
7196	tweeners: {
7197		"*": [ function( prop, value ) {
7198			var tween = this.createTween( prop, value );
7199			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7200			return tween;
7201		} ]
7202	},
7203
7204	tweener: function( props, callback ) {
7205		if ( isFunction( props ) ) {
7206			callback = props;
7207			props = [ "*" ];
7208		} else {
7209			props = props.match( rnothtmlwhite );
7210		}
7211
7212		var prop,
7213			index = 0,
7214			length = props.length;
7215
7216		for ( ; index < length; index++ ) {
7217			prop = props[ index ];
7218			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7219			Animation.tweeners[ prop ].unshift( callback );
7220		}
7221	},
7222
7223	prefilters: [ defaultPrefilter ],
7224
7225	prefilter: function( callback, prepend ) {
7226		if ( prepend ) {
7227			Animation.prefilters.unshift( callback );
7228		} else {
7229			Animation.prefilters.push( callback );
7230		}
7231	}
7232} );
7233
7234jQuery.speed = function( speed, easing, fn ) {
7235	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7236		complete: fn || !fn && easing ||
7237			isFunction( speed ) && speed,
7238		duration: speed,
7239		easing: fn && easing || easing && !isFunction( easing ) && easing
7240	};
7241
7242	// Go to the end state if fx are off
7243	if ( jQuery.fx.off ) {
7244		opt.duration = 0;
7245
7246	} else {
7247		if ( typeof opt.duration !== "number" ) {
7248			if ( opt.duration in jQuery.fx.speeds ) {
7249				opt.duration = jQuery.fx.speeds[ opt.duration ];
7250
7251			} else {
7252				opt.duration = jQuery.fx.speeds._default;
7253			}
7254		}
7255	}
7256
7257	// Normalize opt.queue - true/undefined/null -> "fx"
7258	if ( opt.queue == null || opt.queue === true ) {
7259		opt.queue = "fx";
7260	}
7261
7262	// Queueing
7263	opt.old = opt.complete;
7264
7265	opt.complete = function() {
7266		if ( isFunction( opt.old ) ) {
7267			opt.old.call( this );
7268		}
7269
7270		if ( opt.queue ) {
7271			jQuery.dequeue( this, opt.queue );
7272		}
7273	};
7274
7275	return opt;
7276};
7277
7278jQuery.fn.extend( {
7279	fadeTo: function( speed, to, easing, callback ) {
7280
7281		// Show any hidden elements after setting opacity to 0
7282		return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
7283
7284			// Animate to the value specified
7285			.end().animate( { opacity: to }, speed, easing, callback );
7286	},
7287	animate: function( prop, speed, easing, callback ) {
7288		var empty = jQuery.isEmptyObject( prop ),
7289			optall = jQuery.speed( speed, easing, callback ),
7290			doAnimation = function() {
7291
7292				// Operate on a copy of prop so per-property easing won't be lost
7293				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7294
7295				// Empty animations, or finishing resolves immediately
7296				if ( empty || dataPriv.get( this, "finish" ) ) {
7297					anim.stop( true );
7298				}
7299			};
7300			doAnimation.finish = doAnimation;
7301
7302		return empty || optall.queue === false ?
7303			this.each( doAnimation ) :
7304			this.queue( optall.queue, doAnimation );
7305	},
7306	stop: function( type, clearQueue, gotoEnd ) {
7307		var stopQueue = function( hooks ) {
7308			var stop = hooks.stop;
7309			delete hooks.stop;
7310			stop( gotoEnd );
7311		};
7312
7313		if ( typeof type !== "string" ) {
7314			gotoEnd = clearQueue;
7315			clearQueue = type;
7316			type = undefined;
7317		}
7318		if ( clearQueue && type !== false ) {
7319			this.queue( type || "fx", [] );
7320		}
7321
7322		return this.each( function() {
7323			var dequeue = true,
7324				index = type != null && type + "queueHooks",
7325				timers = jQuery.timers,
7326				data = dataPriv.get( this );
7327
7328			if ( index ) {
7329				if ( data[ index ] && data[ index ].stop ) {
7330					stopQueue( data[ index ] );
7331				}
7332			} else {
7333				for ( index in data ) {
7334					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7335						stopQueue( data[ index ] );
7336					}
7337				}
7338			}
7339
7340			for ( index = timers.length; index--; ) {
7341				if ( timers[ index ].elem === this &&
7342					( type == null || timers[ index ].queue === type ) ) {
7343
7344					timers[ index ].anim.stop( gotoEnd );
7345					dequeue = false;
7346					timers.splice( index, 1 );
7347				}
7348			}
7349
7350			// Start the next in the queue if the last step wasn't forced.
7351			// Timers currently will call their complete callbacks, which
7352			// will dequeue but only if they were gotoEnd.
7353			if ( dequeue || !gotoEnd ) {
7354				jQuery.dequeue( this, type );
7355			}
7356		} );
7357	},
7358	finish: function( type ) {
7359		if ( type !== false ) {
7360			type = type || "fx";
7361		}
7362		return this.each( function() {
7363			var index,
7364				data = dataPriv.get( this ),
7365				queue = data[ type + "queue" ],
7366				hooks = data[ type + "queueHooks" ],
7367				timers = jQuery.timers,
7368				length = queue ? queue.length : 0;
7369
7370			// Enable finishing flag on private data
7371			data.finish = true;
7372
7373			// Empty the queue first
7374			jQuery.queue( this, type, [] );
7375
7376			if ( hooks && hooks.stop ) {
7377				hooks.stop.call( this, true );
7378			}
7379
7380			// Look for any active animations, and finish them
7381			for ( index = timers.length; index--; ) {
7382				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
7383					timers[ index ].anim.stop( true );
7384					timers.splice( index, 1 );
7385				}
7386			}
7387
7388			// Look for any animations in the old queue and finish them
7389			for ( index = 0; index < length; index++ ) {
7390				if ( queue[ index ] && queue[ index ].finish ) {
7391					queue[ index ].finish.call( this );
7392				}
7393			}
7394
7395			// Turn off finishing flag
7396			delete data.finish;
7397		} );
7398	}
7399} );
7400
7401jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
7402	var cssFn = jQuery.fn[ name ];
7403	jQuery.fn[ name ] = function( speed, easing, callback ) {
7404		return speed == null || typeof speed === "boolean" ?
7405			cssFn.apply( this, arguments ) :
7406			this.animate( genFx( name, true ), speed, easing, callback );
7407	};
7408} );
7409
7410// Generate shortcuts for custom animations
7411jQuery.each( {
7412	slideDown: genFx( "show" ),
7413	slideUp: genFx( "hide" ),
7414	slideToggle: genFx( "toggle" ),
7415	fadeIn: { opacity: "show" },
7416	fadeOut: { opacity: "hide" },
7417	fadeToggle: { opacity: "toggle" }
7418}, function( name, props ) {
7419	jQuery.fn[ name ] = function( speed, easing, callback ) {
7420		return this.animate( props, speed, easing, callback );
7421	};
7422} );
7423
7424jQuery.timers = [];
7425jQuery.fx.tick = function() {
7426	var timer,
7427		i = 0,
7428		timers = jQuery.timers;
7429
7430	fxNow = Date.now();
7431
7432	for ( ; i < timers.length; i++ ) {
7433		timer = timers[ i ];
7434
7435		// Run the timer and safely remove it when done (allowing for external removal)
7436		if ( !timer() && timers[ i ] === timer ) {
7437			timers.splice( i--, 1 );
7438		}
7439	}
7440
7441	if ( !timers.length ) {
7442		jQuery.fx.stop();
7443	}
7444	fxNow = undefined;
7445};
7446
7447jQuery.fx.timer = function( timer ) {
7448	jQuery.timers.push( timer );
7449	jQuery.fx.start();
7450};
7451
7452jQuery.fx.interval = 13;
7453jQuery.fx.start = function() {
7454	if ( inProgress ) {
7455		return;
7456	}
7457
7458	inProgress = true;
7459	schedule();
7460};
7461
7462jQuery.fx.stop = function() {
7463	inProgress = null;
7464};
7465
7466jQuery.fx.speeds = {
7467	slow: 600,
7468	fast: 200,
7469
7470	// Default speed
7471	_default: 400
7472};
7473
7474
7475// Based off of the plugin by Clint Helfers, with permission.
7476// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7477jQuery.fn.delay = function( time, type ) {
7478	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7479	type = type || "fx";
7480
7481	return this.queue( type, function( next, hooks ) {
7482		var timeout = window.setTimeout( next, time );
7483		hooks.stop = function() {
7484			window.clearTimeout( timeout );
7485		};
7486	} );
7487};
7488
7489
7490( function() {
7491	var input = document.createElement( "input" ),
7492		select = document.createElement( "select" ),
7493		opt = select.appendChild( document.createElement( "option" ) );
7494
7495	input.type = "checkbox";
7496
7497	// Support: Android <=4.3 only
7498	// Default value for a checkbox should be "on"
7499	support.checkOn = input.value !== "";
7500
7501	// Support: IE <=11 only
7502	// Must access selectedIndex to make default options select
7503	support.optSelected = opt.selected;
7504
7505	// Support: IE <=11 only
7506	// An input loses its value after becoming a radio
7507	input = document.createElement( "input" );
7508	input.value = "t";
7509	input.type = "radio";
7510	support.radioValue = input.value === "t";
7511} )();
7512
7513
7514var boolHook,
7515	attrHandle = jQuery.expr.attrHandle;
7516
7517jQuery.fn.extend( {
7518	attr: function( name, value ) {
7519		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7520	},
7521
7522	removeAttr: function( name ) {
7523		return this.each( function() {
7524			jQuery.removeAttr( this, name );
7525		} );
7526	}
7527} );
7528
7529jQuery.extend( {
7530	attr: function( elem, name, value ) {
7531		var ret, hooks,
7532			nType = elem.nodeType;
7533
7534		// Don't get/set attributes on text, comment and attribute nodes
7535		if ( nType === 3 || nType === 8 || nType === 2 ) {
7536			return;
7537		}
7538
7539		// Fallback to prop when attributes are not supported
7540		if ( typeof elem.getAttribute === "undefined" ) {
7541			return jQuery.prop( elem, name, value );
7542		}
7543
7544		// Attribute hooks are determined by the lowercase version
7545		// Grab necessary hook if one is defined
7546		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7547			hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
7548				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7549		}
7550
7551		if ( value !== undefined ) {
7552			if ( value === null ) {
7553				jQuery.removeAttr( elem, name );
7554				return;
7555			}
7556
7557			if ( hooks && "set" in hooks &&
7558				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7559				return ret;
7560			}
7561
7562			elem.setAttribute( name, value + "" );
7563			return value;
7564		}
7565
7566		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7567			return ret;
7568		}
7569
7570		ret = jQuery.find.attr( elem, name );
7571
7572		// Non-existent attributes return null, we normalize to undefined
7573		return ret == null ? undefined : ret;
7574	},
7575
7576	attrHooks: {
7577		type: {
7578			set: function( elem, value ) {
7579				if ( !support.radioValue && value === "radio" &&
7580					nodeName( elem, "input" ) ) {
7581					var val = elem.value;
7582					elem.setAttribute( "type", value );
7583					if ( val ) {
7584						elem.value = val;
7585					}
7586					return value;
7587				}
7588			}
7589		}
7590	},
7591
7592	removeAttr: function( elem, value ) {
7593		var name,
7594			i = 0,
7595
7596			// Attribute names can contain non-HTML whitespace characters
7597			// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
7598			attrNames = value && value.match( rnothtmlwhite );
7599
7600		if ( attrNames && elem.nodeType === 1 ) {
7601			while ( ( name = attrNames[ i++ ] ) ) {
7602				elem.removeAttribute( name );
7603			}
7604		}
7605	}
7606} );
7607
7608// Hooks for boolean attributes
7609boolHook = {
7610	set: function( elem, value, name ) {
7611		if ( value === false ) {
7612
7613			// Remove boolean attributes when set to false
7614			jQuery.removeAttr( elem, name );
7615		} else {
7616			elem.setAttribute( name, name );
7617		}
7618		return name;
7619	}
7620};
7621
7622jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7623	var getter = attrHandle[ name ] || jQuery.find.attr;
7624
7625	attrHandle[ name ] = function( elem, name, isXML ) {
7626		var ret, handle,
7627			lowercaseName = name.toLowerCase();
7628
7629		if ( !isXML ) {
7630
7631			// Avoid an infinite loop by temporarily removing this function from the getter
7632			handle = attrHandle[ lowercaseName ];
7633			attrHandle[ lowercaseName ] = ret;
7634			ret = getter( elem, name, isXML ) != null ?
7635				lowercaseName :
7636				null;
7637			attrHandle[ lowercaseName ] = handle;
7638		}
7639		return ret;
7640	};
7641} );
7642
7643
7644
7645
7646var rfocusable = /^(?:input|select|textarea|button)$/i,
7647	rclickable = /^(?:a|area)$/i;
7648
7649jQuery.fn.extend( {
7650	prop: function( name, value ) {
7651		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7652	},
7653
7654	removeProp: function( name ) {
7655		return this.each( function() {
7656			delete this[ jQuery.propFix[ name ] || name ];
7657		} );
7658	}
7659} );
7660
7661jQuery.extend( {
7662	prop: function( elem, name, value ) {
7663		var ret, hooks,
7664			nType = elem.nodeType;
7665
7666		// Don't get/set properties on text, comment and attribute nodes
7667		if ( nType === 3 || nType === 8 || nType === 2 ) {
7668			return;
7669		}
7670
7671		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7672
7673			// Fix name and attach hooks
7674			name = jQuery.propFix[ name ] || name;
7675			hooks = jQuery.propHooks[ name ];
7676		}
7677
7678		if ( value !== undefined ) {
7679			if ( hooks && "set" in hooks &&
7680				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7681				return ret;
7682			}
7683
7684			return ( elem[ name ] = value );
7685		}
7686
7687		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7688			return ret;
7689		}
7690
7691		return elem[ name ];
7692	},
7693
7694	propHooks: {
7695		tabIndex: {
7696			get: function( elem ) {
7697
7698				// Support: IE <=9 - 11 only
7699				// elem.tabIndex doesn't always return the
7700				// correct value when it hasn't been explicitly set
7701				// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7702				// Use proper attribute retrieval(#12072)
7703				var tabindex = jQuery.find.attr( elem, "tabindex" );
7704
7705				if ( tabindex ) {
7706					return parseInt( tabindex, 10 );
7707				}
7708
7709				if (
7710					rfocusable.test( elem.nodeName ) ||
7711					rclickable.test( elem.nodeName ) &&
7712					elem.href
7713				) {
7714					return 0;
7715				}
7716
7717				return -1;
7718			}
7719		}
7720	},
7721
7722	propFix: {
7723		"for": "htmlFor",
7724		"class": "className"
7725	}
7726} );
7727
7728// Support: IE <=11 only
7729// Accessing the selectedIndex property
7730// forces the browser to respect setting selected
7731// on the option
7732// The getter ensures a default option is selected
7733// when in an optgroup
7734// eslint rule "no-unused-expressions" is disabled for this code
7735// since it considers such accessions noop
7736if ( !support.optSelected ) {
7737	jQuery.propHooks.selected = {
7738		get: function( elem ) {
7739
7740			/* eslint no-unused-expressions: "off" */
7741
7742			var parent = elem.parentNode;
7743			if ( parent && parent.parentNode ) {
7744				parent.parentNode.selectedIndex;
7745			}
7746			return null;
7747		},
7748		set: function( elem ) {
7749
7750			/* eslint no-unused-expressions: "off" */
7751
7752			var parent = elem.parentNode;
7753			if ( parent ) {
7754				parent.selectedIndex;
7755
7756				if ( parent.parentNode ) {
7757					parent.parentNode.selectedIndex;
7758				}
7759			}
7760		}
7761	};
7762}
7763
7764jQuery.each( [
7765	"tabIndex",
7766	"readOnly",
7767	"maxLength",
7768	"cellSpacing",
7769	"cellPadding",
7770	"rowSpan",
7771	"colSpan",
7772	"useMap",
7773	"frameBorder",
7774	"contentEditable"
7775], function() {
7776	jQuery.propFix[ this.toLowerCase() ] = this;
7777} );
7778
7779
7780
7781
7782	// Strip and collapse whitespace according to HTML spec
7783	// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
7784	function stripAndCollapse( value ) {
7785		var tokens = value.match( rnothtmlwhite ) || [];
7786		return tokens.join( " " );
7787	}
7788
7789
7790function getClass( elem ) {
7791	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7792}
7793
7794function classesToArray( value ) {
7795	if ( Array.isArray( value ) ) {
7796		return value;
7797	}
7798	if ( typeof value === "string" ) {
7799		return value.match( rnothtmlwhite ) || [];
7800	}
7801	return [];
7802}
7803
7804jQuery.fn.extend( {
7805	addClass: function( value ) {
7806		var classes, elem, cur, curValue, clazz, j, finalValue,
7807			i = 0;
7808
7809		if ( isFunction( value ) ) {
7810			return this.each( function( j ) {
7811				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7812			} );
7813		}
7814
7815		classes = classesToArray( value );
7816
7817		if ( classes.length ) {
7818			while ( ( elem = this[ i++ ] ) ) {
7819				curValue = getClass( elem );
7820				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7821
7822				if ( cur ) {
7823					j = 0;
7824					while ( ( clazz = classes[ j++ ] ) ) {
7825						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7826							cur += clazz + " ";
7827						}
7828					}
7829
7830					// Only assign if different to avoid unneeded rendering.
7831					finalValue = stripAndCollapse( cur );
7832					if ( curValue !== finalValue ) {
7833						elem.setAttribute( "class", finalValue );
7834					}
7835				}
7836			}
7837		}
7838
7839		return this;
7840	},
7841
7842	removeClass: function( value ) {
7843		var classes, elem, cur, curValue, clazz, j, finalValue,
7844			i = 0;
7845
7846		if ( isFunction( value ) ) {
7847			return this.each( function( j ) {
7848				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7849			} );
7850		}
7851
7852		if ( !arguments.length ) {
7853			return this.attr( "class", "" );
7854		}
7855
7856		classes = classesToArray( value );
7857
7858		if ( classes.length ) {
7859			while ( ( elem = this[ i++ ] ) ) {
7860				curValue = getClass( elem );
7861
7862				// This expression is here for better compressibility (see addClass)
7863				cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
7864
7865				if ( cur ) {
7866					j = 0;
7867					while ( ( clazz = classes[ j++ ] ) ) {
7868
7869						// Remove *all* instances
7870						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7871							cur = cur.replace( " " + clazz + " ", " " );
7872						}
7873					}
7874
7875					// Only assign if different to avoid unneeded rendering.
7876					finalValue = stripAndCollapse( cur );
7877					if ( curValue !== finalValue ) {
7878						elem.setAttribute( "class", finalValue );
7879					}
7880				}
7881			}
7882		}
7883
7884		return this;
7885	},
7886
7887	toggleClass: function( value, stateVal ) {
7888		var type = typeof value,
7889			isValidValue = type === "string" || Array.isArray( value );
7890
7891		if ( typeof stateVal === "boolean" && isValidValue ) {
7892			return stateVal ? this.addClass( value ) : this.removeClass( value );
7893		}
7894
7895		if ( isFunction( value ) ) {
7896			return this.each( function( i ) {
7897				jQuery( this ).toggleClass(
7898					value.call( this, i, getClass( this ), stateVal ),
7899					stateVal
7900				);
7901			} );
7902		}
7903
7904		return this.each( function() {
7905			var className, i, self, classNames;
7906
7907			if ( isValidValue ) {
7908
7909				// Toggle individual class names
7910				i = 0;
7911				self = jQuery( this );
7912				classNames = classesToArray( value );
7913
7914				while ( ( className = classNames[ i++ ] ) ) {
7915
7916					// Check each className given, space separated list
7917					if ( self.hasClass( className ) ) {
7918						self.removeClass( className );
7919					} else {
7920						self.addClass( className );
7921					}
7922				}
7923
7924			// Toggle whole class name
7925			} else if ( value === undefined || type === "boolean" ) {
7926				className = getClass( this );
7927				if ( className ) {
7928
7929					// Store className if set
7930					dataPriv.set( this, "__className__", className );
7931				}
7932
7933				// If the element has a class name or if we're passed `false`,
7934				// then remove the whole classname (if there was one, the above saved it).
7935				// Otherwise bring back whatever was previously saved (if anything),
7936				// falling back to the empty string if nothing was stored.
7937				if ( this.setAttribute ) {
7938					this.setAttribute( "class",
7939						className || value === false ?
7940						"" :
7941						dataPriv.get( this, "__className__" ) || ""
7942					);
7943				}
7944			}
7945		} );
7946	},
7947
7948	hasClass: function( selector ) {
7949		var className, elem,
7950			i = 0;
7951
7952		className = " " + selector + " ";
7953		while ( ( elem = this[ i++ ] ) ) {
7954			if ( elem.nodeType === 1 &&
7955				( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
7956					return true;
7957			}
7958		}
7959
7960		return false;
vendor: 5,544 bytes, lines 7961-8196
7961	}
7962} );
7963
7964
7965
7966
7967var rreturn = /\r/g;
7968
7969jQuery.fn.extend( {
7970	val: function( value ) {
7971		var hooks, ret, valueIsFunction,
7972			elem = this[ 0 ];
7973
7974		if ( !arguments.length ) {
7975			if ( elem ) {
7976				hooks = jQuery.valHooks[ elem.type ] ||
7977					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7978
7979				if ( hooks &&
7980					"get" in hooks &&
7981					( ret = hooks.get( elem, "value" ) ) !== undefined
7982				) {
7983					return ret;
7984				}
7985
7986				ret = elem.value;
7987
7988				// Handle most common string cases
7989				if ( typeof ret === "string" ) {
7990					return ret.replace( rreturn, "" );
7991				}
7992
7993				// Handle cases where value is null/undef or number
7994				return ret == null ? "" : ret;
7995			}
7996
7997			return;
7998		}
7999
8000		valueIsFunction = isFunction( value );
8001
8002		return this.each( function( i ) {
8003			var val;
8004
8005			if ( this.nodeType !== 1 ) {
8006				return;
8007			}
8008
8009			if ( valueIsFunction ) {
8010				val = value.call( this, i, jQuery( this ).val() );
8011			} else {
8012				val = value;
8013			}
8014
8015			// Treat null/undefined as ""; convert numbers to string
8016			if ( val == null ) {
8017				val = "";
8018
8019			} else if ( typeof val === "number" ) {
8020				val += "";
8021
8022			} else if ( Array.isArray( val ) ) {
8023				val = jQuery.map( val, function( value ) {
8024					return value == null ? "" : value + "";
8025				} );
8026			}
8027
8028			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8029
8030			// If set returns undefined, fall back to normal setting
8031			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8032				this.value = val;
8033			}
8034		} );
8035	}
8036} );
8037
8038jQuery.extend( {
8039	valHooks: {
8040		option: {
8041			get: function( elem ) {
8042
8043				var val = jQuery.find.attr( elem, "value" );
8044				return val != null ?
8045					val :
8046
8047					// Support: IE <=10 - 11 only
8048					// option.text throws exceptions (#14686, #14858)
8049					// Strip and collapse whitespace
8050					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8051					stripAndCollapse( jQuery.text( elem ) );
8052			}
8053		},
8054		select: {
8055			get: function( elem ) {
8056				var value, option, i,
8057					options = elem.options,
8058					index = elem.selectedIndex,
8059					one = elem.type === "select-one",
8060					values = one ? null : [],
8061					max = one ? index + 1 : options.length;
8062
8063				if ( index < 0 ) {
8064					i = max;
8065
8066				} else {
8067					i = one ? index : 0;
8068				}
8069
8070				// Loop through all the selected options
8071				for ( ; i < max; i++ ) {
8072					option = options[ i ];
8073
8074					// Support: IE <=9 only
8075					// IE8-9 doesn't update selected after form reset (#2551)
8076					if ( ( option.selected || i === index ) &&
8077
8078							// Don't return options that are disabled or in a disabled optgroup
8079							!option.disabled &&
8080							( !option.parentNode.disabled ||
8081								!nodeName( option.parentNode, "optgroup" ) ) ) {
8082
8083						// Get the specific value for the option
8084						value = jQuery( option ).val();
8085
8086						// We don't need an array for one selects
8087						if ( one ) {
8088							return value;
8089						}
8090
8091						// Multi-Selects return an array
8092						values.push( value );
8093					}
8094				}
8095
8096				return values;
8097			},
8098
8099			set: function( elem, value ) {
8100				var optionSet, option,
8101					options = elem.options,
8102					values = jQuery.makeArray( value ),
8103					i = options.length;
8104
8105				while ( i-- ) {
8106					option = options[ i ];
8107
8108					/* eslint-disable no-cond-assign */
8109
8110					if ( option.selected =
8111						jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
8112					) {
8113						optionSet = true;
8114					}
8115
8116					/* eslint-enable no-cond-assign */
8117				}
8118
8119				// Force browsers to behave consistently when non-matching value is set
8120				if ( !optionSet ) {
8121					elem.selectedIndex = -1;
8122				}
8123				return values;
8124			}
8125		}
8126	}
8127} );
8128
8129// Radios and checkboxes getter/setter
8130jQuery.each( [ "radio", "checkbox" ], function() {
8131	jQuery.valHooks[ this ] = {
8132		set: function( elem, value ) {
8133			if ( Array.isArray( value ) ) {
8134				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8135			}
8136		}
8137	};
8138	if ( !support.checkOn ) {
8139		jQuery.valHooks[ this ].get = function( elem ) {
8140			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8141		};
8142	}
8143} );
8144
8145
8146
8147
8148// Return jQuery for attributes-only inclusion
8149
8150
8151support.focusin = "onfocusin" in window;
8152
8153
8154var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
8155	stopPropagationCallback = function( e ) {
8156		e.stopPropagation();
8157	};
8158
8159jQuery.extend( jQuery.event, {
8160
8161	trigger: function( event, data, elem, onlyHandlers ) {
8162
8163		var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
8164			eventPath = [ elem || document ],
8165			type = hasOwn.call( event, "type" ) ? event.type : event,
8166			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
8167
8168		cur = lastElement = tmp = elem = elem || document;
8169
8170		// Don't do events on text and comment nodes
8171		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
8172			return;
8173		}
8174
8175		// focus/blur morphs to focusin/out; ensure we're not firing them right now
8176		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
8177			return;
8178		}
8179
8180		if ( type.indexOf( "." ) > -1 ) {
8181
8182			// Namespaced trigger; create a regexp to match event type in handle()
8183			namespaces = type.split( "." );
8184			type = namespaces.shift();
8185			namespaces.sort();
8186		}
8187		ontype = type.indexOf( ":" ) < 0 && "on" + type;
8188
8189		// Caller can pass in a jQuery.Event object, Object, or just an event type string
8190		event = event[ jQuery.expando ] ?
8191			event :
8192			new jQuery.Event( type, typeof event === "object" && event );
8193
8194		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
8195		event.isTrigger = onlyHandlers ? 2 : 3;
8196		event.namespace = namespaces.join( "." );
vendor: 32,532 bytes, lines 8197-9468
8197		event.rnamespace = event.namespace ?
8198			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
8199			null;
8200
8201		// Clean up the event in case it is being reused
8202		event.result = undefined;
8203		if ( !event.target ) {
8204			event.target = elem;
8205		}
8206
8207		// Clone any incoming data and prepend the event, creating the handler arg list
8208		data = data == null ?
8209			[ event ] :
8210			jQuery.makeArray( data, [ event ] );
8211
8212		// Allow special events to draw outside the lines
8213		special = jQuery.event.special[ type ] || {};
8214		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
8215			return;
8216		}
8217
8218		// Determine event propagation path in advance, per W3C events spec (#9951)
8219		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
8220		if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
8221
8222			bubbleType = special.delegateType || type;
8223			if ( !rfocusMorph.test( bubbleType + type ) ) {
8224				cur = cur.parentNode;
8225			}
8226			for ( ; cur; cur = cur.parentNode ) {
8227				eventPath.push( cur );
8228				tmp = cur;
8229			}
8230
8231			// Only add window if we got to document (e.g., not plain obj or detached DOM)
8232			if ( tmp === ( elem.ownerDocument || document ) ) {
8233				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
8234			}
8235		}
8236
8237		// Fire handlers on the event path
8238		i = 0;
8239		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
8240			lastElement = cur;
8241			event.type = i > 1 ?
8242				bubbleType :
8243				special.bindType || type;
8244
8245			// jQuery handler
8246			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
8247				dataPriv.get( cur, "handle" );
8248			if ( handle ) {
8249				handle.apply( cur, data );
8250			}
8251
8252			// Native handler
8253			handle = ontype && cur[ ontype ];
8254			if ( handle && handle.apply && acceptData( cur ) ) {
8255				event.result = handle.apply( cur, data );
8256				if ( event.result === false ) {
8257					event.preventDefault();
8258				}
8259			}
8260		}
8261		event.type = type;
8262
8263		// If nobody prevented the default action, do it now
8264		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
8265
8266			if ( ( !special._default ||
8267				special._default.apply( eventPath.pop(), data ) === false ) &&
8268				acceptData( elem ) ) {
8269
8270				// Call a native DOM method on the target with the same name as the event.
8271				// Don't do default actions on window, that's where global variables be (#6170)
8272				if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
8273
8274					// Don't re-trigger an onFOO event when we call its FOO() method
8275					tmp = elem[ ontype ];
8276
8277					if ( tmp ) {
8278						elem[ ontype ] = null;
8279					}
8280
8281					// Prevent re-triggering of the same event, since we already bubbled it above
8282					jQuery.event.triggered = type;
8283
8284					if ( event.isPropagationStopped() ) {
8285						lastElement.addEventListener( type, stopPropagationCallback );
8286					}
8287
8288					elem[ type ]();
8289
8290					if ( event.isPropagationStopped() ) {
8291						lastElement.removeEventListener( type, stopPropagationCallback );
8292					}
8293
8294					jQuery.event.triggered = undefined;
8295
8296					if ( tmp ) {
8297						elem[ ontype ] = tmp;
8298					}
8299				}
8300			}
8301		}
8302
8303		return event.result;
8304	},
8305
8306	// Piggyback on a donor event to simulate a different one
8307	// Used only for `focus(in | out)` events
8308	simulate: function( type, elem, event ) {
8309		var e = jQuery.extend(
8310			new jQuery.Event(),
8311			event,
8312			{
8313				type: type,
8314				isSimulated: true
8315			}
8316		);
8317
8318		jQuery.event.trigger( e, null, elem );
8319	}
8320
8321} );
8322
8323jQuery.fn.extend( {
8324
8325	trigger: function( type, data ) {
8326		return this.each( function() {
8327			jQuery.event.trigger( type, data, this );
8328		} );
8329	},
8330	triggerHandler: function( type, data ) {
8331		var elem = this[ 0 ];
8332		if ( elem ) {
8333			return jQuery.event.trigger( type, data, elem, true );
8334		}
8335	}
8336} );
8337
8338
8339// Support: Firefox <=44
8340// Firefox doesn't have focus(in | out) events
8341// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
8342//
8343// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
8344// focus(in | out) events fire after focus & blur events,
8345// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
8346// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
8347if ( !support.focusin ) {
8348	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
8349
8350		// Attach a single capturing handler on the document while someone wants focusin/focusout
8351		var handler = function( event ) {
8352			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
8353		};
8354
8355		jQuery.event.special[ fix ] = {
8356			setup: function() {
8357				var doc = this.ownerDocument || this,
8358					attaches = dataPriv.access( doc, fix );
8359
8360				if ( !attaches ) {
8361					doc.addEventListener( orig, handler, true );
8362				}
8363				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
8364			},
8365			teardown: function() {
8366				var doc = this.ownerDocument || this,
8367					attaches = dataPriv.access( doc, fix ) - 1;
8368
8369				if ( !attaches ) {
8370					doc.removeEventListener( orig, handler, true );
8371					dataPriv.remove( doc, fix );
8372
8373				} else {
8374					dataPriv.access( doc, fix, attaches );
8375				}
8376			}
8377		};
8378	} );
8379}
8380var location = window.location;
8381
8382var nonce = Date.now();
8383
8384var rquery = ( /\?/ );
8385
8386
8387
8388// Cross-browser xml parsing
8389jQuery.parseXML = function( data ) {
8390	var xml;
8391	if ( !data || typeof data !== "string" ) {
8392		return null;
8393	}
8394
8395	// Support: IE 9 - 11 only
8396	// IE throws on parseFromString with invalid input.
8397	try {
8398		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
8399	} catch ( e ) {
8400		xml = undefined;
8401	}
8402
8403	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
8404		jQuery.error( "Invalid XML: " + data );
8405	}
8406	return xml;
8407};
8408
8409
8410var
8411	rbracket = /\[\]$/,
8412	rCRLF = /\r?\n/g,
8413	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8414	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8415
8416function buildParams( prefix, obj, traditional, add ) {
8417	var name;
8418
8419	if ( Array.isArray( obj ) ) {
8420
8421		// Serialize array item.
8422		jQuery.each( obj, function( i, v ) {
8423			if ( traditional || rbracket.test( prefix ) ) {
8424
8425				// Treat each array item as a scalar.
8426				add( prefix, v );
8427
8428			} else {
8429
8430				// Item is non-scalar (array or object), encode its numeric index.
8431				buildParams(
8432					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8433					v,
8434					traditional,
8435					add
8436				);
8437			}
8438		} );
8439
8440	} else if ( !traditional && toType( obj ) === "object" ) {
8441
8442		// Serialize object item.
8443		for ( name in obj ) {
8444			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8445		}
8446
8447	} else {
8448
8449		// Serialize scalar item.
8450		add( prefix, obj );
8451	}
8452}
8453
8454// Serialize an array of form elements or a set of
8455// key/values into a query string
8456jQuery.param = function( a, traditional ) {
8457	var prefix,
8458		s = [],
8459		add = function( key, valueOrFunction ) {
8460
8461			// If value is a function, invoke it and use its return value
8462			var value = isFunction( valueOrFunction ) ?
8463				valueOrFunction() :
8464				valueOrFunction;
8465
8466			s[ s.length ] = encodeURIComponent( key ) + "=" +
8467				encodeURIComponent( value == null ? "" : value );
8468		};
8469
8470	// If an array was passed in, assume that it is an array of form elements.
8471	if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8472
8473		// Serialize the form elements
8474		jQuery.each( a, function() {
8475			add( this.name, this.value );
8476		} );
8477
8478	} else {
8479
8480		// If traditional, encode the "old" way (the way 1.3.2 or older
8481		// did it), otherwise encode params recursively.
8482		for ( prefix in a ) {
8483			buildParams( prefix, a[ prefix ], traditional, add );
8484		}
8485	}
8486
8487	// Return the resulting serialization
8488	return s.join( "&" );
8489};
8490
8491jQuery.fn.extend( {
8492	serialize: function() {
8493		return jQuery.param( this.serializeArray() );
8494	},
8495	serializeArray: function() {
8496		return this.map( function() {
8497
8498			// Can add propHook for "elements" to filter or add form elements
8499			var elements = jQuery.prop( this, "elements" );
8500			return elements ? jQuery.makeArray( elements ) : this;
8501		} )
8502		.filter( function() {
8503			var type = this.type;
8504
8505			// Use .is( ":disabled" ) so that fieldset[disabled] works
8506			return this.name && !jQuery( this ).is( ":disabled" ) &&
8507				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
8508				( this.checked || !rcheckableType.test( type ) );
8509		} )
8510		.map( function( i, elem ) {
8511			var val = jQuery( this ).val();
8512
8513			if ( val == null ) {
8514				return null;
8515			}
8516
8517			if ( Array.isArray( val ) ) {
8518				return jQuery.map( val, function( val ) {
8519					return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8520				} );
8521			}
8522
8523			return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
8524		} ).get();
8525	}
8526} );
8527
8528
8529var
8530	r20 = /%20/g,
8531	rhash = /#.*$/,
8532	rantiCache = /([?&])_=[^&]*/,
8533	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
8534
8535	// #7653, #8125, #8152: local protocol detection
8536	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
8537	rnoContent = /^(?:GET|HEAD)$/,
8538	rprotocol = /^\/\//,
8539
8540	/* Prefilters
8541	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8542	 * 2) These are called:
8543	 *    - BEFORE asking for a transport
8544	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8545	 * 3) key is the dataType
8546	 * 4) the catchall symbol "*" can be used
8547	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8548	 */
8549	prefilters = {},
8550
8551	/* Transports bindings
8552	 * 1) key is the dataType
8553	 * 2) the catchall symbol "*" can be used
8554	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8555	 */
8556	transports = {},
8557
8558	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8559	allTypes = "*/".concat( "*" ),
8560
8561	// Anchor tag for parsing the document origin
8562	originAnchor = document.createElement( "a" );
8563	originAnchor.href = location.href;
8564
8565// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8566function addToPrefiltersOrTransports( structure ) {
8567
8568	// dataTypeExpression is optional and defaults to "*"
8569	return function( dataTypeExpression, func ) {
8570
8571		if ( typeof dataTypeExpression !== "string" ) {
8572			func = dataTypeExpression;
8573			dataTypeExpression = "*";
8574		}
8575
8576		var dataType,
8577			i = 0,
8578			dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
8579
8580		if ( isFunction( func ) ) {
8581
8582			// For each dataType in the dataTypeExpression
8583			while ( ( dataType = dataTypes[ i++ ] ) ) {
8584
8585				// Prepend if requested
8586				if ( dataType[ 0 ] === "+" ) {
8587					dataType = dataType.slice( 1 ) || "*";
8588					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8589
8590				// Otherwise append
8591				} else {
8592					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8593				}
8594			}
8595		}
8596	};
8597}
8598
8599// Base inspection function for prefilters and transports
8600function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8601
8602	var inspected = {},
8603		seekingTransport = ( structure === transports );
8604
8605	function inspect( dataType ) {
8606		var selected;
8607		inspected[ dataType ] = true;
8608		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8609			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8610			if ( typeof dataTypeOrTransport === "string" &&
8611				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8612
8613				options.dataTypes.unshift( dataTypeOrTransport );
8614				inspect( dataTypeOrTransport );
8615				return false;
8616			} else if ( seekingTransport ) {
8617				return !( selected = dataTypeOrTransport );
8618			}
8619		} );
8620		return selected;
8621	}
8622
8623	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8624}
8625
8626// A special extend for ajax options
8627// that takes "flat" options (not to be deep extended)
8628// Fixes #9887
8629function ajaxExtend( target, src ) {
8630	var key, deep,
8631		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8632
8633	for ( key in src ) {
8634		if ( src[ key ] !== undefined ) {
8635			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8636		}
8637	}
8638	if ( deep ) {
8639		jQuery.extend( true, target, deep );
8640	}
8641
8642	return target;
8643}
8644
8645/* Handles responses to an ajax request:
8646 * - finds the right dataType (mediates between content-type and expected dataType)
8647 * - returns the corresponding response
8648 */
8649function ajaxHandleResponses( s, jqXHR, responses ) {
8650
8651	var ct, type, finalDataType, firstDataType,
8652		contents = s.contents,
8653		dataTypes = s.dataTypes;
8654
8655	// Remove auto dataType and get content-type in the process
8656	while ( dataTypes[ 0 ] === "*" ) {
8657		dataTypes.shift();
8658		if ( ct === undefined ) {
8659			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8660		}
8661	}
8662
8663	// Check if we're dealing with a known content-type
8664	if ( ct ) {
8665		for ( type in contents ) {
8666			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8667				dataTypes.unshift( type );
8668				break;
8669			}
8670		}
8671	}
8672
8673	// Check to see if we have a response for the expected dataType
8674	if ( dataTypes[ 0 ] in responses ) {
8675		finalDataType = dataTypes[ 0 ];
8676	} else {
8677
8678		// Try convertible dataTypes
8679		for ( type in responses ) {
8680			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8681				finalDataType = type;
8682				break;
8683			}
8684			if ( !firstDataType ) {
8685				firstDataType = type;
8686			}
8687		}
8688
8689		// Or just use first one
8690		finalDataType = finalDataType || firstDataType;
8691	}
8692
8693	// If we found a dataType
8694	// We add the dataType to the list if needed
8695	// and return the corresponding response
8696	if ( finalDataType ) {
8697		if ( finalDataType !== dataTypes[ 0 ] ) {
8698			dataTypes.unshift( finalDataType );
8699		}
8700		return responses[ finalDataType ];
8701	}
8702}
8703
8704/* Chain conversions given the request and the original response
8705 * Also sets the responseXXX fields on the jqXHR instance
8706 */
8707function ajaxConvert( s, response, jqXHR, isSuccess ) {
8708	var conv2, current, conv, tmp, prev,
8709		converters = {},
8710
8711		// Work with a copy of dataTypes in case we need to modify it for conversion
8712		dataTypes = s.dataTypes.slice();
8713
8714	// Create converters map with lowercased keys
8715	if ( dataTypes[ 1 ] ) {
8716		for ( conv in s.converters ) {
8717			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8718		}
8719	}
8720
8721	current = dataTypes.shift();
8722
8723	// Convert to each sequential dataType
8724	while ( current ) {
8725
8726		if ( s.responseFields[ current ] ) {
8727			jqXHR[ s.responseFields[ current ] ] = response;
8728		}
8729
8730		// Apply the dataFilter if provided
8731		if ( !prev && isSuccess && s.dataFilter ) {
8732			response = s.dataFilter( response, s.dataType );
8733		}
8734
8735		prev = current;
8736		current = dataTypes.shift();
8737
8738		if ( current ) {
8739
8740			// There's only work to do if current dataType is non-auto
8741			if ( current === "*" ) {
8742
8743				current = prev;
8744
8745			// Convert response if prev dataType is non-auto and differs from current
8746			} else if ( prev !== "*" && prev !== current ) {
8747
8748				// Seek a direct converter
8749				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8750
8751				// If none found, seek a pair
8752				if ( !conv ) {
8753					for ( conv2 in converters ) {
8754
8755						// If conv2 outputs current
8756						tmp = conv2.split( " " );
8757						if ( tmp[ 1 ] === current ) {
8758
8759							// If prev can be converted to accepted input
8760							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8761								converters[ "* " + tmp[ 0 ] ];
8762							if ( conv ) {
8763
8764								// Condense equivalence converters
8765								if ( conv === true ) {
8766									conv = converters[ conv2 ];
8767
8768								// Otherwise, insert the intermediate dataType
8769								} else if ( converters[ conv2 ] !== true ) {
8770									current = tmp[ 0 ];
8771									dataTypes.unshift( tmp[ 1 ] );
8772								}
8773								break;
8774							}
8775						}
8776					}
8777				}
8778
8779				// Apply converter (if not an equivalence)
8780				if ( conv !== true ) {
8781
8782					// Unless errors are allowed to bubble, catch and return them
8783					if ( conv && s.throws ) {
8784						response = conv( response );
8785					} else {
8786						try {
8787							response = conv( response );
8788						} catch ( e ) {
8789							return {
8790								state: "parsererror",
8791								error: conv ? e : "No conversion from " + prev + " to " + current
8792							};
8793						}
8794					}
8795				}
8796			}
8797		}
8798	}
8799
8800	return { state: "success", data: response };
8801}
8802
8803jQuery.extend( {
8804
8805	// Counter for holding the number of active queries
8806	active: 0,
8807
8808	// Last-Modified header cache for next request
8809	lastModified: {},
8810	etag: {},
8811
8812	ajaxSettings: {
8813		url: location.href,
8814		type: "GET",
8815		isLocal: rlocalProtocol.test( location.protocol ),
8816		global: true,
8817		processData: true,
8818		async: true,
8819		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8820
8821		/*
8822		timeout: 0,
8823		data: null,
8824		dataType: null,
8825		username: null,
8826		password: null,
8827		cache: null,
8828		throws: false,
8829		traditional: false,
8830		headers: {},
8831		*/
8832
8833		accepts: {
8834			"*": allTypes,
8835			text: "text/plain",
8836			html: "text/html",
8837			xml: "application/xml, text/xml",
8838			json: "application/json, text/javascript"
8839		},
8840
8841		contents: {
8842			xml: /\bxml\b/,
8843			html: /\bhtml/,
8844			json: /\bjson\b/
8845		},
8846
8847		responseFields: {
8848			xml: "responseXML",
8849			text: "responseText",
8850			json: "responseJSON"
8851		},
8852
8853		// Data converters
8854		// Keys separate source (or catchall "*") and destination types with a single space
8855		converters: {
8856
8857			// Convert anything to text
8858			"* text": String,
8859
8860			// Text to html (true = no transformation)
8861			"text html": true,
8862
8863			// Evaluate text as a json expression
8864			"text json": JSON.parse,
8865
8866			// Parse text as xml
8867			"text xml": jQuery.parseXML
8868		},
8869
8870		// For options that shouldn't be deep extended:
8871		// you can add your own custom options here if
8872		// and when you create one that shouldn't be
8873		// deep extended (see ajaxExtend)
8874		flatOptions: {
8875			url: true,
8876			context: true
8877		}
8878	},
8879
8880	// Creates a full fledged settings object into target
8881	// with both ajaxSettings and settings fields.
8882	// If target is omitted, writes into ajaxSettings.
8883	ajaxSetup: function( target, settings ) {
8884		return settings ?
8885
8886			// Building a settings object
8887			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8888
8889			// Extending ajaxSettings
8890			ajaxExtend( jQuery.ajaxSettings, target );
8891	},
8892
8893	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8894	ajaxTransport: addToPrefiltersOrTransports( transports ),
8895
8896	// Main method
8897	ajax: function( url, options ) {
8898
8899		// If url is an object, simulate pre-1.5 signature
8900		if ( typeof url === "object" ) {
8901			options = url;
8902			url = undefined;
8903		}
8904
8905		// Force options to be an object
8906		options = options || {};
8907
8908		var transport,
8909
8910			// URL without anti-cache param
8911			cacheURL,
8912
8913			// Response headers
8914			responseHeadersString,
8915			responseHeaders,
8916
8917			// timeout handle
8918			timeoutTimer,
8919
8920			// Url cleanup var
8921			urlAnchor,
8922
8923			// Request state (becomes false upon send and true upon completion)
8924			completed,
8925
8926			// To know if global events are to be dispatched
8927			fireGlobals,
8928
8929			// Loop variable
8930			i,
8931
8932			// uncached part of the url
8933			uncached,
8934
8935			// Create the final options object
8936			s = jQuery.ajaxSetup( {}, options ),
8937
8938			// Callbacks context
8939			callbackContext = s.context || s,
8940
8941			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8942			globalEventContext = s.context &&
8943				( callbackContext.nodeType || callbackContext.jquery ) ?
8944					jQuery( callbackContext ) :
8945					jQuery.event,
8946
8947			// Deferreds
8948			deferred = jQuery.Deferred(),
8949			completeDeferred = jQuery.Callbacks( "once memory" ),
8950
8951			// Status-dependent callbacks
8952			statusCode = s.statusCode || {},
8953
8954			// Headers (they are sent all at once)
8955			requestHeaders = {},
8956			requestHeadersNames = {},
8957
8958			// Default abort message
8959			strAbort = "canceled",
8960
8961			// Fake xhr
8962			jqXHR = {
8963				readyState: 0,
8964
8965				// Builds headers hashtable if needed
8966				getResponseHeader: function( key ) {
8967					var match;
8968					if ( completed ) {
8969						if ( !responseHeaders ) {
8970							responseHeaders = {};
8971							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8972								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8973							}
8974						}
8975						match = responseHeaders[ key.toLowerCase() ];
8976					}
8977					return match == null ? null : match;
8978				},
8979
8980				// Raw string
8981				getAllResponseHeaders: function() {
8982					return completed ? responseHeadersString : null;
8983				},
8984
8985				// Caches the header
8986				setRequestHeader: function( name, value ) {
8987					if ( completed == null ) {
8988						name = requestHeadersNames[ name.toLowerCase() ] =
8989							requestHeadersNames[ name.toLowerCase() ] || name;
8990						requestHeaders[ name ] = value;
8991					}
8992					return this;
8993				},
8994
8995				// Overrides response content-type header
8996				overrideMimeType: function( type ) {
8997					if ( completed == null ) {
8998						s.mimeType = type;
8999					}
9000					return this;
9001				},
9002
9003				// Status-dependent callbacks
9004				statusCode: function( map ) {
9005					var code;
9006					if ( map ) {
9007						if ( completed ) {
9008
9009							// Execute the appropriate callbacks
9010							jqXHR.always( map[ jqXHR.status ] );
9011						} else {
9012
9013							// Lazy-add the new callbacks in a way that preserves old ones
9014							for ( code in map ) {
9015								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9016							}
9017						}
9018					}
9019					return this;
9020				},
9021
9022				// Cancel the request
9023				abort: function( statusText ) {
9024					var finalText = statusText || strAbort;
9025					if ( transport ) {
9026						transport.abort( finalText );
9027					}
9028					done( 0, finalText );
9029					return this;
9030				}
9031			};
9032
9033		// Attach deferreds
9034		deferred.promise( jqXHR );
9035
9036		// Add protocol if not provided (prefilters might expect it)
9037		// Handle falsy url in the settings object (#10093: consistency with old signature)
9038		// We also use the url parameter if available
9039		s.url = ( ( url || s.url || location.href ) + "" )
9040			.replace( rprotocol, location.protocol + "//" );
9041
9042		// Alias method option to type as per ticket #12004
9043		s.type = options.method || options.type || s.method || s.type;
9044
9045		// Extract dataTypes list
9046		s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9047
9048		// A cross-domain request is in order when the origin doesn't match the current origin.
9049		if ( s.crossDomain == null ) {
9050			urlAnchor = document.createElement( "a" );
9051
9052			// Support: IE <=8 - 11, Edge 12 - 15
9053			// IE throws exception on accessing the href property if url is malformed,
9054			// e.g. http://example.com:80x/
9055			try {
9056				urlAnchor.href = s.url;
9057
9058				// Support: IE <=8 - 11 only
9059				// Anchor's host property isn't correctly set when s.url is relative
9060				urlAnchor.href = urlAnchor.href;
9061				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9062					urlAnchor.protocol + "//" + urlAnchor.host;
9063			} catch ( e ) {
9064
9065				// If there is an error parsing the URL, assume it is crossDomain,
9066				// it can be rejected by the transport if it is invalid
9067				s.crossDomain = true;
9068			}
9069		}
9070
9071		// Convert data if not already a string
9072		if ( s.data && s.processData && typeof s.data !== "string" ) {
9073			s.data = jQuery.param( s.data, s.traditional );
9074		}
9075
9076		// Apply prefilters
9077		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9078
9079		// If request was aborted inside a prefilter, stop there
9080		if ( completed ) {
9081			return jqXHR;
9082		}
9083
9084		// We can fire global events as of now if asked to
9085		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9086		fireGlobals = jQuery.event && s.global;
9087
9088		// Watch for a new set of requests
9089		if ( fireGlobals && jQuery.active++ === 0 ) {
9090			jQuery.event.trigger( "ajaxStart" );
9091		}
9092
9093		// Uppercase the type
9094		s.type = s.type.toUpperCase();
9095
9096		// Determine if request has content
9097		s.hasContent = !rnoContent.test( s.type );
9098
9099		// Save the URL in case we're toying with the If-Modified-Since
9100		// and/or If-None-Match header later on
9101		// Remove hash to simplify url manipulation
9102		cacheURL = s.url.replace( rhash, "" );
9103
9104		// More options handling for requests with no content
9105		if ( !s.hasContent ) {
9106
9107			// Remember the hash so we can put it back
9108			uncached = s.url.slice( cacheURL.length );
9109
9110			// If data is available and should be processed, append data to url
9111			if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
9112				cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
9113
9114				// #9682: remove data so that it's not used in an eventual retry
9115				delete s.data;
9116			}
9117
9118			// Add or update anti-cache param if needed
9119			if ( s.cache === false ) {
9120				cacheURL = cacheURL.replace( rantiCache, "$1" );
9121				uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + uncached;
9122			}
9123
9124			// Put hash and anti-cache on the URL that will be requested (gh-1732)
9125			s.url = cacheURL + uncached;
9126
9127		// Change '%20' to '+' if this is encoded form body content (gh-2658)
9128		} else if ( s.data && s.processData &&
9129			( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
9130			s.data = s.data.replace( r20, "+" );
9131		}
9132
9133		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9134		if ( s.ifModified ) {
9135			if ( jQuery.lastModified[ cacheURL ] ) {
9136				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9137			}
9138			if ( jQuery.etag[ cacheURL ] ) {
9139				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9140			}
9141		}
9142
9143		// Set the correct header, if data is being sent
9144		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9145			jqXHR.setRequestHeader( "Content-Type", s.contentType );
9146		}
9147
9148		// Set the Accepts header for the server, depending on the dataType
9149		jqXHR.setRequestHeader(
9150			"Accept",
9151			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9152				s.accepts[ s.dataTypes[ 0 ] ] +
9153					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9154				s.accepts[ "*" ]
9155		);
9156
9157		// Check for headers option
9158		for ( i in s.headers ) {
9159			jqXHR.setRequestHeader( i, s.headers[ i ] );
9160		}
9161
9162		// Allow custom headers/mimetypes and early abort
9163		if ( s.beforeSend &&
9164			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
9165
9166			// Abort if not done already and return
9167			return jqXHR.abort();
9168		}
9169
9170		// Aborting is no longer a cancellation
9171		strAbort = "abort";
9172
9173		// Install callbacks on deferreds
9174		completeDeferred.add( s.complete );
9175		jqXHR.done( s.success );
9176		jqXHR.fail( s.error );
9177
9178		// Get transport
9179		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9180
9181		// If no transport, we auto-abort
9182		if ( !transport ) {
9183			done( -1, "No Transport" );
9184		} else {
9185			jqXHR.readyState = 1;
9186
9187			// Send global event
9188			if ( fireGlobals ) {
9189				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9190			}
9191
9192			// If request was aborted inside ajaxSend, stop there
9193			if ( completed ) {
9194				return jqXHR;
9195			}
9196
9197			// Timeout
9198			if ( s.async && s.timeout > 0 ) {
9199				timeoutTimer = window.setTimeout( function() {
9200					jqXHR.abort( "timeout" );
9201				}, s.timeout );
9202			}
9203
9204			try {
9205				completed = false;
9206				transport.send( requestHeaders, done );
9207			} catch ( e ) {
9208
9209				// Rethrow post-completion exceptions
9210				if ( completed ) {
9211					throw e;
9212				}
9213
9214				// Propagate others as results
9215				done( -1, e );
9216			}
9217		}
9218
9219		// Callback for when everything is done
9220		function done( status, nativeStatusText, responses, headers ) {
9221			var isSuccess, success, error, response, modified,
9222				statusText = nativeStatusText;
9223
9224			// Ignore repeat invocations
9225			if ( completed ) {
9226				return;
9227			}
9228
9229			completed = true;
9230
9231			// Clear timeout if it exists
9232			if ( timeoutTimer ) {
9233				window.clearTimeout( timeoutTimer );
9234			}
9235
9236			// Dereference transport for early garbage collection
9237			// (no matter how long the jqXHR object will be used)
9238			transport = undefined;
9239
9240			// Cache response headers
9241			responseHeadersString = headers || "";
9242
9243			// Set readyState
9244			jqXHR.readyState = status > 0 ? 4 : 0;
9245
9246			// Determine if successful
9247			isSuccess = status >= 200 && status < 300 || status === 304;
9248
9249			// Get response data
9250			if ( responses ) {
9251				response = ajaxHandleResponses( s, jqXHR, responses );
9252			}
9253
9254			// Convert no matter what (that way responseXXX fields are always set)
9255			response = ajaxConvert( s, response, jqXHR, isSuccess );
9256
9257			// If successful, handle type chaining
9258			if ( isSuccess ) {
9259
9260				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9261				if ( s.ifModified ) {
9262					modified = jqXHR.getResponseHeader( "Last-Modified" );
9263					if ( modified ) {
9264						jQuery.lastModified[ cacheURL ] = modified;
9265					}
9266					modified = jqXHR.getResponseHeader( "etag" );
9267					if ( modified ) {
9268						jQuery.etag[ cacheURL ] = modified;
9269					}
9270				}
9271
9272				// if no content
9273				if ( status === 204 || s.type === "HEAD" ) {
9274					statusText = "nocontent";
9275
9276				// if not modified
9277				} else if ( status === 304 ) {
9278					statusText = "notmodified";
9279
9280				// If we have data, let's convert it
9281				} else {
9282					statusText = response.state;
9283					success = response.data;
9284					error = response.error;
9285					isSuccess = !error;
9286				}
9287			} else {
9288
9289				// Extract error from statusText and normalize for non-aborts
9290				error = statusText;
9291				if ( status || !statusText ) {
9292					statusText = "error";
9293					if ( status < 0 ) {
9294						status = 0;
9295					}
9296				}
9297			}
9298
9299			// Set data for the fake xhr object
9300			jqXHR.status = status;
9301			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9302
9303			// Success/Error
9304			if ( isSuccess ) {
9305				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9306			} else {
9307				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9308			}
9309
9310			// Status-dependent callbacks
9311			jqXHR.statusCode( statusCode );
9312			statusCode = undefined;
9313
9314			if ( fireGlobals ) {
9315				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9316					[ jqXHR, s, isSuccess ? success : error ] );
9317			}
9318
9319			// Complete
9320			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9321
9322			if ( fireGlobals ) {
9323				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9324
9325				// Handle the global AJAX counter
9326				if ( !( --jQuery.active ) ) {
9327					jQuery.event.trigger( "ajaxStop" );
9328				}
9329			}
9330		}
9331
9332		return jqXHR;
9333	},
9334
9335	getJSON: function( url, data, callback ) {
9336		return jQuery.get( url, data, callback, "json" );
9337	},
9338
9339	getScript: function( url, callback ) {
9340		return jQuery.get( url, undefined, callback, "script" );
9341	}
9342} );
9343
9344jQuery.each( [ "get", "post" ], function( i, method ) {
9345	jQuery[ method ] = function( url, data, callback, type ) {
9346
9347		// Shift arguments if data argument was omitted
9348		if ( isFunction( data ) ) {
9349			type = type || callback;
9350			callback = data;
9351			data = undefined;
9352		}
9353
9354		// The url can be an options object (which then must have .url)
9355		return jQuery.ajax( jQuery.extend( {
9356			url: url,
9357			type: method,
9358			dataType: type,
9359			data: data,
9360			success: callback
9361		}, jQuery.isPlainObject( url ) && url ) );
9362	};
9363} );
9364
9365
9366jQuery._evalUrl = function( url ) {
9367	return jQuery.ajax( {
9368		url: url,
9369
9370		// Make this explicit, since user can override this through ajaxSetup (#11264)
9371		type: "GET",
9372		dataType: "script",
9373		cache: true,
9374		async: false,
9375		global: false,
9376		"throws": true
9377	} );
9378};
9379
9380
9381jQuery.fn.extend( {
9382	wrapAll: function( html ) {
9383		var wrap;
9384
9385		if ( this[ 0 ] ) {
9386			if ( isFunction( html ) ) {
9387				html = html.call( this[ 0 ] );
9388			}
9389
9390			// The elements to wrap the target around
9391			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9392
9393			if ( this[ 0 ].parentNode ) {
9394				wrap.insertBefore( this[ 0 ] );
9395			}
9396
9397			wrap.map( function() {
9398				var elem = this;
9399
9400				while ( elem.firstElementChild ) {
9401					elem = elem.firstElementChild;
9402				}
9403
9404				return elem;
9405			} ).append( this );
9406		}
9407
9408		return this;
9409	},
9410
9411	wrapInner: function( html ) {
9412		if ( isFunction( html ) ) {
9413			return this.each( function( i ) {
9414				jQuery( this ).wrapInner( html.call( this, i ) );
9415			} );
9416		}
9417
9418		return this.each( function() {
9419			var self = jQuery( this ),
9420				contents = self.contents();
9421
9422			if ( contents.length ) {
9423				contents.wrapAll( html );
9424
9425			} else {
9426				self.append( html );
9427			}
9428		} );
9429	},
9430
9431	wrap: function( html ) {
9432		var htmlIsFunction = isFunction( html );
9433
9434		return this.each( function( i ) {
9435			jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
9436		} );
9437	},
9438
9439	unwrap: function( selector ) {
9440		this.parent( selector ).not( "body" ).each( function() {
9441			jQuery( this ).replaceWith( this.childNodes );
9442		} );
9443		return this;
9444	}
9445} );
9446
9447
9448jQuery.expr.pseudos.hidden = function( elem ) {
9449	return !jQuery.expr.pseudos.visible( elem );
9450};
9451jQuery.expr.pseudos.visible = function( elem ) {
9452	return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
9453};
9454
9455
9456
9457
9458jQuery.ajaxSettings.xhr = function() {
9459	try {
9460		return new window.XMLHttpRequest();
9461	} catch ( e ) {}
9462};
9463
9464var xhrSuccessStatus = {
9465
9466		// File protocol always yields status code 0, assume 200
9467		0: 200,
9468
vendor: 1,240 bytes, lines 9469-9511
9469		// Support: IE <=9 only
9470		// #1450: sometimes IE returns 1223 when it should be 204
9471		1223: 204
9472	},
9473	xhrSupported = jQuery.ajaxSettings.xhr();
9474
9475support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9476support.ajax = xhrSupported = !!xhrSupported;
9477
9478jQuery.ajaxTransport( function( options ) {
9479	var callback, errorCallback;
9480
9481	// Cross domain only allowed if supported through XMLHttpRequest
9482	if ( support.cors || xhrSupported && !options.crossDomain ) {
9483		return {
9484			send: function( headers, complete ) {
9485				var i,
9486					xhr = options.xhr();
9487
9488				xhr.open(
9489					options.type,
9490					options.url,
9491					options.async,
9492					options.username,
9493					options.password
9494				);
9495
9496				// Apply custom fields if provided
9497				if ( options.xhrFields ) {
9498					for ( i in options.xhrFields ) {
9499						xhr[ i ] = options.xhrFields[ i ];
9500					}
9501				}
9502
9503				// Override mime type if needed
9504				if ( options.mimeType && xhr.overrideMimeType ) {
9505					xhr.overrideMimeType( options.mimeType );
9506				}
9507
9508				// X-Requested-With header
9509				// For cross-domain requests, seeing as conditions for a preflight are
9510				// akin to a jigsaw puzzle, we simply never set it to be sure.
9511				// (it can always be set on a per-request basis or even using ajaxSetup)
vendor: 5,627 bytes, lines 9512-9733
9512				// For same-domain requests, won't change header if already provided.
9513				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9514					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9515				}
9516
9517				// Set headers
9518				for ( i in headers ) {
9519					xhr.setRequestHeader( i, headers[ i ] );
9520				}
9521
9522				// Callback
9523				callback = function( type ) {
9524					return function() {
9525						if ( callback ) {
9526							callback = errorCallback = xhr.onload =
9527								xhr.onerror = xhr.onabort = xhr.ontimeout =
9528									xhr.onreadystatechange = null;
9529
9530							if ( type === "abort" ) {
9531								xhr.abort();
9532							} else if ( type === "error" ) {
9533
9534								// Support: IE <=9 only
9535								// On a manual native abort, IE9 throws
9536								// errors on any property access that is not readyState
9537								if ( typeof xhr.status !== "number" ) {
9538									complete( 0, "error" );
9539								} else {
9540									complete(
9541
9542										// File: protocol always yields status 0; see #8605, #14207
9543										xhr.status,
9544										xhr.statusText
9545									);
9546								}
9547							} else {
9548								complete(
9549									xhrSuccessStatus[ xhr.status ] || xhr.status,
9550									xhr.statusText,
9551
9552									// Support: IE <=9 only
9553									// IE9 has no XHR2 but throws on binary (trac-11426)
9554									// For XHR2 non-text, let the caller handle it (gh-2498)
9555									( xhr.responseType || "text" ) !== "text"  ||
9556									typeof xhr.responseText !== "string" ?
9557										{ binary: xhr.response } :
9558										{ text: xhr.responseText },
9559									xhr.getAllResponseHeaders()
9560								);
9561							}
9562						}
9563					};
9564				};
9565
9566				// Listen to events
9567				xhr.onload = callback();
9568				errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
9569
9570				// Support: IE 9 only
9571				// Use onreadystatechange to replace onabort
9572				// to handle uncaught aborts
9573				if ( xhr.onabort !== undefined ) {
9574					xhr.onabort = errorCallback;
9575				} else {
9576					xhr.onreadystatechange = function() {
9577
9578						// Check readyState before timeout as it changes
9579						if ( xhr.readyState === 4 ) {
9580
9581							// Allow onerror to be called first,
9582							// but that will not handle a native abort
9583							// Also, save errorCallback to a variable
9584							// as xhr.onerror cannot be accessed
9585							window.setTimeout( function() {
9586								if ( callback ) {
9587									errorCallback();
9588								}
9589							} );
9590						}
9591					};
9592				}
9593
9594				// Create the abort callback
9595				callback = callback( "abort" );
9596
9597				try {
9598
9599					// Do send the request (this may raise an exception)
9600					xhr.send( options.hasContent && options.data || null );
9601				} catch ( e ) {
9602
9603					// #14683: Only rethrow if this hasn't been notified as an error yet
9604					if ( callback ) {
9605						throw e;
9606					}
9607				}
9608			},
9609
9610			abort: function() {
9611				if ( callback ) {
9612					callback();
9613				}
9614			}
9615		};
9616	}
9617} );
9618
9619
9620
9621
9622// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
9623jQuery.ajaxPrefilter( function( s ) {
9624	if ( s.crossDomain ) {
9625		s.contents.script = false;
9626	}
9627} );
9628
9629// Install script dataType
9630jQuery.ajaxSetup( {
9631	accepts: {
9632		script: "text/javascript, application/javascript, " +
9633			"application/ecmascript, application/x-ecmascript"
9634	},
9635	contents: {
9636		script: /\b(?:java|ecma)script\b/
9637	},
9638	converters: {
9639		"text script": function( text ) {
9640			jQuery.globalEval( text );
9641			return text;
9642		}
9643	}
9644} );
9645
9646// Handle cache's special case and crossDomain
9647jQuery.ajaxPrefilter( "script", function( s ) {
9648	if ( s.cache === undefined ) {
9649		s.cache = false;
9650	}
9651	if ( s.crossDomain ) {
9652		s.type = "GET";
9653	}
9654} );
9655
9656// Bind script tag hack transport
9657jQuery.ajaxTransport( "script", function( s ) {
9658
9659	// This transport only deals with cross domain requests
9660	if ( s.crossDomain ) {
9661		var script, callback;
9662		return {
9663			send: function( _, complete ) {
9664				script = jQuery( "<script>" ).prop( {
9665					charset: s.scriptCharset,
9666					src: s.url
9667				} ).on(
9668					"load error",
9669					callback = function( evt ) {
9670						script.remove();
9671						callback = null;
9672						if ( evt ) {
9673							complete( evt.type === "error" ? 404 : 200, evt.type );
9674						}
9675					}
9676				);
9677
9678				// Use native DOM manipulation to avoid our domManip AJAX trickery
9679				document.head.appendChild( script[ 0 ] );
9680			},
9681			abort: function() {
9682				if ( callback ) {
9683					callback();
9684				}
9685			}
9686		};
9687	}
9688} );
9689
9690
9691
9692
9693var oldCallbacks = [],
9694	rjsonp = /(=)\?(?=&|$)|\?\?/;
9695
9696// Default jsonp settings
9697jQuery.ajaxSetup( {
9698	jsonp: "callback",
9699	jsonpCallback: function() {
9700		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9701		this[ callback ] = true;
9702		return callback;
9703	}
9704} );
9705
9706// Detect, normalize options and install callbacks for jsonp requests
9707jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9708
9709	var callbackName, overwritten, responseContainer,
9710		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9711			"url" :
9712			typeof s.data === "string" &&
9713				( s.contentType || "" )
9714					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9715				rjsonp.test( s.data ) && "data"
9716		);
9717
9718	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9719	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9720
9721		// Get callback name, remembering preexisting value associated with it
9722		callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
9723			s.jsonpCallback() :
9724			s.jsonpCallback;
9725
9726		// Insert callback into url or form data
9727		if ( jsonProp ) {
9728			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9729		} else if ( s.jsonp !== false ) {
9730			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9731		}
9732
9733		// Use data converter to retrieve json after script execution
vendor: 2,987 bytes, lines 9734-9843
9734		s.converters[ "script json" ] = function() {
9735			if ( !responseContainer ) {
9736				jQuery.error( callbackName + " was not called" );
9737			}
9738			return responseContainer[ 0 ];
9739		};
9740
9741		// Force json dataType
9742		s.dataTypes[ 0 ] = "json";
9743
9744		// Install callback
9745		overwritten = window[ callbackName ];
9746		window[ callbackName ] = function() {
9747			responseContainer = arguments;
9748		};
9749
9750		// Clean-up function (fires after converters)
9751		jqXHR.always( function() {
9752
9753			// If previous value didn't exist - remove it
9754			if ( overwritten === undefined ) {
9755				jQuery( window ).removeProp( callbackName );
9756
9757			// Otherwise restore preexisting value
9758			} else {
9759				window[ callbackName ] = overwritten;
9760			}
9761
9762			// Save back as free
9763			if ( s[ callbackName ] ) {
9764
9765				// Make sure that re-using the options doesn't screw things around
9766				s.jsonpCallback = originalSettings.jsonpCallback;
9767
9768				// Save the callback name for future use
9769				oldCallbacks.push( callbackName );
9770			}
9771
9772			// Call if it was a function and we have a response
9773			if ( responseContainer && isFunction( overwritten ) ) {
9774				overwritten( responseContainer[ 0 ] );
9775			}
9776
9777			responseContainer = overwritten = undefined;
9778		} );
9779
9780		// Delegate to script
9781		return "script";
9782	}
9783} );
9784
9785
9786
9787
9788// Support: Safari 8 only
9789// In Safari 8 documents created via document.implementation.createHTMLDocument
9790// collapse sibling forms: the second one becomes a child of the first one.
9791// Because of that, this security measure has to be disabled in Safari 8.
9792// https://bugs.webkit.org/show_bug.cgi?id=137337
9793support.createHTMLDocument = ( function() {
9794	var body = document.implementation.createHTMLDocument( "" ).body;
9795	body.innerHTML = "<form></form><form></form>";
9796	return body.childNodes.length === 2;
9797} )();
9798
9799
9800// Argument "data" should be string of html
9801// context (optional): If specified, the fragment will be created in this context,
9802// defaults to document
9803// keepScripts (optional): If true, will include scripts passed in the html string
9804jQuery.parseHTML = function( data, context, keepScripts ) {
9805	if ( typeof data !== "string" ) {
9806		return [];
9807	}
9808	if ( typeof context === "boolean" ) {
9809		keepScripts = context;
9810		context = false;
9811	}
9812
9813	var base, parsed, scripts;
9814
9815	if ( !context ) {
9816
9817		// Stop scripts or inline event handlers from being executed immediately
9818		// by using document.implementation
9819		if ( support.createHTMLDocument ) {
9820			context = document.implementation.createHTMLDocument( "" );
9821
9822			// Set the base href for the created document
9823			// so any parsed elements with URLs
9824			// are based on the document's URL (gh-2965)
9825			base = context.createElement( "base" );
9826			base.href = document.location.href;
9827			context.head.appendChild( base );
9828		} else {
9829			context = document;
9830		}
9831	}
9832
9833	parsed = rsingleTag.exec( data );
9834	scripts = !keepScripts && [];
9835
9836	// Single tag
9837	if ( parsed ) {
9838		return [ context.createElement( parsed[ 1 ] ) ];
9839	}
9840
9841	parsed = buildFragment( [ data ], context, scripts );
9842
9843	if ( scripts && scripts.length ) {
vendor: 14,511 bytes, lines 9844-10364
9844		jQuery( scripts ).remove();
9845	}
9846
9847	return jQuery.merge( [], parsed.childNodes );
9848};
9849
9850
9851/**
9852 * Load a url into a page
9853 */
9854jQuery.fn.load = function( url, params, callback ) {
9855	var selector, type, response,
9856		self = this,
9857		off = url.indexOf( " " );
9858
9859	if ( off > -1 ) {
9860		selector = stripAndCollapse( url.slice( off ) );
9861		url = url.slice( 0, off );
9862	}
9863
9864	// If it's a function
9865	if ( isFunction( params ) ) {
9866
9867		// We assume that it's the callback
9868		callback = params;
9869		params = undefined;
9870
9871	// Otherwise, build a param string
9872	} else if ( params && typeof params === "object" ) {
9873		type = "POST";
9874	}
9875
9876	// If we have elements to modify, make the request
9877	if ( self.length > 0 ) {
9878		jQuery.ajax( {
9879			url: url,
9880
9881			// If "type" variable is undefined, then "GET" method will be used.
9882			// Make value of this field explicit since
9883			// user can override it through ajaxSetup method
9884			type: type || "GET",
9885			dataType: "html",
9886			data: params
9887		} ).done( function( responseText ) {
9888
9889			// Save response for use in complete callback
9890			response = arguments;
9891
9892			self.html( selector ?
9893
9894				// If a selector was specified, locate the right elements in a dummy div
9895				// Exclude scripts to avoid IE 'Permission Denied' errors
9896				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9897
9898				// Otherwise use the full result
9899				responseText );
9900
9901		// If the request succeeds, this function gets "data", "status", "jqXHR"
9902		// but they are ignored because response was set above.
9903		// If it fails, this function gets "jqXHR", "status", "error"
9904		} ).always( callback && function( jqXHR, status ) {
9905			self.each( function() {
9906				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
9907			} );
9908		} );
9909	}
9910
9911	return this;
9912};
9913
9914
9915
9916
9917// Attach a bunch of functions for handling common AJAX events
9918jQuery.each( [
9919	"ajaxStart",
9920	"ajaxStop",
9921	"ajaxComplete",
9922	"ajaxError",
9923	"ajaxSuccess",
9924	"ajaxSend"
9925], function( i, type ) {
9926	jQuery.fn[ type ] = function( fn ) {
9927		return this.on( type, fn );
9928	};
9929} );
9930
9931
9932
9933
9934jQuery.expr.pseudos.animated = function( elem ) {
9935	return jQuery.grep( jQuery.timers, function( fn ) {
9936		return elem === fn.elem;
9937	} ).length;
9938};
9939
9940
9941
9942
9943jQuery.offset = {
9944	setOffset: function( elem, options, i ) {
9945		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9946			position = jQuery.css( elem, "position" ),
9947			curElem = jQuery( elem ),
9948			props = {};
9949
9950		// Set position first, in-case top/left are set even on static elem
9951		if ( position === "static" ) {
9952			elem.style.position = "relative";
9953		}
9954
9955		curOffset = curElem.offset();
9956		curCSSTop = jQuery.css( elem, "top" );
9957		curCSSLeft = jQuery.css( elem, "left" );
9958		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9959			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9960
9961		// Need to be able to calculate position if either
9962		// top or left is auto and position is either absolute or fixed
9963		if ( calculatePosition ) {
9964			curPosition = curElem.position();
9965			curTop = curPosition.top;
9966			curLeft = curPosition.left;
9967
9968		} else {
9969			curTop = parseFloat( curCSSTop ) || 0;
9970			curLeft = parseFloat( curCSSLeft ) || 0;
9971		}
9972
9973		if ( isFunction( options ) ) {
9974
9975			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9976			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9977		}
9978
9979		if ( options.top != null ) {
9980			props.top = ( options.top - curOffset.top ) + curTop;
9981		}
9982		if ( options.left != null ) {
9983			props.left = ( options.left - curOffset.left ) + curLeft;
9984		}
9985
9986		if ( "using" in options ) {
9987			options.using.call( elem, props );
9988
9989		} else {
9990			curElem.css( props );
9991		}
9992	}
9993};
9994
9995jQuery.fn.extend( {
9996
9997	// offset() relates an element's border box to the document origin
9998	offset: function( options ) {
9999
10000		// Preserve chaining for setter
10001		if ( arguments.length ) {
10002			return options === undefined ?
10003				this :
10004				this.each( function( i ) {
10005					jQuery.offset.setOffset( this, options, i );
10006				} );
10007		}
10008
10009		var rect, win,
10010			elem = this[ 0 ];
10011
10012		if ( !elem ) {
10013			return;
10014		}
10015
10016		// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10017		// Support: IE <=11 only
10018		// Running getBoundingClientRect on a
10019		// disconnected node in IE throws an error
10020		if ( !elem.getClientRects().length ) {
10021			return { top: 0, left: 0 };
10022		}
10023
10024		// Get document-relative position by adding viewport scroll to viewport-relative gBCR
10025		rect = elem.getBoundingClientRect();
10026		win = elem.ownerDocument.defaultView;
10027		return {
10028			top: rect.top + win.pageYOffset,
10029			left: rect.left + win.pageXOffset
10030		};
10031	},
10032
10033	// position() relates an element's margin box to its offset parent's padding box
10034	// This corresponds to the behavior of CSS absolute positioning
10035	position: function() {
10036		if ( !this[ 0 ] ) {
10037			return;
10038		}
10039
10040		var offsetParent, offset, doc,
10041			elem = this[ 0 ],
10042			parentOffset = { top: 0, left: 0 };
10043
10044		// position:fixed elements are offset from the viewport, which itself always has zero offset
10045		if ( jQuery.css( elem, "position" ) === "fixed" ) {
10046
10047			// Assume position:fixed implies availability of getBoundingClientRect
10048			offset = elem.getBoundingClientRect();
10049
10050		} else {
10051			offset = this.offset();
10052
10053			// Account for the *real* offset parent, which can be the document or its root element
10054			// when a statically positioned element is identified
10055			doc = elem.ownerDocument;
10056			offsetParent = elem.offsetParent || doc.documentElement;
10057			while ( offsetParent &&
10058				( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10059				jQuery.css( offsetParent, "position" ) === "static" ) {
10060
10061				offsetParent = offsetParent.parentNode;
10062			}
10063			if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10064
10065				// Incorporate borders into its offset, since they are outside its content origin
10066				parentOffset = jQuery( offsetParent ).offset();
10067				parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10068				parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10069			}
10070		}
10071
10072		// Subtract parent offsets and element margins
10073		return {
10074			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10075			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10076		};
10077	},
10078
10079	// This method will return documentElement in the following cases:
10080	// 1) For the element inside the iframe without offsetParent, this method will return
10081	//    documentElement of the parent window
10082	// 2) For the hidden or detached element
10083	// 3) For body or html element, i.e. in case of the html node - it will return itself
10084	//
10085	// but those exceptions were never presented as a real life use-cases
10086	// and might be considered as more preferable results.
10087	//
10088	// This logic, however, is not guaranteed and can change at any point in the future
10089	offsetParent: function() {
10090		return this.map( function() {
10091			var offsetParent = this.offsetParent;
10092
10093			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
10094				offsetParent = offsetParent.offsetParent;
10095			}
10096
10097			return offsetParent || documentElement;
10098		} );
10099	}
10100} );
10101
10102// Create scrollLeft and scrollTop methods
10103jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10104	var top = "pageYOffset" === prop;
10105
10106	jQuery.fn[ method ] = function( val ) {
10107		return access( this, function( elem, method, val ) {
10108
10109			// Coalesce documents and windows
10110			var win;
10111			if ( isWindow( elem ) ) {
10112				win = elem;
10113			} else if ( elem.nodeType === 9 ) {
10114				win = elem.defaultView;
10115			}
10116
10117			if ( val === undefined ) {
10118				return win ? win[ prop ] : elem[ method ];
10119			}
10120
10121			if ( win ) {
10122				win.scrollTo(
10123					!top ? val : win.pageXOffset,
10124					top ? val : win.pageYOffset
10125				);
10126
10127			} else {
10128				elem[ method ] = val;
10129			}
10130		}, method, val, arguments.length );
10131	};
10132} );
10133
10134// Support: Safari <=7 - 9.1, Chrome <=37 - 49
10135// Add the top/left cssHooks using jQuery.fn.position
10136// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10137// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
10138// getComputedStyle returns percent when specified for top/left/bottom/right;
10139// rather than make the css module depend on the offset module, just check for it here
10140jQuery.each( [ "top", "left" ], function( i, prop ) {
10141	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10142		function( elem, computed ) {
10143			if ( computed ) {
10144				computed = curCSS( elem, prop );
10145
10146				// If curCSS returns percentage, fallback to offset
10147				return rnumnonpx.test( computed ) ?
10148					jQuery( elem ).position()[ prop ] + "px" :
10149					computed;
10150			}
10151		}
10152	);
10153} );
10154
10155
10156// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10157jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10158	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10159		function( defaultExtra, funcName ) {
10160
10161		// Margin is only for outerHeight, outerWidth
10162		jQuery.fn[ funcName ] = function( margin, value ) {
10163			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10164				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10165
10166			return access( this, function( elem, type, value ) {
10167				var doc;
10168
10169				if ( isWindow( elem ) ) {
10170
10171					// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
10172					return funcName.indexOf( "outer" ) === 0 ?
10173						elem[ "inner" + name ] :
10174						elem.document.documentElement[ "client" + name ];
10175				}
10176
10177				// Get document width or height
10178				if ( elem.nodeType === 9 ) {
10179					doc = elem.documentElement;
10180
10181					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10182					// whichever is greatest
10183					return Math.max(
10184						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10185						elem.body[ "offset" + name ], doc[ "offset" + name ],
10186						doc[ "client" + name ]
10187					);
10188				}
10189
10190				return value === undefined ?
10191
10192					// Get width or height on the element, requesting but not forcing parseFloat
10193					jQuery.css( elem, type, extra ) :
10194
10195					// Set width or height on the element
10196					jQuery.style( elem, type, value, extra );
10197			}, type, chainable ? margin : undefined, chainable );
10198		};
10199	} );
10200} );
10201
10202
10203jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
10204	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
10205	"change select submit keydown keypress keyup contextmenu" ).split( " " ),
10206	function( i, name ) {
10207
10208	// Handle event binding
10209	jQuery.fn[ name ] = function( data, fn ) {
10210		return arguments.length > 0 ?
10211			this.on( name, null, data, fn ) :
10212			this.trigger( name );
10213	};
10214} );
10215
10216jQuery.fn.extend( {
10217	hover: function( fnOver, fnOut ) {
10218		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
10219	}
10220} );
10221
10222
10223
10224
10225jQuery.fn.extend( {
10226
10227	bind: function( types, data, fn ) {
10228		return this.on( types, null, data, fn );
10229	},
10230	unbind: function( types, fn ) {
10231		return this.off( types, null, fn );
10232	},
10233
10234	delegate: function( selector, types, data, fn ) {
10235		return this.on( types, selector, data, fn );
10236	},
10237	undelegate: function( selector, types, fn ) {
10238
10239		// ( namespace ) or ( selector, types [, fn] )
10240		return arguments.length === 1 ?
10241			this.off( selector, "**" ) :
10242			this.off( types, selector || "**", fn );
10243	}
10244} );
10245
10246// Bind a function to a context, optionally partially applying any
10247// arguments.
10248// jQuery.proxy is deprecated to promote standards (specifically Function#bind)
10249// However, it is not slated for removal any time soon
10250jQuery.proxy = function( fn, context ) {
10251	var tmp, args, proxy;
10252
10253	if ( typeof context === "string" ) {
10254		tmp = fn[ context ];
10255		context = fn;
10256		fn = tmp;
10257	}
10258
10259	// Quick check to determine if target is callable, in the spec
10260	// this throws a TypeError, but we will just return undefined.
10261	if ( !isFunction( fn ) ) {
10262		return undefined;
10263	}
10264
10265	// Simulated bind
10266	args = slice.call( arguments, 2 );
10267	proxy = function() {
10268		return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
10269	};
10270
10271	// Set the guid of unique handler to the same of original handler, so it can be removed
10272	proxy.guid = fn.guid = fn.guid || jQuery.guid++;
10273
10274	return proxy;
10275};
10276
10277jQuery.holdReady = function( hold ) {
10278	if ( hold ) {
10279		jQuery.readyWait++;
10280	} else {
10281		jQuery.ready( true );
10282	}
10283};
10284jQuery.isArray = Array.isArray;
10285jQuery.parseJSON = JSON.parse;
10286jQuery.nodeName = nodeName;
10287jQuery.isFunction = isFunction;
10288jQuery.isWindow = isWindow;
10289jQuery.camelCase = camelCase;
10290jQuery.type = toType;
10291
10292jQuery.now = Date.now;
10293
10294jQuery.isNumeric = function( obj ) {
10295
10296	// As of jQuery 3.0, isNumeric is limited to
10297	// strings and numbers (primitives or objects)
10298	// that can be coerced to finite numbers (gh-2662)
10299	var type = jQuery.type( obj );
10300	return ( type === "number" || type === "string" ) &&
10301
10302		// parseFloat NaNs numeric-cast false positives ("")
10303		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
10304		// subtraction forces infinities to NaN
10305		!isNaN( obj - parseFloat( obj ) );
10306};
10307
10308
10309
10310
10311// Register as a named AMD module, since jQuery can be concatenated with other
10312// files that may use define, but not via a proper concatenation script that
10313// understands anonymous AMD modules. A named AMD is safest and most robust
10314// way to register. Lowercase jquery is used because AMD module names are
10315// derived from file names, and jQuery is normally delivered in a lowercase
10316// file name. Do this after creating the global so that if an AMD module wants
10317// to call noConflict to hide this version of jQuery, it will work.
10318
10319// Note that for maximum portability, libraries that are not jQuery should
10320// declare themselves as anonymous modules, and avoid setting a global if an
10321// AMD loader is present. jQuery is a special case. For more information, see
10322// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10323
10324if ( typeof define === "function" && define.amd ) {
10325	define( "jquery", [], function() {
10326		return jQuery;
10327	} );
10328}
10329
10330
10331
10332
10333var
10334
10335	// Map over jQuery in case of overwrite
10336	_jQuery = window.jQuery,
10337
10338	// Map over the $ in case of overwrite
10339	_$ = window.$;
10340
10341jQuery.noConflict = function( deep ) {
10342	if ( window.$ === jQuery ) {
10343		window.$ = _$;
10344	}
10345
10346	if ( deep && window.jQuery === jQuery ) {
10347		window.jQuery = _jQuery;
10348	}
10349
10350	return jQuery;
10351};
10352
10353// Expose jQuery and $ identifiers, even in AMD
10354// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
10355// and CommonJS for browser emulators (#13566)
10356if ( !noGlobal ) {
10357	window.jQuery = window.$ = jQuery;
10358}
10359
10360
10361
10362
10363return jQuery;
10364} );
10365
10366// no conflict mode for jquery
10367
10368var ct_$ = $.noConflict(true);
10369/**
10370* jQuery AOP - jQuery plugin to add features of aspect-oriented programming (AOP) to jQuery.
10371* https://github.com/gonzalocasas/jquery-aop
10372*
10373* Licensed under the MIT license:
10374* http://www.opensource.org/licenses/mit-license.php
10375*
10376* Version: 1.3
10377*
10378* Cross-frame type detection based on Daniel Steigerwald's code (http://daniel.steigerwald.cz)
10379* http://gist.github.com/204554
10380*
10381*/
10382
10383(function() {
10384
10385	var _after			= 1;
10386	var _afterThrow		= 2;
10387	var _afterFinally	= 3;
10388	var _before			= 4;
10389	var _around			= 5;
10390	var _intro			= 6;
10391	var _regexEnabled = true;
10392	var _arguments = 'arguments';
10393	var _undef = 'undefined';
10394
10395	var getType = (function() {
10396	 
10397		var toString = Object.prototype.toString,
10398			toStrings = {},
10399			nodeTypes = { 1: 'element', 3: 'textnode', 9: 'document', 11: 'fragment' },
10400			types = 'Arguments Array Boolean Date Document Element Error Fragment Function NodeList Null Number Object RegExp String TextNode Undefined Window'.split(' ');
10401	 
10402		for (var i = types.length; i--; ) {
10403			var type = types[i], constructor = window[type];
10404			if (constructor) {
10405				try { toStrings[toString.call(new constructor)] = type.toLowerCase(); }
10406				catch (e) { }
10407			}
10408		}
10409	 
10410		return function(item) {
10411			return item == null && (item === undefined ? _undef : 'null') ||
10412				item.nodeType && nodeTypes[item.nodeType] ||
10413				typeof item.length == 'number' && (
10414					item.callee && _arguments ||
10415					item.alert && 'window' ||
10416					item.item && 'nodelist') ||
10417				toStrings[toString.call(item)];
10418		};
10419	 
10420	})();
10421
10422	var isFunc = function(obj) { return getType(obj) == 'function'; };
10423
10424	/**
10425	 * Private weaving function.
10426	 */
10427	var weaveOne = function(source, method, advice) {
10428
10429		var old = source[method];
10430
10431		// Work-around IE6/7 behavior on some native method that return object instances
10432		if (advice.type != _intro && !isFunc(old)) {
10433			var oldObject = old;
10434			old = function() {
10435				var code = arguments.length > 0 ? _arguments + '[0]' : '';
10436
10437				for (var i=1;i<arguments.length;i++) {
10438					code += ',' + _arguments + '[' + i + ']';
10439				}
10440
10441				return eval('oldObject(' + code + ');');
10442			};
10443		}
10444
10445		var aspect;
10446		if (advice.type == _after || advice.type == _afterThrow || advice.type == _afterFinally)
10447			aspect = function() {
10448				var returnValue, exceptionThrown = null;
10449
10450				try {
10451					returnValue = old.apply(this, arguments);
10452				} catch (e) {
10453					exceptionThrown = e;
10454				}
10455
10456				if (advice.type == _after)
10457					if (exceptionThrown == null)
10458						returnValue = advice.value.apply(this, [returnValue, method]);
10459					else
10460						throw exceptionThrown;
10461				else if (advice.type == _afterThrow && exceptionThrown != null)
10462					returnValue = advice.value.apply(this, [exceptionThrown, method]);
10463				else if (advice.type == _afterFinally)
10464					returnValue = advice.value.apply(this, [returnValue, exceptionThrown, method]);
10465
10466				return returnValue;
10467			};
10468		else if (advice.type == _before)
10469			aspect = function() {
10470				advice.value.apply(this, [arguments, method]);
10471				return old.apply(this, arguments);
10472			};
10473		else if (advice.type == _intro)
10474			aspect = function() {
10475				return advice.value.apply(this, arguments);
10476			};
10477		else if (advice.type == _around) {
10478			aspect = function() {
10479				var invocation = { object: this, args: Array.prototype.slice.call(arguments) };
10480				return advice.value.apply(invocation.object, [{ arguments: invocation.args, method: method, proceed : 
10481					function() {
10482						return old.apply(invocation.object, invocation.args);
10483					}
10484				}] );
10485			};
10486		}
10487
10488		aspect.unweave = function() { 
10489			source[method] = old;
10490			pointcut = source = aspect = old = null;
10491		};
10492
10493		source[method] = aspect;
10494
10495		return aspect;
10496
10497	};
10498
10499	/**
10500	 * Private method search
10501	 */
10502	var search = function(source, pointcut, advice) {
10503		
10504		var methods = [];
10505
10506		for (var method in source) {
10507
10508			var item = null;
10509
10510			// Ignore exceptions during method retrival
10511			try {
10512				item = source[method];
10513			}
10514			catch (e) { }
10515
10516			if (item != null && method.match(pointcut.method) && isFunc(item))
10517				methods[methods.length] = { source: source, method: method, advice: advice };
10518
10519		}
10520
10521		return methods;
10522	};
10523
10524	/**
10525	 * Private weaver and pointcut parser.
10526	 */
10527	var weave = function(pointcut, advice) {
10528
10529		var source = typeof(pointcut.target.prototype) != _undef ? pointcut.target.prototype : pointcut.target;
10530		var advices = [];
10531
10532		// If it's not an introduction and no method was found, try with regex...
10533		if (advice.type != _intro && typeof(source[pointcut.method]) == _undef) {
10534
10535			// First try directly on target
10536			var methods = search(pointcut.target, pointcut, advice);
10537
10538			// No method found, re-try directly on prototype
10539			if (methods.length == 0)
10540				methods = search(source, pointcut, advice);
10541
10542			for (var i in methods)
10543				advices[advices.length] = weaveOne(methods[i].source, methods[i].method, methods[i].advice);
10544
10545		} 
10546		else
10547		{
10548			// Return as an array of one element
10549			advices[0] = weaveOne(source, pointcut.method, advice);
10550		}
10551
10552		return _regexEnabled ? advices : advices[0];
10553
10554	};
10555
10556	aop =
10557	{
10558		/**
10559		 * Creates an advice after the defined point-cut. The advice will be executed after the point-cut method 
10560		 * has completed execution successfully, and will receive one parameter with the result of the execution.
10561		 * This function returns an array of weaved aspects (Function).
10562		 *
10563		 * @example jQuery.aop.after( {target: window, method: 'MyGlobalMethod'}, function(result) { 
10564		 *                alert('Returned: ' + result); 
10565		 *                return result;
10566		 *          } );
10567		 * @result Array<Function>
10568		 *
10569		 * @example jQuery.aop.after( {target: String, method: 'indexOf'}, function(index) { 
10570		 *                alert('Result found at: ' + index + ' on:' + this); 
10571		 *                return index;
10572		 *          } );
10573		 * @result Array<Function>
10574		 *
10575		 * @name after
10576		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10577		 * @option Object target Target object to be weaved. 
10578		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
10579		 * @param Function advice Function containing the code that will get called after the execution of the point-cut. It receives one parameter
10580		 *                        with the result of the point-cut's execution. The function can choose to return this same value or a different one.
10581		 *
10582		 * @type Array<Function>
10583		 * @cat Plugins/General
10584		 */
10585		after : function(pointcut, advice)
10586		{
10587			return weave( pointcut, { type: _after, value: advice } );
10588		},
10589
10590		/**
10591		 * Creates an advice after the defined point-cut only for unhandled exceptions. The advice will be executed 
10592		 * after the point-cut method only if the execution failed and an exception has been thrown. It will receive one 
10593		 * parameter with the exception thrown by the point-cut method.
10594		 * This function returns an array of weaved aspects (Function).
10595		 *
10596		 * @example jQuery.aop.afterThrow( {target: String, method: 'indexOf'}, function(exception) { 
10597		 *                alert('Unhandled exception: ' + exception); 
10598		 *                return -1;
10599		 *          } );
10600		 * @result Array<Function>
10601		 *
10602		 * @example jQuery.aop.afterThrow( {target: calculator, method: 'Calculate'}, function(exception) { 
10603		 *                console.log('Unhandled exception: ' + exception);
10604		 *                throw exception;
10605		 *          } );
10606		 * @result Array<Function>
10607		 *
10608		 * @name afterThrow
10609		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10610		 * @option Object target Target object to be weaved. 
10611		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
10612		 * @param Function advice Function containing the code that will get called after the execution of the point-cut. It receives one parameter
10613		 *                        with the exception thrown by the point-cut method.
10614		 *
10615		 * @type Array<Function>
10616		 * @cat Plugins/General
10617		 */
10618		afterThrow : function(pointcut, advice)
10619		{
10620			return weave( pointcut, { type: _afterThrow, value: advice } );
10621		},
10622
10623		/**
10624		 * Creates an advice after the defined point-cut. The advice will be executed after the point-cut method 
10625		 * regardless of its success or failure, and it will receive two parameters: one with the 
10626		 * result of a successful execution or null, and another one with the exception thrown or null.
10627		 * This function returns an array of weaved aspects (Function).
10628		 *
10629		 * @example jQuery.aop.afterFinally( {target: window, method: 'MyGlobalMethod'}, function(result, exception) {
10630		 *                if (exception == null)
10631		 *                    return 'Returned: ' + result;
10632		 *                else
10633		 *                    return 'Unhandled exception: ' + exception;
10634		 *          } );
10635		 * @result Array<Function>
10636		 *
10637		 * @name afterFinally
10638		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10639		 * @option Object target Target object to be weaved. 
10640		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
10641		 * @param Function advice Function containing the code that will get called after the execution of the point-cut regardless of its success or failure.
10642		 *                        It receives two parameters, the first one with the result of a successful execution or null, and the second one with the 
10643		 *                        exception or null.
10644		 *
10645		 * @type Array<Function>
10646		 * @cat Plugins/General
10647		 */
10648		afterFinally : function(pointcut, advice)
10649		{
10650			return weave( pointcut, { type: _afterFinally, value: advice } );
10651		},
10652
10653
10654		/**
10655		 * Creates an advice before the defined point-cut. The advice will be executed before the point-cut method 
10656		 * but cannot modify the behavior of the method, or prevent its execution.
10657		 * This function returns an array of weaved aspects (Function).
10658		 *
10659		 * @example jQuery.aop.before( {target: window, method: 'MyGlobalMethod'}, function() { 
10660		 *                alert('About to execute MyGlobalMethod'); 
10661		 *          } );
10662		 * @result Array<Function>
10663		 *
10664		 * @example jQuery.aop.before( {target: String, method: 'indexOf'}, function(index) {
10665		 *                alert('About to execute String.indexOf on: ' + this);
10666		 *          } );
10667		 * @result Array<Function>
10668		 *
10669		 * @name before
10670		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10671		 * @option Object target Target object to be weaved. 
10672		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
10673		 * @param Function advice Function containing the code that will get called before the execution of the point-cut.
10674		 *
10675		 * @type Array<Function>
10676		 * @cat Plugins/General
10677		 */
10678		before : function(pointcut, advice)
10679		{
10680			return weave( pointcut, { type: _before, value: advice } );
10681		},
10682
10683
10684		/**
10685		 * Creates an advice 'around' the defined point-cut. This type of advice can control the point-cut method execution by calling
10686		 * the functions '.proceed()' on the 'invocation' object, and also, can modify the arguments collection before sending them to the function call.
10687		 * This function returns an array of weaved aspects (Function).
10688		 *
10689		 * @example jQuery.aop.around( {target: window, method: 'MyGlobalMethod'}, function(invocation) {
10690		 *                alert('# of Arguments: ' + invocation.arguments.length); 
10691		 *                return invocation.proceed(); 
10692		 *          } );
10693		 * @result Array<Function>
10694		 *
10695		 * @example jQuery.aop.around( {target: String, method: 'indexOf'}, function(invocation) { 
10696		 *                alert('Searching: ' + invocation.arguments[0] + ' on: ' + this); 
10697		 *                return invocation.proceed(); 
10698		 *          } );
10699		 * @result Array<Function>
10700		 *
10701		 * @example jQuery.aop.around( {target: window, method: /Get(\d+)/}, function(invocation) {
10702		 *                alert('Executing ' + invocation.method); 
10703		 *                return invocation.proceed(); 
10704		 *          } );
10705		 * @desc Matches all global methods starting with 'Get' and followed by a number.
10706		 * @result Array<Function>
10707		 *
10708		 *
10709		 * @name around
10710		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10711		 * @option Object target Target object to be weaved. 
10712		 * @option String method Name of the function to be weaved. Regex are supported, but not on built-in objects.
10713		 * @param Function advice Function containing the code that will get called around the execution of the point-cut. This advice will be called with one
10714		 *                        argument containing one function '.proceed()', the collection of arguments '.arguments', and the matched method n
10714ame '.method'.
10715		 *
10716		 * @type Array<Function>
10717		 * @cat Plugins/General
10718		 */
10719		around : function(pointcut, advice)
10720		{
10721			return weave( pointcut, { type: _around, value: advice } );
10722		},
10723
10724		/**
10725		 * Creates an introduction on the defined point-cut. This type of advice replaces any existing methods with the same
10726		 * name. To restore them, just unweave it.
10727		 * This function returns an array with only one weaved aspect (Function).
10728		 *
10729		 * @example jQuery.aop.introduction( {target: window, method: 'MyGlobalMethod'}, function(result) {
10730		 *                alert('Returned: ' + result);
10731		 *          } );
10732		 * @result Array<Function>
10733		 *
10734		 * @example jQuery.aop.introduction( {target: String, method: 'log'}, function() {
10735		 *                alert('Console: ' + this);
10736		 *          } );
10737		 * @result Array<Function>
10738		 *
10739		 * @name introduction
10740		 * @param Map pointcut Definition of the point-cut to apply the advice. A point-cut is the definition of the object/s and method/s to be weaved.
10741		 * @option Object target Target object to be weaved. 
10742		 * @option String method Name of the function to be weaved.
10743		 * @param Function advice Function containing the code that will be executed on the point-cut. 
10744		 *
10745		 * @type Array<Function>
10746		 * @cat Plugins/General
10747		 */
10748		introduction : function(pointcut, advice)
10749		{
10750			return weave( pointcut, { type: _intro, value: advice } );
10751		},
10752		
10753		/**
10754		 * Configures global options.
10755		 *
10756		 * @name setup
10757		 * @param Map settings Configuration options.
10758		 * @option Boolean regexMatch Enables/disables regex matching of method names.
10759		 *
10760		 * @example jQuery.aop.setup( { regexMatch: false } );
10761		 * @desc Disable regex matching.
10762		 *
10763		 * @type Void
10764		 * @cat Plugins/General
10765		 */
10766		setup: function(settings)
10767		{
10768			_regexEnabled = settings.regexMatch;
10769		}
10770	};
10771
10772})();
10773
vendor: 23,062 bytes, lines 10774-11480
10774///#source 1 1 /src/1.0.0/load.js
10775/*! head.load - v1.0.3 */
10776/*
10777 * HeadJS     The only script in your <HEAD>
10778 * Author     Tero Piirainen  (tipiirai)
10779 * Maintainer Robert Hoffmann (itechnology)
10780 * License    MIT / http://bit.ly/mit-license
10781 * WebSite    http://headjs.com
10782 */
10783(function (win, undefined) {
10784    "use strict";
10785
10786    //#region variables
10787    var doc        = win.document,
10788        domWaiters = [],
10789        handlers   = {}, // user functions waiting for events
10790        assets     = {}, // loadable items in various states
10791        isAsync    = "async" in doc.createElement("script") || "MozAppearance" in doc.documentElement.style || win.opera,
10792        isDomReady,
10793
10794        /*** public API ***/
10795        headVar = win.head_conf && win.head_conf.head || "head",
10796        api     = win[headVar] = (win[headVar] || function () { api.ready.apply(null, arguments); }),
10797
10798        // states
10799        PRELOADING = 1,
10800        PRELOADED  = 2,
10801        LOADING    = 3,
10802        LOADED     = 4;
10803    //#endregion
10804
10805    //#region PRIVATE functions
10806
10807    //#region Helper functions
10808    function noop() {
10809        // does nothing
10810    }
10811
10812    function each(arr, callback) {
10813        if (!arr) {
10814            return;
10815        }
10816
10817        // arguments special type
10818        if (typeof arr === "object") {
10819            arr = [].slice.call(arr);
10820        }
10821
10822        // do the job
10823        for (var i = 0, l = arr.length; i < l; i++) {
10824            callback.call(arr, arr[i], i);
10825        }
10826    }
10827
10828    /* A must read: http://bonsaiden.github.com/JavaScript-Garden
10829     ************************************************************/
10830    function is(type, obj) {
10831        var clas = Object.prototype.toString.call(obj).slice(8, -1);
10832        return obj !== undefined && obj !== null && clas === type;
10833    }
10834
10835    function isFunction(item) {
10836        return is("Function", item);
10837    }
10838
10839    function isArray(item) {
10840        return is("Array", item);
10841    }
10842
10843    function toLabel(url) {
10844        ///<summary>Converts a url to a file label</summary>
10845        var items = url.split("/"),
10846             name = items[items.length - 1],
10847             i    = name.indexOf("?");
10848
10849        return i !== -1 ? name.substring(0, i) : name;
10850    }
10851
10852    // INFO: this look like a "im triggering callbacks all over the place, but only wanna run it one time function" ..should try to make everything work without it if possible
10853    // INFO: Even better. Look into promises/defered's like jQuery is doing
10854    function one(callback) {
10855        ///<summary>Execute a callback only once</summary>
10856        callback = callback || noop;
10857
10858        if (callback._done) {
10859            return;
10860        }
10861
10862        callback();
10863        callback._done = 1;
10864    }
10865    //#endregion
10866
10867    function conditional(test, success, failure, callback) {
10868        ///<summary>
10869        /// INFO: use cases:
10870        ///    head.test(condition, null       , "file.NOk" , callback);
10871        ///    head.test(condition, "fileOk.js", null       , callback);
10872        ///    head.test(condition, "fileOk.js", "file.NOk" , callback);
10873        ///    head.test(condition, "fileOk.js", ["file.NOk", "file.NOk"], callback);
10874        ///    head.test({
10875        ///               test    : condition,
10876        ///               success : [{ label1: "file1Ok.js"  }, { label2: "file2Ok.js" }],
10877        ///               failure : [{ label1: "file1NOk.js" }, { label2: "file2NOk.js" }],
10878        ///               callback: callback
10879        ///    );
10880        ///    head.test({
10881        ///               test    : condition,
10882        ///               success : ["file1Ok.js" , "file2Ok.js"],
10883        ///               failure : ["file1NOk.js", "file2NOk.js"],
10884        ///               callback: callback
10885        ///    );
10886        ///</summary>
10887        var obj = (typeof test === "object") ? test : {
10888            test: test,
10889            success: !!success ? isArray(success) ? success : [success] : false,
10890            failure: !!failure ? isArray(failure) ? failure : [failure] : false,
10891            callback: callback || noop
10892        };
10893
10894        // Test Passed ?
10895        var passed = !!obj.test;
10896
10897        // Do we have a success case
10898        if (passed && !!obj.success) {
10899            obj.success.push(obj.callback);
10900            api.load.apply(null, obj.success);
10901        }
10902        // Do we have a fail case
10903        else if (!passed && !!obj.failure) {
10904            obj.failure.push(obj.callback);
10905            api.load.apply(null, obj.failure);
10906        }
10907        else {
10908            callback();
10909        }
10910
10911        return api;
10912    }
10913
10914    function getAsset(item) {
10915        ///<summary>
10916        /// Assets are in the form of
10917        /// {
10918        ///     name : label,
10919        ///     url  : url,
10920        ///     state: state
10921        /// }
10922        ///</summary>
10923        var asset = {};
10924
10925        if (typeof item === "object") {
10926            for (var label in item) {
10927                if (!!item[label]) {
10928                    asset = {
10929                        name: label,
10930                        url : item[label]
10931                    };
10932                }
10933            }
10934        }
10935        else {
10936            asset = {
10937                name: toLabel(item),
10938                url : item
10939            };
10940        }
10941
10942        // is the item already existant
10943        var existing = assets[asset.name];
10944        if (existing && existing.url === asset.url) {
10945            return existing;
10946        }
10947
10948        assets[asset.name] = asset;
10949        return asset;
10950    }
10951
10952    function allLoaded(items) {
10953        items = items || assets;
10954
10955        for (var name in items) {
10956            if (items.hasOwnProperty(name) && items[name].state !== LOADED) {
10957                return false;
10958            }
10959        }
10960
10961        return true;
10962    }
10963
10964    function onPreload(asset) {
10965        asset.state = PRELOADED;
10966
10967        each(asset.onpreload, function (afterPreload) {
10968            afterPreload.call();
10969        });
10970    }
10971
10972    function preLoad(asset, callback) {
10973        if (asset.state === undefined) {
10974
10975            asset.state     = PRELOADING;
10976            asset.onpreload = [];
10977
10978            loadAsset({ url: asset.url, type: "cache" }, function () {
10979                onPreload(asset);
10980            });
10981        }
10982    }
10983
10984    function apiLoadHack() {
10985        /// <summary>preload with text/cache hack
10986        ///
10987        /// head.load("http://domain.com/file.js","http://domain.com/file.js", callBack)
10988        /// head.load(["http://domain.com/file.js","http://domain.com/file.js"], callBack)
10989        /// head.load({ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }, callBack)
10990        /// head.load([{ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }], callBack)
10991        /// </summary>
10992        var args     = arguments,
10993            callback = args[args.length - 1],
10994            rest     = [].slice.call(args, 1),
10995            next     = rest[0];
10996
10997        if (!isFunction(callback)) {
10998            callback = null;
10999        }
11000
11001        // if array, repush as args
11002        if (isArray(args[0])) {
11003            args[0].push(callback);
11004            api.load.apply(null, args[0]);
11005
11006            return api;
11007        }
11008
11009        // multiple arguments
11010        if (!!next) {
11011            /* Preload with text/cache hack (not good!)
11012             * http://blog.getify.com/on-script-loaders/
11013             * http://www.nczonline.net/blog/2010/12/21/thoughts-on-script-loaders/
11014             * If caching is not configured correctly on the server, then items could load twice !
11015             *************************************************************************************/
11016            each(rest, function (item) {
11017                // item is not a callback or empty string
11018                if (!isFunction(item) && !!item) {
11019                    preLoad(getAsset(item));
11020                }
11021            });
11022
11023            // execute
11024            load(getAsset(args[0]), isFunction(next) ? next : function () {
11025                api.load.apply(null, rest);
11026            });
11027        }
11028        else {
11029            // single item
11030            load(getAsset(args[0]));
11031        }
11032
11033        return api;
11034    }
11035
11036    function apiLoadAsync() {
11037        ///<summary>
11038        /// simply load and let browser take care of ordering
11039        ///
11040        /// head.load("http://domain.com/file.js","http://domain.com/file.js", callBack)
11041        /// head.load(["http://domain.com/file.js","http://domain.com/file.js"], callBack)
11042        /// head.load({ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }, callBack)
11043        /// head.load([{ label1: "http://domain.com/file.js" }, { label2: "http://domain.com/file.js" }], callBack)
11044        ///</summary>
11045        var args     = arguments,
11046            callback = args[args.length - 1],
11047            items    = {};
11048
11049        if (!isFunction(callback)) {
11050            callback = null;
11051        }
11052
11053        // if array, repush as args
11054        if (isArray(args[0])) {
11055            args[0].push(callback);
11056            api.load.apply(null, args[0]);
11057
11058            return api;
11059        }
11060
11061        // JRH 262#issuecomment-26288601
11062        // First populate the items array.
11063        // When allLoaded is called, all items will be populated.
11064        // Issue when lazy loaded, the callback can execute early.
11065        each(args, function (item, i) {
11066            if (item !== callback) {
11067                item             = getAsset(item);
11068                items[item.name] = item;
11069            }
11070        });
11071
11072        each(args, function (item, i) {
11073            if (item !== callback) {
11074                item = getAsset(item);
11075
11076                load(item, function () {
11077                    if (allLoaded(items)) {
11078                        one(callback);
11079                    }
11080                });
11081            }
11082        });
11083
11084        return api;
11085    }
11086
11087    function load(asset, callback) {
11088        ///<summary>Used with normal loading logic</summary>
11089        callback = callback || noop;
11090
11091        if (asset.state === LOADED) {
11092            callback();
11093            return;
11094        }
11095
11096        // INFO: why would we trigger a ready event when its not really loaded yet ?
11097        if (asset.state === LOADING) {
11098            api.ready(asset.name, callback);
11099            return;
11100        }
11101
11102        if (asset.state === PRELOADING) {
11103            asset.onpreload.push(function () {
11104                load(asset, callback);
11105            });
11106            return;
11107        }
11108
11109        asset.state = LOADING;
11110
11111        loadAsset(asset, function () {
11112            asset.state = LOADED;
11113
11114            callback();
11115
11116            // handlers for this asset
11117            each(handlers[asset.name], function (fn) {
11118                one(fn);
11119            });
11120
11121            // dom is ready & no assets are queued for loading
11122            // INFO: shouldn't we be doing the same test above ?
11123            if (isDomReady && allLoaded()) {
11124                each(handlers.ALL, function (fn) {
11125                    one(fn);
11126                });
11127            }
11128        });
11129    }
11130
11131    function getExtension(url) {
11132        url = url || "";
11133
11134        var items = url.split("?")[0].split(".");
11135        return items[items.length-1].toLowerCase();
11136    }
11137
11138    /* Parts inspired from: https://github.com/cujojs/curl
11139    ******************************************************/
11140    function loadAsset(asset, callback) {
11141        callback = callback || noop;
11142
11143        function error(event) {
11144            event = event || win.event;
11145
11146            // release event listeners
11147            ele.onload = ele.onreadystatechange = ele.onerror = null;
11148
11149            // do callback
11150            callback();
11151
11152            // need some more detailed error handling here
11153        }
11154
11155        function process(event) {
11156            event = event || win.event;
11157
11158            // IE 7/8 (2 events on 1st load)
11159            // 1) event.type = readystatechange, s.readyState = loading
11160            // 2) event.type = readystatechange, s.readyState = loaded
11161
11162            // IE 7/8 (1 event on reload)
11163            // 1) event.type = readystatechange, s.readyState = complete
11164
11165            // event.type === 'readystatechange' && /loaded|complete/.test(s.readyState)
11166
11167            // IE 9 (3 events on 1st load)
11168            // 1) event.type = readystatechange, s.readyState = loading
11169            // 2) event.type = readystatechange, s.readyState = loaded
11170            // 3) event.type = load            , s.readyState = loaded
11171
11172            // IE 9 (2 events on reload)
11173            // 1) event.type = readystatechange, s.readyState = complete
11174            // 2) event.type = load            , s.readyState = complete
11175
11176            // event.type === 'load'             && /loaded|complete/.test(s.readyState)
11177            // event.type === 'readystatechange' && /loaded|complete/.test(s.readyState)
11178
11179            // IE 10 (3 events on 1st load)
11180            // 1) event.type = readystatechange, s.readyState = loading
11181            // 2) event.type = load            , s.readyState = complete
11182            // 3) event.type = readystatechange, s.readyState = loaded
11183
11184            // IE 10 (3 events on reload)
11185            // 1) event.type = readystatechange, s.readyState = loaded
11186            // 2) event.type = load            , s.readyState = complete
11187            // 3) event.type = readystatechange, s.readyState = complete
11188
11189            // event.type === 'load'             && /loaded|complete/.test(s.readyState)
11190            // event.type === 'readystatechange' && /complete/.test(s.readyState)
11191
11192            // Other Browsers (1 event on 1st load)
11193            // 1) event.type = load, s.readyState = undefined
11194
11195            // Other Browsers (1 event on reload)
11196            // 1) event.type = load, s.readyState = undefined
11197
11198            // event.type == 'load' && s.readyState = undefined
11199
11200            // !doc.documentMode is for IE6/7, IE8+ have documentMode
11201            if (event.type === "load" || (/loaded|complete/.test(ele.readyState) && (!doc.documentMode || doc.documentMode < 9))) {
11202                // remove timeouts
11203                win.clearTimeout(asset.errorTimeout);
11204                win.clearTimeout(asset.cssTimeout);
11205
11206                // release event listeners
11207                ele.onload = ele.onreadystatechange = ele.onerror = null;
11208
11209                // do callback   
11210                callback();
11211            }
11212        }
11213
11214        function isCssLoaded() {
11215            // should we test again ? 20 retries = 5secs ..after that, the callback will be triggered by the error handler at 7secs
11216            if (asset.state !== LOADED && asset.cssRetries <= 20) {
11217
11218                // loop through stylesheets
11219                for (var i = 0, l = doc.styleSheets.length; i < l; i++) {
11220                    // do we have a match ?
11221                    // we need to tests agains ele.href and not asset.url, because a local file will be assigned the full http path on a link element
11222                    if (doc.styleSheets[i].href === ele.href) {
11223                        process({ "type": "load" });
11224                        return;
11225                    }
11226                }
11227
11228                // increment & try again
11229                asset.cssRetries++;
11230                asset.cssTimeout = win.setTimeout(isCssLoaded, 250);
11231            }
11232        }
11233
11234        var ele;
11235        var ext = getExtension(asset.url);
11236
11237        if (ext === "css") {
11238            ele      = doc.createElement("link");
11239            ele.type = "text/" + (asset.type || "css");
11240            ele.rel  = "stylesheet";
11241            ele.href = asset.url;
11242
11243            /* onload supported for CSS on unsupported browsers
11244             * Safari windows 5.1.7, FF < 10
11245             */
11246
11247            // Set counter to zero
11248            asset.cssRetries = 0;
11249            asset.cssTimeout = win.setTimeout(isCssLoaded, 500);         
11250        }
11251        else {
11252            ele      = doc.createElement("script");
11253            ele.type = "text/" + (asset.type || "javascript");
11254            ele.src = asset.url;
11255        }
11256
11257        ele.onload  = ele.onreadystatechange = process;
11258        ele.onerror = error;
11259
11260        /* Good read, but doesn't give much hope !
11261         * http://blog.getify.com/on-script-loaders/
11262         * http://www.nczonline.net/blog/2010/12/21/thoughts-on-script-loaders/
11263         * https://hacks.mozilla.org/2009/06/defer/
11264         */
11265
11266        // ASYNC: load in parallel and execute as soon as possible
11267        ele.async = false;
11268        // DEFER: load in parallel but maintain execution order
11269        ele.defer = false;
11270
11271        // timout for asset loading
11272        asset.errorTimeout = win.setTimeout(function () {
11273            error({ type: "timeout" });
11274        }, 7e3);
11275
11276        // use insertBefore to keep IE from throwing Operation Aborted (thx Bryan Forbes!)
11277        var head = doc.head || doc.getElementsByTagName("head")[0];
11278
11279        // but insert at end of head, because otherwise if it is a stylesheet, it will not override values      
11280        head.insertBefore(ele, head.lastChild);
11281    }
11282
11283    /* Parts inspired from: https://github.com/jrburke/requirejs
11284    ************************************************************/
11285    function init() {
11286        var items = doc.getElementsByTagName("script");
11287
11288        // look for a script with a data-head-init attribute
11289        for (var i = 0, l = items.length; i < l; i++) {
11290            var dataMain = items[i].getAttribute("data-headjs-load");
11291            if (!!dataMain) {
11292                api.load(dataMain);
11293                return;
11294            }
11295        }
11296    }
11297
11298    function ready(key, callback) {
11299        ///<summary>
11300        /// INFO: use cases:
11301        ///    head.ready(callBack);
11302        ///    head.ready(document , callBack);
11303        ///    head.ready("file.js", callBack);
11304        ///    head.ready("label"  , callBack);
11305        ///    head.ready(["label1", "label2"], callback);
11306        ///</summary>
11307
11308        // DOM ready check: head.ready(document, function() { });
11309        if (key === doc) {
11310            if (isDomReady) {
11311                one(callback);
11312            }
11313            else {
11314                domWaiters.push(callback);
11315            }
11316
11317            return api;
11318        }
11319
11320        // shift arguments
11321        if (isFunction(key)) {
11322            callback = key;
11323            key      = "ALL"; // holds all callbacks that where added without labels: ready(callBack)
11324        }
11325
11326        // queue all items from key and return. The callback will be executed if all items from key are already loaded.
11327        if (isArray(key)) {
11328            var items = {};
11329
11330            each(key, function (item) {
11331                items[item] = assets[item];
11332
11333                api.ready(item, function() {
11334                    if (allLoaded(items)) {
11335                        one(callback);
11336                    }
11337                });
11338            });
11339
11340            return api;
11341        }
11342
11343        // make sure arguments are sane
11344        if (typeof key !== "string" || !isFunction(callback)) {
11345            return api;
11346        }
11347
11348        // this can also be called when we trigger events based on filenames & labels
11349        var asset = assets[key];
11350
11351        // item already loaded --> execute and return
11352        if (asset && asset.state === LOADED || key === "ALL" && allLoaded() && isDomReady) {
11353            one(callback);
11354            return api;
11355        }
11356
11357        var arr = handlers[key];
11358        if (!arr) {
11359            arr = handlers[key] = [callback];
11360        }
11361        else {
11362            arr.push(callback);
11363        }
11364
11365        return api;
11366    }
11367
11368    /* Mix of stuff from jQuery & IEContentLoaded
11369     * http://dev.w3.org/html5/spec/the-end.html#the-end
11370     ***************************************************/
11371    function domReady() {
11372        // Make sure body exists, at least, in case IE gets a little overzealous (jQuery ticket #5443).
11373        if (!doc.body) {
11374            // let's not get nasty by setting a timeout too small.. (loop mania guaranteed if assets are queued)
11375            win.clearTimeout(api.readyTimeout);
11376            api.readyTimeout = win.setTimeout(domReady, 50);
11377            return;
11378        }
11379
11380        if (!isDomReady) {
11381            isDomReady = true;
11382
11383            init();
11384            each(domWaiters, function (fn) {
11385                one(fn);
11386            });
11387        }
11388    }
11389
11390    function domContentLoaded() {
11391        // W3C
11392        if (doc.addEventListener) {
11393            doc.removeEventListener("DOMContentLoaded", domContentLoaded, false);
11394            domReady();
11395        }
11396
11397        // IE
11398        else if (doc.readyState === "complete") {
11399            // we're here because readyState === "complete" in oldIE
11400            // which is good enough for us to call the dom ready!
11401            doc.detachEvent("onreadystatechange", domContentLoaded);
11402            domReady();
11403        }
11404    }
11405
11406    // Catch cases where ready() is called after the browser event has already occurred.
11407    // we once tried to use readyState "interactive" here, but it caused issues like the one
11408    // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
11409    if (doc.readyState === "complete") {
11410        domReady();
11411    }
11412
11413    // W3C
11414    else if (doc.addEventListener) {
11415        doc.addEventListener("DOMContentLoaded", domContentLoaded, false);
11416
11417        // A fallback to window.onload, that will always work
11418        win.addEventListener("load", domReady, false);
11419    }
11420
11421    // IE
11422    else {
11423        // Ensure firing before onload, maybe late but safe also for iframes
11424        doc.attachEvent("onreadystatechange", domContentLoaded);
11425
11426        // A fallback to window.onload, that will always work
11427        win.attachEvent("onload", domReady);
11428
11429        // If IE and not a frame
11430        // continually check to see if the document is ready
11431        var top = false;
11432
11433        try {
11434            top = !win.frameElement && doc.documentElement;
11435        } catch (e) { }
11436
11437        if (top && top.doScroll) {
11438            (function doScrollCheck() {
11439                if (!isDomReady) {
11440                    try {
11441                        // Use the trick by Diego Perini
11442                        // http://javascript.nwbox.com/IEContentLoaded/
11443                        top.doScroll("left");
11444                    } catch (error) {
11445                        // let's not get nasty by setting a timeout too small.. (loop mania guaranteed if assets are queued)
11446                        win.clearTimeout(api.readyTimeout);
11447                        api.readyTimeout = win.setTimeout(doScrollCheck, 50);
11448                        return;
11449                    }
11450
11451                    // and execute any waiting functions
11452                    domReady();
11453                }
11454            }());
11455        }
11456    }
11457    //#endregion
11458
11459    //#region Public Exports
11460    // INFO: determine which method to use for loading
11461    api.load  = api.js = isAsync ? apiLoadAsync : apiLoadHack;
11462    api.test  = conditional;
11463    api.ready = ready;
11464    //#endregion
11465
11466    //#region INIT
11467    // perform this when DOM is ready
11468    api.ready(doc, function () {
11469        if (allLoaded()) {
11470            each(handlers.ALL, function (callback) {
11471                one(callback);
11472            });
11473        }
11474
11475        if (api.feature) {
11476            api.feature("domloaded", true);
11477        }
11478    });
11479    //#endregion
11480}(window));
11481
11482/*
11483  Version: 1.6 (2018-12-11)
11484 */
11485
11486
11487;(function ($, window, document, undefined) {
11488    "use strict";
11489
11490    // Create the defaults once
11491    var pluginName = "ultimateGDPR",
11492        defaults = {
11493            popup_style: {
11494                position: 'bottom-right', // bottom-left, bottom-right, bottom-panel, top-left, top-right, top-panel
11495                distance: '20px', // distance betwen popup and window border
11496                box_style: 'classic', // classic, modern
11497                box_shape: 'rounded', // rounded, squared
11498                background_color: '#fff584', // color in hex
11499                text_color: '#542d04', // color in hex
11500                button_shape: 'squared', // squared, rounded
11501                button_color: '#e1e1e1', // color in hex
11502                button_size: 'normal', // normal, large
11503                box_skin: 'skin-default-theme', // skin-default-theme, skin-dark-theme, skin-light-theme
11504                gear_icon_position: 'top-right', // top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right
11505                gear_icon_color: '#000000', //color in hex
11506            },
11507            popup_options: {
11508                parent_container: 'body', // append plugin html to this element selector
11509                always_show: false, // true, false, when true popup is displayed always even when consent is given
11510                gear_display: false, // true, false when true displays icon with cookie settings
11511                popup_title: 'Cookies Information', // title for popup
11512                popup_text: 'To make this site work properly, we sometimes place small data files called cookies on your device. Most big websites do this too.', // text for popup
11513                accept_button_text: 'Accept', // string, text for accept button
11514                read_button_text: 'Read More', // string, text for read more button
11515                read_more_link: '', // string, link to the Read More page
11516                advenced_button_text: 'Change Settings', // string, text for advenced button
11517                grouped_popup: true, // true, false, when true cookies are grouped
11518                default_group: 'group_2', // string: name, select group that will be selected by default
11519                content_before_slider: '<h2>Privacy settings</h2><div class="ct-ultimate-gdpr-cookie-modal-desc"><p>Decide which cookies you want to allow.</p><p>You can change these settings at any time. However, this can result in some functions no longer being available. For information on deleting the cookies, please consult your browser’s help function.</p> <span>Learn more about the cookies we use.</span></div><h3>With the slider, you can enable or disable different types of cookies:</h3>',
11520                // string: this content will be displayed before cookies slider, html tags alowed
11521                accepted_text: 'This website will:',
11522                declined_text: "This website won't:",
11523                save_btn: 'Save & Close', // string, text for modal close btn
11524                prevent_cookies_on_document_write: true, // prevent cookies on document write when there is no agreement for cookies
11525                reset_link_selector: '.ct-uGdpr-reset',
11526                check_country: true,
11527                countries_prefixes: ['AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR', 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL', 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', '
11527SE', 'GB'],
11528                cookies_expire_time: 30, // set number of days, you can use 0 for session only
11529                cookies_path: '/', // sets custom path use / for global, '/your_path' for custom path or 'current' for current path
11530                first_party_cookies_whitelist: [],
11531                third_party_cookies_whitelist: [],
11532                accept_cookie_subdomain: false,
11533                accept_url_subdomain: "example.com",
11534                cookies_groups_design: 'skin-1', // skin-1, skin-2, skin-3
11535                assets_path : 'assets', // absolute path to directory with assets
11536                video_blocked: 'This content is blocked',
11537                cookies_groups: {
11538                    group_1: {
11539                        name: 'Essential', // string: name
11540                        enable: true, // true, false, you can disable this group by using false
11541                        icon: 'fas fa-check', // string icon class from font-awesome see -> http://fontawesome.io
11542                        list: ['Remember your cookie permission setting', 'Allow session cookies', 'Gather information you input into a contact forms, newsletter and other forms across all pages', 'Keep track of what you input in shopping cart', 'Authenticate that you are logged into your user account', 'Remember language version you selected'], // array list of options
11543                        blocked_url: ['http://get.exitintel.com/load.js?exitintelAccount=371'], // array list of url blocked scripts
11544                        local_cookies_name: [''], // array, list of local cookies names
11545                    },
11546                    group_2: {
11547                        name: 'Functionality', // string: name
11548                        enable: true, // true, false, you can disable this group by using false
11549                        icon: 'fas fa-cog', // string icon class from font-awesome see -> http://fontawesome.io
11550                        list: ['Remember social media settings', 'Remember selected region and country',],
11551                        blocked_url: [''], // array list of url blocked scripts
11552                        local_cookies_name: [''], // array, list of local cookies names
11553                    },
11554                    group_3: {
11555                        name: 'Analytics', // string: name
11556                        enable: true, // true, false, you can disable this group by using false
11557                        icon: 'fas fa-chart-bar', // string icon class from font-awesome see -> http://fontawesome.io
11558                        list: ['Keep track of your visited pages and interaction taken', 'Keep track about your location and region based on your IP number', 'Keep track on the time spent on each page', 'Increase the data quality of the statistics functions'],
11559                        blocked_url: [''], // array list of url blocked scripts
11560                        local_cookies_name: [''], // array, list of local cookies names
11561                    },
11562                    group_4: {
11563                        name: 'Advertising', // string: name
11564                        enable: true, // true, false, you can disable this group by using false
11565                        icon: 'fas fa-exchange-alt', // string icon class from font-awesome see -> http://fontawesome.io
11566                        list: ['Use information for tailored advertising with third parties', 'Allow you to connect to social sites', 'Identify device you are using', 'Gather personally identifiable information such as name and location'],
11567                        blocked_url: [''], // array list of url blocked scripts
11568                        local_cookies_name: [''], // array, list of local cookies names
11569                    },
11570                },
11571            },
11572            age_popup_style: {
11573                position: 'bottom-right', // bottom-left, bottom-right, bottom-panel, top-left, top-right, top-panel
11574                distance: '20px', // distance betwen popup and window border
11575                box_style: 'classic', // classic, modern
11576                box_shape: 'rounded', // rounded, squared
11577                background_color: '#fff584', // color in hex
11578                text_color: '#542d04', // color in hex
11579                button_shape: 'squared', // squared, rounded
11580                button_color: '#e1e1e1', // color in hex
11581                box_skin: 'skin-default-theme', // skin-default-theme, skin-dark-theme, skin-light-theme
11582            },
11583            age_popup_options: {
11584                parent_container: 'body', // append plugin html to this element selector
11585                always_show: false, // true, false, when true popup is displayed always even when consent is given
11586                popup_title: 'Age verification', // title for popup
11587                popup_text: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.', // text for popup
11588                age_limit: 0, // age limit to enter
11589                assets_path : 'assets', // absolute path to directory with assets
11590            },
11591            forms: {
11592                prevent_forms_send: true, // true, false, when enabled forms get checkbox with info that need to be checked for form send
11593                prevent_forms_text: 'I consent to the storage of my data according to the Privacy Policy', // string: information for checkbox info
11594                prevent_forms_exclude: [], // array of selectors (classes, id), this forms will be excluded from prevent
11595            },
11596            configure_mode: {
11597                on: true,
11598                parametr: '?configure123456',
11599                dependencies: ['https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', 'assets/css/ct-ultimate-gdpr.min.css', 'https://use.fontawesome.com/releases/v5.0.13/css/all.css'],
11600                debug: false, // bool: true false, debug mode on/off (showing all 3rd party cookies urls, blockes urls names of all local cookies and names of blocked local cookies )
11601            },
11602        },
11603
11604        values = {
11605            popup_style: {
11606                position: ['bottom-left', 'bottom-right', 'bottom-panel', 'top-left', 'top-right', 'top-panel'],
11607                distance: 'text',
11608                box_style: ['classic', 'modern'],
11609                box_shape: ['rounded', 'squared'],
11610                background_color: 'color',
11611                text_color: 'color',
11612                button_shape: ['squared', 'rounded'],
11613                button_color: 'color',
11614                button_size: ['normal', 'large'],
11615                box_skin: ['skin-default-theme', 'skin-dark-theme', 'skin-light-theme'],
11616                gear_icon_position: ['top-left', 'top-center', 'top-right', 'center-left', 'center-right', 'bottom-left', 'bottom-center', 'bottom-right'],
11617                gear_icon_color: 'color',
11618            },
11619            popup_options: {
11620                parent_container: 'text',
11621                always_show: 'checkbox',
11622                gear_display: 'checkbox',
11623                popup_title: 'textarea',
11624                popup_text: 'textarea',
11625                accept_button_text: 'text',
11626                read_button_text: 'text',
11627                read_more_link: 'text',
11628                advenced_button_text: 'text',
11629                grouped_popup: 'checkbox',
11630                default_group: 'text',
11631                content_before_slider: 'textarea',
11632                accepted_text: 'text',
11633                declined_text: "text",
11634                save_btn: 'text',
11635                prevent_cookies_on_document_write: 'checkbox',
11636                check_country: 'checkbox',
11637                countries_prefixes: 'list',
11638                reset_link_selector: 'text',
11639                first_party_cookies_whitelist: 'list',
11640                third_party_cookies_whitelist: 'list',
11641                cookies_groups_design: ['skin-1', 'skin-2', 'skin-3'],
11642                accept_cookie_subdomain: "checkbox",
11643                accept_url_subdomain: "text",
11644                assets_path : 'textarea',
11645                video_blocked: 'text',
11646                cookies_groups: {
11647                    group_1: {
11648                        name: 'text',
11649                        enable: 'checkbox',
11650                        icon: 'text',
11651                        list: 'list',
11652                        blocked_url: 'list',
11653                        local_cookies_name: 'list',
11654                    },
11655                    group_2: {
11656                        name: 'text',
11657                        enable: 'checkbox',
11658                        icon: 'text',
11659                        list: 'list',
11660                        blocked_url: 'list',
11661                        local_cookies_name: 'list',
11662                    },
11663                    group_3: {
11664                        name: 'text',
11665                        enable: 'checkbox',
11666                        icon: 'text',
11667                        list: 'list',
11668                        blocked_url: 'list',
11669                        local_cookies_name: 'list',
11670                    },
11671                    group_4: {
11672                        name: 'text',
11673                        enable: 'checkbox',
11674                        icon: 'text',
11675                        list: 'list',
11676                        blocked_url: 'list',
11677                        local_cookies_name: 'list',
11678                    },
11679                },
11680            },
11681            age_popup_style: {
11682                position: ['bottom-left', 'bottom-right', 'bottom-panel', 'top-left', 'top-right', 'top-panel'],
11683                distance: 'text',
11684                box_style: ['classic', 'modern'],
11685                box_shape: ['rounded', 'squared'],
11686                background_color: 'color',
11687                text_color: 'color',
11688                button_shape: ['squared', 'rounded'],
11689                button_color: 'color',
11690                box_skin: ['skin-default-theme', 'skin-dark-theme', 'skin-light-theme'],
11691            },
11692            age_popup_options: {
11693                parent_container: 'text',
11694                always_show: 'checkbox',
11695                popup_title: 'textarea',
11696                popup_text: 'textarea',
11697                age_limit: 'number',
11698                assets_path : 'textarea',
11699            },
11700            forms: {
11701                prevent_forms_send: 'checkbox', // true, false, when enabled forms get checkbox with info that need to be checked for form send
11702                prevent_forms_text: 'text', // string: information for checkbox info
11703                prevent_forms_exclude: 'list', // array of selectors (classes, id), this forms will be excluded from prevent
11704            },
11705            configure_mode: {
11706                on: 'checkbox',
11707                parametr: 'text',
11708                dependencies: 'list',
11709                debug: 'checkbox', // bool: true false, debug mode on/off (showing all 3rd party cookies urls, blockes urls names of all local cookies and names of blocked local cookies )
11710            },
11711        },
11712
11713        descriptions = {
11714            popup_style: {
11715                position: 'Position of popup box',
11716                distance: 'Distance between ',
11717                box_style: 'Style of popup box',
11718                box_shape: 'Shape of popup box',
11719                background_color: 'Background color for popup box',
11720                text_color: 'Popup box text color',
11721                button_shape: 'Popup box buttons shape',
11722                button_color: 'Buttons color for popup box',
11723                button_size: 'Buttons size',
11724                box_skin: 'Box skin theme',
11725                gear_icon_position: 'Gear icon position',
11726                gear_icon_color: 'Gear icon color',
11727            },
11728            popup_options: {
11729                parent_container: 'Parent Container CSS Selector, append plugin html there',
11730                always_show: 'Always show popup box',
11731                gear_display: 'Show gear',
11732                popup_title: 'Header in popup box',
11733                popup_text: 'Text in popup box',
11734                accept_button_text: 'Text for accept button',
11735                read_button_text: 'Text for read more button',
11736                read_more_link: 'Link for read more button',
11737                advenced_button_text: 'Text for advenced button',
11738                grouped_popup: 'Display groups in popup',
11739                default_group: 'Default group of cookies',
11740                content_before_slider: 'Content displayed before groups in modal window',
11741                accepted_text: 'Text for used options',
11742                declined_text: "Text for not used options",
11743                save_btn: 'Text for save button',
11744                prevent_cookies_on_document_write: 'Prevent cookies created with document.write() when there is no agreement for cookies',
11745                check_country: 'Display popup only in some of the countries',
11746                countries_prefixes: 'List of countries, use prefixes example: UK, FR',
11747                reset_link_selector: 'Selector (class or id) for link used to reset cookies consent',
11748                first_party_cookies_whitelist: 'White list of first party cookies that will be always allowed',
11749                third_party_cookies_whitelist: 'White list of second party cookies that will be always allowed',
11750                accept_cookie_subdomain: "If you are using sub-domains",
11751                accept_url_subdomain: "Subdomain URL ex. (example.com)",
11752                video_blocked: 'Text to be displayed on blocked videos',
11753                cookies_groups: {
11754                    group_1: {
11755                        name: 'Group name', // string: name
11756                        enable: "Enable this group?", // true, false, you can disable this group by using false
11757                        icon: 'Icon class, please go to https://fontawesome.com/ and choose icon class, you can use another font set but you must add them as a dependency', // string icon class from font-awesome see -> http://fontawesome.io
11758                        list: 'List of cookies functions', // array list of options
11759                        blocked_url: 'List of allowed external cookies', // array list of url blocked scripts
11760                        local_cookies_name: "List of allowed local cookies", // array, list of local cookies names
11761                    },
11762                    group_2: {
11763                        name: 'Group name', // string: name
11764                        enable: "Enable this group?", // true, false, you can disable this group by using false
11765                        icon: 'Icon class, please go to https://fontawesome.com/ and choose icon class, you can use another font set but you must add them as a dependency', // string icon class from font-awesome see -> http://fontawesome.io
11766                        list: 'List of cookies functions', // array list of options
11767                        blocked_url: 'List of allowed external cookies', // array list of url blocked scripts
11768                        local_cookies_name: "List of allowed local cookies", // array, list of local cookies names
11769                    },
11770                    group_3: {
11771                        name: 'Group name', // string: name
11772                        enable: "Enable this group?", // true, false, you can disable this group by using false
11773                        icon: 'Icon class, please go to https://fontawesome.com/ and choose icon class, you can use another font set but you must add them as a dependency', // string icon class from font-awesome see -> http://fontawesome.io
11774                        list: 'List of cookies functions', // array list of options
11775                        blocked_url: 'List of allowed external cookies', // array list of url blocked scripts
11776                        local_cookies_name: "List of allowed local cookies", // array, list of local cookies names
11777                    },
11778                    group_4: {
11779                        name: 'Group name', // string: name
11780                        enable: "Enable this group?", // true, false, you can disable this group by using false
11781                        icon: 'Icon class, please go to https://fontawesome.com/ and choose icon class, you can use another font set but you must add them as a dependency', // string icon class from font-awesome see -> http://fontawesome.io
11782                        list: 'List of cookies functions', // array list of options
11783                        blocked_url: 'List of allowed external cookies', // array list of url blocked scripts
11784                        local_cookies_name: "List of allowed local cookies", // array, list of local cookies names
11785                    },
11786                },
11787                cookies_groups_design: 'Skin of popup modal',
11788                assets_path : 'absolute path to directory assets', // absolute path to directory with assets
11789            },
11790            age_popup_style: {
11791                position: 'Position of popup box',
11792                distance: 'Distance between ',
11793                box_style: 'Style of popup box',
11794                box_shape: 'Shape of popup box',
11795                background_color: 'Background color for popup box',
11796                text_color: 'Popup box text color',
11797                button_shape: 'Popup box buttons shape',
11798                button_color: 'Buttons color for popup box',
11799                box_skin: 'Box skin theme',
11800            },
11801            age_popup_options: {
11802                parent_container: 'Parent Container CSS Selector, append plugin html there',
11803                always_show: 'Always show popup box',
11804                popup_title: 'Header in popup box',
11805                popup_text: 'Text in popup box',
11806                age_limit: 'Age limit to enter',
11807                assets_path : 'absolute path to directory assets', // absolute path to directory with assets
11808            },
11809            forms: {
11810                prevent_forms_send: 'This option add checkbox for all forms with information about Privacy policy', // true, false, when enabled forms get checkbox with info that need to be checked for form send
11811                prevent_forms_text: 'Information that will be displayed with checkbox', // string: information for checkbox info
11812                prevent_forms_exclude: 'List of classes and id, this forms will be excluded from form preventing', // array of selectors (classes, id), this forms will be excluded from prevent
11813            },
11814            configure_mode: {
11815                on: 'On/off for this mode',
11816                parametr: 'String that is used to enter configuration manager when he is on',
11817                dependencies: 'List of dependencies, be careful when you delete default dependencie plugin may not work',
11818                debug: 'Plugin debug mode, for advenced users only', // bool: true false, debug mode on/off (showing all 3rd party cookies urls, blockes urls names of all local cookies and names of blocked local cookies )
11819            }
11820        };
11821
11822    // The actual plugin constructor
11823    function Plugin(element, options) {
11824        this.element = element;
11825        this.settings = $.extend({}, defaults, options);
11826        this.values = $.extend({}, values);
11827        this.descriptions = $.extend({}, descriptions);
11828        this._defaults = defaults;
11829        // this._values = values;
11830        // this._descriptions = descriptions;
11831        this._name = pluginName;
11832        this.body = $('html');
11833        this.html = element;
11834        this.init();
11835        this.buttonCount = 0;
11836        this.countryGlobal;
11837        this.cookieDate = '';
11838    }
11839
11840    // Avoid Plugin.prototype conflicts
11841    $.extend(Plugin.prototype, {
11842
11843        // main method
11844        init: function () {
11845
11846            // variebles
11847            var self = this;
11848
11849            // getting cookies exp date
11850            self.cookiesProp();
11851
11852            var scriptParent = document.getElementsByTagName('script')[0].parentNode;
11853            var popupOptionStyle = self.settings.popup_style;
11854            var popupOptions = self.settings.popup_options;
11855            var formsOptions = self.settings.forms;
11856            var configurationOptions = self.settings.configure_mode;
11857
11858
11859            // loading assets
11860            self.loadAssets();
11861
11862            // configuration mode
11863            if (configurationOptions.on && document.URL.indexOf(configurationOptions.parametr) >= 0) {
11864                $(function () {
11865                    var $body = $('body');
11866                    var $modal = $('<div id="ct-ultimate-gdpr-cookie-modal" style="display: block;"><div class="ct-ultimate-gdpr-cookie-modal-content"></div></div>')
11867                    var $firstContent = $('<div class="ct-uGdpr-modalWelcome"><h1>Please select option:</h1><br><br><div class="form-group"><label class="ct-uGdpr__BlockLabel" for="license">Please enter here your license number:</label><input id="license" type="text" value="XYZ"></div><div class="ct-uGdpr-error"></div><br><br><button class="ct-gdpr-cookieList pull-left btn btn-primary mb-2">Cookie list</button><button class="ct-gdpr-ownCookieList pull-left btn btn-primary mb-2">Add your own cookie list</button><div class="clearfix"></div></div>');
11868                    $modal.find('.ct-ultimate-gdpr-cookie-modal-content').append($firstContent);
11869                    $body.append($modal);
11870
11871					var buttonCount = 0;
11872
11873                    $('.ct-gdpr-ownCookieList').on('click', function (e) {
11874                        e.preventDefault(); 
11875                        self.confInit(false, buttonCount);
11876                    });
11877
11878                    $('.ct-gdpr-cookieList').on('click', function (e) {
11879                        e.preventDefault();
11880                        buttonCount++;
11881                        var lic = $('#license').val();
11882                        self.confInit(true, buttonCount, lic);
11883                    });
11884                });
11885            } else {
11886
11887                // setting cookies reset on link when exists
11888                $(function(){
11889                    var slectroForCookiesReet = self.settings.popup_options.reset_link_selector;
11890                    if ($(slectroForCookiesReet).length > 0){
11891                        self.resetCookies();
11892                    }
11893                });
11894
11895                // preventing 3rd parthy cookies
11896                self.aopAround(scriptParent, "insertBefore");
11897                self.aopAround(scriptParent, "appendChild");
11898                if (popupOptions.prevent_cookies_on_document_write){
11899                    self.aopAroundForDocumentWrite();
11900                }
11901
11902                // preventing 1st party cookies
11903                self.localCookies();
11904                if (self.settings.debug) {
11905                    self.localCookiesList();
11906                }
11907
11908                if (popupOptions.check_country){
11909                    // if country cookie is not set
11910
11911                    if (this.checkCookie('gdprPluginCountry') == null){
11912                        // checking country
11913
11914                        $.ajax({
11915                            url: 'https://json.geoiplookup.io/',
11916                            type: 'get',
11917                            dataType: 'json',
11918                            success : function( response ) {
11919                                var country = response.country_code;
11920                                self.countryGlobal = country;
11921                                // if country is not on a list
11922                                if (popupOptions.countries_prefixes.indexOf(country) < 0){
11923                                    // setting cookies
11924                                    document.cookie = "gdprPluginCountry=" + country + self.cookieProperties;
11925                                    document.cookie = "gdprPlugin=false"  + self.cookieProperties;
11926                                }else{
11927                                    // showing setting when option is enabled
11928                                    if (popupOptions.gear_display && popupOptions.grouped_popup) {
11929                                        self.settingPopUp();
11930                                    }
11931
11932                                    // showing popup when cookies arent accepted or always show option is enabled
11933                                    if (self.checkCookie('gdprPlugin') !== 'true' || popupOptions.always_show) {
11934                                        self.popUpBox();
11935                                        self.agePopup();
11936                                    }
11937
11938                                    // creating modal when grouped plugin is enabled
11939                                    if (popupOptions.grouped_popup) {
11940                                        self.popupModal();
11941                                    }
11942
11943                                    // preventing forms send
11944                                    if (formsOptions.prevent_forms_send) {
11945                                        self.preventForms();
11946                                    }
11947
11948                                    // adding events to modal windows (show, hide etc)
11949                                    self.modalEvents();
11950
11951                                    // setting active group in groups select
11952                                    self.selectCookieGroup();
11953                                }
11954
11955                            },
11956                            error: function(jqXHR, textStatus, errorThrown){
11957                                console.log(jqXHR);
11958                                console.log(textStatus);
11959                                console.log(errorThrown);
11960                            },
11961                        });
11962
11963                        // if country cookie is set
11964                    }else{
11965                        // checking if country is on a list
11966                        var country = self.checkCookie('gdprPluginCountry');
11967
11968                        if (popupOptions.countries_prefixes.indexOf(country) >= 0){
11969                            // showing setting when option is enabled
11970                            if (popupOptions.gear_display && popupOptions.grouped_popup) {
11971                                self.settingPopUp();
11972                            }
11973
11974                            // showing popup when cookies arent accepted or always show option is enabled
11975                            if (this.checkCookie('gdprPlugin') !== 'true' || popupOptions.always_show) {
11976                                self.popUpBox();
11977                                self.agePopup();
11978                            }
11979
11980                            // creating modal when grouped plugin is enabled
11981                            if (popupOptions.grouped_popup) {
11982                                self.popupModal();
11983                            }
11984
11985                            // preventing forms send
11986                            if (formsOptions.prevent_forms_send) {
11987                                self.preventForms();
11988                            }
11989
11990                            // adding events to modal windows (show, hide etc)
11991                            self.modalEvents();
11992
11993                            // setting active group in groups select
11994                            self.selectCookieGroup();
11995                        }else {
11996                            return;
11997                        }
11998                    }
11999                }else{
12000                    // showing setting when option is enabled
12001                    if (popupOptions.gear_display && popupOptions.grouped_popup) {
12002                        self.settingPopUp();
12003                    }
12004
12005                    // showing popup when cookies arent accepted or always show option is enabled
12006                    if (this.checkCookie('gdprPlugin') !== 'true' || popupOptions.always_show) {
12007                        this.popUpBox();
12008                        self.agePopup();
12009                    }
12010
12011                    // creating modal when grouped plugin is enabled
12012                    if (popupOptions.grouped_popup) {
12013                        self.popupModal();
12014                    }
12015
12016                    // preventing forms send
12017                    if (formsOptions.prevent_forms_send) {
12018                        self.preventForms();
12019                    }
12020
12021                    // adding events to modal windows (show, hide etc)
12022                    self.modalEvents();
12023
12024                    // setting active group in groups select
12025                    self.selectCookieGroup();
12026                }
12027            }
12028
12029            var skin = self.settings.popup_options.cookies_groups_design;
12030
12031            if (skin === "skin-2") {
12032              $("head").append(
12033                '<link rel="preconnect" href="https://fonts.gstatic.com">'
12034              );
12035              $("head").append(
12036                '<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Hind:wght@300;400;500;700&display=swap">'
12037              );
12038            } else if (skin === "skin-3") {
12039              $("head").append(
12040                '<link rel="preconnect" href="https://fonts.gstatic.com">'
12041              );
12042              $("head").append(
12043                '<link rel="preload" as="style" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&display=swap">'
12044              );
12045            }
12046        },
12047
12048        cookiesProp: function(){
12049            var self, expires, path, properties;
12050            self = this;
12051
12052            // time
12053            var timePeriodinDays = self.settings.popup_options.cookies_expire_time;
12054            var pathFromOptions = self.settings.popup_options.cookies_path;
12055
12056            //sub domain
12057            var accept_cookie_subdomain = self.settings.popup_options.accept_cookie_subdomain;
12058            var accept_url_subdomain = self.settings.popup_options.accept_url_subdomain;
12059
12060            // Detect if link is HTTP or HTTPS
12061            var locationProtocol = location.protocol;
12062
12063            if (timePeriodinDays == 0) {
12064                expires = '';
12065            }else if (timePeriodinDays == 'unlimited'){
12066                expires = '; expires=Fri, 31 Dec 9999 23:59:59 GMT;';
12067            }else{
12068                var date = new Date();
12069
12070                if (typeof timePeriodinDays == 'string'){
12071                    timePeriodinDays = parseInt(timePeriodinDays);
12072                }
12073
12074                date.setTime(+ date + (timePeriodinDays * 24 * 60 * 60 * 1000));
12075
12076                if(locationProtocol == 'https:'){
12077                    expires = '; expires=' + date.toUTCString() +';secure;';
12078                }else{
12079                    expires = '; expires=' + date.toUTCString() +';';
12080                }
12081            }
12082
12083            properties = expires;
12084
12085            if( accept_cookie_subdomain ){
12086                properties += "domain=" + accept_url_subdomain + ";";
12087            }
12088
12089            if (pathFromOptions == 'current'){
12090                // do nothing
12091                path = '';
12092            }else {
12093                properties += ' path=' + pathFromOptions;
12094            }
12095
12096            self.cookiePath = path;
12097            self.cookieDate = expires;
12098
12099            self.cookieProperties = properties;
12100
12101            return properties;
12102
12103        },
12104
12105        checkCountry: function () {
12106            $.ajax({
12107                url: 'https://json.geoiplookup.io/',
12108                type: 'get',
12109                dataType: 'json',
12110                success : function( response ) {
12111                    console.log(response)
12112                    return response.country_code;
12113                },
12114                error: function(jqXHR, textStatus, errorThrown){
12115                    console.log(jqXHR);
12116                    console.log(textStatus);
12117                    console.log(errorThrown);
12118                },
12119            });
12120        },
12121
12122        resetCookies: function(e){
12123            var selector = this.settings.popup_options.reset_link_selector;
12124            $(selector).on('click', function(e){
12125                e.preventDefault();
12126                document.cookie = 'gdprPlugin=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12127                document.cookie = 'gdprPluginCountry=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12128                document.cookie = 'gdprPluginGroup=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12129                document.cookie = 'group_1=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12130                document.cookie = 'group_2=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12131                document.cookie = 'group_3=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12132                document.cookie = 'group_4=; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
12133            });
12134        },
12135
12136        // escaping HTML
12137        escapeHTML: function (html) {
12138            return document.createElement('div').appendChild(document.createTextNode(html)).parentNode.innerHTML;
12139        },
12140
12141        // creating configuration forms
12142        confInit: function (ajax, buttonCount, license) {
12143            this.firstForm(ajax, buttonCount, license);
12144        },
12145
12146        confSteps: function () {
12147
12148            this.secondForm();
12149            this.thirdForm();
12150            this.ageForm();
12151            this.fourthForm();
12152            this.summary();
12153
12154            $(document).on('click', '.ct-uGdpr-btn__Step', function (e) {
12155                e.preventDefault();
12156                var $this = $(this);
12157                var $nextStep = $this.attr('data-step');
12158                var $parent = $this.parent();
12159                $parent.fadeOut(200, function () {
12160                    $('.ct-uGdpr-configForm--Step' + $nextStep).fadeIn(200);
12161                });
12162            });
12163
12164            this.saveSettings();
12165        },
12166
12167        // first form
12168
12169        firstForm: function (ajax, buttonCount, license) {
12170            var self = this;
12171            var localCookies = [];
12172            var externalCookies = [];
12173
12174            // when document is ready
12175            $(function () {
12176                var $body = $('body');
12177                // when ajax call is required
12178                if (ajax) {
12179                    var url = 'https://api.gdpr.createit.com/site-scan-wp?license=3d282a701c645536f81da1a3eea2e018&url=' + document.URL;
12180                    var domain = document.URL.slice(document.URL.indexOf('//') + 2, document.URL.length);
12181                    domain = domain.slice(0, domain.indexOf('/'));
12182
12183                    $('#ct-ultimate-gdpr-cookie-modal').css('opacity', '0.5');
12184                    $('body').append(('<div class="ct-loader" style="position: absolute; top: 50%; left: 50%; z-index: 100; transform: translate(-50%, -50%);"></div>'));
12185
12186                    $.ajax({
12187                        dataType: "json",
12188                        url: url,
12189                        type: 'GET',
12190                        crossDomain: true,
12191                    }).done(function (data) {
12192
12193                        if (data.result.error){
12194                            $('#ct-ultimate-gdpr-cookie-modal').css('opacity', '1');
12195                            $('.ct-loader').remove();
12196                            var currentdate = new Date();
12197                            var presentTime = currentdate.toLocaleTimeString();
12198                            $('.ct-uGdpr-error').append('<div class="text-danger">' + presentTime + ': '+ data.result.message +'</div>');
12199
12200                        }else {
12201                            $('#ct-ultimate-gdpr-cookie-modal').css('opacity', '1');
12202                            $('.ct-loader').remove();
12203                            self.confSteps();
12204
12205                            if (data.result.cookies.length >= 0) {
12206                                data.result.cookies.forEach(function (element) {
12207                                    if (element.domain.indexOf(domain) > -1) {
12208                                        localCookies.push(element);
12209                                    } else {
12210                                        externalCookies.push(element);
12211                                    }
12212                                });
12213                            }
12214
12215                            var $formOne = $('<form class="ct-uGdpr-configForm ct-uGdpr-configForm--Step1"> </form>');
12216                            var confType = self.values.popup_options.cookies_groups;
12217                            var confDesc = self.descriptions.popup_options.cookies_groups;
12218                            var confValue = self.settings.popup_options.cookies_groups;
12219                            $formOne.append('<h2 class="ct-uGdpr__GroupTitle">Main cookies options:</h2>');
12220
12221                            if (data.result.message.length > 0){
12222                                var currentdate = new Date();
12223                                var presentTime = currentdate.toLocaleTimeString();
12224                                $formOne.append('<div class="text-danger">' + presentTime + ': ' + data.result.message + '</div>');
12225                            }
12226
12227                            if (localCookies.length > 0) {
12228                                $formOne.append('<div class="ct-uGdpr__CookieListContainer"><h3 class="ct-uGdpr__GroupTitle">Local cookies:</h3></div>');
12229                                var $cookieList = $('<ol class="ct-uGdpr__CookieList"></ol>');
12230                                localCookies.forEach(function (element) {
12231                                    var $listElement = $('<li>' + element['name'] + '</li>');
12232                                    var $select = $('<select></select>');
12233                                    for (var key in confValue) {
12234                                        $select.append('<option data-value="'+ element['name'] +'" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="local_cookies_name" data-keyNumbers="4">' + key + '</option>');
12235                                    }
12236                                    $listElement.append($select);
12237                                    $cookieList.append($listElement);
12238                                });
12239                                $formOne.find('.ct-uGdpr__CookieListContainer').append($cookieList);
12240                            }
12241
12242                            if (externalCookies.length > 0) {
12243                                $formOne.append('<div class="ct-uGdpr__CookieListContainer ct-uGdpr__CookieListContainer--Second"><h3 class="ct-uGdpr__GroupTitle">External cookies:</h3></div>');
12244                                var $cookieList = $('<ol class="ct-uGdpr__CookieList"></ol>');
12245                                externalCookies.forEach(function (element) {
12246                                    var $listElement = $('<li>' +element['name'] + ' / ' + element['domain'] + '</li>');
12247                                    var $select = $('<select></select>');
12248                                    for (var key in confValue) {
12249                                        $select.append('<option data-value="'+ element['domain'] +'" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="blocked_url" data-keyNumbers="4">' + key + '</option>');
12250                                    }
12251                                    $listElement.append($select);
12252                                    $cookieList.append($listElement);
12253                                });
12254                                $formOne.find('.ct-uGdpr__CookieListContainer--Second').append($cookieList);
12255                                $formOne.append('<div class="clearfix"></div>');
12256                            }
12257
12258                            for (var key in confType) {
12259                                var currentObject = confType[key];
12260                                $formOne.append('<h3 class="ct-uGdpr__GroupTitle">' + key + '</h3>');
12261                                for (var key2 in currentObject) {
12262                                    if (currentObject[key2] === 'text' || currentObject[key2] === 'checkbox') {
12263                                        var $newItem = $('<div class="form-group"><label for="' + key + '_' + key2 + '"> ' + confDesc[key][key2] + '</label><input data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '" class="form-control" id="' + key + '_' + key2 + '" type="' + confType[key][key2] + '" value="' + confValue[key][key2] + '"></div>');
12264                                    } else if (currentObject[key2] === 'list') {
12265                                        var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="' + key + '_' + key + '">' + confDesc[key][key2] + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '" id="' + key + '_' + key2 + '" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12266                                        if (confValue[key][key2].length > 0) {
12267                                            confValue[key][key2].forEach(function (element) {
12268                                                $todoForm.find('ol').append('<li data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12269                                            });
12270                                        }
12271                                        $formOne.append($todoForm);
12272                                    }
12273                                    $formOne.append($newItem);
12274                                }
12275                            }
12276
12277                            $formOne.append('<input class="ct-uGdpr-btn__Step pull-right btn btn-primary mb-2" data-step="2" type="submit" value="Next Step"><div class="clearfix"></div>');
12278                            var $modal = $('#ct-ultimate-gdpr-cookie-modal');
12279                            var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12280
12281                            $modal.fadeOut(200, function () {
12282                                $('.ct-uGdpr-modalWelcome').remove();
12283                                $modalContent.append($formOne);
12284                                $modal.fadeIn(200, function () {
12285                                    $('.ct-uGdpr-list__Button').off('click');
12286                                    $('.ct-uGdpr-list__Button').on('click', function (e) {
12287                                        e.preventDefault();
12288                                        var $this = $(this);
12289                                        var $parrent = $this.parent();
12290                                        var $list = $parrent.find('ol');
12291                                        var $input = $parrent.find('input');
12292                                        var key = $input.attr('data-key');
12293                                        var key2 = $input.attr('data-key2');
12294                                        var keyNumbers = $input.attr('data-keyNumbers');
12295                                        if (keyNumbers === '3') {
12296                                            var key3 = $input.attr('data-key3');
12297                                            var key4 = 'no_key';
12298                                        } else if (keyNumbers === '4') {
12299                                            var key3 = $input.attr('data-key3');
12300                                            var key4 = $input.attr('data-key4');
12301                                        }
12302                                        var $value = $input.val();
12303
12304                                        $list.append('<li data-keyNumbers="' + keyNumbers + '" data-key="' + key + '" data-key2="' + key2 + '" data-key3="' + key3 + '" data-key4="' + key4 + '"><span class="ct-uGdpr-list__Value">' + $value + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12305                                        $input.val('');
12306                                        $('.ct-uGdpr-list__RemoveButton').off('click');
12307
12308                                        $('.ct-uGdpr-list__RemoveButton').on('click', function () {
12309                                            var $this = $(this);
12310                                            $this.parent().remove();
12311                                        });
12312                                    });
12313                                    $('.ct-uGdpr-list__RemoveButton').on('click', function () {
12314                                        var $this = $(this);
12315                                        $this.parent().remove();
12316                                    });
12317                                });
12318                            });
12319                        }
12320                    }).fail(function (error) {
12321                        $('#ct-ultimate-gdpr-cookie-modal').css('opacity', '1');
12322                        $('.ct-loader').remove();
12323                        var currentdate = new Date();
12324                        var presentTime = currentdate.toLocaleTimeString();
12325
12326                        if (buttonCount != 10) {
12327                            $('.ct-uGdpr-error').append('<div class="text-danger">' + presentTime + ': Something is wrong, please wait 5 seconds and try again.</div>');
12328                        } else {
12329                            $('.ct-uGdpr-error').append('<div class="text-danger">' + presentTime + ': There is some problem with external service, try again later or add cookies manually.</div>');
12330                        }
12331                        if (buttonCount == 10) {
12332                            $('.ct-gdpr-cookieList').remove();
12333                        } else {
12334                            $('.ct-gdpr-cookieList').attr('disabled', 'true').removeClass('btn-primary').addClass('btn-default');
12335                            setTimeout(function () {
12336                                $('.ct-gdpr-cookieList').removeAttr('disabled').removeClass('btn-default').addClass('btn-primary');
12337                            }, 5000);
12338                        }
12339                    });
12340
12341                    // when cookies are set manualy
12342                } else {
12343                    self.confSteps();
12344
12345                    var $formOne = $('<form class="ct-uGdpr-configForm ct-uGdpr-configForm--Step1"> </form>');
12346                    var confType = self.values.popup_options.cookies_groups;
12347                    var confDesc = self.descriptions.popup_options.cookies_groups;
12348                    var confValue = self.settings.popup_options.cookies_groups;
12349                    $formOne.append('<h2 class="ct-uGdpr__GroupTitle">Main cookies options:</h2>');
12350
12351                    for (var key in confType) {
12352                        var currentObject = confType[key];
12353                        $formOne.append('<h3 class="ct-uGdpr__GroupTitle">' + key + '</h3>');
12354                        for (var key2 in currentObject) {
12355                            if (currentObject[key2] === 'text' || currentObject[key2] === 'checkbox') {
12356                                var $newItem = $('<div class="form-group"><label for="' + key + '_' + key2 + '"> ' + confDesc[key][key2] + '</label><input data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '" class="form-control" id="' + key + '_' + key2 + '" type="' + confType[key][key2] + '" value="' + confValue[key][key2] + '"></div>');
12357                            } else if (currentObject[key2] === 'list') {
12358                                var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="' + key + '_' + key + '">' + confDesc[key][key2] + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '" id="' + key + '_' + key2 + '" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12359                                if (confValue[key][key2].length > 0) {
12360                                    confValue[key][key2].forEach(function (element) {
12361                                        $todoForm.find('ol').append('<li data-keyNumbers="4" data-key="popup_options" data-key2="cookies_groups" data-key3="' + key + '" data-key4="' + key2 + '"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12362                                    });
12363                                }
12364                                $formOne.append($todoForm);
12365                            }
12366                            $formOne.append($newItem);
12367                        }
12368                    }
12369
12370                    $formOne.append('<input class="ct-uGdpr-btn__Step pull-right btn btn-primary mb-2" data-step="2" type="submit" value="Next Step"><div class="clearfix"></div>');
12371                    var $modal = $('#ct-ultimate-gdpr-cookie-modal');
12372                    var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12373
12374                    $modal.fadeOut(200, function () {
12375                        $('.ct-uGdpr-modalWelcome').remove();
12376                        $modalContent.append($formOne);
12377                        $modal.fadeIn(200, function () {
12378                            $('.ct-uGdpr-list__Button').off('click');
12379                            $('.ct-uGdpr-list__Button').on('click', function (e) {
12380                                e.preventDefault();
12381                                var $this = $(this);
12382                                var $parrent = $this.parent();
12383                                var $list = $parrent.find('ol');
12384                                var $input = $parrent.find('input');
12385                                var key = $input.attr('data-key');
12386                                var key2 = $input.attr('data-key2');
12387                                var keyNumbers = $input.attr('data-keyNumbers');
12388                                if (keyNumbers === '3') {
12389                                    var key3 = $input.attr('data-key3');
12390                                    var key4 = 'no_key';
12391                                } else if (keyNumbers === '4') {
12392                                    var key3 = $input.attr('data-key3');
12393                                    var key4 = $input.attr('data-key4');
12394                                }
12395                                var $value = $input.val();
12396
12397                                $list.append('<li data-keyNumbers="' + keyNumbers + '" data-key="' + key + '" data-key2="' + key2 + '" data-key3="' + key3 + '" data-key4="' + key4 + '"><span class="ct-uGdpr-list__Value">' + $value + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12398                                $input.val('');
12399                                $('.ct-uGdpr-list__RemoveButton').off('click');
12400
12401                                $('.ct-uGdpr-list__RemoveButton').on('click', function () {
12402                                    var $this = $(this);
12403                                    $this.parent().remove();
12404                                });
12405                            });
12406                            $('.ct-uGdpr-list__RemoveButton').on('click', function () {
12407                                var $this = $(this);
12408                                $this.parent().remove();
12409                            });
12410                        });
12411                    });
12412                }
12413            });
12414        },
12415
12416        // second form
12417        secondForm: function () {
12418            var self = this;
12419
12420            var popupOptionStyle = self.settings.popup_style;
12421            var popupOptions = self.settings.popup_style;
12422            var formsOptions = self.settings.forms;
12423
12424            var confStyle = self.values.popup_style;
12425            var confDescription = self.descriptions.popup_style;
12426            var $formTwo = $('<form style="display: none;" class="ct-uGdpr-configForm ct-uGdpr-configForm--Step2"></form>');
12427            $formTwo.append('<h2 class="ct-uGdpr__GroupTitle">Style options:</h2>');
12428            for (var key in confStyle) {
12429
12430                if (typeof confStyle[key] === 'object') {
12431                    var $newItem = $('<div class="form-group"><label for="' + key + '">' + confDescription[key] + '</label><select class="form-control" id="' + key + '"></select></div>');
12432                    var $newItemSelect = $newItem.find('select');
12433                    confStyle[key].forEach(function (element) {
12434                        $newItemSelect.append('<option data-keyNumbers="2" data-key="' + 'popup_style' + '" data-key2="' + key + '" value="' + element + '">' + element + '</option>');
12435                    });
12436                } else if (confStyle[key] === 'text' || 'textfield') {
12437                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + confDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'popup_style' + '" data-key2="' + key + '" class="form-control" id="' + key + '" type="' + confStyle[key] + '" value="' + popupOptions[key] + '"></div>');
12438                } else {
12439                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + confDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'popup_style' + '" data-key2="' + key + '" class="form-control" id="' + key + '" type="' + confStyle[key] + '" ></div>');
12440                }
12441                // $newItem.insertBefore($formSubmit);
12442                $formTwo.append($newItem);
12443            }
12444
12445            $(function () {
12446                var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12447                $formTwo.append('<input class="left-right btn btn-primary mb-2 ct-uGdpr-btn__Step" type="submit" data-step="1" value="Previous Step"><input class="pull-right btn btn-primary mb-2 ct-uGdpr-btn__Step" type="submit" data-step="3" value="Next Step"><div class="clearfix"></div>');
12448                $modalContent.append($formTwo);
12449            });
12450        },
12451
12452        //third form
12453
12454        thirdForm: function () {
12455            var self = this;
12456
12457            var $formThree = $('<form style="display: none;" class="ct-uGdpr-configForm ct-uGdpr-configForm--Step3"> </form>');
12458            $formThree.append('<h2 class="ct-uGdpr__GroupTitle">Content options:</h2>');
12459            var confStyle = self.values.popup_options;
12460            var confDescription = self.descriptions.popup_options;
12461            var confValue = self.settings.popup_options;
12462
12463            for (var key in confStyle) {
12464                if (typeof confStyle[key] === 'object' && key !== 'cookies_groups') {
12465                    var $newItem = $('<div class="form-group"><label for="' + key + '">' + confDescription[key] + '</label><select class="form-control" id="' + key + '"></select></div>');
12466                    var $newItemSelect = $newItem.find('select');
12467                    confStyle[key].forEach(function (element) {
12468                        $newItemSelect.append('<option data-keyNumbers="2" data-key="' + 'popup_options' + '" data-key2="' + key + '"  value="' + element + '">' + element + '</option>');
12469                    });
12470                } else if (confStyle[key] === 'text') {
12471                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + confDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + confStyle[key] + '" value="' + self.settings.popup_options[key] + '"></div>');
12472                } else if (confStyle[key] === 'textarea') {
12473                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + confDescription[key] + '</label><textarea data-keyNumbers="2" data-key="' + 'popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + confStyle[key] + '">' + self.settings.popup_options[key] + '</textarea></div>');
12474                } else if (key !== 'cookies_groups' && key !== 'countries_prefixes' && key !==  'first_party_cookies_whitelist' && key !==  'third_party_cookies_whitelist')  {
12475                    var $newItem = $('<div class="form-group "><label for="' + key + '"> ' + confDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + confStyle[key] + '" ></div>');
12476                }
12477                // $newItem.insertBefore($formSubmit);
12478                $formThree.append($newItem);
12479            }
12480
12481            var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="popup_options_countries_prefixes">' + self.descriptions.popup_options.countries_prefixes + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="2" data-key="popup_options" data-key2="countries_prefixes" id="popup_options_countries_prefixes" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12482            if (self.settings.popup_options.countries_prefixes.length > 0) {
12483                self.settings.popup_options.countries_prefixes.forEac
12483h(function(element){
12484                    $todoForm.find('ol').append('<li data-keyNumbers="2" data-key="popup_options" data-key2="countries_prefixes"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12485                });
12486            }
12487            $formThree.append($todoForm);
12488
12489            var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="first_party_cookies_whitelist">' + self.descriptions.popup_options.first_party_cookies_whitelist + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="2" data-key="popup_options" data-key2="first_party_cookies_whitelist" id="first_party_cookies_whitelist" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12490            if (self.settings.popup_options.first_party_cookies_whitelist.length > 0) {
12491                self.settings.popup_options.first_party_cookies_whitelist.forEach(function(element){
12492                    $todoForm.find('ol').append('<li data-keyNumbers="2" data-key="popup_options" data-key2="first_party_cookies_whitelist"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12493                });
12494            }
12495            $formThree.append($todoForm);
12496
12497            var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="third_party_cookies_whitelist">' + self.descriptions.popup_options.third_party_cookies_whitelist + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="2" data-key="popup_options" data-key2="third_party_cookies_whitelist" id="third_party_cookies_whitelist" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12498            if (self.settings.popup_options.third_party_cookies_whitelist.length > 0) {
12499                self.settings.popup_options.third_party_cookies_whitelist.forEach(function(element){
12500                    $todoForm.find('ol').append('<li data-keyNumbers="2" data-key="popup_options" data-key2="third_party_cookies_whitelist"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12501                });
12502            }
12503            $formThree.append($todoForm);
12504
12505            $(function () {
12506                var self = this;
12507                var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12508                $formThree.append('<input class="pull-left btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="2" type="submit" value="Previous Step"><input class="pull-right btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="3-a" type="submit" value="Next Step"><div class="clearfix"></div>');
12509                $modalContent.append($formThree);
12510            });
12511        },
12512
12513        // fourth form
12514
12515        fourthForm: function () {
12516            var self = this;
12517
12518            var $fourthForm = $('<form style="display: none;" class="ct-uGdpr-configForm ct-uGdpr-configForm--Step4"> </form>');
12519            $fourthForm.append('<h2 class="ct-uGdpr__GroupTitle">Configuration options:</h2>');
12520
12521            var confType = self.values.forms;
12522            var confDesc = self.descriptions.forms;
12523            var confValue = self.settings.forms;
12524
12525            var currentObject = confType;
12526            for (var key in currentObject) {
12527                if (currentObject[key] === 'text' || currentObject[key] === 'checkbox') {
12528                    var $newItem = $('<div class="form-group"><label for="forms_' + key + '"> ' + confDesc[key] + '</label><input data-keyNumbers="2" data-key="forms" data-key2="' + key + '" class="form-control" id="forms_' + key + '" type="' + confType[key] + '" value="' + confValue[key] + '"></div>');
12529                }
12529 else if (currentObject[key] === 'list') {
12530                    var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="forms_' + key + '">' + confDesc[key] + '</label><input class="form-control ct-uGdpr-ignore ct-uGdpr__InlineInput" type="text" data-keyNumbers="2" data-key="forms" data-key2="' + key + '" id="forms_' + key + '" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12531                    if (confValue[key].length > 0) {
12532                        confValue[key].forEach(function (element) {
12533                            $todoForm.find('ol').append('<li data-keyNumbers="2" data-key="forms" data-key2="' + key + '"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12534                        });
12535                    }
12536                    $fourthForm.append($todoForm);
12537                }
12538                $fourthForm.append($newItem);
12539            }
12540
12541
12542            var confType = self.values.configure_mode;
12543            var confDesc = self.descriptions.configure_mode;
12544            var confValue = self.settings.configure_mode;
12545
12546            var currentObject = confType;
12547            for (var key in currentObject) {
12548                if (currentObject[key] === 'text' || currentObject[key] === 'checkbox') {
12549                    var $newItem = $('<div class="form-group"><label for="configure_mode_' + key + '"> ' + confDesc[key] + '</label><input data-keyNumbers="2" data-key="configure_mode" data-key2="' + key + '" class="form-control" id="configure_mode_' + key + '" type="' + confType[key] + '" value="' + confValue[key] + '"></div>');
12550                } else if (currentObject[key] === 'list') {
12551                    var $todoForm = $('<div class="form-group ct-uGdpr-list"><label class="ct-uGdpr__BlockLabel" for="configure_mode_' + key + '">' + confDesc[key] + '</label><input class="form-control ct-uGdpr__InlineInput ct-uGdpr-ignore" type="text" data-keyNumbers="2" data-key="configure_mode" data-key2="' + key + '" id="configure_mode_' + key + '" name="ct-uGdpr-list"><button class="ct-uGdpr-list__Button ct-uGdpr__InlineButton btn btn-success">Add</button><br><ol></ol></div>');
12552                    if (confValue[key].length > 0) {
12553                        confValue[key].forEach(function (element) {
12554                            $todoForm.find('ol').append('<li data-keyNumbers="2" data-key="configure_mode" data-key2="' + key + '"><span class="ct-uGdpr-list__Value">' + element + '</span><span class="ct-uGdpr-list__RemoveButton fas fa-times-circle" aria-hidden="true"></span></li>');
12555                        });
12556                    }
12557                    $fourthForm.append($todoForm);
12558                }
12559                $fourthForm.append($newItem);
12560            }
12561
12562
12563            $(function () {
12564                var self = this;
12565                var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12566                $fourthForm.append('<input class="pull-left btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="3" type="submit" value="Previous Step"><input class="ct-uGdpr-Save pull-right btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="5" type="submit" value="Finish"><div class="clearfix"></div>');
12567                $modalContent.append($fourthForm);
12568            });
12569        },
12570
12571        ageForm: function () {
12572            var self = this;
12573
12574            var $ageForm = $('<form style="display: none;" class="ct-uGdpr-configForm ct-uGdpr-configForm--Step3-a"> </form>');
12575            $ageForm.append('<h2 class="ct-uGdpr__GroupTitle">Age Form:</h2>');
12576            var ageStyleForm = self.values.age_popup_style;
12577            var ageStyleDescription = self.descriptions.age_popup_style;
12578            var agePopupOptions = self.values.age_popup_options;
12579            var agePopupOptionsDescription = self.descriptions.age_popup_options;
12580            var confValue = self.settings.age_popup_style;
12581
12582            for (var key in ageStyleForm) {
12583                if (typeof ageStyleForm[key] === 'object' && key !== 'cookies_groups') {
12584                    var $newItem = $('<div class="form-group"><label for="' + key + '">' + ageStyleDescription[key] + '</label><select class="form-control" id="' + key + '"></select></div>');
12585                    var $newItemSelect = $newItem.find('select');
12586                    ageStyleForm[key].forEach(function (element) {
12587                        $newItemSelect.append('<option data-keyNumbers="2" data-key="' + 'age_popup_style' + '" data-key2="' + key + '"  value="' + element + '">' + element + '</option>');
12588                    });
12589                } else if (ageStyleForm[key] === 'text') {
12590                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + ageStyleDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_style' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + ageStyleForm[key] + '" value="' + self.settings.age_popup_style[key]  + '"></div>');
12591                } else if (ageStyleForm[key] === 'number') {
12592                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + ageStyleDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_style' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + ageStyleForm[key] + '" value="' + self.settings.age_popup_style[key]  + '"></div>');
12593                } else if (ageStyleForm[key] === 'textarea') {
12594                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + ageStyleDescription[key] + '</label><textarea data-keyNumbers="2" data-key="' + 'age_popup_style' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + ageStyleForm[key] + '">' + self.settings.age_popup_style[key] + '</textarea></div>');
12595                } else if (key !== 'cookies_groups' && key !== 'countries_prefixes' && key !==  'first_party_cookies_whitelist' && key !==  'third_party_cookies_whitelist')  {
12596                    var $newItem = $('<div class="form-group "><label for="' + key + '"> ' + ageStyleDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_style' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + ageStyleForm[key] + '" ></div>');
12597                }
12598                // $newItem.insertBefore($formSubmit);
12599                $ageForm.append($newItem);
12600            }
12601
12602            for (var key in agePopupOptions) {
12603                if (typeof agePopupOptions[key] === 'object' && key !== 'cookies_groups') {
12604                    var $newItem = $('<div class="form-group"><label for="' + key + '">' + agePopupOptionsDescription[key] + '</label><select class="form-control" id="' + key + '"></select></div>');
12605                    var $newItemSelect = $newItem.find('select');
12606                    agePopupOptions[key].forEach(function (element) {
12607                        $newItemSelect.append('<option data-keyNumbers="2" data-key="' + 'age_popup_options' + '" data-key2="' + key + '"  value="' + element + '">' + element + '</option>');
12608                    });
12609                } else if (agePopupOptions[key] === 'text') {
12610                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + agePopupOptionsDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + agePopupOptions[key] + '" value="' + self.settings.age_popup_options[key] + '"></div>');
12611                } else if (agePopupOptions[key] === 'number') {
12612                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + agePopupOptionsDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + agePopupOptions[key] + '" value="' + self.settings.age_popup_options[key] + '"></div>');
12613                } else if (agePopupOptions[key] === 'textarea') {
12614                    var $newItem = $('<div class="form-group"><label for="' + key + '"> ' + agePopupOptionsDescription[key] + '</label><textarea data-keyNumbers="2" data-key="' + 'age_popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + agePopupOptions[key] + '">' + self.settings.age_popup_options[key] + '</textarea></div>');
12615                } else if (key !== 'cookies_groups' && key !== 'countries_prefixes' && key !==  'first_party_cookies_whitelist' && key !==  'third_party_cookies_whitelist')  {
12616                    var $newItem = $('<div class="form-group "><label for="' + key + '"> ' + agePopupOptionsDescription[key] + '</label><input data-keyNumbers="2" data-key="' + 'age_popup_options' + '" data-key2="' + key + '"  class="form-control" id="' + key + '" type="' + agePopupOptions[key] + '" ></div>');
12617                }
12618                // $newItem.insertBefore($formSubmit);
12619                $ageForm.append($newItem);
12620            }
12621
12622            $(function () {
12623                var self = this;
12624                var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12625                $ageForm.append('<input class="pull-left btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="2" type="submit" value="Previous Step"><input class="pull-right btn btn-primary mb-2 ct-uGdpr-btn__Step" data-step="4" type="submit" value="Next Step"><div class="clearfix"></div>');
12626                $modalContent.append($ageForm);
12627            });
12628        },
12629
12630        summary: function () {
12631            var self = this;
12632            var $formSummary = $('<div style="display: none;" class="ct-uGdpr-configForm ct-uGdpr-configForm--Step5"> </div>');
12633            $formSummary.append('<h2 class="ct-uGdpr__GroupTitle">Configuration Finished:</h2><div class="ct-uGdpr-finished"></div>');
12634
12635            $(function () {
12636                var self = this;
12637                var $modalContent = $('.ct-ultimate-gdpr-cookie-modal-content');
12638                $modalContent.append($formSummary);
12639            });
12640        },
12641        // saving configuration settings to object
12642        saveSettings: function () {
12643            var self = this;
12644
12645            $(function () {
12646                // array json create
12647                var outputObject = {
12648                    popup_style: {
12649                        position: '', // bottom-left, bottom-right, bottom-panel, top-left, top-right, top-panel
12650                        distance: '', // distance betwen popup and window border
12651                        box_style: '', // classic, modern
12652                        box_shape: '', // rounded, squared
12653                        background_color: '', // color in hex
12654                        text_color: '', // color in hex
12655                        button_shape: '', // squared, rounded
12656                        button_color: '', // color in hex
12657                        button_size: '', // normal, large
12658                        gear_icon_position: '', // top-left, top-center, top-right, center-left, center-right, bottom-left, bottom-center, bottom-right
12659                        gear_icon_color: '', //color in hex
12660                    },
12661                    popup_options: {
12662                        always_show: false, // true, false, when true popup is displayed always even when consent is given
12663                        gear_display: false, // true, false when true displays icon with cookie settings
12664                        popup_text: '', // text for popup
12665                        accept_button_text: '', // string, text for accept button
12666                        read_button_text: '', // string, text for read more button
12667                        read_more_link: '', // string, link to the Read More page
12668                        advenced_button_text: '', // string, text for advenced button
12669                        grouped_popup: true, // true, false, when true cookies are grouped
12670                        default_group: '', // string: name, select group that will be selected by default
12671                        content_before_slider: '',
12672                        // string: this content will be displayed before cookies slider, html tags alowed
12673                        accepted_text: '',
12674                        declined_text: '',
12675                        save_btn: '',
12676                        prevent_cookies_on_document_write: true,
12677                        check_country: true,
12678                        reset_link_selector: '',
12679                        countries_prefixes: [],
12680                        first_party_cookies_whitelist: [],
12681                        third_party_cookies_whitelist: [],
12682                        accept_cookie_subdomain: false,
12683                        accept_url_subdomain: '',
12684                        video_blocked: '',
12685                        cookies_groups: {
12686                            group_1: {
12687                                name: '',
12688                                enable: true,
12689                                icon: '',
12690                                list: [],
12691                                blocked_url: [],
12692                                local_cookies_name: [],
12693                            },
12694                            group_2: {
12695                                name: '',
12696                                enable: true,
12697                                icon: '',
12698                                list: [],
12699                                blocked_url: [],
12700                                local_cookies_name: [],
12701                            },
12702                            group_3: {
12703                                name: '',
12704                                enable: true,
12705                                icon: '',
12706                                list: [],
12707                                blocked_url: [],
12708                                local_cookies_name: [],
12709                            },
12710                            group_4: {
12711                                name: '',
12712                                enable: true,
12713                                icon: '',
12714                                list: [],
12715                                blocked_url: [],
12716                                local_cookies_name: [],
12717                            },
12718                        },
12719                    },
12720                    age_popup_style: {
12721                        position: '',
12722                        distance: '',
12723                        box_style: '',
12724                        box_shape: '',
12725                        background_color: '',
12726                        text_color: '',
12727                        button_shape: '',
12728                        button_color: '',
12729                        box_skin: '',
12730                    },
12731                    age_popup_options: {
12732                        parent_container: '',
12733                        always_show: true,
12734                        popup_title: '',
12735                        popup_text: '',
12736                        age_limit: 0,
12737                        assets_path : ''
12738                    },
12739                    forms: {
12740                        prevent_forms_send: true,
12741                        prevent_forms_text: '',
12742                        prevent_forms_exclude: [],
12743                    },
12744                    configure_mode: {
12745                        on: true,
12746                        parametr: '',
12747                        dependencies: [],
12748                        debug: false,
12749                    },
12750                };
12751
12752
12753                $(document).on('click', '.ct-uGdpr-Save', function (e) {
12754
12755                    $('.ct-uGdpr-configForm input[type="text"]').each(function () {
12756                        var $value = $(this).val();
12757                        $(this).attr('value', $value);
12758                    });
12759
12760                    $('.ct-uGdpr-configForm input[type="number"]').each(function () {
12761                        var $value = $(this).val();
12762                        $(this).attr('value', $value);
12763                    });
12764
12765                    $('.ct-uGdpr-configForm input[type="color"]').each(function () {
12766                        var $value = $(this).val();
12767                        $(this).attr('value', $value);
12768                    });
12769
12770                    $('.ct-uGdpr-configForm textarea').each(function () {
12771                        var $value = $(this).val();
12772                        $(this).attr('value', $value);
12773                    });
12774
12775
12776                    var $formInputs = $('.ct-uGdpr-configForm input:not([type="submit"]):not(.ct-uGdpr-ignore)');
12777                    var $formSelects = $('.ct-uGdpr-configForm select option:selected');
12778                    var $textareas = $('.ct-uGdpr-configForm textarea');
12779                    var $listElements = $('.ct-uGdpr-list li');
12780
12781                    e.preventDefault();
12782
12783                    // checking all forms Inputs
12784                    $formInputs.each(function () {
12785                        var $this = $(this);
12786                        var keyName = $this.attr('data-key');
12787                        var keyName2 = $this.attr('data-key2');
12788                        var $thisValue = $this.attr('value');
12789                        if ($this.attr('type') === 'checkbox') {
12790                            if ($this.attr('data-keyNumbers') === '2') {
12791                                outputObject[keyName][keyName2] = $this.prop('checked');
12792                            } else if ($this.attr('data-keyNumbers') === '3') {
12793                                var keyName3 = $this.attr('data-key3');
12794                                outputObject[keyName][keyName2][keyName3] = $this.prop('checked');
12795                            } else if ($this.attr('data-keyNumbers') === '4') {
12796                                var keyName3 = $this.attr('data-key3');
12797                                var keyName4 = $this.attr('data-key4');
12798                                outputObject[keyName][keyName2][keyName3][keyName4] = $this.prop('checked');
12799                            }
12800                        } else {
12801                            if ($this.attr('data-keyNumbers') === '2') {
12802                                outputObject[keyName][keyName2] = $thisValue;
12803                            } else if ($this.attr('data-keyNumbers') === '3') {
12804                                var keyName3 = $this.attr('data-key3');
12805                                outputObject[keyName][keyName2][keyName3] = $thisValue;
12806                            } else if ($this.attr('data-keyNumbers') === '4') {
12807                                var keyName3 = $this.attr('data-key3');
12808                                var keyName4 = $this.attr('data-key4');
12809                                outputObject[keyName][keyName2][keyName3][keyName4] = $thisValue;
12810                            }
12811                        }
12812                    });
12813
12814                    // checking all forms selects
12815                    $formSelects.each(function () {
12816                        var $this = $(this);
12817                        var keyName = $this.attr('data-key');
12818                        var keyName2 = $this.attr('data-key2');
12819                        if ($this.attr('data-key2') == 'cookies_groups'){
12820                            var $thisValue = $this.attr('data-value');
12821                        }else{
12822                            var $thisValue = $this.val();
12823                        }
12824
12825
12826
12827                        if ($this.attr('data-keyNumbers') === '2') {
12828                            outputObject[keyName][keyName2] = $thisValue;
12829                        } else if ($this.attr('data-keyNumbers') === '3') {
12830                            var keyName3 = $this.attr('data-key3');
12831                            outputObject[keyName][keyName2][keyName3] = $thisValue;
12832                        } else if ($this.attr('data-keyNumbers') === '4') {
12833                            var keyName3 = $this.attr('data-key3');
12834                            var keyName4 = $this.attr('data-key4');
12835                            outputObject[keyName][keyName2][keyName3][keyName4].push($thisValue);
12836                        }
12837                    });
12838
12839                    // checking all forms textareas
12840                    $textareas.each(function () {
12841                        var $this = $(this);
12842                        var $thisValue = $this.val();
12843                        var keyName = $this.attr('data-key');
12844                        var keyName2 = $this.attr('data-key2')
12845                        if ($this.attr('data-keyNumbers') === '2') {
12846                            outputObject[keyName][keyName2] = $thisValue;
12847                        } else if ($this.attr('data-keyNumbers') === '3') {
12848                            var keyName3 = $this.attr('data-key3');
12849                            outputObject[keyName][keyName2][keyName3] = $thisValue;
12850                        } else if ($this.attr('data-keyNumbers') === '4') {
12851                            var keyName3 = $this.attr('data-key3');
12852                            var keyName4 = $this.attr('data-key4');
12853                            outputObject[keyName][keyName2][keyName3][keyName4].push($thisValue);
12854                        }
12855                    });
12856
12857                    // checking all lists
12858                    $listElements.each(function () {
12859                        var $this = $(this);
12860                        var $thisValue = $this.find('.ct-uGdpr-list__Value').html();
12861                        var keyName = $this.attr('data-key');
12862                        var keyName2 = $this.attr('data-key2');
12863                        if ($this.attr('data-keyNumbers') === '2') {
12864                            outputObject[keyName][keyName2].push($thisValue);
12865                        } else if ($this.attr('data-keyNumbers') === '3') {
12866                            var keyName3 = $this.attr('data-key3');
12867                            outputObject[keyName][keyName2][keyName3].push($thisValue);
12868                        } else if ($this.attr('data-keyNumbers') === '4') {
12869                            var keyName3 = $this.attr('data-key3');
12870                            var keyName4 = $this.attr('data-key4');
12871                            outputObject[keyName][keyName2][keyName3][keyName4].push($thisValue);
12872                        }
12873                    });
12874
12875
12876                    // copying first group to the second one
12877                    outputObject.popup_options.cookies_groups.group_1.blocked_url.forEach(function (element){
12878                        outputObject.popup_options.cookies_groups.group_2.blocked_url.push(element);
12879                    });
12880
12881                    // copying second group to the third
12882                    outputObject.popup_options.cookies_groups.group_2.blocked_url.forEach(function (element){
12883                        outputObject.popup_options.cookies_groups.group_3.blocked_url.push(element);
12884                    });
12885
12886                    // copying third group to the fourth
12887                    outputObject.popup_options.cookies_groups.group_3.blocked_url.forEach(function (element){
12888                        outputObject.popup_options.cookies_groups.group_4.blocked_url.push(element);
12889                    });
12890
12891                    // copying first group to the second one (local)
12892                    outputObject.popup_options.cookies_groups.group_1.local_cookies_name.forEach(function (element){
12893                        outputObject.popup_options.cookies_groups.group_2.local_cookies_name.push(element);
12894                    });
12895
12896                    // copying second group to the third (local)
12897                    outputObject.popup_options.cookies_groups.group_2.local_cookies_name.forEach(function (element){
12898                        outputObject.popup_options.cookies_groups.group_3.local_cookies_name.push(element);
12899                    });
12900
12901                    // copying third group to fourth (local)
12902                    outputObject.popup_options.cookies_groups.group_3.local_cookies_name.forEach(function (element){
12903                        outputObject.popup_options.cookies_groups.group_4.local_cookies_name.push(element);
12904                    });
12905
12906                    var outputObjectStringed = JSON.stringify(outputObject);
12907
12908                    var output = self.escapeHTML(outputObjectStringed);
12909
12910                    $('.ct-uGdpr-configForm--Step5 .ct-uGdpr-finished').append('<p>Please paste this code into init.js: </p><pre><code> ct_$("html").ultimateGDPR(' + output + ');</code></pre>');
12911
12912
12913                });
12914
12915            });
12916
12917        },
12918
12919        removeSettings: function () {
12920            $('.ct-uGdpr-configForm input[type="submit"]').off('click');
12921        },
12922
12923        // method for block 3rd pathy cookies
12924        aopAround: function (myTarget, myMethod) {
12925
12926            // variebles
12927            var self = this;
12928            var cookiesGroups = this.settings.popup_options.cookies_groups;
12929            var groupedPlugin = this.settings.popup_options.grouped_popup;
12930            var cookiesAllowed = [];
12931            var cookiesBlocked = [];
12932            var debug = this.settings.configure_mode.debug;
12933
12934            function insertAfter(referenceNode, newNode) {
12935                referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
12936            }
12937            // if cookies are accepted and plugin is in group moede creating array of alowed cookies and array with blocked cookies
12938            if (self.checkCookie('gdprPlugin')) {
12939                if (groupedPlugin) {
12940                    var a = 0, flat = [];
12941                    for (var key in cookiesGroups) {
12942                        a++;
12943                        flat = flat.concat(cookiesGroups[key].blocked_url);
12944                        if (a === 4) {
12945                            var popupOptions = self.settings.popup_options;
12946                            var iframeBlocked = popupOptions.iframe_blocked;
12947                            if(iframeBlocked == true) {
12948                                window.addEventListener("load", function (event) {
12949                                    document.querySelectorAll('iframe').forEach(function (elem) {
12950                                        var iframeWidth = elem.offsetWidth;
12951                                        if (flat.includes(elem.src) === false) {
12952                                            var el = document.createElement("div");
12953                                            el.innerHTML = "<h2>" + popupOptions.video_blocked + "</h2>";
12954                                            el.style.cssText = 'display:flex;background-color:#f2f2f2;text-align:center;height:300px;align-items:center;justify-content:center;width:' + iframeWidth + 'px;max-width: 100%;';
12955                                            insertAfter(elem, el);
12956                                            elem.parentNode.removeChild(elem);
12957                                        }
12958                                    });
12959                                });
12960                            }
12961                        }
12962                        if (self.checkCookie(key) === 'false') {
12963                            cookiesGroups[key].blocked_url.forEach(function (element) {
12964                                cookiesBlocked.push(element);
12965                                var popupOptions = self.settings.popup_options;
12966                                window.addEventListener("load", function (event) {
12967                                    document.querySelectorAll('iframe').forEach(function (elem) {
12968                                        var iframeWidth = elem.offsetWidth;
12969                                        if (elem.src === element) {
12970                                            var el = document.createElement("div");
12971                                            el.innerHTML = "<h2>" + popupOptions.video_blocked + "</h2>";
12972                                            el.style.cssText = 'display:flex;background-color:#f2f2f2;text-align:center;height:300px;align-items:center;justify-content:center;width:' + iframeWidth + 'px;max-width: 100%;';
12973                                            insertAfter(elem, el);
12974                                            elem.parentNode.removeChild(elem);
12975                                        }
12976                                    });
12977                                });
12978                            });
12979                        } else {
12980                            cookiesGroups[key].blocked_url.forEach(function (element) {
12981                                cookiesAllowed.push(element);
12982                            });
12983                        }
12984                    }
12985                }
12986            } else {
12987                var popupOptions = self.settings.popup_options;
12988                window.addEventListener("load", function (event) {
12989                    document.querySelectorAll('iframe').forEach(function (elem) {
12990                        var iframeWidth = elem.offsetWidth;
12991                        var el = document.createElement("div");
12992                        el.innerHTML = "<h2>" + popupOptions.video_blocked + "</h2>";
12993                        el.style.cssText = 'display:flex;background-color:#f2f2f2;text-align:center;height:300px;align-items:center;justify-content:center;width:' + iframeWidth + 'px;max-width: 100%;';
12994                        insertAfter(elem, el);
12995                        elem.parentNode.removeChild(elem);
12996                    });
12997                });
12998            }
12999
13000
13001            cookiesAllowed = cookiesAllowed.concat(this.settings.popup_options.third_party_cookies_whitelist);
13002            // body of function
13003            aop.around({target: myTarget, method: myMethod},
13004
13005                function (invocation) {
13006                    // if debug mode is set to true displaying url of script
13007                    if (debug) {
13008                        console.log("%c" + invocation.arguments[0].src, "background: #333; color: black; font-size: medium; padding:10px; border:10px solid #333; margin:2px;");
13009                    }
13010
13011                    // when cookies plugin is set and plugin is in grouped mode
13012                    if (self.checkCookie('gdprPlugin') === 'true' && groupedPlugin || (cookie
13012sAllowed && groupedPlugin)) {
13013                        // if cookie src is not in array of allowed cookies
13014                        var cookieBlock = true;
13015
13016                        cookiesAllowed.some(function(index){
13017
13018                            // checking if address have * on his end
13019                            if(index[index.length-1] == '*'){
13020                                var address = index.substring(0, index.length-2);
13021                                // if he has * and adress of script contains part of him setting cookie block to false and leaving function
13022                                if(typeof invocation.arguments[0].src !== 'undefined' && invocation.arguments[0].src.match(address)){
13023                                    cookieBlock = false;
13024                                    return true;
13025                                }
13026                            }else {
13027                                // if address in array is full and is == to src setting cookie bloc to false and leaving
13028                                if (index === invocation.arguments[0].src ){
13029                                    cookieBlock = false;
13030                                    return true;
13031                                }
13032                            }
13033                        });
13034
13035                        if (cookieBlock) {
13036                            // console log for src in debug mode
13037                            if (debug) {
13038                                console.log('[ultimate gdpr] cookie blocked: ' + invocation.arguments[0].src);
13039                            }
13040                            // changing src attr to data src and inserting blank string for src
13041                            invocation.arguments[0].dataset.src = invocation.arguments[0].src;
13042                            invocation.arguments[0].src = '';
13043                        }
13044                        // if cookie plugin is set and plugin is in simple mode not blocking any cookie (cookies are allowed)
13045                    } else if (self.checkCookie('gdprPlugin') === 'true' && !groupedPlugin) {
13046
13047                        // in case when plugin cookie is not set (no cookies allowed) blocking all cookies
13048                    } else if ((typeof(invocation.arguments[0].src) === 'string') && ((invocation.arguments[0].tagName.toLowerCase() === 'script') || (invocation.arguments[0].tagName.toLowerCase() === 'img') || (invocation.arguments[0].tagName.toLowerCase() === 'iframe')) && (invocation.arguments[0].src !== 'javascript:void(0)')) {
13049
13050                        // in debug mode console log for src
13051                        if (debug) {
13052                            console.log('[ultimate gdpr] cookie blocked: ' + invocation.arguments[0].src);
13053                        }
13054
13055                        // changing src attr to data src and inserting blank string for src
13056                        invocation.arguments[0].dataset.src = invocation.arguments[0].src;
13057                        invocation.arguments[0].src = '';
13058                    }
13059                    return invocation.proceed();
13060                }
13061            );
13062        },
13063
13064        // method for preventing document write scripts
13065        aopAroundForDocumentWrite: function () {
13066
13067            // variebles
13068            var self = this;
13069            var cookiesGroups = this.settings.popup_options.cookies_groups;
13070            var groupedPlugin = this.settings.popup_options.grouped_popup;
13071            var cookiesAllowed = [];
13072            var cookiesBlocked = [];
13073            var debug = this.settings.configure_mode.debug;
13074
13075
13076            // if cookies are accepted and plugin is in group moede creating array of alowed cookies and array with blocked cookies
13077            if (self.checkCookie('gdprPlugin') === 'true') {
13078                if (groupedPlugin) {
13079                    for (var key in cookiesGroups) {
13080                        if (self.checkCookie(key) === 'false') {
13081                            cookiesGroups[key].blocked_url.forEach(function (element) {
13082                                cookiesBlocked.push(element);
13083                            });
13084                        } else {
13085                            cookiesGroups[key].blocked_url.forEach(function (element) {
13086                                cookiesAllowed.push(element);
13087                            });
13088                        }
13089                    }
13090                }
13091            }
13092
13093
13094            aop.around({target: document, method: 'write'},
13095                function (invocation) {
13096                    // if debug mode is set to true displaying url of script
13097                    if (debug) {
13098                        console.log("%c" + $(invocation.arguments[0]).attr('src'), "background: #333; color: black; font-size: medium; padding:10px; border:10px solid #333; margin:2px;");
13099                    }
13100
13101                    // when cookies plugin is set and plugin is in grouped mode
13102                    if (self.checkCookie('gdprPlugin') === 'true' && groupedPlugin) {
13103                        // if cookie src is not in array of allowed cookies
13104                        var $test = $(invocation.arguments[0]).attr('src');
13105
13106                        if ( typeof $test === "undefined" || typeof $test === "null"){
13107
13108                        }else {
13109                            if ((cookiesAllowed.indexOf($(invocation.arguments[0]).attr('src')) == -1)) {
13110                                if (debug) {
13111                                    console.log('[ultimate gdpr] cookie blocked: ' + $(invocation.arguments[0]).attr('src'));
13112                                }
13113                                // changing src attr to data src and inserting blank string for src
13114                                invocation.arguments[0] = invocation.arguments[0].replace(/</g, '<!-- ').replace(/>/g, ' -->');
13115                            }
13116                        }
13117
13118                        // if cookie plugin is set and plugin is in simple mode not blocking any cookie (cookie
13118s are allowed)
13119                    } else if (self.checkCookie('gdprPlugin') === 'true' && !groupedPlugin) {
13120
13121                        // in case when plugin cookie is not set (no cookies allowed) blocking all cookies
13122                    } else if (self.op && $(invocation.arguments[0]).attr('src') !== 'javascript:void(0)') {
13123                        // in debug mode console log for src
13124                        if (debug) {
13125                            console.log('[ultimate gdpr] cookie blocked: ' + $(invocation.arguments[0]).attr('src'));
13126                        }
13127
13128                        // changing src attr to data src and inserting blank string for src
13129                        invocation.arguments[0] = invocation.arguments[0].replace(/</g, '<!-- ').replace(/>/g, ' -->');
13130                    }
13131                    return invocation.proceed();
13132                }
13133            );
13134        },
13135
13136        // function for 1st party cookies
13137        localCookies: function () {
13138
13139            // variebles
13140            var self = this;
13141            var debug = this.settings.configure_mode.debug;
13142            var groupedPlugin = this.settings.popup_options.grouped_popup;
13143            var cookiesGroups = this.settings.popup_options.cookies_groups;
13144            // adding gdprPlugin cookies to array
13145            var cookiesAllowed = this.settings.popup_options.first_party_cookies_whitelist.concat(['gdprPluginGroup', 'gdprPlugin', 'gdprPluginCountry', 'gdprAge']);
13146            var cookiesBlocked = [];
13147
13148            // adding groups names for alowed cookies array
13149            for (key in cookiesGroups) {
13150                cookiesAllowed.push(key);
13151            }
13152            // when plugin cookies are set
13153            if (self.checkCookie('gdprPlugin') === 'true') {
13154
13155                for (var key in cookiesGroups) {
13156                    // when gropus in plugin are off adding all cookies from arrays to allowed array
13157                    if (groupedPlugin === 'false') {
13158                        cookiesGroups[key].local_cookies_name.forEach(function (element) {
13159                            cookiesAllowed.push(element);
13160                        });
13161                        // when grouped plugin is on, adding cookies to arrays
13162                    } else {
13163                        if (self.checkCookie(key) === 'false') {
13164                            cookiesGroups[key].local_cookies_name.forEach(function (element) {
13165                                cookiesBlocked.push(element);
13166                            });
13167                        } else {
13168                            cookiesGroups[key].local_cookies_name.forEach(function (element) {
13169                                cookiesAllowed.push(element);
13170                            });
13171                        }
13172                    }
13173                }
13174            }
13175            // catching cookies
13176            try {
13177                var ct_ultimate_gdpr_cookie_setter_original = document.__lookupSetter__("cookie");
13178                var ct_ultimate_gdpr_cookie_getter_original = document.__lookupGetter__("cookie");
13179                var old_cookie = document.cookie;
13180
13181                //"Looks like currently plugin is not working in IE11 Compatibility fix. Javascript is crashed (error in console). Possible fix"
13182                if (typeof ct_ultimate_gdpr_cookie_setter_original == "undefined") {
13183                    throw new Error("not supported");
13184                }
13185
13186                Object.defineProperty(document, 'cookie', {
13187
13188                    get: function get() {
13189                        return ct_ultimate_gdpr_cookie_getter_original ? ct_ultimate_gdpr_cookie_getter_original.apply(document) : this._value;
13190                    },
13191
13192                    set: function set(val) {
13193                        // spliting cookies to single cookie
13194                        var parts = val.split(';');
13195                        var name = parts[0].split('=')[0];
13196                        var value = parts[0].split('=')[1];
13197
13198                        // allowed cookies are passed
13199                        if (name === 'gdprPlugin' || cookiesAllowed.indexOf(name) > -1) {
13200                            this._value = val;
13201                            ct_ultimate_gdpr_cookie_setter_original && ct_ultimate_gdpr_cookie_setter_original.apply(document, arguments);
13202                            // quit when cookie is on black list
13203                        } else {
13204                            // console log for debug
13205                            if (debug) {
13206                                console.log("[ultimate gdpr] cookie blocked: " + name);
13207                            }
13208                            return;
13209                        }
13210                    },
13211                    configurable: true
13212                });
13213
13214                document.cookie = old_cookie + self.cookieProperties;
13215            } catch (e) {
13216                // console.log(e);
13217            }
13218        },
13219
13220        // method that return value from cookie
13221        checkCookie: function (name) {
13222            var self = this;
13223
13224            function escape(s) {
13225                return s.replace(/([.*+?\^${}()|\[\]\/\\])/g, '\\$1');
13226            }
13227
13228            var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escape(name) + '=([^;]*)'));
13229            return match ? match[1] : null;
13230        },
13231
13232
13233        checkCookieGroup: function (url) {
13234
13235            // variebles
13236            var self = this;
13237            var cookiesGroups = this.settings.popup_options.cookies_groups;
13238
13239            if (this.checkCookie('gdprPlugin') === 'true') {
13240                for (var key in cookiesGroups) {
13241                    if (this.checkCookie(key) === 'true') {
13242                        return true;
13243                    } else {
13244                        return false;
13245                    }
13246                }
13247            } else {
13248                return false;
13249            }
13250        },
13251
13252        // method for cookies choice save
13253        onAcceptModal: function () {
13254
13255            // variebles
13256            var self = this;
13257            var popupOptions = this.settings.popup_options;
13258
13259            $('.ct-ultimate-gdpr-cookie-modal-btn.save').on('click', function (e) {
13260
13261                e.preventDefault();
13262
13263                var $modalBody = $('body');
13264                var $modal = $("#ct-ultimate-gdpr-cookie-modal");
13265
13266                // checking slider settings and saving cookies for every froup
13267                for (var key in popupOptions.cookies_groups) {
13268                    var $currentGroup = $('#' + key);
13269                    if ($currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--active') || $currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected')) {
13270                        document.cookie = key + '=true'  + self.cookieProperties;
13271                    } else {
13272                        document.cookie = key + '=false'  + self.cookieProperties;
13273                    }
13274                }
13275
13276                var groupSelected = $('.ct-ultimate-gdpr-cookie-modal-slider-item--active input').data('count');
13277                // remember elected group
13278                document.cookie = 'gdprPluginGroup=' + groupSelected + self.cookieProperties;
13279                // setting gdpr cookie to true
13280                document.cookie = 'gdprPlugin=true' + self.cookieProperties;
13281
13282
13283
13284                $modal.fadeOut(400);
13285                $('#ct-ultimate-gdpr-cookie-popup').hide();
13286                $('html').removeClass("cookie-modal-open");
13287                location.reload();
13288            });
13289        },
13290
13291        // method for popup accept action
13292        onAcceptPopup: function () {
13293
13294            // variebles
13295            var self = this;
13296            var popupOptions = this.settings.popup_options;
13297
13298            $('#ct-ultimate-gdpr-cookie-accept').on('click', function () {
13299                for (var key in popupOptions.cookies_groups) {
13300                    var $currentGroup = $('#' + key);
13301                    if ($currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--active') || $currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected')) {
13302                        document.cookie = key + '=true' + self.cookieProperties;
13303                    } else {
13304                        document.cookie = key + '=false' + self.cookieProperties;
13305                    }
13306                }
13307                var groupSelected = $('.ct-ultimate-gdpr-cookie-modal-slider-item--active input').data('count');
13308                document.cookie = 'gdprPluginGroup=' + groupSelected + self.cookieProperties;
13309                document.cookie = 'gdprPlugin=true' + self.cookieProperties;
13310                document.cookie = 'gdprPluginCountry=' + self.countryGlobal + self.cookieProperties;
13311
13312                $('#ct-ultimate-gdpr-cookie-popup').hide();
13313                location.reload();
13314            });
13315        },
13316
13317        // method for popup cookie decline action with default settings selected
13318        declineCookiePopup: function () {
13319
13320            // variebles
13321            var self = this;
13322            var popupOptions = this.settings.popup_options;
13323
13324            $('#cookie-popup-close-button').on('click', function () {
13325                for (var key in popupOptions.cookies_groups) {
13326                    var $currentGroup = $('#' + key);
13327                    if ($currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--active') || $currentGroup.parent().hasClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected')) {
13328                        document.cookie = key + '=true' + self.cookieProperties;
13329                    } else {
13330                        document.cookie = key + '=false' + self.cookieProperties;
13331                    }
13332                }
13333                var groupSelected = $('.ct-ultimate-gdpr-cookie-modal-slider-item--active input').data('count');
13334                document.cookie = 'gdprPluginGroup=' + groupSelected + self.cookieProperties;
13335                document.cookie = 'gdprPlugin=true' + self.cookieProperties;
13336                document.cookie = 'gdprPluginCountry=' + self.countryGlobal + self.cookieProperties;
13337
13338                $('#ct-ultimate-gdpr-cookie-popup').hide();
13339                location.reload();
13340            });
13341        },
13342
13343
13344        // method for age popup submit action
13345        submitAgePopup: function (popupOptions) {
13346            var popupOptionsData = popupOptions;
13347            $('#ct-gdpr-age-accept').on('click', function () {
13348                var dob =
13349                    $('.ct-gdpr-input-month').val()
13350                    + '/'
13351                    + $('.ct-gdpr-input-day').val()
13352                    + '/'
13353                    + $('.ct-gdpr-input-year').val();
13354
13355                var now = new Date();
13356                var birthdate = dob.split("/");
13357                var born = new Date(birthdate[2], birthdate[1]-1, birthdate[0]);
13358                var age = get_age(born,now);
13359                var ageLimit = popupOptionsData.age_limit;
13360
13361                if (age < ageLimit) {
13362                    alert('Age should be greater than or equal to ' + ageLimit);
13363                } else {
13364                    document.cookie = 'gdprAge=' + born + '; expires=Fri, 31 Dec 9999 23:59:59 GMT;';
13365                    $('#ct-ultimate-gdpr-cookie-age-popup').removeClass('show');
13366                }
13367
13368            });
13369
13370            function get_age(born, now) {
13371                var birthday = new Date(now.getFullYear(), born.getMonth(), born.getDate());
13372
13373                if (now >= birthday) {
13374                    return now.getFullYear() - born.getFullYear();
13375                } else {
13376                    return now.getFullYear() - born.getFullYear() - 1;
13377                }
13378            }
13379
13380        },
13381
13382        // method for displaying cookie list
13383        localCookiesList: function () {
13384
13385            // variebles
13386            var self = this;
13387            var cookiesList = document.cookie;
13388
13389            cookiesList.split(' ').forEach(function (element) {
13390                console.log('[ultimate gdpr] Local cookie name: ' + element.slice(0, element.indexOf('=')));
13391            });
13392        },
13393
13394        // methods for adding checkbox for forms
13395        preventForms: function () {
13396
13397            // variebles
13398            var self = this;
13399            var formsOptions = this.settings.forms;
13400            var formsAllowed = this.settings.forms.prevent_forms_exclude;
13401
13402            // excluding selectors from array
13403            $(function () {
13404                var selector = 'body form';
13405                formsAllowed.forEach(function (element) {
13406                    selector += ':not(' + element + ')';
13407                });
13408                var $allForms = $(selector);
13409
13410                var counter = 0;
13411                // adding checkbox before submit button
13412                $allForms.each(function () {
13413
13414                    var $formCheckbox = $('<div class="form-group ct-ultimate-gdpr-form-block"><label for="ct-ultimate-gdpr-form-blockInput-'+ counter +'">' + formsOptions.prevent_forms_text + '</label><input type="checkbox" id="ct-ultimate-gdpr-form-blockInput-' + counter + '" name="ct-ultimate-gdpr-form-blockInput" required style="margin-left: 10px;"></div>');
13415                    var $sumbitButton = $(this).find(':submit');
13416                    $formCheckbox.insertBefore($sumbitButton);
13417
13418                    counter++;
13419                });
13420            });
13421        },
13422
13423        // method for assets from dependencies array
13424        loadAssets: function () {
13425            var self = this;
13426
13427            // load up some CSS and js
13428            var dependencies = this.settings.configure_mode.dependencies;
13429
13430            dependencies.forEach(function (element) {
13431                head.load(element, function(){
13432                    if (element.indexOf('ct-ultimate-gdpr') > -1){
13433                        $(function(){
13434                            $('#ct-ultimate-gdpr-cookie-popup').show();
13435                        });
13436                    }
13437                });
13438            });
13439        },
13440
13441        // method for popup creating
13442        popUpBox: function () {
13443            // variebles
13444            var self = this;
13445            var popup = $('<div id="ct-ultimate-gdpr-cookie-popup" style="display: none"></div>');
13446            var popupOptionStyle = self.settings.popup_style;
13447            var popupOptions = self.settings.popup_options;
13448            var popupCookieCloseButton = '<div id = "cookie-popup-close-button" style="color:'+ popupOptions.cookie_popup_close_color + '"><span class="fas fa-times fa-2x" aria-hidden="true"></span></div>'
13449
13450            var headerPopup = '';
13451
13452            if(popupOptions.popup_title){
13453                headerPopup = '<h2 class="ct-header-popup">' + popupOptions.popup_title + '</h2>';
13454            }
13455
13456            // styles for cookies box theme
13457            popup.addClass(popupOptionStyle.box_skin);
13458
13459            // class for popup position
13460            if (popupOptionStyle.position === 'top-panel') {
13461                popup.addClass('ct-ultimate-gdpr-cookie-topPanel');
13462            }
13463            if (popupOptionStyle.position === 'bottom-panel') {
13464                popup.addClass('ct-ultimate-gdpr-cookie-bottomPanel');
13465            }
13466            if (popupOptionStyle.position === 'bottom-left') {
13467                popup.addClass('ct-ultimate-gdpr-cookie-bottomLeft');
13468            }
13469            if (popupOptionStyle.position === 'bottom-right') {
13470                popup.addClass('ct-ultimate-gdpr-cookie-bottomRight');
13471            }
13472            if (popupOptionStyle.position === 'top-left') {
13473                popup.addClass('ct-ultimate-gdpr-cookie-topLeft');
13474            }
13475            if (popupOptionStyle.position === 'top-right') {
13476                popup.addClass('ct-ultimate-gdpr-cookie-topRight');
13477            }
13478            if (popupOptionStyle.box_style === 'modern') {
13479                popup.addClass('ct-ultimate-gdpr-cookie-popup-modern');
13480            }
13481            if (popupOptionStyle.box_shape === 'squared') {
13482                popup.addClass('ct-ultimate-gdpr-cookie-popup-squared');
13483            }
13484            if (popupOptionStyle.button_shape === 'rounded') {
13485                popup.addClass('ct-ultimate-gdpr-cookie-popup-button-rounded');
13486            }
13487            if (popupOptionStyle.button_size === 'large') {
13488                popup.addClass('ct-ultimate-gdpr-cookie-popup-button-large');
13489            }
13490            if (popupOptionStyle.position === 'top-panel') {
13491                popup.css({'top': '0', 'width': '100%', 'border-radius': '0'});
13492            } else if (popupOptionStyle.position === 'bottom-panel') {
13493                popup.css({'bottom': '0', 'width': '100%', 'border-radius': '0'});
13494            }
13495
13496            // css properties
13497            // for skin-default only
13498            if (popupOptionStyle.box_skin === 'skin-default-theme') {
13499                popup.css('background-color', popupOptionStyle.background_color).css('color', popupOptionStyle.text_color);
13500            }
13501            // container
13502            if (popupOptionStyle.position === 'top-panel') {
13503                if (popupOptionStyle.box_skin === 'skin-dark-theme') {
13504                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel"><img src="' + popupOptions.assets_path + '/img/dark-cookie-icon.png" class="ct-skin-dark-icon"/>' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13505                } else if (popupOptionStyle.box_skin === 'skin-light-theme') {
13506                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel"><div class="ct-skin-light-icon"><img src="' + popupOptions.assets_path + '/img/light-cookie-icon.png"/></div>' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13507                } else {
13508                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel">' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13509                }
13510            } else if (popupOptionStyle.position === 'bottom-panel') {
13511                if (popupOptionStyle.box_skin === 'skin-dark-theme') {
13512                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel"><img src="' + popupOptions.assets_path + '/img/dark-cookie-icon.png" class="ct-skin-dark-icon"/>' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13513                }else if(popupOptionStyle.box_skin === 'skin-light-theme'){
13514                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel"><div class="ct-skin-light-icon"><img src="' + popupOptions.assets_path + '/img/light-cookie-icon.png"/></div>' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13515                }else{
13516                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel">' + headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13517                }
13518            } else {
13519
13520                if (popupOptionStyle.box_skin === 'skin-light-theme') {
13521                    popup.append('<div class="ct-skin-light-icon"><img src="' + popupOptions.assets_path + '/img/light-cookie-icon.png"/></div>');
13522                }
13523                if (popupOptionStyle.box_skin === 'skin-dark-theme') {
13524                    popup.append('<div class="ct-skin-dark-icon"><img src="' + popupOptions.assets_path + '/img/dark-cookie-icon.png"/></div>');
13525                }
13526
13527                popup.append(headerPopup + ' ' + popupCookieCloseButton + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div>');
13528                var properties = popupOptionStyle.position.split('-');
13529                properties.forEach(function (element) {
13530                    popup.css(element, popupOptionStyle.distance);
13531                });
13532            }
13533
13534            // buttons
13535            var $acceptButton = $('<div id="ct-ultimate-gdpr-cookie-accept"> ' + popupOptions.accept_button_text + '</div>');
13536            var $readButton = $('<a href="' + popupOptions.read_more_link + '" id="ct-ultimate-gdpr-cookie-read-more"> ' + popupOptions.read_button_text + '</a>');
13537            $acceptButton.css({'border-color': popupOptionStyle.button_color, 'color': popupOptionStyle.text_color});
13538            $readButton.css({'border-color': popupOptionStyle.button_color, 'color': popupOptionStyle.text_color});
13539            if (popupOptions.grouped_popup) {
13540                var $settingsButton = $('<div id="ct-ultimate-gdpr-cookie-change-settings">' + popupOptions.advenced_button_text + '</div>');
13541            }
13542
13543            // styles for buttons
13544            if (popupOptionStyle.box_style === 'modern' && (popupOptionStyle.position === 'top_panel' || 'bottom_panel')) {
13545                $acceptButton.css('background-color', popupOptionStyle.button_color);
13546                $readButton.css('background-color', popupOptionStyle.button_color);
13547                if (popupOptions.grouped_popup) {
13548                    $settingsButton.css('background-color', popupOptionStyle.button_color);
13549                }
13550            } else {
13551                $acceptButton.css('background-color', popupOptionStyle.background_color);
13552                $readButton.css('background-color', popupOptionStyle.background_color);
13553                if (popupOptions.grouped_popup) {
13554                    $settingsButton.css('background-color', popupOptionStyle.background_color);
13555                }
13556            }
13557
13558
13559            // clearfix and settings button
13560            if (popupOptionStyle.position === 'top-panel' || popupOptionStyle.position === 'bottom-panel'){
13561                var oldPopup = popup;
13562                popup = popup.find('.ct-container');
13563            }
13564
13565            if (popupOptionStyle.box_style === 'modern') {
13566                var $buttonsContainer = $('<div class="ct-ultimate-gdpr-cookie-buttons clearfix"> </div>');
13567                $buttonsContainer.append($acceptButton).append($readButton);
13568                if (popupOptions.grouped_popup) {
13569                    $buttonsContainer.append($settingsButton);
13570                }
13571                popup.append($buttonsContainer);
13572            } else {
13573                popup.append($acceptButton).append($readButton);
13574                if (popupOptions.grouped_popup) {
13575                    popup.append($settingsButton);
13576                }
13577            }
13578
13579            if (popupOptionStyle.position === 'top-panel' || popupOptionStyle.position === 'bottom-panel'){
13580                popup = oldPopup;
13581            }
13582
13583            // appending popup and adding event for accept button
13584            self.body.append(popup);
13585            self.onAcceptPopup();
13586            self.declineCookiePopup();
13587
13588            $( function() {
13589                if($(popupOptions.parent_container).length){
13590                    $( popup ).appendTo( popupOptions.parent_container );
13591                }
13592            } );
13593
13594        },
13595
13596        // method for change settings linkg
13597        settingPopUp: function () {
13598
13599            // variebles
13600            var self = this;
13601            var popupOptionStyle = self.settings.popup_style;
13602            var popupOptions = self.settings.popup_options;
13603
13604            // creating element
13605            var $cookieSettings = $('<div id="ct-ultimate-gdpr-cookie-open"><span class="fas fa-cog" aria-hidden="true"></span> <span class="sr-only">Cookie Box Settings</span> </div>')
13606            $cookieSettings.css('color', popupOptionStyle.gear_icon_color);
13607
13608            //condition on gear_icon_position
13609            var $GearIconPositions = popupOptionStyle.gear_icon_position;
13610            if($GearIconPositions === ('center-left')){
13611                $cookieSettings.css({'top':'50%','left':'20px','right':'auto','bottom':'auto'});
13612            }
13613            else if($GearIconPositions === ('center-right')){
13614                $cookieSettings.css({'top':'50%','right':'20px','left':'auto','bottom':'auto'});
13615            }
13616            else if($GearIconPositions === ('top-center')){
13617                $cookieSettings.css({'top':'20px','left':'50%','right':'auto','bottom':'auto'});
13618            }
13619            else if($GearIconPositions === ('bottom-center')){
13620                $cookieSettings.css({'top':'auto','right':'auto','left':'50%','bottom':'20px'});
13621            }
13622            else{
13623                // adding style for position
13624                var properties = popupOptionStyle.gear_icon_position.split('-');
13625                properties.forEach(function (element) {
13626                    $cookieSettings.css(element, popupOptionStyle.distance);
13627                });
13628            }
13629
13630            // apending
13631            self.body.append($cookieSettings);
13632
13633
13634            $( function() {
13635                if($(popupOptions.parent_container).length){
13636                    $( $cookieSettings ).appendTo( popupOptions.parent_container );
13637                }
13638            } );
13639
13640        },
13641
13642        // method for creating modal popup
13643        popupModal: function () {
13644
13645            // variebles
13646            var self = this;
13647            var popupOptionStyle = self.settings.popup_style;
13648            var popupOptions = self.settings.popup_options;
13649
13650            var cookiesSet = self.checkCookie('gdprPlugin');
13651            var groupFromCookie = parseInt(this.checkCookie('gdprPluginGroup'));
13652
13653            var $popupModal = $('<div id="ct-ultimate-gdpr-cookie-modal" style="display: none"><div class="ct-ultimate-gdpr-cookie-modal-content"><div id="ct-ultimate-gdpr-cookie-modal-close"><span class="fas fa-times fa-2x" aria-hidden="true"></span></div><div id="ct-ultimate-gdpr-cookie-modal-body">' + popupOptions.content_before_slider + '</div></div></div>');
13654            var $popupModalBody = $popupModal.find('#ct-ultimate-gdpr-cookie-modal-body');
13655            var $form = $('<form action="#" id="ct-ultimate-gdpr-cookie-modal-slider-form"><div class="ct-ultimate-gdpr-slider"></div><ul class="ct-ultimate-gdpr-cookie-modal-slider"> </ul></form>');
13656            var cookiesGroups = popupOptions.cookies_groups;
13657            var $popupModalBodyInfo = $('<div class="ct-ultimate-gdpr-cookie-modal-slider-wrap"> </div>');
13658
13659            // styles for modal skins
13660            $popupModalBody.addClass(popupOptions.cookies_groups_design);
13661
13662            // creating select from groups option when enabled
13663            var count = 0;
13664            Object.keys(cookiesGroups).forEach(function (element, i, array) {
13665                var thisGroup = cookiesGroups[element];
13666
13667                if (thisGroup.enable) {
13668                    if ((cookiesSet !== 'true' && element === popupOptions.default_group ) || count + 1 == groupFromCookie) {
13669                        var $listItem = $('<li class="ct-ultimate-gdpr-cookie-modal-slider-item ct-ultimate-gdpr-cookie-modal-slider-item--active ' + element + '"><div> <span class="' + thisGroup.icon + ' fa-2x" aria-hidden="true"></span></div><input type="radio" data-count="' + parseInt(i + 1) + '" id="' + element + '" name="radio-group" class="ct-ultimate-gdpr-cookie-modal-slider-radio" value="' + thisGroup.name + '" checked> <label for="' + element + '">' + thisGroup.name + '</label></li>');
13670                        $form.find('.ct-ultimate-gdpr-cookie-modal-slider').append($listItem);
13671                    } else {
13672                        var $listItem = $('<li class="ct-ultimate-gdpr-cookie-modal-slider-item ' + element + '"><div> <span class="' + thisGroup.icon + ' fa-2x" aria-hidden="true"></span></div><input type="radio" data-count="' + parseInt(i + 1) + '" id="' + element + '" name="radio-group" class="ct-ultimate-gdpr-cookie-modal-slider-radio" value="' + thisGroup.name + '"> <label for="' + element + '">' + thisGroup.name + '</label></li>');
13673                        $form.find('.ct-ultimate-gdpr-cookie-modal-slider').append($listItem);
13674                    }
13675                }
13676
13677                // creating list container
13678                var $infoList = $('<div class="ct-ultimate-gdpr-cookie-modal-slider-info ' + element + '"><div class="ct-ultimate-gdpr-cookie-modal-slider-desc"><h4>' + popupOptions.accepted_text + '</h4><ul class="ct-ultimate-gdpr-cookie-modal-slider-able"></ul></div><div class="ct-ultimate-gdpr-cookie-modal-slider-desc"><h4>' + popupOptions.declined_text + '</h4><ul class="ct-ultimate-gdpr-cookie-modal-slider-not-able"></ul></div></div>');
13679                var $infoListAble = $infoList.find('.ct-ultimate-gdpr-cookie-modal-slider-able');
13680                var $infoListNotAble = $infoList.find('.ct-ultimate-gdpr-cookie-modal-slider-not-able');
13681
13682                // adding list items
13683                for (var j = 0; j < array.length; j++) {
13684                    if (j <= count) {
13685                        var list = cookiesGroups[array[j]].list;
13686                        list.forEach(function (element) {
13687                            $infoListAble.append('<li>' + cookiesGroups[array[j]].name + ": " + element + '</li>');
13688                        });
13689                    } else {
13690                        var list = cookiesGroups[array[j]].list;
13691                        list.forEach(function (element) {
13692                            $infoListNotAble.append('<li>' + cookiesGroups[array[j]].name + ": " + element + '</li>');
13693                        });
13694                    }
13695                }
13696                $infoList.append('<div class="clearfix"></div>');
13697                $popupModalBodyInfo.append($infoList);
13698                count++;
13699            });
13700
13701
13702            // apending form
13703
13704            // giving data height for wrapper
13705            var $formItems = $form.find('.ct-ultimate-gdpr-cookie-modal-slider-item');
13706            $formItems.each(function(index, element){
13707                var width = ( 100 / ($formItems.length) * (index + 1));
13708                $(this).attr('data-width', width);
13709            });
13710
13711            $popupModalBody.append($form);
13712            $popupModalBody.append($popupModalBodyInfo);
13713            $popupModalBody.append('<div class="ct-ultimate-gdpr-cookie-modal-btn save"><a href="#">' + popupOptions.save_btn + '</a></div>');
13714            this.body.append($popupModal);
13715            this.onAcceptModal();
13716
13717            $( function() {
13718                if($(popupOptions.parent_container).length){
13719                    $( $popupModal ).appendTo( popupOptions.parent_container );
13720                }
13721            } );
13722
13723            //slider groupings conventions
13724            var numberOfInputs = $('#ct-ultimate-gdpr-cookie-modal-slider-form input[type="radio"]').length;
13725            $('.ct-ultimate-gdpr-cookie-modal-content').addClass('ct-ultimate-gdpr--Groups-' + numberOfInputs);
13726
13727        },
13728
13729        selectCookieGroup: function () {
13730            var $body = $('body');
13731            $(window).on('load', function () {
13732
13733                // variebles
13734
13735                var self = this;
13736                var $selected = $('.ct-ultimate-gdpr-cookie-modal-slider-item--active');
13737                var $checked = $selected.find('input[name=radio-group]');
13738                var $clickedCookieGroup = 'cookie' + $checked.attr('data-count');
13739                var $inputId = $checked.attr('id');
13740
13741
13742                $selected.prevAll().addClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected');
13743
13744                $('#ct-ultimate-gdpr-cookie-modal-slider-form').attr('class', 'ct-slider-' + $clickedCookieGroup);
13745                $('.ct-ultimate-gdpr-cookie-modal-slider-info.' + $inputId).css('display', 'block');
13746
13747            });
13748
13749            $('.ct-ultimate-gdpr-cookie-modal-slider').each(function () {
13750                var $btns = $('.ct-ultimate-gdpr-cookie-modal-slider-item input').click(function () {
13751                    // variebles
13752
13753                    var id = $(this).attr('id');
13754                    var $el = $('.' + id).show();
13755                    var $formClass = $('#ct-ultimate-gdpr-cookie-modal-slider-form');
13756
13757                    $formClass.attr('class', 'ct-slider-cookie' + $(this).attr('data-count'));
13758                    $('.ct-ultimate-gdpr-cookie-modal-slider-wrap > div').not($el).hide();
13759
13760                    var wrapperWidth = $(this).parent().data('width');
13761                    $('.ct-ultimate-gdpr-slider').css('width', wrapperWidth + '%').css('display', 'block');
13762
13763
13764                    $btns.parent().removeClass('ct-ultimate-gdpr-cookie-modal-slider-item--active');
13765                    $(this).parent().addClass('ct-ultimate-gdpr-cookie-modal-slider-item--active');
13766                    $(this).parent().prevAll().addClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected');
13767                    $(this).parent().removeClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected');
13768                    $(this).parent().nextAll().removeClass('ct-ultimate-gdpr-cookie-modal-slider-item--selected');
13769                });
13770            });
13771
13772            if ($("#ct-ultimate-gdpr-cookie-popup").hasClass("ct-ultimate-gdpr-cookie-topPanel")) {
13773                $body.addClass("ct-ultimate-gdpr-cookie-topPanel-padding");
13774            } else {
13775                $body.removeClass("ct-ultimate-gdpr-cookie-topPanel-padding");
13776            }
13777
13778            if ($("#ct-ultimate-gdpr-cookie-popup").hasClass("ct-ultimate-gdpr-cookie-bottomPanel")) {
13779                $body.addClass("ct-ultimate-gdpr-cookie-bottomPanel-padding");
13780            }
13781
13782            if ($("#ct-ultimate-gdpr-cookie-popup").hasClass("ct-ultimate-gdpr-cookie-topPanel ct-ultimate-gdpr-cookie-popup-modern")) {
13783                $body.addClass("popup-modern-style");
13784            }
13785
13786            if ($("#ct-ultimate-gdpr-cookie-popup").hasClass("ct-ultimate-gdpr-cookie-bottomPanel ct-ultimate-gdpr-cookie-popup-modern")) {
13787                $body.addClass("popup-modern-style");
13788            }
13789        },
13790
13791        modalEvents: function () {
13792            // variebles
13793            var self = this;
13794            var $modalBody = this.body;
13795            var $htmlElement = $('html');
13796            var $modal = $("#ct-ultimate-gdpr-cookie-modal");
13797            // open modal on Change Settings button
13798            $('#ct-ultimate-gdpr-cookie-change-settings').on("click", function (e) {
13799                $modal.fadeIn(400);
13800                $modalBody.addClass("cookie-modal-open");
13801                $htmlElement.addClass("cookie-modal-open");
13802                e.stopPropagation();
13803            });
13804
13805            // close modal on x button
13806            $('#ct-ultimate-gdpr-cookie-modal-close').on('click', function () {
13807                $modal.fadeOut(400);
13808                $modalBody.removeClass("cookie-modal-open");
13809                $htmlElement.removeClass("cookie-modal-open");
13810            });
13811
13812            $('#ct-ultimate-gdpr-cookie-open').on('click', function (e) {
13813                $('#ct-ultimate-gdpr-cookie-modal').show();
13814                $('#ct-ultimate-gdpr-cookie-open').hide();
13815                e.stopPropagation();
13816            });
13817
13818            //icons and title clickable
13819            $('.ct-ultimate-gdpr-cookie-modal-slider-item div').on('click', function(e){
13820                var $input = $(this).next();
13821                $input.trigger('click');
13822                e.preventDefault();
13823            });
13824
13825            //clickable whole li
13826            $('li.ct-ultimate-gdpr-cookie-modal-slider-item').click(function(e){
13827                if($(e.target).is('li.ct-ultimate-gdpr-cookie-modal-slider-item')) {
13828                    $(this).children("input[type=radio]").click();
13829                    e.preventDefault();
13830                }
13831            });
13832
13833            // making selected group active
13834            $('.ct-ultimate-gdpr-slider').css('width', $('.ct-ultimate-gdpr-cookie-modal-slider-item--active').data('width') + '%').css('display', 'block');
13835
13836            // close modal when clicking outside of modal area.
13837            $(document).on("click", function (e) {
13838                e.stopPropagation();
13839                if (!($(e.target).closest('#ct-ultimate-gdpr-cookie-change-settings, .ct-ultimate-gdpr-cookie-modal-content'))) {
13840                    $modal.fadeOut(400);
13841                    $modalBody.removeClass("cookie-modal-open");
13842                    $htmlElement.removeClass("cookie-modal-open");
13843
13844                }
13845                $('#ct-ultimate-gdpr-cookie-open').show();
13846            });
13847        },
13848
13849        // method for age popup creating
13850        agePopup: function () {
13851            // variables
13852            var self = this;
13853            var popup = $('<div id="ct-ultimate-gdpr-cookie-age-popup" class="hide"></div>');
13854            var popupOptionStyle = self.settings.age_popup_style;
13855            var popupOptions = self.settings.age_popup_options;
13856
13857            var date = new Date();
13858            var year = date.getFullYear();
13859
13860            function isNumberKey(evt)
13861            {
13862                var charCode = (evt.which) ? evt.which : event.keyCode
13863                if (charCode > 31 && (charCode < 48 || charCode > 57))
13864                    return false;
13865
13866                return true;
13867            }
13868
13869            var headerPopup = '';
13870
13871            if(popupOptions.popup_title){
13872                headerPopup = '<h2 class="ct-header-popup">' + popupOptions.popup_title + '</h2>';
13873            }
13874
13875            // styles for cookies box theme
13876            popup.addClass(popupOptionStyle.box_skin);
13877
13878            // class for popup position
13879            if (popupOptionStyle.position === 'top-panel') {
13880                popup.addClass('ct-ultimate-gdpr-cookie-topPanel');
13881            }
13882            if (popupOptionStyle.position === 'bottom-panel') {
13883                popup.addClass('ct-ultimate-gdpr-cookie-bottomPanel');
13884            }
13885            if (popupOptionStyle.position === 'bottom-left') {
13886                popup.addClass('ct-ultimate-gdpr-cookie-bottomLeft');
13887            }
13888            if (popupOptionStyle.position === 'bottom-right') {
13889                popup.addClass('ct-ultimate-gdpr-cookie-bottomRight');
13890            }
13891            if (popupOptionStyle.position === 'top-left') {
13892                popup.addClass('ct-ultimate-gdpr-cookie-topLeft');
13893            }
13894            if (popupOptionStyle.position === 'top-right') {
13895                popup.addClass('ct-ultimate-gdpr-cookie-topRight');
13896            }
13897            if (popupOptionStyle.box_style === 'modern') {
13898                popup.addClass('ct-ultimate-gdpr-cookie-popup-modern');
13899            }
13900            if (popupOptionStyle.box_shape === 'squared') {
13901                popup.addClass('ct-ultimate-gdpr-cookie-popup-squared');
13902            }
13903            if (popupOptionStyle.button_shape === 'rounded') {
13904                popup.addClass('ct-ultimate-gdpr-cookie-popup-button-rounded');
13905            }
13906            if (popupOptionStyle.button_size === 'large') {
13907                popup.addClass('ct-ultimate-gdpr-cookie-popup-button-large');
13908            }
13909            if (popupOptionStyle.position === 'top-panel') {
13910                popup.css({'top': '0', 'width': '100%', 'border-radius': '0'});
13911            } else if (popupOptionStyle.position === 'bottom-panel') {
13912                popup.css({'bottom': '0', 'width': '100%', 'border-radius': '0'});
13913            }
13914
13915            // css properties
13916            // for skin-default only
13917            if (popupOptionStyle.box_skin === 'skin-default-theme') {
13918                popup.css('background-color', popupOptionStyle.background_color).css('color', popupOptionStyle.text_color);
13919            }
13920            // container
13921            if (popupOptionStyle.position === 'top-panel') {
13922                if (popupOptionStyle.box_skin === 'skin-dark-theme') {
13923                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel">' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13924                } else if (popupOptionStyle.box_skin === 'skin-light-theme') {
13925                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel"><div class="ct-skin-light-icon"></div>' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13926                } else {
13927                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-topPanel">' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13928                }
13929            } else if (popupOptionStyle.position === 'bottom-panel') {
13930                if (popupOptionStyle.box_skin === 'skin-dark-theme') {
13931                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel">' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13932                }else if(popupOptionStyle.box_skin === 'skin-light-theme'){
13933                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel"><div class="ct-skin-light-icon"></div>' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13934                }else{
13935                    popup.append('<div class="ct-container ct-ultimate-gdpr-cookie-popup-bottomPanel">' + headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div></div>');
13936                }
13937            } else {
13938                popup.append(headerPopup + ' ' + '<div id="ct-ultimate-gdpr-cookie-content">' + popupOptions.popup_text + '</div>');
13939                var properties = popupOptionStyle.position.split('-');
13940                properties.forEach(function (element) {
13941                    popup.css(element, popupOptionStyle.distance);
13942                });
13943            }
13944
13945            popup.append('<div class="ct-container ct-gdpr-age-popup-form">\n' +
13946                '<div class="ct-gdpr-select-wrapper">\n' +
13947                '<select name="ct-gdpr-age-date-of-birth-month" id="months" class="ct-gdpr-input ct-gdpr-input-month">\n' +
13948                '<option value="1">January</option><option value="2">February</option><option value="3">March</option><option value="4">April</option><option value="5">May</option><option value="6">June</option><option value="7">July</option><option value="8">August</option><option value="9">September</option><option value="10">October</option><option value="11" selected="">November</option><option value="12">December</option></select>\n' +
13949                '</div>\n' +
13950                '<input name="ct-gdpr-age-date-of-birth-day" type="number" min="1" max="31" value="12" class="ct-gdpr-input ct-gdpr-input-number ct-gdpr-input-day">\n' +
13951                '<input name="ct-gdpr-age-date-of-birth-year" type="number" max="'+year+'" value="'+year+'" class="ct-gdpr-input ct-gdpr-input-number ct-gdpr-input-year">\n' +
13952                '<button id="ct-gdpr-age-accept" class="ct-gdpr-button">Submit</button>\n' +
13953                '</div>');
13954
13955		/*
13956            // appending popup and adding event for accept button
13957            self.body.append(popup);
13958            self.submitAgePopup(popupOptions);
13959
13960            if (!self.checkCookie('gdprAge') || popupOptions.always_show) {
13961                popup.addClass('show');
13962            }
13963		*/
13964            $( function() {
13965                if($(popupOptions.parent_container).length){
13966                    $( popup ).appendTo( popupOptions.parent_container );
13967                }
13968            } );
13969
13970            // load Montserrat font
13971            $("head").append(
13972              '<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&display=swap">'
13973            );
13974        }
13975    });
13976
13977
13978    $.fn[pluginName] = function (options) {
13979        return this.each(function () {
13980            if (!$.data(this, "plugin_" + pluginName)) {
13981                $.data(this, "plugin_" +
13982                    pluginName, new Plugin(this, options));
13983            }
13984        });
13985    };
13986
13987})
13988(ct_$, window, document);

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.