PageSourceSearch

https://www.grousemountain.com/assets/application-08dd70480390edea…5ab3f6dfa14600724f99a300235b7bcc8a493d11.js

js grousemountain.com collected 2026-09-24 17:40:56 UTC 1,565,483 bytes, 50,691 lines download raw bytes

vendor: 4,409 bytes, lines 1-181
1/*!
2 * jQuery JavaScript Library v1.12.4
3 * http://jquery.com/
4 *
5 * Includes Sizzle.js
6 * http://sizzlejs.com/
7 *
8 * Copyright jQuery Foundation and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
11 *
12 * Date: 2016-05-20T17:17Z
13 */
14
15
16(function( global, factory ) {
17
18	if ( typeof module === "object" && typeof module.exports === "object" ) {
19		// For CommonJS and CommonJS-like environments where a proper `window`
20		// is present, execute the factory and get jQuery.
21		// For environments that do not have a `window` with a `document`
22		// (such as Node.js), expose a factory as module.exports.
23		// This accentuates the need for the creation of a real `window`.
24		// e.g. var jQuery = require("jquery")(window);
25		// See ticket #14549 for more info.
26		module.exports = global.document ?
27			factory( global, true ) :
28			function( w ) {
29				if ( !w.document ) {
30					throw new Error( "jQuery requires a window with a document" );
31				}
32				return factory( w );
33			};
34	} else {
35		factory( global );
36	}
37
38// Pass this if window is not defined yet
39}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
40
41// Support: Firefox 18+
42// Can't be in strict mode, several libs including ASP.NET trace
43// the stack via arguments.caller.callee and Firefox dies if
44// you try to trace through "use strict" call chains. (#13335)
45//"use strict";
46var deletedIds = [];
47
48var document = window.document;
49
50var slice = deletedIds.slice;
51
52var concat = deletedIds.concat;
53
54var push = deletedIds.push;
55
56var indexOf = deletedIds.indexOf;
57
58var class2type = {};
59
60var toString = class2type.toString;
61
62var hasOwn = class2type.hasOwnProperty;
63
64var support = {};
65
66
67
68var
69	version = "1.12.4",
70
71	// Define a local copy of jQuery
72	jQuery = function( selector, context ) {
73
74		// The jQuery object is actually just the init constructor 'enhanced'
75		// Need init if jQuery is called (just allow error to be thrown if not included)
76		return new jQuery.fn.init( selector, context );
77	},
78
79	// Support: Android<4.1, IE<9
80	// Make sure we trim BOM and NBSP
81	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
82
83	// Matches dashed string for camelizing
84	rmsPrefix = /^-ms-/,
85	rdashAlpha = /-([\da-z])/gi,
86
87	// Used by jQuery.camelCase as callback to replace()
88	fcamelCase = function( all, letter ) {
89		return letter.toUpperCase();
90	};
91
92jQuery.fn = jQuery.prototype = {
93
94	// The current version of jQuery being used
95	jquery: version,
96
97	constructor: jQuery,
98
99	// Start with an empty selector
100	selector: "",
101
102	// The default length of a jQuery object is 0
103	length: 0,
104
105	toArray: function() {
106		return slice.call( this );
107	},
108
109	// Get the Nth element in the matched element set OR
110	// Get the whole matched element set as a clean array
111	get: function( num ) {
112		return num != null ?
113
114			// Return just the one element from the set
115			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
116
117			// Return all the elements in a clean array
118			slice.call( this );
119	},
120
121	// Take an array of elements and push it onto the stack
122	// (returning the new matched element set)
123	pushStack: function( elems ) {
124
125		// Build a new jQuery matched element set
126		var ret = jQuery.merge( this.constructor(), elems );
127
128		// Add the old object onto the stack (as a reference)
129		ret.prevObject = this;
130		ret.context = this.context;
131
132		// Return the newly-formed element set
133		return ret;
134	},
135
136	// Execute a callback for every element in the matched set.
137	each: function( callback ) {
138		return jQuery.each( this, callback );
139	},
140
141	map: function( callback ) {
142		return this.pushStack( jQuery.map( this, function( elem, i ) {
143			return callback.call( elem, i, elem );
144		} ) );
145	},
146
147	slice: function() {
148		return this.pushStack( slice.apply( this, arguments ) );
149	},
150
151	first: function() {
152		return this.eq( 0 );
153	},
154
155	last: function() {
156		return this.eq( -1 );
157	},
158
159	eq: function( i ) {
160		var len = this.length,
161			j = +i + ( i < 0 ? len : 0 );
162		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
163	},
164
165	end: function() {
166		return this.prevObject || this.constructor();
167	},
168
169	// For internal use only.
170	// Behaves like an Array's method, not like a jQuery method.
171	push: push,
172	sort: deletedIds.sort,
173	splice: deletedIds.splice
174};
175
176jQuery.extend = jQuery.fn.extend = function() {
177	var src, copyIsArray, copy, name, options, clone,
178		target = arguments[ 0 ] || {},
179		i = 1,
180		length = arguments.length,
181		deep = false;
182
183	// Handle a deep copy situation
184	if ( typeof target === "boolean" ) {
185		deep = target;
186
187		// skip the boolean and the target
188		target = arguments[ i ] || {};
189		i++;
190	}
191
192	// Handle case when target is a string or something (possible in deep copy)
193	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
194		target = {};
195	}
196
197	// extend jQuery itself if only one argument is passed
198	if ( i === length ) {
199		target = this;
200		i--;
201	}
202
203	for ( ; i < length; i++ ) {
204
205		// Only deal with non-null/undefined values
206		if ( ( options = arguments[ i ] ) != null ) {
207
208			// Extend the base object
209			for ( name in options ) {
210				src = target[ name ];
211				copy = options[ name ];
212
213				// Prevent never-ending loop
214				if ( target === copy ) {
215					continue;
216				}
217
218				// Recurse if we're merging plain objects or arrays
219				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
220					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
221
222					if ( copyIsArray ) {
223						copyIsArray = false;
224						clone = src && jQuery.isArray( src ) ? src : [];
225
226					} else {
227						clone = src && jQuery.isPlainObject( src ) ? src : {};
228					}
229
230					// Never move original objects, clone them
231					target[ name ] = jQuery.extend( deep, clone, copy );
232
233				// Don't bring in undefined values
234				} else if ( copy !== undefined ) {
235					target[ name ] = copy;
236				}
237			}
238		}
239	}
240
241	// Return the modified object
242	return target;
243};
244
245jQuery.extend( {
246
247	// Unique for each copy of jQuery on the page
248	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
249
250	// Assume jQuery is ready without the ready module
251	isReady: true,
252
253	error: function( msg ) {
254		throw new Error( msg );
255	},
256
257	noop: function() {},
258
259	// See test/unit/core.js for details concerning isFunction.
260	// Since version 1.3, DOM methods and functions like alert
261	// aren't supported. They return false on IE (#2968).
262	isFunction: function( obj ) {
263		return jQuery.type( obj ) === "function";
264	},
265
266	isArray: Array.isArray || function( obj ) {
267		return jQuery.type( obj ) === "array";
268	},
269
270	isWindow: function( obj ) {
271		/* jshint eqeqeq: false */
272		return obj != null && obj == obj.window;
273	},
274
275	isNumeric: function( obj ) {
276
277		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
278		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
279		// subtraction forces infinities to NaN
280		// adding 1 corrects loss of precision from parseFloat (#15100)
281		var realStringObj = obj && obj.toString();
282		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
283	},
284
285	isEmptyObject: function( obj ) {
286		var name;
287		for ( name in obj ) {
288			return false;
289		}
290		return true;
291	},
292
293	isPlainObject: function( obj ) {
294		var key;
295
296		// Must be an Object.
297		// Because of IE, we also have to check the presence of the constructor property.
298		// Make sure that DOM nodes and window objects don't pass through, as well
299		if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
300			return false;
301		}
302
303		try {
304
305			// Not own constructor property must be Object
306			if ( obj.constructor &&
307				!hasOwn.call( obj, "constructor" ) &&
308				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
309				return false;
310			}
311		} catch ( e ) {
312
313			// IE8,9 Will throw exceptions on certain host objects #9897
314			return false;
315		}
316
317		// Support: IE<9
318		// Handle iteration over inherited properties before own properties.
319		if ( !support.ownFirst ) {
320			for ( key in obj ) {
321				return hasOwn.call( obj, key );
322			}
323		}
324
325		// Own properties are enumerated firstly, so to speed up,
326		// if last one is own, then all properties are own.
327		for ( key in obj ) {}
328
329		return key === undefined || hasOwn.call( obj, key );
330	},
331
332	type: function( obj ) {
333		if ( obj == null ) {
334			return obj + "";
335		}
336		return typeof obj === "object" || typeof obj === "function" ?
337			class2type[ toString.call( obj ) ] || "object" :
338			typeof obj;
339	},
340
341	// Workarounds based on findings by Jim Driscoll
342	// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
343	globalEval: function( data ) {
344		if ( data && jQuery.trim( data ) ) {
345
346			// We use execScript on Internet Explorer
347			// We use an anonymous function so that context is window
348			// rather than jQuery in Firefox
349			( window.execScript || function( data ) {
350				window[ "eval" ].call( window, data ); // jscs:ignore requireDotNotation
351			} )( data );
352		}
353	},
354
355	// Convert dashed to camelCase; used by the css and data modules
356	// Microsoft forgot to hump their vendor prefix (#9572)
357	camelCase: function( string ) {
358		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
359	},
360
361	nodeName: function( elem, name ) {
362		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
363	},
364
365	each: function( obj, callback ) {
366		var length, i = 0;
367
368		if ( isArrayLike( obj ) ) {
369			length = obj.length;
370			for ( ; i < length; i++ ) {
371				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
372					break;
373				}
374			}
375		} else {
376			for ( i in obj ) {
377				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
378					break;
379				}
380			}
381		}
382
383		return obj;
384	},
385
386	// Support: Android<4.1, IE<9
387	trim: function( text ) {
388		return text == null ?
389			"" :
390			( text + "" ).replace( rtrim, "" );
391	},
392
393	// results is for internal usage only
394	makeArray: function( arr, results ) {
395		var ret = results || [];
396
397		if ( arr != null ) {
398			if ( isArrayLike( Object( arr ) ) ) {
399				jQuery.merge( ret,
400					typeof arr === "string" ?
401					[ arr ] : arr
402				);
403			} else {
404				push.call( ret, arr );
405			}
406		}
407
408		return ret;
409	},
410
411	inArray: function( elem, arr, i ) {
412		var len;
413
414		if ( arr ) {
415			if ( indexOf ) {
416				return indexOf.call( arr, elem, i );
417			}
418
419			len = arr.length;
420			i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
421
422			for ( ; i < len; i++ ) {
423
424				// Skip accessing in sparse arrays
425				if ( i in arr && arr[ i ] === elem ) {
426					return i;
427				}
428			}
429		}
430
431		return -1;
432	},
433
434	merge: function( first, second ) {
435		var len = +second.length,
436			j = 0,
437			i = first.length;
438
439		while ( j < len ) {
440			first[ i++ ] = second[ j++ ];
441		}
442
443		// Support: IE<9
444		// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
445		if ( len !== len ) {
446			while ( second[ j ] !== undefined ) {
447				first[ i++ ] = second[ j++ ];
448			}
449		}
450
451		first.length = i;
452
453		return first;
454	},
455
456	grep: function( elems, callback, invert ) {
457		var callbackInverse,
458			matches = [],
459			i = 0,
460			length = elems.length,
461			callbackExpect = !invert;
462
463		// Go through the array, only saving the items
464		// that pass the validator function
465		for ( ; i < length; i++ ) {
466			callbackInverse = !callback( elems[ i ], i );
467			if ( callbackInverse !== callbackExpect ) {
468				matches.push( elems[ i ] );
469			}
470		}
471
472		return matches;
473	},
474
475	// arg is for internal usage only
476	map: function( elems, callback, arg ) {
477		var length, value,
478			i = 0,
479			ret = [];
480
481		// Go through the array, translating each of the items to their new values
482		if ( isArrayLike( elems ) ) {
483			length = elems.length;
484			for ( ; i < length; i++ ) {
485				value = callback( elems[ i ], i, arg );
486
487				if ( value != null ) {
488					ret.push( value );
489				}
490			}
491
492		// Go through every key on the object,
493		} else {
494			for ( i in elems ) {
495				value = callback( elems[ i ], i, arg );
496
497				if ( value != null ) {
498					ret.push( value );
499				}
500			}
501		}
502
503		// Flatten any nested arrays
504		return concat.apply( [], ret );
505	},
506
507	// A global GUID counter for objects
508	guid: 1,
509
510	// Bind a function to a context, optionally partially applying any
511	// arguments.
512	proxy: function( fn, context ) {
513		var args, proxy, tmp;
514
515		if ( typeof context === "string" ) {
516			tmp = fn[ context ];
517			context = fn;
518			fn = tmp;
519		}
520
521		// Quick check to determine if target is callable, in the spec
522		// this throws a TypeError, but we will just return undefined.
523		if ( !jQuery.isFunction( fn ) ) {
524			return undefined;
525		}
526
527		// Simulated bind
528		args = slice.call( arguments, 2 );
529		proxy = function() {
530			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
531		};
532
533		// Set the guid of unique handler to the same of original handler, so it can be removed
534		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
535
536		return proxy;
537	},
538
539	now: function() {
540		return +( new Date() );
541	},
542
543	// jQuery.support is not used in Core but other projects attach their
544	// properties to it so it needs to exist.
545	support: support
546} );
547
548// JSHint would error on this code due to the Symbol not being defined in ES5.
549// Defining this global in .jshintrc would create a danger of using the global
550// unguarded in another place, it seems safer to just disable JSHint for these
551// three lines.
552/* jshint ignore: start */
553if ( typeof Symbol === "function" ) {
554	jQuery.fn[ Symbol.iterator ] = deletedIds[ Symbol.iterator ];
555}
556/* jshint ignore: end */
557
558// Populate the class2type map
559jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
560function( i, name ) {
561	class2type[ "[object " + name + "]" ] = name.toLowerCase();
562} );
563
564function isArrayLike( obj ) {
565
566	// Support: iOS 8.2 (not reproducible in simulator)
567	// `in` check used to prevent JIT error (gh-2145)
568	// hasOwn isn't used here due to false negatives
569	// regarding Nodelist length in IE
570	var length = !!obj && "length" in obj && obj.length,
571		type = jQuery.type( obj );
572
573	if ( type === "function" || jQuery.isWindow( obj ) ) {
574		return false;
vendor: 26,428 bytes, lines 575-1499
575	}
576
577	return type === "array" || length === 0 ||
578		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
579}
580var Sizzle =
581/*!
582 * Sizzle CSS Selector Engine v2.2.1
583 * http://sizzlejs.com/
584 *
585 * Copyright jQuery Foundation and other contributors
586 * Released under the MIT license
587 * http://jquery.org/license
588 *
589 * Date: 2015-10-17
590 */
591(function( window ) {
592
593var i,
594	support,
595	Expr,
596	getText,
597	isXML,
598	tokenize,
599	compile,
600	select,
601	outermostContext,
602	sortInput,
603	hasDuplicate,
604
605	// Local document vars
606	setDocument,
607	document,
608	docElem,
609	documentIsHTML,
610	rbuggyQSA,
611	rbuggyMatches,
612	matches,
613	contains,
614
615	// Instance-specific data
616	expando = "sizzle" + 1 * new Date(),
617	preferredDoc = window.document,
618	dirruns = 0,
619	done = 0,
620	classCache = createCache(),
621	tokenCache = createCache(),
622	compilerCache = createCache(),
623	sortOrder = function( a, b ) {
624		if ( a === b ) {
625			hasDuplicate = true;
626		}
627		return 0;
628	},
629
630	// General-purpose constants
631	MAX_NEGATIVE = 1 << 31,
632
633	// Instance methods
634	hasOwn = ({}).hasOwnProperty,
635	arr = [],
636	pop = arr.pop,
637	push_native = arr.push,
638	push = arr.push,
639	slice = arr.slice,
640	// Use a stripped-down indexOf as it's faster than native
641	// http://jsperf.com/thor-indexof-vs-for/5
642	indexOf = function( list, elem ) {
643		var i = 0,
644			len = list.length;
645		for ( ; i < len; i++ ) {
646			if ( list[i] === elem ) {
647				return i;
648			}
649		}
650		return -1;
651	},
652
653	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
654
655	// Regular expressions
656
657	// http://www.w3.org/TR/css3-selectors/#whitespace
658	whitespace = "[\\x20\\t\\r\\n\\f]",
659
660	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
661	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
662
663	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
664	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
665		// Operator (capture 2)
666		"*([*^$|!~]?=)" + whitespace +
667		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
668		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
669		"*\\]",
670
671	pseudos = ":(" + identifier + ")(?:\\((" +
672		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
673		// 1. quoted (capture 3; capture 4 or capture 5)
674		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
675		// 2. simple (capture 6)
676		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
677		// 3. anything else (capture 2)
678		".*" +
679		")\\)|)",
680
681	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
682	rwhitespace = new RegExp( whitespace + "+", "g" ),
683	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
684
685	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
686	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
687
688	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
689
690	rpseudo = new RegExp( pseudos ),
691	ridentifier = new RegExp( "^" + identifier + "$" ),
692
693	matchExpr = {
694		"ID": new RegExp( "^#(" + identifier + ")" ),
695		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
696		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
697		"ATTR": new RegExp( "^" + attributes ),
698		"PSEUDO": new RegExp( "^" + pseudos ),
699		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
700			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
701			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
702		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
703		// For use in libraries implementing .is()
704		// We use this for POS matching in `select`
705		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
706			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
707	},
708
709	rinputs = /^(?:input|select|textarea|button)$/i,
710	rheader = /^h\d$/i,
711
712	rnative = /^[^{]+\{\s*\[native \w/,
713
714	// Easily-parseable/retrievable ID or TAG or CLASS selectors
715	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
716
717	rsibling = /[+~]/,
718	rescape = /'|\\/g,
719
720	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
721	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
722	funescape = function( _, escaped, escapedWhitespace ) {
723		var high = "0x" + escaped - 0x10000;
724		// NaN means non-codepoint
725		// Support: Firefox<24
726		// Workaround erroneous numeric interpretation of +"0x"
727		return high !== high || escapedWhitespace ?
728			escaped :
729			high < 0 ?
730				// BMP codepoint
731				String.fromCharCode( high + 0x10000 ) :
732				// Supplemental Plane codepoint (surrogate pair)
733				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
734	},
735
736	// Used for iframes
737	// See setDocument()
738	// Removing the function wrapper causes a "Permission Denied"
739	// error in IE
740	unloadHandler = function() {
741		setDocument();
742	};
743
744// Optimize for push.apply( _, NodeList )
745try {
746	push.apply(
747		(arr = slice.call( preferredDoc.childNodes )),
748		preferredDoc.childNodes
749	);
750	// Support: Android<4.0
751	// Detect silently failing push.apply
752	arr[ preferredDoc.childNodes.length ].nodeType;
753} catch ( e ) {
754	push = { apply: arr.length ?
755
756		// Leverage slice if possible
757		function( target, els ) {
758			push_native.apply( target, slice.call(els) );
759		} :
760
761		// Support: IE<9
762		// Otherwise append directly
763		function( target, els ) {
764			var j = target.length,
765				i = 0;
766			// Can't trust NodeList.length
767			while ( (target[j++] = els[i++]) ) {}
768			target.length = j - 1;
769		}
770	};
771}
772
773function Sizzle( selector, context, results, seed ) {
774	var m, i, elem, nid, nidselect, match, groups, newSelector,
775		newContext = context && context.ownerDocument,
776
777		// nodeType defaults to 9, since context defaults to document
778		nodeType = context ? context.nodeType : 9;
779
780	results = results || [];
781
782	// Return early from calls with invalid selector or context
783	if ( typeof selector !== "string" || !selector ||
784		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
785
786		return results;
787	}
788
789	// Try to shortcut find operations (as opposed to filters) in HTML documents
790	if ( !seed ) {
791
792		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
793			setDocument( context );
794		}
795		context = context || document;
796
797		if ( documentIsHTML ) {
798
799			// If the selector is sufficiently simple, try using a "get*By*" DOM method
800			// (excepting DocumentFragment context, where the methods don't exist)
801			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
802
803				// ID selector
804				if ( (m = match[1]) ) {
805
806					// Document context
807					if ( nodeType === 9 ) {
808						if ( (elem = context.getElementById( m )) ) {
809
810							// Support: IE, Opera, Webkit
811							// TODO: identify versions
812							// getElementById can match elements by name instead of ID
813							if ( elem.id === m ) {
814								results.push( elem );
815								return results;
816							}
817						} else {
818							return results;
819						}
820
821					// Element context
822					} else {
823
824						// Support: IE, Opera, Webkit
825						// TODO: identify versions
826						// getElementById can match elements by name instead of ID
827						if ( newContext && (elem = newContext.getElementById( m )) &&
828							contains( context, elem ) &&
829							elem.id === m ) {
830
831							results.push( elem );
832							return results;
833						}
834					}
835
836				// Type selector
837				} else if ( match[2] ) {
838					push.apply( results, context.getElementsByTagName( selector ) );
839					return results;
840
841				// Class selector
842				} else if ( (m = match[3]) && support.getElementsByClassName &&
843					context.getElementsByClassName ) {
844
845					push.apply( results, context.getElementsByClassName( m ) );
846					return results;
847				}
848			}
849
850			// Take advantage of querySelectorAll
851			if ( support.qsa &&
852				!compilerCache[ selector + " " ] &&
853				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
854
855				if ( nodeType !== 1 ) {
856					newContext = context;
857					newSelector = selector;
858
859				// qSA looks outside Element context, which is not what we want
860				// Thanks to Andrew Dupont for this workaround technique
861				// Support: IE <=8
862				// Exclude object elements
863				} else if ( context.nodeName.toLowerCase() !== "object" ) {
864
865					// Capture the context ID, setting it first if necessary
866					if ( (nid = context.getAttribute( "id" )) ) {
867						nid = nid.replace( rescape, "\\$&" );
868					} else {
869						context.setAttribute( "id", (nid = expando) );
870					}
871
872					// Prefix every selector in the list
873					groups = tokenize( selector );
874					i = groups.length;
875					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
876					while ( i-- ) {
877						groups[i] = nidselect + " " + toSelector( groups[i] );
878					}
879					newSelector = groups.join( "," );
880
881					// Expand context for sibling selectors
882					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
883						context;
884				}
885
886				if ( newSelector ) {
887					try {
888						push.apply( results,
889							newContext.querySelectorAll( newSelector )
890						);
891						return results;
892					} catch ( qsaError ) {
893					} finally {
894						if ( nid === expando ) {
895							context.removeAttribute( "id" );
896						}
897					}
898				}
899			}
900		}
901	}
902
903	// All others
904	return select( selector.replace( rtrim, "$1" ), context, results, seed );
905}
906
907/**
908 * Create key-value caches of limited size
909 * @returns {function(string, object)} Returns the Object data after storing it on itself with
910 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
911 *	deleting the oldest entry
912 */
913function createCache() {
914	var keys = [];
915
916	function cache( key, value ) {
917		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
918		if ( keys.push( key + " " ) > Expr.cacheLength ) {
919			// Only keep the most recent entries
920			delete cache[ keys.shift() ];
921		}
922		return (cache[ key + " " ] = value);
923	}
924	return cache;
925}
926
927/**
928 * Mark a function for special use by Sizzle
929 * @param {Function} fn The function to mark
930 */
931function markFunction( fn ) {
932	fn[ expando ] = true;
933	return fn;
934}
935
936/**
937 * Support testing using an element
938 * @param {Function} fn Passed the created div and expects a boolean result
939 */
940function assert( fn ) {
941	var div = document.createElement("div");
942
943	try {
944		return !!fn( div );
945	} catch (e) {
946		return false;
947	} finally {
948		// Remove from its parent by default
949		if ( div.parentNode ) {
950			div.parentNode.removeChild( div );
951		}
952		// release memory in IE
953		div = null;
954	}
955}
956
957/**
958 * Adds the same handler for all of the specified attrs
959 * @param {String} attrs Pipe-separated list of attributes
960 * @param {Function} handler The method that will be applied
961 */
962function addHandle( attrs, handler ) {
963	var arr = attrs.split("|"),
964		i = arr.length;
965
966	while ( i-- ) {
967		Expr.attrHandle[ arr[i] ] = handler;
968	}
969}
970
971/**
972 * Checks document order of two siblings
973 * @param {Element} a
974 * @param {Element} b
975 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
976 */
977function siblingCheck( a, b ) {
978	var cur = b && a,
979		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
980			( ~b.sourceIndex || MAX_NEGATIVE ) -
981			( ~a.sourceIndex || MAX_NEGATIVE );
982
983	// Use IE sourceIndex if available on both nodes
984	if ( diff ) {
985		return diff;
986	}
987
988	// Check if b follows a
989	if ( cur ) {
990		while ( (cur = cur.nextSibling) ) {
991			if ( cur === b ) {
992				return -1;
993			}
994		}
995	}
996
997	return a ? 1 : -1;
998}
999
1000/**
1001 * Returns a function to use in pseudos for input types
1002 * @param {String} type
1003 */
1004function createInputPseudo( type ) {
1005	return function( elem ) {
1006		var name = elem.nodeName.toLowerCase();
1007		return name === "input" && elem.type === type;
1008	};
1009}
1010
1011/**
1012 * Returns a function to use in pseudos for buttons
1013 * @param {String} type
1014 */
1015function createButtonPseudo( type ) {
1016	return function( elem ) {
1017		var name = elem.nodeName.toLowerCase();
1018		return (name === "input" || name === "button") && elem.type === type;
1019	};
1020}
1021
1022/**
1023 * Returns a function to use in pseudos for positionals
1024 * @param {Function} fn
1025 */
1026function createPositionalPseudo( fn ) {
1027	return markFunction(function( argument ) {
1028		argument = +argument;
1029		return markFunction(function( seed, matches ) {
1030			var j,
1031				matchIndexes = fn( [], seed.length, argument ),
1032				i = matchIndexes.length;
1033
1034			// Match elements found at the specified indexes
1035			while ( i-- ) {
1036				if ( seed[ (j = matchIndexes[i]) ] ) {
1037					seed[j] = !(matches[j] = seed[j]);
1038				}
1039			}
1040		});
1041	});
1042}
1043
1044/**
1045 * Checks a node for validity as a Sizzle context
1046 * @param {Element|Object=} context
1047 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1048 */
1049function testContext( context ) {
1050	return context && typeof context.getElementsByTagName !== "undefined" && context;
1051}
1052
1053// Expose support vars for convenience
1054support = Sizzle.support = {};
1055
1056/**
1057 * Detects XML nodes
1058 * @param {Element|Object} elem An element or a document
1059 * @returns {Boolean} True iff elem is a non-HTML XML node
1060 */
1061isXML = Sizzle.isXML = function( elem ) {
1062	// documentElement is verified for cases where it doesn't yet exist
1063	// (such as loading iframes in IE - #4833)
1064	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1065	return documentElement ? documentElement.nodeName !== "HTML" : false;
1066};
1067
1068/**
1069 * Sets document-related variables once based on the current document
1070 * @param {Element|Object} [doc] An element or document object to use to set the document
1071 * @returns {Object} Returns the current document
1072 */
1073setDocument = Sizzle.setDocument = function( node ) {
1074	var hasCompare, parent,
1075		doc = node ? node.ownerDocument || node : preferredDoc;
1076
1077	// Return early if doc is invalid or already selected
1078	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1079		return document;
1080	}
1081
1082	// Update global variables
1083	document = doc;
1084	docElem = document.documentElement;
1085	documentIsHTML = !isXML( document );
1086
1087	// Support: IE 9-11, Edge
1088	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1089	if ( (parent = document.defaultView) && parent.top !== parent ) {
1090		// Support: IE 11
1091		if ( parent.addEventListener ) {
1092			parent.addEventListener( "unload", unloadHandler, false );
1093
1094		// Support: IE 9 - 10 only
1095		} else if ( parent.attachEvent ) {
1096			parent.attachEvent( "onunload", unloadHandler );
1097		}
1098	}
1099
1100	/* Attributes
1101	---------------------------------------------------------------------- */
1102
1103	// Support: IE<8
1104	// Verify that getAttribute really returns attributes and not properties
1105	// (excepting IE8 booleans)
1106	support.attributes = assert(function( div ) {
1107		div.className = "i";
1108		return !div.getAttribute("className");
1109	});
1110
1111	/* getElement(s)By*
1112	---------------------------------------------------------------------- */
1113
1114	// Check if getElementsByTagName("*") returns only elements
1115	support.getElementsByTagName = assert(function( div ) {
1116		div.appendChild( document.createComment("") );
1117		return !div.getElementsByTagName("*").length;
1118	});
1119
1120	// Support: IE<9
1121	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1122
1123	// Support: IE<10
1124	// Check if getElementById returns elements by name
1125	// The broken getElementById methods don't pick up programatically-set names,
1126	// so use a roundabout getElementsByName test
1127	support.getById = assert(function( div ) {
1128		docElem.appendChild( div ).id = expando;
1129		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1130	});
1131
1132	// ID find and filter
1133	if ( support.getById ) {
1134		Expr.find["ID"] = function( id, context ) {
1135			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1136				var m = context.getElementById( id );
1137				return m ? [ m ] : [];
1138			}
1139		};
1140		Expr.filter["ID"] = function( id ) {
1141			var attrId = id.replace( runescape, funescape );
1142			return function( elem ) {
1143				return elem.getAttribute("id") === attrId;
1144			};
1145		};
1146	} else {
1147		// Support: IE6/7
1148		// getElementById is not reliable as a find shortcut
1149		delete Expr.find["ID"];
1150
1151		Expr.filter["ID"] =  function( id ) {
1152			var attrId = id.replace( runescape, funescape );
1153			return function( elem ) {
1154				var node = typeof elem.getAttributeNode !== "undefined" &&
1155					elem.getAttributeNode("id");
1156				return node && node.value === attrId;
1157			};
1158		};
1159	}
1160
1161	// Tag
1162	Expr.find["TAG"] = support.getElementsByTagName ?
1163		function( tag, context ) {
1164			if ( typeof context.getElementsByTagName !== "undefined" ) {
1165				return context.getElementsByTagName( tag );
1166
1167			// DocumentFragment nodes don't have gEBTN
1168			} else if ( support.qsa ) {
1169				return context.querySelectorAll( tag );
1170			}
1171		} :
1172
1173		function( tag, context ) {
1174			var elem,
1175				tmp = [],
1176				i = 0,
1177				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1178				results = context.getElementsByTagName( tag );
1179
1180			// Filter out possible comments
1181			if ( tag === "*" ) {
1182				while ( (elem = results[i++]) ) {
1183					if ( elem.nodeType === 1 ) {
1184						tmp.push( elem );
1185					}
1186				}
1187
1188				return tmp;
1189			}
1190			return results;
1191		};
1192
1193	// Class
1194	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1195		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1196			return context.getElementsByClassName( className );
1197		}
1198	};
1199
1200	/* QSA/matchesSelector
1201	---------------------------------------------------------------------- */
1202
1203	// QSA and matchesSelector support
1204
1205	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1206	rbuggyMatches = [];
1207
1208	// qSa(:focus) reports false when true (Chrome 21)
1209	// We allow this because of a bug in IE8/9 that throws an error
1210	// whenever `document.activeElement` is accessed on an iframe
1211	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1212	// See http://bugs.jquery.com/ticket/13378
1213	rbuggyQSA = [];
1214
1215	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1216		// Build QSA regex
1217		// Regex strategy adopted from Diego Perini
1218		assert(function( div ) {
1219			// Select is set to empty string on purpose
1220			// This is to test IE's treatment of not explicitly
1221			// setting a boolean content attribute,
1222			// since its presence should be enough
1223			// http://bugs.jquery.com/ticket/12359
1224			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1225				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1226				"<option selected=''></option></select>";
1227
1228			// Support: IE8, Opera 11-12.16
1229			// Nothing should be selected when empty strings follow ^= or $= or *=
1230			// The test attribute must be unknown in Opera but "safe" for WinRT
1231			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1232			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1233				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1234			}
1235
1236			// Support: IE8
1237			// Boolean attributes and "value" are not treated correctly
1238			if ( !div.querySelectorAll("[selected]").length ) {
1239				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1240			}
1241
1242			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1243			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1244				rbuggyQSA.push("~=");
1245			}
1246
1247			// Webkit/Opera - :checked should return selected option elements
1248			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1249			// IE8 throws error here and will not see later tests
1250			if ( !div.querySelectorAll(":checked").length ) {
1251				rbuggyQSA.push(":checked");
1252			}
1253
1254			// Support: Safari 8+, iOS 8+
1255			// https://bugs.webkit.org/show_bug.cgi?id=136851
1256			// In-page `selector#id sibing-combinator selector` fails
1257			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1258				rbuggyQSA.push(".#.+[+~]");
1259			}
1260		});
1261
1262		assert(function( div ) {
1263			// Support: Windows 8 Native Apps
1264			// The type and name attributes are restricted during .innerHTML assignment
1265			var input = document.createElement("input");
1266			input.setAttribute( "type", "hidden" );
1267			div.appendChild( input ).setAttribute( "name", "D" );
1268
1269			// Support: IE8
1270			// Enforce case-sensitivity of name attribute
1271			if ( div.querySelectorAll("[name=d]").length ) {
1272				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1273			}
1274
1275			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1276			// IE8 throws error here and will not see later tests
1277			if ( !div.querySelectorAll(":enabled").length ) {
1278				rbuggyQSA.push( ":enabled", ":disabled" );
1279			}
1280
1281			// Opera 10-11 does not throw on post-comma invalid pseudos
1282			div.querySelectorAll("*,:x");
1283			rbuggyQSA.push(",.*:");
1284		});
1285	}
1286
1287	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1288		docElem.webkitMatchesSelector ||
1289		docElem.mozMatchesSelector ||
1290		docElem.oMatchesSelector ||
1291		docElem.msMatchesSelector) )) ) {
1292
1293		assert(function( div ) {
1294			// Check to see if it's possible to do matchesSelector
1295			// on a disconnected node (IE 9)
1296			support.disconnectedMatch = matches.call( div, "div" );
1297
1298			// This should fail with an exception
1299			// Gecko does not error, returns false instead
1300			matches.call( div, "[s!='']:x" );
1301			rbuggyMatches.push( "!=", pseudos );
1302		});
1303	}
1304
1305	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1306	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1307
1308	/* Contains
1309	---------------------------------------------------------------------- */
1310	hasCompare = rnative.test( docElem.compareDocumentPosition );
1311
1312	// Element contains another
1313	// Purposefully self-exclusive
1314	// As in, an element does not contain itself
1315	contains = hasCompare || rnative.test( docElem.contains ) ?
1316		function( a, b ) {
1317			var adown = a.nodeType === 9 ? a.documentElement : a,
1318				bup = b && b.parentNode;
1319			return a === bup || !!( bup && bup.nodeType === 1 && (
1320				adown.contains ?
1321					adown.contains( bup ) :
1322					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1323			));
1324		} :
1325		function( a, b ) {
1326			if ( b ) {
1327				while ( (b = b.parentNode) ) {
1328					if ( b === a ) {
1329						return true;
1330					}
1331				}
1332			}
1333			return false;
1334		};
1335
1336	/* Sorting
1337	---------------------------------------------------------------------- */
1338
1339	// Document order sorting
1340	sortOrder = hasCompare ?
1341	function( a, b ) {
1342
1343		// Flag for duplicate removal
1344		if ( a === b ) {
1345			hasDuplicate = true;
1346			return 0;
1347		}
1348
1349		// Sort on method existence if only one input has compareDocumentPosition
1350		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1351		if ( compare ) {
1352			return compare;
1353		}
1354
1355		// Calculate position if both inputs belong to the same document
1356		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1357			a.compareDocumentPosition( b ) :
1358
1359			// Otherwise we know they are disconnected
1360			1;
1361
1362		// Disconnected nodes
1363		if ( compare & 1 ||
1364			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1365
1366			// Choose the first element that is related to our preferred document
1367			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1368				return -1;
1369			}
1370			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1371				return 1;
1372			}
1373
1374			// Maintain original order
1375			return sortInput ?
1376				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1377				0;
1378		}
1379
1380		return compare & 4 ? -1 : 1;
1381	} :
1382	function( a, b ) {
1383		// Exit early if the nodes are identical
1384		if ( a === b ) {
1385			hasDuplicate = true;
1386			return 0;
1387		}
1388
1389		var cur,
1390			i = 0,
1391			aup = a.parentNode,
1392			bup = b.parentNode,
1393			ap = [ a ],
1394			bp = [ b ];
1395
1396		// Parentless nodes are either documents or disconnected
1397		if ( !aup || !bup ) {
1398			return a === document ? -1 :
1399				b === document ? 1 :
1400				aup ? -1 :
1401				bup ? 1 :
1402				sortInput ?
1403				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1404				0;
1405
1406		// If the nodes are siblings, we can do a quick check
1407		} else if ( aup === bup ) {
1408			return siblingCheck( a, b );
1409		}
1410
1411		// Otherwise we need full lists of their ancestors for comparison
1412		cur = a;
1413		while ( (cur = cur.parentNode) ) {
1414			ap.unshift( cur );
1415		}
1416		cur = b;
1417		while ( (cur = cur.parentNode) ) {
1418			bp.unshift( cur );
1419		}
1420
1421		// Walk down the tree looking for a discrepancy
1422		while ( ap[i] === bp[i] ) {
1423			i++;
1424		}
1425
1426		return i ?
1427			// Do a sibling check if the nodes have a common ancestor
1428			siblingCheck( ap[i], bp[i] ) :
1429
1430			// Otherwise nodes in our document sort first
1431			ap[i] === preferredDoc ? -1 :
1432			bp[i] === preferredDoc ? 1 :
1433			0;
1434	};
1435
1436	return document;
1437};
1438
1439Sizzle.matches = function( expr, elements ) {
1440	return Sizzle( expr, null, null, elements );
1441};
1442
1443Sizzle.matchesSelector = function( elem, expr ) {
1444	// Set document vars if needed
1445	if ( ( elem.ownerDocument || elem ) !== document ) {
1446		setDocument( elem );
1447	}
1448
1449	// Make sure that attribute selectors are quoted
1450	expr = expr.replace( rattributeQuotes, "='$1']" );
1451
1452	if ( support.matchesSelector && documentIsHTML &&
1453		!compilerCache[ expr + " " ] &&
1454		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1455		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1456
1457		try {
1458			var ret = matches.call( elem, expr );
1459
1460			// IE 9's matchesSelector returns false on disconnected nodes
1461			if ( ret || support.disconnectedMatch ||
1462					// As well, disconnected nodes are said to be in a document
1463					// fragment in IE 9
1464					elem.document && elem.document.nodeType !== 11 ) {
1465				return ret;
1466			}
1467		} catch (e) {}
1468	}
1469
1470	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1471};
1472
1473Sizzle.contains = function( context, elem ) {
1474	// Set document vars if needed
1475	if ( ( context.ownerDocument || context ) !== document ) {
1476		setDocument( context );
1477	}
1478	return contains( context, elem );
1479};
1480
1481Sizzle.attr = function( elem, name ) {
1482	// Set document vars if needed
1483	if ( ( elem.ownerDocument || elem ) !== document ) {
1484		setDocument( elem );
1485	}
1486
1487	var fn = Expr.attrHandle[ name.toLowerCase() ],
1488		// Don't get fooled by Object.prototype properties (jQuery #13807)
1489		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1490			fn( elem, name, !documentIsHTML ) :
1491			undefined;
1492
1493	return val !== undefined ?
1494		val :
1495		support.attributes || !documentIsHTML ?
1496			elem.getAttribute( name ) :
1497			(val = elem.getAttributeNode(name)) && val.specified ?
1498				val.value :
1499				null
vendor: 13,569 bytes, lines 1499-1969
1499;
1500};
1501
1502Sizzle.error = function( msg ) {
1503	throw new Error( "Syntax error, unrecognized expression: " + msg );
1504};
1505
1506/**
1507 * Document sorting and removing duplicates
1508 * @param {ArrayLike} results
1509 */
1510Sizzle.uniqueSort = function( results ) {
1511	var elem,
1512		duplicates = [],
1513		j = 0,
1514		i = 0;
1515
1516	// Unless we *know* we can detect duplicates, assume their presence
1517	hasDuplicate = !support.detectDuplicates;
1518	sortInput = !support.sortStable && results.slice( 0 );
1519	results.sort( sortOrder );
1520
1521	if ( hasDuplicate ) {
1522		while ( (elem = results[i++]) ) {
1523			if ( elem === results[ i ] ) {
1524				j = duplicates.push( i );
1525			}
1526		}
1527		while ( j-- ) {
1528			results.splice( duplicates[ j ], 1 );
1529		}
1530	}
1531
1532	// Clear input after sorting to release objects
1533	// See https://github.com/jquery/sizzle/pull/225
1534	sortInput = null;
1535
1536	return results;
1537};
1538
1539/**
1540 * Utility function for retrieving the text value of an array of DOM nodes
1541 * @param {Array|Element} elem
1542 */
1543getText = Sizzle.getText = function( elem ) {
1544	var node,
1545		ret = "",
1546		i = 0,
1547		nodeType = elem.nodeType;
1548
1549	if ( !nodeType ) {
1550		// If no nodeType, this is expected to be an array
1551		while ( (node = elem[i++]) ) {
1552			// Do not traverse comment nodes
1553			ret += getText( node );
1554		}
1555	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1556		// Use textContent for elements
1557		// innerText usage removed for consistency of new lines (jQuery #11153)
1558		if ( typeof elem.textContent === "string" ) {
1559			return elem.textContent;
1560		} else {
1561			// Traverse its children
1562			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1563				ret += getText( elem );
1564			}
1565		}
1566	} else if ( nodeType === 3 || nodeType === 4 ) {
1567		return elem.nodeValue;
1568	}
1569	// Do not include comment or processing instruction nodes
1570
1571	return ret;
1572};
1573
1574Expr = Sizzle.selectors = {
1575
1576	// Can be adjusted by the user
1577	cacheLength: 50,
1578
1579	createPseudo: markFunction,
1580
1581	match: matchExpr,
1582
1583	attrHandle: {},
1584
1585	find: {},
1586
1587	relative: {
1588		">": { dir: "parentNode", first: true },
1589		" ": { dir: "parentNode" },
1590		"+": { dir: "previousSibling", first: true },
1591		"~": { dir: "previousSibling" }
1592	},
1593
1594	preFilter: {
1595		"ATTR": function( match ) {
1596			match[1] = match[1].replace( runescape, funescape );
1597
1598			// Move the given value to match[3] whether quoted or unquoted
1599			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1600
1601			if ( match[2] === "~=" ) {
1602				match[3] = " " + match[3] + " ";
1603			}
1604
1605			return match.slice( 0, 4 );
1606		},
1607
1608		"CHILD": function( match ) {
1609			/* matches from matchExpr["CHILD"]
1610				1 type (only|nth|...)
1611				2 what (child|of-type)
1612				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1613				4 xn-component of xn+y argument ([+-]?\d*n|)
1614				5 sign of xn-component
1615				6 x of xn-component
1616				7 sign of y-component
1617				8 y of y-component
1618			*/
1619			match[1] = match[1].toLowerCase();
1620
1621			if ( match[1].slice( 0, 3 ) === "nth" ) {
1622				// nth-* requires argument
1623				if ( !match[3] ) {
1624					Sizzle.error( match[0] );
1625				}
1626
1627				// numeric x and y parameters for Expr.filter.CHILD
1628				// remember that false/true cast respectively to 0/1
1629				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1630				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1631
1632			// other types prohibit arguments
1633			} else if ( match[3] ) {
1634				Sizzle.error( match[0] );
1635			}
1636
1637			return match;
1638		},
1639
1640		"PSEUDO": function( match ) {
1641			var excess,
1642				unquoted = !match[6] && match[2];
1643
1644			if ( matchExpr["CHILD"].test( match[0] ) ) {
1645				return null;
1646			}
1647
1648			// Accept quoted arguments as-is
1649			if ( match[3] ) {
1650				match[2] = match[4] || match[5] || "";
1651
1652			// Strip excess characters from unquoted arguments
1653			} else if ( unquoted && rpseudo.test( unquoted ) &&
1654				// Get excess from tokenize (recursively)
1655				(excess = tokenize( unquoted, true )) &&
1656				// advance to the next closing parenthesis
1657				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1658
1659				// excess is a negative index
1660				match[0] = match[0].slice( 0, excess );
1661				match[2] = unquoted.slice( 0, excess );
1662			}
1663
1664			// Return only captures needed by the pseudo filter method (type and argument)
1665			return match.slice( 0, 3 );
1666		}
1667	},
1668
1669	filter: {
1670
1671		"TAG": function( nodeNameSelector ) {
1672			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1673			return nodeNameSelector === "*" ?
1674				function() { return true; } :
1675				function( elem ) {
1676					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1677				};
1678		},
1679
1680		"CLASS": function( className ) {
1681			var pattern = classCache[ className + " " ];
1682
1683			return pattern ||
1684				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1685				classCache( className, function( elem ) {
1686					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1687				});
1688		},
1689
1690		"ATTR": function( name, operator, check ) {
1691			return function( elem ) {
1692				var result = Sizzle.attr( elem, name );
1693
1694				if ( result == null ) {
1695					return operator === "!=";
1696				}
1697				if ( !operator ) {
1698					return true;
1699				}
1700
1701				result += "";
1702
1703				return operator === "=" ? result === check :
1704					operator === "!=" ? result !== check :
1705					operator === "^=" ? check && result.indexOf( check ) === 0 :
1706					operator === "*=" ? check && result.indexOf( check ) > -1 :
1707					operator === "$=" ? check && result.slice( -check.length ) === check :
1708					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1709					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1710					false;
1711			};
1712		},
1713
1714		"CHILD": function( type, what, argument, first, last ) {
1715			var simple = type.slice( 0, 3 ) !== "nth",
1716				forward = type.slice( -4 ) !== "last",
1717				ofType = what === "of-type";
1718
1719			return first === 1 && last === 0 ?
1720
1721				// Shortcut for :nth-*(n)
1722				function( elem ) {
1723					return !!elem.parentNode;
1724				} :
1725
1726				function( elem, context, xml ) {
1727					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1728						dir = simple !== forward ? "nextSibling" : "previousSibling",
1729						parent = elem.parentNode,
1730						name = ofType && elem.nodeName.toLowerCase(),
1731						useCache = !xml && !ofType,
1732						diff = false;
1733
1734					if ( parent ) {
1735
1736						// :(first|last|only)-(child|of-type)
1737						if ( simple ) {
1738							while ( dir ) {
1739								node = elem;
1740								while ( (node = node[ dir ]) ) {
1741									if ( ofType ?
1742										node.nodeName.toLowerCase() === name :
1743										node.nodeType === 1 ) {
1744
1745										return false;
1746									}
1747								}
1748								// Reverse direction for :only-* (if we haven't yet done so)
1749								start = dir = type === "only" && !start && "nextSibling";
1750							}
1751							return true;
1752						}
1753
1754						start = [ forward ? parent.firstChild : parent.lastChild ];
1755
1756						// non-xml :nth-child(...) stores cache data on `parent`
1757						if ( forward && useCache ) {
1758
1759							// Seek `elem` from a previously-cached index
1760
1761							// ...in a gzip-friendly way
1762							node = parent;
1763							outerCache = node[ expando ] || (node[ expando ] = {});
1764
1765							// Support: IE <9 only
1766							// Defend against cloned attroperties (jQuery gh-1709)
1767							uniqueCache = outerCache[ node.uniqueID ] ||
1768								(outerCache[ node.uniqueID ] = {});
1769
1770							cache = uniqueCache[ type ] || [];
1771							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1772							diff = nodeIndex && cache[ 2 ];
1773							node = nodeIndex && parent.childNodes[ nodeIndex ];
1774
1775							while ( (node = ++nodeIndex && node && node[ dir ] ||
1776
1777								// Fallback to seeking `elem` from the start
1778								(diff = nodeIndex = 0) || start.pop()) ) {
1779
1780								// When found, cache indexes on `parent` and break
1781								if ( node.nodeType === 1 && ++diff && node === elem ) {
1782									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1783									break;
1784								}
1785							}
1786
1787						} else {
1788							// Use previously-cached element index if available
1789							if ( useCache ) {
1790								// ...in a gzip-friendly way
1791								node = elem;
1792								outerCache = node[ expando ] || (node[ expando ] = {});
1793
1794								// Support: IE <9 only
1795								// Defend against cloned attroperties (jQuery gh-1709)
1796								uniqueCache = outerCache[ node.uniqueID ] ||
1797									(outerCache[ node.uniqueID ] = {});
1798
1799								cache = uniqueCache[ type ] || [];
1800								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1801								diff = nodeIndex;
1802							}
1803
1804							// xml :nth-child(...)
1805							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1806							if ( diff === false ) {
1807								// Use the same loop as above to seek `elem` from the start
1808								while ( (node = ++nodeIndex && node && node[ dir ] ||
1809									(diff = nodeIndex = 0) || start.pop()) ) {
1810
1811									if ( ( ofType ?
1812										node.nodeName.toLowerCase() === name :
1813										node.nodeType === 1 ) &&
1814										++diff ) {
1815
1816										// Cache the index of each encountered element
1817										if ( useCache ) {
1818											outerCache = node[ expando ] || (node[ expando ] = {});
1819
1820											// Support: IE <9 only
1821											// Defend against cloned attroperties (jQuery gh-1709)
1822											uniqueCache = outerCache[ node.uniqueID ] ||
1823												(outerCache[ node.uniqueID ] = {});
1824
1825											uniqueCache[ type ] = [ dirruns, diff ];
1826										}
1827
1828										if ( node === elem ) {
1829											break;
1830										}
1831									}
1832								}
1833							}
1834						}
1835
1836						// Incorporate the offset, then check against cycle size
1837						diff -= last;
1838						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1839					}
1840				};
1841		},
1842
1843		"PSEUDO": function( pseudo, argument ) {
1844			// pseudo-class names are case-insensitive
1845			// http://www.w3.org/TR/selectors/#pseudo-classes
1846			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1847			// Remember that setFilters inherits from pseudos
1848			var args,
1849				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1850					Sizzle.error( "unsupported pseudo: " + pseudo );
1851
1852			// The user may use createPseudo to indicate that
1853			// arguments are needed to create the filter function
1854			// just as Sizzle does
1855			if ( fn[ expando ] ) {
1856				return fn( argument );
1857			}
1858
1859			// But maintain support for old signatures
1860			if ( fn.length > 1 ) {
1861				args = [ pseudo, pseudo, "", argument ];
1862				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1863					markFunction(function( seed, matches ) {
1864						var idx,
1865							matched = fn( seed, argument ),
1866							i = matched.length;
1867						while ( i-- ) {
1868							idx = indexOf( seed, matched[i] );
1869							seed[ idx ] = !( matches[ idx ] = matched[i] );
1870						}
1871					}) :
1872					function( elem ) {
1873						return fn( elem, 0, args );
1874					};
1875			}
1876
1877			return fn;
1878		}
1879	},
1880
1881	pseudos: {
1882		// Potentially complex pseudos
1883		"not": markFunction(function( selector ) {
1884			// Trim the selector passed to compile
1885			// to avoid treating leading and trailing
1886			// spaces as combinators
1887			var input = [],
1888				results = [],
1889				matcher = compile( selector.replace( rtrim, "$1" ) );
1890
1891			return matcher[ expando ] ?
1892				markFunction(function( seed, matches, context, xml ) {
1893					var elem,
1894						unmatched = matcher( seed, null, xml, [] ),
1895						i = seed.length;
1896
1897					// Match elements unmatched by `matcher`
1898					while ( i-- ) {
1899						if ( (elem = unmatched[i]) ) {
1900							seed[i] = !(matches[i] = elem);
1901						}
1902					}
1903				}) :
1904				function( elem, context, xml ) {
1905					input[0] = elem;
1906					matcher( input, null, xml, results );
1907					// Don't keep the element (issue #299)
1908					input[0] = null;
1909					return !results.pop();
1910				};
1911		}),
1912
1913		"has": markFunction(function( selector ) {
1914			return function( elem ) {
1915				return Sizzle( selector, elem ).length > 0;
1916			};
1917		}),
1918
1919		"contains": markFunction(function( text ) {
1920			text = text.replace( runescape, funescape );
1921			return function( elem ) {
1922				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1923			};
1924		}),
1925
1926		// "Whether an element is represented by a :lang() selector
1927		// is based solely on the element's language value
1928		// being equal to the identifier C,
1929		// or beginning with the identifier C immediately followed by "-".
1930		// The matching of C against the element's language value is performed case-insensitively.
1931		// The identifier C does not have to be a valid language name."
1932		// http://www.w3.org/TR/selectors/#lang-pseudo
1933		"lang": markFunction( function( lang ) {
1934			// lang value must be a valid identifier
1935			if ( !ridentifier.test(lang || "") ) {
1936				Sizzle.error( "unsupported lang: " + lang );
1937			}
1938			lang = lang.replace( runescape, funescape ).toLowerCase();
1939			return function( elem ) {
1940				var elemLang;
1941				do {
1942					if ( (elemLang = documentIsHTML ?
1943						elem.lang :
1944						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1945
1946						elemLang = elemLang.toLowerCase();
1947						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1948					}
1949				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1950				return false;
1951			};
1952		}),
1953
1954		// Miscellaneous
1955		"target": function( elem ) {
1956			var hash = window.location && window.location.hash;
1957			return hash && hash.slice( 1 ) === elem.id;
1958		},
1959
1960		"root": function( elem ) {
1961			return elem === docElem;
1962		},
1963
1964		"focus": function( elem ) {
1965			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1966		},
1967
1968		// Boolean properties
1969		"enabled": 
vendor: 6,738 bytes, lines 1969-2220
1969function( elem ) {
1970			return elem.disabled === false;
1971		},
1972
1973		"disabled": function( elem ) {
1974			return elem.disabled === true;
1975		},
1976
1977		"checked": function( elem ) {
1978			// In CSS3, :checked should return both checked and selected elements
1979			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1980			var nodeName = elem.nodeName.toLowerCase();
1981			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1982		},
1983
1984		"selected": function( elem ) {
1985			// Accessing this property makes selected-by-default
1986			// options in Safari work properly
1987			if ( elem.parentNode ) {
1988				elem.parentNode.selectedIndex;
1989			}
1990
1991			return elem.selected === true;
1992		},
1993
1994		// Contents
1995		"empty": function( elem ) {
1996			// http://www.w3.org/TR/selectors/#empty-pseudo
1997			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1998			//   but not by others (comment: 8; processing instruction: 7; etc.)
1999			// nodeType < 6 works because attributes (2) do not appear as children
2000			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2001				if ( elem.nodeType < 6 ) {
2002					return false;
2003				}
2004			}
2005			return true;
2006		},
2007
2008		"parent": function( elem ) {
2009			return !Expr.pseudos["empty"]( elem );
2010		},
2011
2012		// Element/input types
2013		"header": function( elem ) {
2014			return rheader.test( elem.nodeName );
2015		},
2016
2017		"input": function( elem ) {
2018			return rinputs.test( elem.nodeName );
2019		},
2020
2021		"button": function( elem ) {
2022			var name = elem.nodeName.toLowerCase();
2023			return name === "input" && elem.type === "button" || name === "button";
2024		},
2025
2026		"text": function( elem ) {
2027			var attr;
2028			return elem.nodeName.toLowerCase() === "input" &&
2029				elem.type === "text" &&
2030
2031				// Support: IE<8
2032				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2033				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2034		},
2035
2036		// Position-in-collection
2037		"first": createPositionalPseudo(function() {
2038			return [ 0 ];
2039		}),
2040
2041		"last": createPositionalPseudo(function( matchIndexes, length ) {
2042			return [ length - 1 ];
2043		}),
2044
2045		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2046			return [ argument < 0 ? argument + length : argument ];
2047		}),
2048
2049		"even": createPositionalPseudo(function( matchIndexes, length ) {
2050			var i = 0;
2051			for ( ; i < length; i += 2 ) {
2052				matchIndexes.push( i );
2053			}
2054			return matchIndexes;
2055		}),
2056
2057		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2058			var i = 1;
2059			for ( ; i < length; i += 2 ) {
2060				matchIndexes.push( i );
2061			}
2062			return matchIndexes;
2063		}),
2064
2065		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2066			var i = argument < 0 ? argument + length : argument;
2067			for ( ; --i >= 0; ) {
2068				matchIndexes.push( i );
2069			}
2070			return matchIndexes;
2071		}),
2072
2073		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2074			var i = argument < 0 ? argument + length : argument;
2075			for ( ; ++i < length; ) {
2076				matchIndexes.push( i );
2077			}
2078			return matchIndexes;
2079		})
2080	}
2081};
2082
2083Expr.pseudos["nth"] = Expr.pseudos["eq"];
2084
2085// Add button/input type pseudos
2086for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2087	Expr.pseudos[ i ] = createInputPseudo( i );
2088}
2089for ( i in { submit: true, reset: true } ) {
2090	Expr.pseudos[ i ] = createButtonPseudo( i );
2091}
2092
2093// Easy API for creating new setFilters
2094function setFilters() {}
2095setFilters.prototype = Expr.filters = Expr.pseudos;
2096Expr.setFilters = new setFilters();
2097
2098tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2099	var matched, match, tokens, type,
2100		soFar, groups, preFilters,
2101		cached = tokenCache[ selector + " " ];
2102
2103	if ( cached ) {
2104		return parseOnly ? 0 : cached.slice( 0 );
2105	}
2106
2107	soFar = selector;
2108	groups = [];
2109	preFilters = Expr.preFilter;
2110
2111	while ( soFar ) {
2112
2113		// Comma and first run
2114		if ( !matched || (match = rcomma.exec( soFar )) ) {
2115			if ( match ) {
2116				// Don't consume trailing commas as valid
2117				soFar = soFar.slice( match[0].length ) || soFar;
2118			}
2119			groups.push( (tokens = []) );
2120		}
2121
2122		matched = false;
2123
2124		// Combinators
2125		if ( (match = rcombinators.exec( soFar )) ) {
2126			matched = match.shift();
2127			tokens.push({
2128				value: matched,
2129				// Cast descendant combinators to space
2130				type: match[0].replace( rtrim, " " )
2131			});
2132			soFar = soFar.slice( matched.length );
2133		}
2134
2135		// Filters
2136		for ( type in Expr.filter ) {
2137			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2138				(match = preFilters[ type ]( match ))) ) {
2139				matched = match.shift();
2140				tokens.push({
2141					value: matched,
2142					type: type,
2143					matches: match
2144				});
2145				soFar = soFar.slice( matched.length );
2146			}
2147		}
2148
2149		if ( !matched ) {
2150			break;
2151		}
2152	}
2153
2154	// Return the length of the invalid excess
2155	// if we're just parsing
2156	// Otherwise, throw an error or return tokens
2157	return parseOnly ?
2158		soFar.length :
2159		soFar ?
2160			Sizzle.error( selector ) :
2161			// Cache the tokens
2162			tokenCache( selector, groups ).slice( 0 );
2163};
2164
2165function toSelector( tokens ) {
2166	var i = 0,
2167		len = tokens.length,
2168		selector = "";
2169	for ( ; i < len; i++ ) {
2170		selector += tokens[i].value;
2171	}
2172	return selector;
2173}
2174
2175function addCombinator( matcher, combinator, base ) {
2176	var dir = combinator.dir,
2177		checkNonElements = base && dir === "parentNode",
2178		doneName = done++;
2179
2180	return combinator.first ?
2181		// Check against closest ancestor/preceding element
2182		function( elem, context, xml ) {
2183			while ( (elem = elem[ dir ]) ) {
2184				if ( elem.nodeType === 1 || checkNonElements ) {
2185					return matcher( elem, context, xml );
2186				}
2187			}
2188		} :
2189
2190		// Check against all ancestor/preceding elements
2191		function( elem, context, xml ) {
2192			var oldCache, uniqueCache, outerCache,
2193				newCache = [ dirruns, doneName ];
2194
2195			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2196			if ( xml ) {
2197				while ( (elem = elem[ dir ]) ) {
2198					if ( elem.nodeType === 1 || checkNonElements ) {
2199						if ( matcher( elem, context, xml ) ) {
2200							return true;
2201						}
2202					}
2203				}
2204			} else {
2205				while ( (elem = elem[ dir ]) ) {
2206					if ( elem.nodeType === 1 || checkNonElements ) {
2207						outerCache = elem[ expando ] || (elem[ expando ] = {});
2208
2209						// Support: IE <9 only
2210						// Defend against cloned attroperties (jQuery gh-1709)
2211						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2212
2213						if ( (oldCache = uniqueCache[ dir ]) &&
2214							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2215
2216							// Assign to newCache so results back-propagate to previous elements
2217							return (newCache[ 2 ] = oldCache[ 2 ]);
2218						} else {
2219							// Reuse newcache so results back-propagate to previous elements
2220							uniqueCache[ dir
vendor: 12,959 bytes, lines 2220-2663
2220 ] = newCache;
2221
2222							// A match means we're done; a fail means we have to keep checking
2223							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2224								return true;
2225							}
2226						}
2227					}
2228				}
2229			}
2230		};
2231}
2232
2233function elementMatcher( matchers ) {
2234	return matchers.length > 1 ?
2235		function( elem, context, xml ) {
2236			var i = matchers.length;
2237			while ( i-- ) {
2238				if ( !matchers[i]( elem, context, xml ) ) {
2239					return false;
2240				}
2241			}
2242			return true;
2243		} :
2244		matchers[0];
2245}
2246
2247function multipleContexts( selector, contexts, results ) {
2248	var i = 0,
2249		len = contexts.length;
2250	for ( ; i < len; i++ ) {
2251		Sizzle( selector, contexts[i], results );
2252	}
2253	return results;
2254}
2255
2256function condense( unmatched, map, filter, context, xml ) {
2257	var elem,
2258		newUnmatched = [],
2259		i = 0,
2260		len = unmatched.length,
2261		mapped = map != null;
2262
2263	for ( ; i < len; i++ ) {
2264		if ( (elem = unmatched[i]) ) {
2265			if ( !filter || filter( elem, context, xml ) ) {
2266				newUnmatched.push( elem );
2267				if ( mapped ) {
2268					map.push( i );
2269				}
2270			}
2271		}
2272	}
2273
2274	return newUnmatched;
2275}
2276
2277function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2278	if ( postFilter && !postFilter[ expando ] ) {
2279		postFilter = setMatcher( postFilter );
2280	}
2281	if ( postFinder && !postFinder[ expando ] ) {
2282		postFinder = setMatcher( postFinder, postSelector );
2283	}
2284	return markFunction(function( seed, results, context, xml ) {
2285		var temp, i, elem,
2286			preMap = [],
2287			postMap = [],
2288			preexisting = results.length,
2289
2290			// Get initial elements from seed or context
2291			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2292
2293			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2294			matcherIn = preFilter && ( seed || !selector ) ?
2295				condense( elems, preMap, preFilter, context, xml ) :
2296				elems,
2297
2298			matcherOut = matcher ?
2299				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2300				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2301
2302					// ...intermediate processing is necessary
2303					[] :
2304
2305					// ...otherwise use results directly
2306					results :
2307				matcherIn;
2308
2309		// Find primary matches
2310		if ( matcher ) {
2311			matcher( matcherIn, matcherOut, context, xml );
2312		}
2313
2314		// Apply postFilter
2315		if ( postFilter ) {
2316			temp = condense( matcherOut, postMap );
2317			postFilter( temp, [], context, xml );
2318
2319			// Un-match failing elements by moving them back to matcherIn
2320			i = temp.length;
2321			while ( i-- ) {
2322				if ( (elem = temp[i]) ) {
2323					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2324				}
2325			}
2326		}
2327
2328		if ( seed ) {
2329			if ( postFinder || preFilter ) {
2330				if ( postFinder ) {
2331					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2332					temp = [];
2333					i = matcherOut.length;
2334					while ( i-- ) {
2335						if ( (elem = matcherOut[i]) ) {
2336							// Restore matcherIn since elem is not yet a final match
2337							temp.push( (matcherIn[i] = elem) );
2338						}
2339					}
2340					postFinder( null, (matcherOut = []), temp, xml );
2341				}
2342
2343				// Move matched elements from seed to results to keep them synchronized
2344				i = matcherOut.length;
2345				while ( i-- ) {
2346					if ( (elem = matcherOut[i]) &&
2347						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2348
2349						seed[temp] = !(results[temp] = elem);
2350					}
2351				}
2352			}
2353
2354		// Add elements to results, through postFinder if defined
2355		} else {
2356			matcherOut = condense(
2357				matcherOut === results ?
2358					matcherOut.splice( preexisting, matcherOut.length ) :
2359					matcherOut
2360			);
2361			if ( postFinder ) {
2362				postFinder( null, results, matcherOut, xml );
2363			} else {
2364				push.apply( results, matcherOut );
2365			}
2366		}
2367	});
2368}
2369
2370function matcherFromTokens( tokens ) {
2371	var checkContext, matcher, j,
2372		len = tokens.length,
2373		leadingRelative = Expr.relative[ tokens[0].type ],
2374		implicitRelative = leadingRelative || Expr.relative[" "],
2375		i = leadingRelative ? 1 : 0,
2376
2377		// The foundational matcher ensures that elements are reachable from top-level context(s)
2378		matchContext = addCombinator( function( elem ) {
2379			return elem === checkContext;
2380		}, implicitRelative, true ),
2381		matchAnyContext = addCombinator( function( elem ) {
2382			return indexOf( checkContext, elem ) > -1;
2383		}, implicitRelative, true ),
2384		matchers = [ function( elem, context, xml ) {
2385			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2386				(checkContext = context).nodeType ?
2387					matchContext( elem, context, xml ) :
2388					matchAnyContext( elem, context, xml ) );
2389			// Avoid hanging onto element (issue #299)
2390			checkContext = null;
2391			return ret;
2392		} ];
2393
2394	for ( ; i < len; i++ ) {
2395		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2396			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2397		} else {
2398			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2399
2400			// Return special upon seeing a positional matcher
2401			if ( matcher[ expando ] ) {
2402				// Find the next relative operator (if any) for proper handling
2403				j = ++i;
2404				for ( ; j < len; j++ ) {
2405					if ( Expr.relative[ tokens[j].type ] ) {
2406						break;
2407					}
2408				}
2409				return setMatcher(
2410					i > 1 && elementMatcher( matchers ),
2411					i > 1 && toSelector(
2412						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2413						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2414					).replace( rtrim, "$1" ),
2415					matcher,
2416					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2417					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2418					j < len && toSelector( tokens )
2419				);
2420			}
2421			matchers.push( matcher );
2422		}
2423	}
2424
2425	return elementMatcher( matchers );
2426}
2427
2428function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2429	var bySet = setMatchers.length > 0,
2430		byElement = elementMatchers.length > 0,
2431		superMatcher = function( seed, context, xml, results, outermost ) {
2432			var elem, j, matcher,
2433				matchedCount = 0,
2434				i = "0",
2435				unmatched = seed && [],
2436				setMatched = [],
2437				contextBackup = outermostContext,
2438				// We must always have either seed elements or outermost context
2439				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2440				// Use integer dirruns iff this is the outermost matcher
2441				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2442				len = elems.length;
2443
2444			if ( outermost ) {
2445				outermostContext = context === document || context || outermost;
2446			}
2447
2448			// Add elements passing elementMatchers directly to results
2449			// Support: IE<9, Safari
2450			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2451			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2452				if ( byElement && elem ) {
2453					j = 0;
2454					if ( !context && elem.ownerDocument !== document ) {
2455						setDocument( elem );
2456						xml = !documentIsHTML;
2457					}
2458					while ( (matcher = elementMatchers[j++]) ) {
2459						if ( matcher( elem, context || document, xml) ) {
2460							results.push( elem );
2461							break;
2462						}
2463					}
2464					if ( outermost ) {
2465						dirruns = dirrunsUnique;
2466					}
2467				}
2468
2469				// Track unmatched elements for set filters
2470				if ( bySet ) {
2471					// They will have gone through all possible matchers
2472					if ( (elem = !matcher && elem) ) {
2473						matchedCount--;
2474					}
2475
2476					// Lengthen the array for every element, matched or not
2477					if ( seed ) {
2478						unmatched.push( elem );
2479					}
2480				}
2481			}
2482
2483			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2484			// makes the latter nonnegative.
2485			matchedCount += i;
2486
2487			// Apply set filters to unmatched elements
2488			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2489			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2490			// no element matchers and no seed.
2491			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2492			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2493			// numerically zero.
2494			if ( bySet && i !== matchedCount ) {
2495				j = 0;
2496				while ( (matcher = setMatchers[j++]) ) {
2497					matcher( unmatched, setMatched, context, xml );
2498				}
2499
2500				if ( seed ) {
2501					// Reintegrate element matches to eliminate the need for sorting
2502					if ( matchedCount > 0 ) {
2503						while ( i-- ) {
2504							if ( !(unmatched[i] || setMatched[i]) ) {
2505								setMatched[i] = pop.call( results );
2506							}
2507						}
2508					}
2509
2510					// Discard index placeholder values to get only actual matches
2511					setMatched = condense( setMatched );
2512				}
2513
2514				// Add matches to results
2515				push.apply( results, setMatched );
2516
2517				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2518				if ( outermost && !seed && setMatched.length > 0 &&
2519					( matchedCount + setMatchers.length ) > 1 ) {
2520
2521					Sizzle.uniqueSort( results );
2522				}
2523			}
2524
2525			// Override manipulation of globals by nested matchers
2526			if ( outermost ) {
2527				dirruns = dirrunsUnique;
2528				outermostContext = contextBackup;
2529			}
2530
2531			return unmatched;
2532		};
2533
2534	return bySet ?
2535		markFunction( superMatcher ) :
2536		superMatcher;
2537}
2538
2539compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2540	var i,
2541		setMatchers = [],
2542		elementMatchers = [],
2543		cached = compilerCache[ selector + " " ];
2544
2545	if ( !cached ) {
2546		// Generate a function of recursive functions that can be used to check each element
2547		if ( !match ) {
2548			match = tokenize( selector );
2549		}
2550		i = match.length;
2551		while ( i-- ) {
2552			cached = matcherFromTokens( match[i] );
2553			if ( cached[ expando ] ) {
2554				setMatchers.push( cached );
2555			} else {
2556				elementMatchers.push( cached );
2557			}
2558		}
2559
2560		// Cache the compiled function
2561		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2562
2563		// Save selector and tokenization
2564		cached.selector = selector;
2565	}
2566	return cached;
2567};
2568
2569/**
2570 * A low-level selection function that works with Sizzle's compiled
2571 *  selector functions
2572 * @param {String|Function} selector A selector or a pre-compiled
2573 *  selector function built with Sizzle.compile
2574 * @param {Element} context
2575 * @param {Array} [results]
2576 * @param {Array} [seed] A set of elements to match against
2577 */
2578select = Sizzle.select = function( selector, context, results, seed ) {
2579	var i, tokens, token, type, find,
2580		compiled = typeof selector === "function" && selector,
2581		match = !seed && tokenize( (selector = compiled.selector || selector) );
2582
2583	results = results || [];
2584
2585	// Try to minimize operations if there is only one selector in the list and no seed
2586	// (the latter of which guarantees us context)
2587	if ( match.length === 1 ) {
2588
2589		// Reduce context if the leading compound selector is an ID
2590		tokens = match[0] = match[0].slice( 0 );
2591		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2592				support.getById && context.nodeType === 9 && documentIsHTML &&
2593				Expr.relative[ tokens[1].type ] ) {
2594
2595			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2596			if ( !context ) {
2597				return results;
2598
2599			// Precompiled matchers will still verify ancestry, so step up a level
2600			} else if ( compiled ) {
2601				context = context.parentNode;
2602			}
2603
2604			selector = selector.slice( tokens.shift().value.length );
2605		}
2606
2607		// Fetch a seed set for right-to-left matching
2608		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2609		while ( i-- ) {
2610			token = tokens[i];
2611
2612			// Abort if we hit a combinator
2613			if ( Expr.relative[ (type = token.type) ] ) {
2614				break;
2615			}
2616			if ( (find = Expr.find[ type ]) ) {
2617				// Search, expanding context for leading sibling combinators
2618				if ( (seed = find(
2619					token.matches[0].replace( runescape, funescape ),
2620					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2621				)) ) {
2622
2623					// If seed is empty or no tokens remain, we can return early
2624					tokens.splice( i, 1 );
2625					selector = seed.length && toSelector( tokens );
2626					if ( !selector ) {
2627						push.apply( results, seed );
2628						return results;
2629					}
2630
2631					break;
2632				}
2633			}
2634		}
2635	}
2636
2637	// Compile and execute a filtering function if one is not provided
2638	// Provide `match` to avoid retokenization if we modified the selector above
2639	( compiled || compile( selector, match ) )(
2640		seed,
2641		context,
2642		!documentIsHTML,
2643		results,
2644		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2645	);
2646	return results;
2647};
2648
2649// One-time assignments
2650
2651// Sort stability
2652support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2653
2654// Support: Chrome 14-35+
2655// Always assume duplicates if they aren't passed to the comparison function
2656support.detectDuplicates = !!hasDuplicate;
2657
2658// Initialize against the default document
2659setDocument();
2660
2661// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2662// Detached nodes confoundingly follow *each other*
2663support.sortDetached = assert(function( 
vendor: 3,546 bytes, lines 2663-2816
2663div1 ) {
2664	// Should return 1, but returns 4 (following)
2665	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2666});
2667
2668// Support: IE<8
2669// Prevent attribute/property "interpolation"
2670// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2671if ( !assert(function( div ) {
2672	div.innerHTML = "<a href='#'></a>";
2673	return div.firstChild.getAttribute("href") === "#" ;
2674}) ) {
2675	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2676		if ( !isXML ) {
2677			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2678		}
2679	});
2680}
2681
2682// Support: IE<9
2683// Use defaultValue in place of getAttribute("value")
2684if ( !support.attributes || !assert(function( div ) {
2685	div.innerHTML = "<input/>";
2686	div.firstChild.setAttribute( "value", "" );
2687	return div.firstChild.getAttribute( "value" ) === "";
2688}) ) {
2689	addHandle( "value", function( elem, name, isXML ) {
2690		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2691			return elem.defaultValue;
2692		}
2693	});
2694}
2695
2696// Support: IE<9
2697// Use getAttributeNode to fetch booleans when getAttribute lies
2698if ( !assert(function( div ) {
2699	return div.getAttribute("disabled") == null;
2700}) ) {
2701	addHandle( booleans, function( elem, name, isXML ) {
2702		var val;
2703		if ( !isXML ) {
2704			return elem[ name ] === true ? name.toLowerCase() :
2705					(val = elem.getAttributeNode( name )) && val.specified ?
2706					val.value :
2707				null;
2708		}
2709	});
2710}
2711
2712return Sizzle;
2713
2714})( window );
2715
2716
2717
2718jQuery.find = Sizzle;
2719jQuery.expr = Sizzle.selectors;
2720jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2721jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2722jQuery.text = Sizzle.getText;
2723jQuery.isXMLDoc = Sizzle.isXML;
2724jQuery.contains = Sizzle.contains;
2725
2726
2727
2728var dir = function( elem, dir, until ) {
2729	var matched = [],
2730		truncate = until !== undefined;
2731
2732	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2733		if ( elem.nodeType === 1 ) {
2734			if ( truncate && jQuery( elem ).is( until ) ) {
2735				break;
2736			}
2737			matched.push( elem );
2738		}
2739	}
2740	return matched;
2741};
2742
2743
2744var siblings = function( n, elem ) {
2745	var matched = [];
2746
2747	for ( ; n; n = n.nextSibling ) {
2748		if ( n.nodeType === 1 && n !== elem ) {
2749			matched.push( n );
2750		}
2751	}
2752
2753	return matched;
2754};
2755
2756
2757var rneedsContext = jQuery.expr.match.needsContext;
2758
2759var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2760
2761
2762
2763var risSimple = /^.[^:#\[\.,]*$/;
2764
2765// Implement the identical functionality for filter and not
2766function winnow( elements, qualifier, not ) {
2767	if ( jQuery.isFunction( qualifier ) ) {
2768		return jQuery.grep( elements, function( elem, i ) {
2769			/* jshint -W018 */
2770			return !!qualifier.call( elem, i, elem ) !== not;
2771		} );
2772
2773	}
2774
2775	if ( qualifier.nodeType ) {
2776		return jQuery.grep( elements, function( elem ) {
2777			return ( elem === qualifier ) !== not;
2778		} );
2779
2780	}
2781
2782	if ( typeof qualifier === "string" ) {
2783		if ( risSimple.test( qualifier ) ) {
2784			return jQuery.filter( qualifier, elements, not );
2785		}
2786
2787		qualifier = jQuery.filter( qualifier, elements );
2788	}
2789
2790	return jQuery.grep( elements, function( elem ) {
2791		return ( jQuery.inArray( elem, qualifier ) > -1 ) !== not;
2792	} );
2793}
2794
2795jQuery.filter = function( expr, elems, not ) {
2796	var elem = elems[ 0 ];
2797
2798	if ( not ) {
2799		expr = ":not(" + expr + ")";
2800	}
2801
2802	return elems.length === 1 && elem.nodeType === 1 ?
2803		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2804		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2805			return elem.nodeType === 1;
2806		} ) );
2807};
2808
2809jQuery.fn.extend( {
2810	find: function( selector ) {
2811		var i,
2812			ret = [],
2813			self = this,
2814			len = self.length;
2815
2816		if ( typeof selector !== "string" ) {
2817			return this.pushStack( jQuery( selector ).filter( function() {
2818				for ( i = 0; i < len; i++ ) {
2819					if ( jQuery.contains( self[ i ], this ) ) {
2820						return true;
2821					}
2822				}
2823			} ) );
2824		}
2825
2826		for ( i = 0; i < len; i++ ) {
2827			jQuery.find( selector, self[ i ], ret );
2828		}
2829
2830		// Needed because $( selector, context ) becomes $( context ).find( selector )
2831		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2832		ret.selector = this.selector ? this.selector + " " + selector : selector;
2833		return ret;
2834	},
2835	filter: function( selector ) {
2836		return this.pushStack( winnow( this, selector || [], false ) );
2837	},
2838	not: function( selector ) {
2839		return this.pushStack( winnow( this, selector || [], true ) );
2840	},
2841	is: function( selector ) {
2842		return !!winnow(
2843			this,
2844
2845			// If this is a positional/relative selector, check membership in the returned set
2846			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2847			typeof selector === "string" && rneedsContext.test( selector ) ?
2848				jQuery( selector ) :
2849				selector || [],
2850			false
2851		).length;
2852	}
2853} );
2854
2855
2856// Initialize a jQuery object
2857
2858
2859// A central reference to the root jQuery(document)
2860var rootjQuery,
2861
2862	// A simple way to check for HTML strings
2863	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2864	// Strict HTML recognition (#11290: must start with <)
2865	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2866
2867	init = jQuery.fn.init = function( selector, context, root ) {
2868		var match, elem;
2869
2870		// HANDLE: $(""), $(null), $(undefined), $(false)
2871		if ( !selector ) {
2872			return this;
2873		}
2874
2875		// init accepts an alternate rootjQuery
2876		// so migrate can support jQuery.sub (gh-2101)
2877		root = root || rootjQuery;
2878
2879		// Handle HTML strings
2880		if ( typeof selector === "string" ) {
2881			if ( selector.charAt( 0 ) === "<" &&
2882				selector.charAt( selector.length - 1 ) === ">" &&
2883				selector.length >= 3 ) {
2884
2885				// Assume that strings that start and end with <> are HTML and skip the regex check
2886				match = [ null, selector, null ];
2887
2888			} else {
2889				match = rquickExpr.exec( selector );
2890			}
2891
2892			// Match html or make sure no context is specified for #id
2893			if ( match && ( match[ 1 ] || !context ) ) {
2894
2895				// HANDLE: $(html) -> $(array)
2896				if ( match[ 1 ] ) {
2897					context = context instanceof jQuery ? context[ 0 ] : context;
2898
2899					// scripts is true for back-compat
2900					// Intentionally let the error be thrown if parseHTML is not present
2901					jQuery.merge( this, jQuery.parseHTML(
2902						match[ 1 ],
2903						context && context.nodeType ? context.ownerDocument || context : document,
2904						true
2905					) );
2906
2907					// HANDLE: $(html, props)
2908					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2909						for ( match in context ) {
2910
2911							// Properties of context are called as methods if possible
2912							if ( jQuery.isFunction( this[ match ] ) ) {
2913								this[ match ]( context[ match ] );
2914
2915							// ...and otherwise set as attributes
2916							} else {
2917								this.attr( match, context[ match ] );
2918							}
2919						}
2920					}
2921
2922					return this;
2923
2924				// HANDLE: $(#id)
2925				} else {
2926					elem = document.getElementById( match[ 2 ] );
2927
2928					// Check parentNode to catch when Blackberry 4.6 returns
2929					// nodes that are no longer in the document #6963
2930					if ( elem && elem.parentNode ) {
2931
2932						// Handle the case where IE and Opera return items
2933						// by name instead of ID
2934						if ( elem.id !== match[ 2 ] ) {
2935							return rootjQuery.find( selector );
2936						}
2937
2938						// Otherwise, we inject the element directly into the jQuery object
2939						this.length = 1;
2940						this[ 0 ] = elem;
2941					}
2942
2943					this.context = document;
2944					this.selector = selector;
2945					return this;
2946				}
2947
2948			// HANDLE: $(expr, $(...))
2949			} else if ( !context || context.jquery ) {
2950				return ( context || root ).find( selector );
2951
2952			// HANDLE: $(expr, context)
2953			// (which is just equivalent to: $(context).find(expr)
2954			} else {
2955				return this.constructor( context ).find( selector );
2956			}
2957
2958		// HANDLE: $(DOMElement)
2959		} else if ( selector.nodeType ) {
2960			this.context = this[ 0 ] = selector;
2961			this.length = 1;
2962			return this;
2963
2964		// HANDLE: $(function)
2965		// Shortcut for document ready
2966		} else if ( jQuery.isFunction( selector ) ) {
2967			return typeof root.ready !== "undefined" ?
2968				root.ready( selector ) :
2969
2970				// Execute immediately if ready is not present
2971				selector( jQuery );
2972		}
2973
2974		if ( selector.selector !== undefined ) {
2975			this.selector = selector.selector;
2976			this.context = selector.context;
2977		}
2978
2979		return jQuery.makeArray( selector, this );
2980	};
2981
2982// Give the init function the jQuery prototype for later instantiation
2983init.prototype = jQuery.fn;
2984
2985// Initialize central reference
2986rootjQuery = jQuery( document );
2987
2988
2989var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2990
2991	// methods guaranteed to produce a unique set when starting from a unique set
2992	guaranteedUnique = {
2993		children: true,
2994		contents: true,
2995		next: true,
2996		prev: true
2997	};
2998
2999jQuery.fn.extend( {
3000	has: function( target ) {
3001		var i,
3002			targets = jQuery( target, this ),
3003			len = targets.length;
3004
3005		return this.filter( function() {
3006			for ( i = 0; i < len; i++ ) {
3007				if ( jQuery.contains( this, targets[ i ] ) ) {
3008					return true;
3009				}
3010			}
3011		} );
3012	},
3013
3014	closest: function( selectors, context ) {
3015		var cur,
3016			i = 0,
3017			l = this.length,
3018			matched = [],
3019			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
vendor: 5,562 bytes, lines 3020-3238
3020				jQuery( selectors, context || this.context ) :
3021				0;
3022
3023		for ( ; i < l; i++ ) {
3024			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3025
3026				// Always skip document fragments
3027				if ( cur.nodeType < 11 && ( pos ?
3028					pos.index( cur ) > -1 :
3029
3030					// Don't pass non-elements to Sizzle
3031					cur.nodeType === 1 &&
3032						jQuery.find.matchesSelector( cur, selectors ) ) ) {
3033
3034					matched.push( cur );
3035					break;
3036				}
3037			}
3038		}
3039
3040		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3041	},
3042
3043	// Determine the position of an element within
3044	// the matched set of elements
3045	index: function( elem ) {
3046
3047		// No argument, return index in parent
3048		if ( !elem ) {
3049			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3050		}
3051
3052		// index in selector
3053		if ( typeof elem === "string" ) {
3054			return jQuery.inArray( this[ 0 ], jQuery( elem ) );
3055		}
3056
3057		// Locate the position of the desired element
3058		return jQuery.inArray(
3059
3060			// If it receives a jQuery object, the first element is used
3061			elem.jquery ? elem[ 0 ] : elem, this );
3062	},
3063
3064	add: function( selector, context ) {
3065		return this.pushStack(
3066			jQuery.uniqueSort(
3067				jQuery.merge( this.get(), jQuery( selector, context ) )
3068			)
3069		);
3070	},
3071
3072	addBack: function( selector ) {
3073		return this.add( selector == null ?
3074			this.prevObject : this.prevObject.filter( selector )
3075		);
3076	}
3077} );
3078
3079function sibling( cur, dir ) {
3080	do {
3081		cur = cur[ dir ];
3082	} while ( cur && cur.nodeType !== 1 );
3083
3084	return cur;
3085}
3086
3087jQuery.each( {
3088	parent: function( elem ) {
3089		var parent = elem.parentNode;
3090		return parent && parent.nodeType !== 11 ? parent : null;
3091	},
3092	parents: function( elem ) {
3093		return dir( elem, "parentNode" );
3094	},
3095	parentsUntil: function( elem, i, until ) {
3096		return dir( elem, "parentNode", until );
3097	},
3098	next: function( elem ) {
3099		return sibling( elem, "nextSibling" );
3100	},
3101	prev: function( elem ) {
3102		return sibling( elem, "previousSibling" );
3103	},
3104	nextAll: function( elem ) {
3105		return dir( elem, "nextSibling" );
3106	},
3107	prevAll: function( elem ) {
3108		return dir( elem, "previousSibling" );
3109	},
3110	nextUntil: function( elem, i, until ) {
3111		return dir( elem, "nextSibling", until );
3112	},
3113	prevUntil: function( elem, i, until ) {
3114		return dir( elem, "previousSibling", until );
3115	},
3116	siblings: function( elem ) {
3117		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3118	},
3119	children: function( elem ) {
3120		return siblings( elem.firstChild );
3121	},
3122	contents: function( elem ) {
3123		return jQuery.nodeName( elem, "iframe" ) ?
3124			elem.contentDocument || elem.contentWindow.document :
3125			jQuery.merge( [], elem.childNodes );
3126	}
3127}, function( name, fn ) {
3128	jQuery.fn[ name ] = function( until, selector ) {
3129		var ret = jQuery.map( this, fn, until );
3130
3131		if ( name.slice( -5 ) !== "Until" ) {
3132			selector = until;
3133		}
3134
3135		if ( selector && typeof selector === "string" ) {
3136			ret = jQuery.filter( selector, ret );
3137		}
3138
3139		if ( this.length > 1 ) {
3140
3141			// Remove duplicates
3142			if ( !guaranteedUnique[ name ] ) {
3143				ret = jQuery.uniqueSort( ret );
3144			}
3145
3146			// Reverse order for parents* and prev-derivatives
3147			if ( rparentsprev.test( name ) ) {
3148				ret = ret.reverse();
3149			}
3150		}
3151
3152		return this.pushStack( ret );
3153	};
3154} );
3155var rnotwhite = ( /\S+/g );
3156
3157
3158
3159// Convert String-formatted options into Object-formatted ones
3160function createOptions( options ) {
3161	var object = {};
3162	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3163		object[ flag ] = true;
3164	} );
3165	return object;
3166}
3167
3168/*
3169 * Create a callback list using the following parameters:
3170 *
3171 *	options: an optional list of space-separated options that will change how
3172 *			the callback list behaves or a more traditional option object
3173 *
3174 * By default a callback list will act like an event callback list and can be
3175 * "fired" multiple times.
3176 *
3177 * Possible options:
3178 *
3179 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3180 *
3181 *	memory:			will keep track of previous values and will call any callback added
3182 *					after the list has been fired right away with the latest "memorized"
3183 *					values (like a Deferred)
3184 *
3185 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3186 *
3187 *	stopOnFalse:	interrupt callings when a callback returns false
3188 *
3189 */
3190jQuery.Callbacks = function( options ) {
3191
3192	// Convert options from String-formatted to Object-formatted if needed
3193	// (we check in cache first)
3194	options = typeof options === "string" ?
3195		createOptions( options ) :
3196		jQuery.extend( {}, options );
3197
3198	var // Flag to know if list is currently firing
3199		firing,
3200
3201		// Last fire value for non-forgettable lists
3202		memory,
3203
3204		// Flag to know if list was already fired
3205		fired,
3206
3207		// Flag to prevent firing
3208		locked,
3209
3210		// Actual callback list
3211		list = [],
3212
3213		// Queue of execution data for repeatable lists
3214		queue = [],
3215
3216		// Index of currently firing callback (modified by add/remove as needed)
3217		firingIndex = -1,
3218
3219		// Fire callbacks
3220		fire = function() {
3221
3222			// Enforce single-firing
3223			locked = options.once;
3224
3225			// Execute callbacks for all pending executions,
3226			// respecting firingIndex overrides and runtime changes
3227			fired = firing = true;
3228			for ( ; queue.length; firingIndex = -1 ) {
3229				memory = queue.shift();
3230				while ( ++firingIndex < list.length ) {
3231
3232					// Run callback and check for early termination
3233					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3234						options.stopOnFalse ) {
3235
3236						// Jump to end and forget the data so .add doesn't re-fire
3237						firingIndex = list.length;
3238						memory = false;
3239					}
3240				}
3241			}
3242
3243			// Forget the data if we're done with it
3244			if ( !options.memory ) {
3245				memory = false;
3246			}
3247
3248			firing = false;
3249
3250			// Clean up if we're done firing for good
3251			if ( locked ) {
3252
3253				// Keep an empty list if we have data for future add calls
3254				if ( memory ) {
3255					list = [];
3256
3257				// Otherwise, this object is spent
3258				} else {
3259					list = "";
3260				}
3261			}
3262		},
3263
3264		// Actual Callbacks object
3265		self = {
3266
3267			// Add a callback or a collection of callbacks to the list
3268			add: function() {
3269				if ( list ) {
3270
3271					// If we have memory from a past run, we should fire after adding
3272					if ( memory && !firing ) {
3273						firingIndex = list.length - 1;
3274						queue.push( memory );
3275					}
3276
3277					( function add( args ) {
3278						jQuery.each( args, function( _, arg ) {
3279							if ( jQuery.isFunction( arg ) ) {
3280								if ( !options.unique || !self.has( arg ) ) {
3281									list.push( arg );
3282								}
3283							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3284
3285								// Inspect recursively
3286								add( arg );
3287							}
3288						} );
3289					} )( arguments );
3290
3291					if ( memory && !firing ) {
3292						fire();
3293					}
3294				}
3295				return this;
3296			},
3297
3298			// Remove a callback from the list
3299			remove: function() {
3300				jQuery.each( arguments, function( _, arg ) {
3301					var index;
3302					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3303						list.splice( index, 1 );
3304
3305						// Handle firing indexes
3306						if ( index <= firingIndex ) {
3307							firingIndex--;
3308						}
3309					}
3310				} );
3311				return this;
3312			},
3313
3314			// Check if a given callback is in the list.
3315			// If no argument is given, return whether or not list has callbacks attached.
3316			has: function( fn ) {
3317				return fn ?
3318					jQuery.inArray( fn, list ) > -1 :
3319					list.length > 0;
3320			},
3321
3322			// Remove all callbacks from the list
3323			empty: function() {
3324				if ( list ) {
3325					list = [];
3326				}
3327				return this;
3328			},
3329
3330			// Disable .fire and .add
3331			// Abort any current/pending executions
3332			// Clear all callbacks and values
3333			disable: function() {
3334				locked = queue = [];
3335				list = memory = "";
3336				return this;
3337			},
3338			disabled: function() {
3339				return !list;
3340			},
3341
3342			// Disable .fire
3343			// Also disable .add unless we have memory (since it would have no effect)
3344			// Abort any pending executions
3345			lock: function() {
3346				locked = true;
3347				if ( !memory ) {
3348					self.disable();
3349				}
3350				return this;
3351			},
3352			locked: function() {
3353				return !!locked;
3354			},
3355
3356			// Call all callbacks with the given context and arguments
3357			fireWith: function( context, args ) {
3358				if ( !locked ) {
3359					args = args || [];
3360					args = [ context, args.slice ? args.slice() : args ];
3361					queue.push( args );
3362					if ( !firing ) {
3363						fire();
3364					}
3365				}
3366				return this;
3367			},
3368
3369			// Call all the callbacks with the given arguments
3370			fire: function() {
3371				self.fireWith( this, arguments );
3372				return this;
3373			},
3374
3375			// To know if the callbacks have already been called at least once
3376			fired: function() {
3377				return !!fired;
3378			}
3379		};
3380
3381	return self;
3382};
3383
3384
3385jQuery.extend( {
3386
3387	Deferred: function( func ) {
3388		var tuples = [
3389
3390				// action, add listener, listener list, final state
3391				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3392				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3393				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3394			],
3395			state = "pending",
3396			promise = {
3397				state: function() {
3398					return state;
3399				},
3400				always: function() {
3401					deferred.done( arguments ).fail( arguments );
3402					return this;
3403				},
3404				then: function( /* fnDone, fnFail, fnProgress */ ) {
3405					var fns = arguments;
3406					return jQuery.Deferred( function( newDefer ) {
3407						jQuery.each( tuples, function( i, tuple ) {
3408							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3409
3410							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3411							deferred[ tuple[ 1 ] ]( function() {
3412								var returned = fn && fn.apply( this, arguments );
3413								if ( returned && jQuery.isFunction( returned.promise ) ) {
3414									returned.promise()
3415										.progress( newDefer.notify )
3416										.done( newDefer.resolve )
3417										.fail( newDefer.reject );
3418								} else {
3419									newDefer[ tuple[ 0 ] + "With" ](
3420										this === promise ? newDefer.promise() : this,
3421										fn ? [ returned ] : arguments
3422									);
3423								}
3424							} );
3425						} );
3426						fns = null;
3427					} ).promise();
3428				},
3429
3430				// Get a promise for this deferred
3431				// If obj is provided, the promise aspect is added to the object
3432				promise: function( obj ) {
3433					return obj != null ? jQuery.extend( obj, promise ) : promise;
3434				}
3435			},
3436			deferred = {};
3437
3438		// Keep pipe for back-compat
3439		promise.pipe = promise.then;
3440
3441		// Add list-specific methods
3442		jQuery.each( tuples, function( i, tuple ) {
3443			var list = tuple[ 2 ],
3444				stateString = tuple[ 3 ];
3445
3446			// promise[ done | fail | progress ] = list.add
3447			promise[ tuple[ 1 ] ] = list.add;
3448
3449			// Handle state
3450			if ( stateString ) {
3451				list.add( function() {
3452
3453					// state = [ resolved | rejected ]
3454					state = stateString;
3455
3456				// [ reject_list | resolve_list ].disable; progress_list.lock
3457				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3458			}
3459
3460			// deferred[ resolve | reject | notify ]
3461			deferred[ tuple[ 0 ] ] = function() {
3462				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3463				return this;
3464			};
3465			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3466		} );
3467
3468		// Make the deferred a promise
3469		promise.promise( deferred );
3470
3471		// Call given func if any
3472		if ( func ) {
3473			func.call( deferred, deferred );
3474		}
3475
3476		// All done!
3477		return deferred;
3478	},
3479
3480	// Deferred helper
3481	when: function( subordinate /* , ..., subordinateN */ ) {
3482		var i = 0,
3483			resolveValues = slice.call( arguments ),
3484			length = resolveValues.length,
3485
3486			// the count of uncompleted subordinates
3487			remaining = length !== 1 ||
3488				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3489
3490			// the master Deferred.
3491			// If resolveValues consist of only a single Deferred, just use that.
3492			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3493
3494			// Update function for both resolve and progress values
3495			updateFunc = function( i, contexts, values ) {
3496				return function( value ) {
3497					contexts[ i ] = this;
3498					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3499					if ( values === progressValues ) {
3500						deferred.notifyWith( contexts, values );
3501
3502					} else if ( !( --remaining ) ) {
3503						deferred.resolveWith( contexts, values );
3504					}
3505				};
3506			},
3507
3508			progressValues, progressContexts, resolveContexts;
3509
3510		// add listeners to Deferred subordinates; treat others as resolved
3511		if ( length > 1 ) {
3512			progressValues = new Array( length );
3513			progressContexts = new Array( length );
3514			resolveContexts = new Array( length );
3515			for ( ; i < length; i++ ) {
3516				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3517					resolveValues[ i ].promise()
3518						.progress( updateFunc( i, progressContexts, progressValues ) )
3519						.done( updateFunc( i, resolveContexts, resolveValues ) )
3520						.fail( deferred.reject );
3521				} else {
3522					--remaining;
3523				}
3524			}
3525		}
3526
3527		// if we're not waiting on anything, resolve the master
3528		if ( !remaining ) {
3529			deferred.resolveWith( resolveContexts, resolveValues );
3530		}
3531
3532		return deferred.promise();
3533	}
3534} );
3535
3536
3537// The deferred used on DOM ready
3538var readyList;
3539
3540jQuery.fn.ready = function( fn ) {
3541
3542	// Add the callback
3543	jQuery.ready.promise().done( fn );
3544
3545	return this;
3546};
3547
3548jQuery.extend( {
3549
3550	// Is the DOM ready to be used? Set to true once it occurs.
3551	isReady: false,
3552
3553	// A counter to track how many items to wait for before
3554	// the ready event fires. See #6781
3555	readyWait: 1,
3556
3557	// Hold (or release) the ready event
3558	holdReady: function( hold ) {
3559		if ( hold ) {
3560			jQuery.readyWait++;
3561		} else {
3562			jQuery.ready( true );
3563		}
3564	},
3565
3566	// Handle when the DOM is ready
3567	ready: function( wait ) {
3568
3569		// Abort if there are pending holds or we're already ready
3570		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3571			return;
3572		}
3573
3574		// Remember that the DOM is ready
3575		jQuery.isReady = true;
3576
3577		// If a normal DOM Ready event fired, decrement, and wait if need be
3578		if ( wait !== true && --jQuery.readyWait > 0 ) {
3579			return;
3580		}
3581
3582		// If there are functions bound, to execute
3583		readyList.resolveWith( document, [ jQuery ] );
3584
3585		// Trigger any bound ready events
3586		if ( jQuery.fn.triggerHandler ) {
3587			jQuery( document ).triggerHandler( "ready" );
3588			jQuery( document ).off( "ready" );
3589		}
3590	}
3591} );
3592
3593/**
3594 * Clean-up method for dom ready events
3595 */
3596function detach() {
3597	if ( document.addEventListener ) {
3598		document.removeEventListener( "DOMContentLoaded", completed );
3599		window.removeEventListener( "load", completed );
3600
3601	} else {
3602		document.detachEvent( "onreadystatechange", completed );
3603		window.detachEvent( "onload", completed );
3604	}
3605}
3606
3607/**
3608 * The ready event handler and self cleanup method
3609 */
3610function completed() {
3611
3612	// readyState === "complete" is good enough for us to call the dom ready in oldIE
3613	if ( document.addEventListener ||
3614		window.event.type === "load" ||
3615		document.readyState === "complete" ) {
3616
3617		detach();
3618		jQuery.ready();
3619	}
3620}
3621
3622jQuery.ready.promise = function( obj ) {
3623	if ( !readyList ) {
3624
3625		readyList = jQuery.Deferred();
3626
3627		// Catch cases where $(document).ready() is called
3628		// after the browser event has already occurred.
3629		// Support: IE6-10
3630		// Older IE sometimes signals "interactive" too soon
3631		if ( document.readyState === "complete" ||
3632			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3633
3634			// Handle it asynchronously to allow scripts the opportunity to delay ready
3635			window.setTimeout( jQuery.ready );
3636
3637		// Standards-based browsers support DOMContentLoaded
3638		} else if ( document.addEventListener ) {
3639
3640			// Use the handy event callback
3641			document.addEventListener( "DOMContentLoaded", completed );
3642
3643			// A fallback to window.onload, that will always work
3644			window.addEventListener( "load", completed );
3645
3646		// If IE event model is used
3647		} else {
3648
3649			// Ensure firing before onload, maybe late but safe also for iframes
3650			document.attachEvent( "onreadystatechange", completed );
3651
3652			// A fallback to window.onload, that will always work
3653			window.attachEvent( "onload", completed );
3654
3655			// If IE and not a frame
3656			// continually check to see if the document is ready
3657			var top = false;
3658
3659			try {
3660				top = window.frameElement == null && document.documentElement;
3661			} catch ( e ) {}
3662
3663			if ( top && top.doScroll ) {
3664				( function doScrollCheck() {
3665					if ( !jQuery.isReady ) {
3666
3667						try {
3668
3669							// Use the trick by Diego Perini
3670							// http://javascript.nwbox.com/IEContentLoaded/
3671							top.doScroll( "left" );
3672						} catch ( e ) {
3673							return window.setTimeout( doScrollCheck, 50 );
3674						}
3675
3676						// detach all dom ready events
3677						detach();
3678
3679						// and execute any waiting functions
3680						jQuery.ready();
3681					}
3682				} )();
3683			}
3684		}
3685	}
3686	return readyList.promise( obj );
3687};
3688
3689// Kick off the DOM ready check even if the user does not
3690jQuery.ready.promise();
3691
3692
3693
3694
3695// Support: IE<9
3696// Iteration over object's inherited properties before its own
3697var i;
3698for ( i in jQuery( support ) ) {
3699	break;
3700}
3701support.ownFirst = i === "0";
3702
3703// Note: most support tests are defined in their respective modules.
3704// false until the test is run
3705support.inlineBlockNeedsLayout = false;
3706
3707// Execute ASAP in case we need to set body.style.zoom
3708jQuery( function() {
3709
3710	// Minified: var a,b,c,d
3711	var val, div, body, container;
3712
3713	body = document.getElementsByTagName( "body" )[ 0 ];
3714	if ( !body || !body.style ) {
3715
3716		// Return for frameset docs that don't have a body
3717		return;
3718	}
3719
3720	// Setup
3721	div = document.createElement( "div" );
3722	container = document.createElement( "div" );
3723	container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
3724	body.appendChild( container ).appendChild( div );
3725
3726	if ( typeof div.style.zoom !== "undefined" ) {
3727
3728		// Support: IE<8
3729		// Check if natively block-level elements act like inline-block
3730		// elements when setting their display to 'inline' and giving
3731		// them layout
3732		div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
3733
3734		support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
3735		if ( val ) {
3736
3737			// Prevent IE 6 from affecting layout for positioned elements #11048
3738			// Prevent IE from shrinking the body in IE 7 mode #12869
3739			// Support: IE<8
3740			body.style.zoom = 1;
3741		}
3742	}
3743
3744	body.removeChild( container );
3745} );
3746
3747
3748( function() {
3749	var div = document.createElement( "div" );
3750
3751	// Support: IE<9
3752	support.deleteExpando = true;
3753	try {
3754		delete div.test;
3755	} catch ( e ) {
3756		support.deleteExpando = false;
3757	}
3758
3759	// Null elements to avoid leaks in IE.
3760	div = null;
3761} )();
3762var acceptData = function( elem ) {
3763	var noData = jQuery.noData[ ( elem.nodeName + " " ).toLowerCase() ],
3764		nodeType = +elem.nodeType || 1;
3765
3766	// Do not set data on non-element DOM nodes because it will not be cleared (#8335).
3767	return nodeType !== 1 && nodeType !== 9 ?
3768		false :
3769
3770		// Nodes accept data unless otherwise specified; rejection can be conditional
3771		!noData || noData !== true && elem.getAttribute( "classid" ) === noData;
3772};
3773
3774
3775
3776
3777var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3778	rmultiDash = /([A-Z])/g;
3779
3780function dataAttr( elem, key, data ) {
3781
3782	// If nothing was found internally, try to fetch any
3783	// data from the HTML5 data-* attribute
3784	if ( data === undefined && elem.nodeType === 1 ) {
3785
3786		var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3787
3788		data = elem.getAttribute( name );
3789
3790		if ( typeof data === "string" ) {
3791			try {
3792				data = data === "true" ? true :
3793					data === "false" ? false :
3794					data === "null" ? null :
3795
3796					// Only convert to a number if it doesn't change the string
3797					+data + "" === data ? +data :
3798					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3799					data;
3800			} catch ( e ) {}
3801
3802			// Make sure we set the data so it isn't changed later
3803			jQuery.data( elem, key, data );
3804
3805		} else {
3806			data = undefined;
3807		}
3808	}
3809
3810	return data;
3811}
3812
3813// checks a cache object for emptiness
3814function isEmptyDataObject( obj ) {
3815	var name;
3816	for ( name in obj ) {
3817
3818		// if the public data object is empty, the private is still empty
3819		if ( name === "data" && jQuery.isEmptyObject( obj[ name ] ) ) {
3820			continue;
3821		}
3822		if ( name !== "toJSON" ) {
3823			return false;
3824		}
3825	}
3826
3827	return true;
3828}
3829
3830function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
3831	if ( !acceptData( elem ) ) {
3832		return;
3833	}
3834
3835	var ret, thisCache,
3836		internalKey = jQuery.expando,
3837
3838		// We have to handle DOM nodes and JS objects differently because IE6-7
3839		// can't GC object references properly across the DOM-JS boundary
3840		isNode = elem.nodeType,
3841
3842		// Only DOM nodes need the global jQuery cache; JS object data is
3843		// attached directly to the object so GC can occur automatically
3844		cache = isNode ? jQuery.cache : elem,
3845
3846		// Only defining an ID for JS objects if its cache already exists allows
3847		// the code to shortcut on the same path as a DOM node with no cache
3848		id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
3849
3850	// Avoid doing any more work than we need to when trying to get data on an
3851	// object that has no data at all
3852	if ( ( !id || !cache[ id ] || ( !pvt && !cache[ id ].data ) ) &&
3853		data === undefined && typeof name === "string" ) {
3854		return;
3855	}
3856
3857	if ( !id ) {
3858
3859		// Only DOM nodes need a new unique ID for each element since their data
3860		// ends up in the global cache
3861		if ( isNode ) {
3862			id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
3863		} else {
3864			id = internalKey;
3865		}
3866	}
3867
3868	if ( !cache[ id ] ) {
3869
3870		// Avoid exposing jQuery metadata on plain JS objects when the object
3871		// is serialized using JSON.stringify
3872		cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
3873	}
3874
3875	// An object can be passed to jQuery.data instead of a key/value pair; this gets
3876	// shallow copied over onto the existing cache
3877	if ( typeof name === "object" || typeof name === "function" ) {
3878		if ( pvt ) {
3879			cache[ id ] = jQuery.extend( cache[ id ], name );
3880		} else {
3881			cache[ id ].data = jQuery.extend( cache[ id ].data, name );
3882		}
3883	}
3884
3885	thisCache = cache[ id ];
3886
3887	// jQuery data() is stored in a separate object inside the object's internal data
3888	// cache in order to avoid key collisions between internal data and user-defined
3889	// data.
3890	if ( !pvt ) {
3891		if ( !thisCache.data ) {
3892			thisCache.data = {};
3893		}
3894
3895		thisCache = thisCache.data;
3896	}
3897
3898	if ( data !== undefined ) {
3899		thisCache[ jQuery.camelCase( name ) ] = data;
3900	}
3901
3902	// Check for both converted-to-camel and non-converted data property names
3903	// If a data property was specified
3904	if ( typeof name === "string" ) {
3905
3906		// First Try to find as-is property data
3907		ret = thisCache[ name ];
3908
3909		// Test for null|undefined property data
3910		if ( ret == null ) {
3911
3912			// Try to find the camelCased property
3913			ret = thisCache[ jQuery.camelCase( name ) ];
3914		}
3915	} else {
3916		ret = thisCache;
3917	}
3918
3919	return ret;
3920}
3921
3922function internalRemoveData( elem, name, pvt ) {
3923	if ( !acceptData( elem ) ) {
3924		return;
3925	}
3926
3927	var thisCache, i,
3928		isNode = elem.nodeType,
3929
3930		// See jQuery.data for more information
3931		cache = isNode ? jQuery.cache : elem,
3932		id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
3933
3934	// If there is already no cache entry for this object, there is no
3935	// purpose in continuing
3936	if ( !cache[ id ] ) {
3937		return;
3938	}
3939
3940	if ( name ) {
3941
3942		thisCache = pvt ? cache[ id ] : cache[ id ].data;
3943
3944		if ( thisCache ) {
3945
3946			// Support array or space separated string names for data keys
3947			if ( !jQuery.isArray( name ) ) {
3948
3949				// try the string as a key before any manipulation
3950				if ( name in thisCache ) {
3951					name = [ name ];
3952				} else {
3953
3954					// split the camel cased version by spaces unless a key with the spaces exists
3955					name = jQuery.camelCase( name );
3956					if ( name in thisCache ) {
3957						name = [ name ];
3958					} else {
3959						name = name.split( " " );
3960					}
3961				}
3962			} else {
3963
3964				// If "name" is an array of keys...
3965				// When data is initially created, via ("key", "val") signature,
3966				// keys will be converted to camelCase.
3967				// Since there is no way to tell _how_ a key was added, remove
3968				// both plain key and camelCase key. #12786
3969				// This will only penalize the array argument path.
3970				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
3971			}
3972
3973			i = name.length;
3974			while ( i-- ) {
3975				delete thisCache[ name[ i ] ];
3976			}
3977
3978			// If there is no data left in the cache, we want to continue
3979			// and let the cache object itself get destroyed
3980			if ( pvt ? !isEmptyDataObject( thisCache ) : !jQuery.isEmptyObject( thisCache ) ) {
3981				return;
3982			}
3983		}
3984	}
3985
3986	// See jQuery.data for more information
3987	if ( !pvt ) {
3988		delete cache[ id ].data;
3989
3990		// Don't destroy the parent cache unless the internal data object
3991		// had been the only thing left in it
3992		if ( !isEmptyDataObject( cache[ id ] ) ) {
3993			return;
3994		}
3995	}
3996
3997	// Destroy the cache
3998	if ( isNode ) {
3999		jQuery.cleanData( [ elem ], true );
4000
4001	// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
4002	/* jshint eqeqeq: false */
4003	} else if ( support.deleteExpando || cache != cache.window ) {
4004		/* jshint eqeqeq: true */
4005		delete cache[ id ];
4006
4007	// When all else fails, undefined
4008	} else {
4009		cache[ id ] = undefined;
4010	}
4011}
4012
4013jQuery.extend( {
4014	cache: {},
4015
4016	// The following elements (space-suffixed to avoid Object.prototype collisions)
4017	// throw uncatchable exceptions if you attempt to set expando properties
4018	noData: {
4019		"applet ": true,
4020		"embed ": true,
4021
4022		// ...but Flash objects (which have this classid) *can* handle expandos
4023		"object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
4024	},
4025
4026	hasData: function( elem ) {
4027		elem = elem.nodeType ? jQuery.cache[ elem[ jQuery.expando ] ] : elem[ jQuery.expando ];
4028		return !!elem && !isEmptyDataObject( elem );
4029	},
4030
4031	data: function( elem, name, data ) {
4032		return internalData( elem, name, data );
4033	},
4034
4035	removeData: function( elem, name ) {
4036		return internalRemoveData( elem, name );
4037	},
4038
4039	// For internal use only.
4040	_data: function( elem, name, data ) {
4041		return internalData( elem, name, data, true );
4042	},
4043
4044	_removeData: function( elem, name ) {
4045		return internalRemoveData( elem, name, true );
4046	}
4047} );
4048
4049jQuery.fn.extend( {
4050	data: function( key, value ) {
4051		var i, name, data,
4052			elem = this[ 0 ],
4053			attrs = elem && elem.attributes;
4054
4055		// Special expections of .data basically thwart jQuery.access,
4056		// so implement the relevant behavior ourselves
4057
4058		// Gets all values
4059		if ( key === undefined ) {
4060			if ( this.length ) {
4061				data = jQuery.data( elem );
4062
4063				if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
4064					i = attrs.length;
4065					while ( i-- ) {
4066
4067						// Support: IE11+
4068						// The attrs elements can be null (#14894)
4069						if ( attrs[ i ] ) {
4070							name = attrs[ i ].name;
4071							if ( name.indexOf( "data-" ) === 0 ) {
4072								name = jQuery.camelCase( name.slice( 5 ) );
4073								dataAttr( elem, name, data[ name ] );
4074							}
4075						}
4076					}
4077					jQuery._data( elem, "parsedAttrs", true );
4078				}
4079			}
4080
4081			return data;
4082		}
4083
4084		// Sets multiple values
4085		if ( typeof key === "object" ) {
4086			return this.each( function() {
4087				jQuery.data( this, key );
4088			} );
4089		}
4090
4091		return arguments.length > 1 ?
4092
4093			// Sets one value
4094			this.each( function() {
4095				jQuery.data( this, key, value );
4096			} ) :
4097
4098			// Gets one value
4099			// Try to fetch any internally stored data first
4100			elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
4101	},
4102
4103	removeData: function( key ) {
4104		return this.each( function() {
4105			jQuery.removeData( this, key );
4106		} );
4107	}
4108} );
4109
4110
4111jQuery.extend( {
4112	queue: function( elem, type, data ) {
4113		var queue;
4114
4115		if ( elem ) {
4116			type = ( type || "fx" ) + "queue";
4117			queue = jQuery._data( elem, type );
4118
4119			// Speed up dequeue by getting out quickly if this is just a lookup
4120			if ( data ) {
4121				if ( !queue || jQuery.isArray( data ) ) {
4122					queue = jQuery._data( elem, type, jQuery.makeArray( data ) );
4123				} else {
4124					queue.push( data );
4125				}
4126			}
4127			return queue || [];
4128		}
4129	},
4130
4131	dequeue: function( elem, type ) {
vendor: 2,750 bytes, lines 4132-4257
4132		type = type || "fx";
4133
4134		var queue = jQuery.queue( elem, type ),
4135			startLength = queue.length,
4136			fn = queue.shift(),
4137			hooks = jQuery._queueHooks( elem, type ),
4138			next = function() {
4139				jQuery.dequeue( elem, type );
4140			};
4141
4142		// If the fx queue is dequeued, always remove the progress sentinel
4143		if ( fn === "inprogress" ) {
4144			fn = queue.shift();
4145			startLength--;
4146		}
4147
4148		if ( fn ) {
4149
4150			// Add a progress sentinel to prevent the fx queue from being
4151			// automatically dequeued
4152			if ( type === "fx" ) {
4153				queue.unshift( "inprogress" );
4154			}
4155
4156			// clear up the last queue stop function
4157			delete hooks.stop;
4158			fn.call( elem, next, hooks );
4159		}
4160
4161		if ( !startLength && hooks ) {
4162			hooks.empty.fire();
4163		}
4164	},
4165
4166	// not intended for public consumption - generates a queueHooks object,
4167	// or returns the current one
4168	_queueHooks: function( elem, type ) {
4169		var key = type + "queueHooks";
4170		return jQuery._data( elem, key ) || jQuery._data( elem, key, {
4171			empty: jQuery.Callbacks( "once memory" ).add( function() {
4172				jQuery._removeData( elem, type + "queue" );
4173				jQuery._removeData( elem, key );
4174			} )
4175		} );
4176	}
4177} );
4178
4179jQuery.fn.extend( {
4180	queue: function( type, data ) {
4181		var setter = 2;
4182
4183		if ( typeof type !== "string" ) {
4184			data = type;
4185			type = "fx";
4186			setter--;
4187		}
4188
4189		if ( arguments.length < setter ) {
4190			return jQuery.queue( this[ 0 ], type );
4191		}
4192
4193		return data === undefined ?
4194			this :
4195			this.each( function() {
4196				var queue = jQuery.queue( this, type, data );
4197
4198				// ensure a hooks for this queue
4199				jQuery._queueHooks( this, type );
4200
4201				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4202					jQuery.dequeue( this, type );
4203				}
4204			} );
4205	},
4206	dequeue: function( type ) {
4207		return this.each( function() {
4208			jQuery.dequeue( this, type );
4209		} );
4210	},
4211	clearQueue: function( type ) {
4212		return this.queue( type || "fx", [] );
4213	},
4214
4215	// Get a promise resolved when queues of a certain type
4216	// are emptied (fx is the type by default)
4217	promise: function( type, obj ) {
4218		var tmp,
4219			count = 1,
4220			defer = jQuery.Deferred(),
4221			elements = this,
4222			i = this.length,
4223			resolve = function() {
4224				if ( !( --count ) ) {
4225					defer.resolveWith( elements, [ elements ] );
4226				}
4227			};
4228
4229		if ( typeof type !== "string" ) {
4230			obj = type;
4231			type = undefined;
4232		}
4233		type = type || "fx";
4234
4235		while ( i-- ) {
4236			tmp = jQuery._data( elements[ i ], type + "queueHooks" );
4237			if ( tmp && tmp.empty ) {
4238				count++;
4239				tmp.empty.add( resolve );
4240			}
4241		}
4242		resolve();
4243		return defer.promise( obj );
4244	}
4245} );
4246
4247
4248( function() {
4249	var shrinkWrapBlocksVal;
4250
4251	support.shrinkWrapBlocks = function() {
4252		if ( shrinkWrapBlocksVal != null ) {
4253			return shrinkWrapBlocksVal;
4254		}
4255
4256		// Will be changed later if needed.
4257		shrinkWrapBlocksVal = false;
4258
4259		// Minified: var b,c,d
4260		var div, body, container;
4261
4262		body = document.getElementsByTagName( "body" )[ 0 ];
4263		if ( !body || !body.style ) {
4264
4265			// Test fired too early or in an unsupported environment, exit.
4266			return;
4267		}
4268
4269		// Setup
4270		div = document.createElement( "div" );
4271		container = document.createElement( "div" );
4272		container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
4273		body.appendChild( container ).appendChild( div );
4274
4275		// Support: IE6
4276		// Check if elements with layout shrink-wrap their children
4277		if ( typeof div.style.zoom !== "undefined" ) {
4278
4279			// Reset CSS: box-sizing; display; margin; border
4280			div.style.cssText =
4281
4282				// Support: Firefox<29, Android 2.3
4283				// Vendor-prefix box-sizing
4284				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
4285				"box-sizing:content-box;display:block;margin:0;border:0;" +
4286				"padding:1px;width:1px;zoom:1";
4287			div.appendChild( document.createElement( "div" ) ).style.width = "5px";
4288			shrinkWrapBlocksVal = div.offsetWidth !== 3;
4289		}
4290
4291		body.removeChild( container );
4292
4293		return shrinkWrapBlocksVal;
4294	};
4295
4296} )();
4297var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4298
4299var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4300
4301
4302var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4303
4304var isHidden = function( elem, el ) {
4305
4306		// isHidden might be called from jQuery#filter function;
4307		// in that case, element will be second argument
4308		elem = el || elem;
4309		return jQuery.css( elem, "display" ) === "none" ||
4310			!jQuery.contains( elem.ownerDocument, elem );
4311	};
4312
4313
4314
4315function adjustCSS( elem, prop, valueParts, tween ) {
4316	var adjusted,
4317		scale = 1,
4318		maxIterations = 20,
4319		currentValue = tween ?
4320			function() { return tween.cur(); } :
4321			function() { return jQuery.css( elem, prop, "" ); },
4322		initial = currentValue(),
4323		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4324
4325		// Starting value computation is required for potential unit mismatches
4326		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4327			rcssNum.exec( jQuery.css( elem, prop ) );
4328
4329	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4330
4331		// Trust units reported by jQuery.css
4332		unit = unit || initialInUnit[ 3 ];
4333
4334		// Make sure we update the tween properties later on
4335		valueParts = valueParts || [];
4336
4337		// Iteratively approximate from a nonzero starting point
4338		initialInUnit = +initial || 1;
4339
4340		do {
4341
4342			// If previous iteration zeroed out, double until we get *something*.
4343			// Use string for doubling so we don't accidentally see scale as unchanged below
4344			scale = scale || ".5";
4345
4346			// Adjust and apply
4347			initialInUnit = initialInUnit / scale;
4348			jQuery.style( elem, prop, initialInUnit + unit );
4349
4350		// Update scale, tolerating zero or NaN from tween.cur()
4351		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4352		} while (
4353			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4354		);
4355	}
4356
4357	if ( valueParts ) {
4358		initialInUnit = +initialInUnit || +initial || 0;
4359
4360		// Apply relative offset (+=/-=) if specified
4361		adjusted = valueParts[ 1 ] ?
4362			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4363			+valueParts[ 2 ];
4364		if ( tween ) {
4365			tween.unit = unit;
4366			tween.start = initialInUnit;
4367			tween.end = adjusted;
4368		}
4369	}
4370	return adjusted;
4371}
4372
4373
4374// Multifunctional method to get and set values of a collection
4375// The value/s can optionally be executed if it's a function
4376var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4377	var i = 0,
4378		length = elems.length,
4379		bulk = key == null;
4380
4381	// Sets many values
4382	if ( jQuery.type( key ) === "object" ) {
4383		chainable = true;
4384		for ( i in key ) {
4385			access( elems, fn, i, key[ i ], true, emptyGet, raw );
4386		}
4387
4388	// Sets one value
4389	} else if ( value !== undefined ) {
4390		chainable = true;
4391
4392		if ( !jQuery.isFunction( value ) ) {
4393			raw = true;
4394		}
4395
4396		if ( bulk ) {
4397
4398			// Bulk operations run against the entire set
4399			if ( raw ) {
4400				fn.call( elems, value );
4401				fn = null;
4402
4403			// ...except when executing function values
4404			} else {
4405				bulk = fn;
4406				fn = function( elem, key, value ) {
4407					return bulk.call( jQuery( elem ), value );
4408				};
4409			}
4410		}
4411
4412		if ( fn ) {
4413			for ( ; i < length; i++ ) {
4414				fn(
4415					elems[ i ],
4416					key,
4417					raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) )
4418				);
4419			}
4420		}
4421	}
4422
4423	return chainable ?
4424		elems :
4425
4426		// Gets
4427		bulk ?
4428			fn.call( elems ) :
4429			length ? fn( elems[ 0 ], key ) : emptyGet;
4430};
4431var rcheckableType = ( /^(?:checkbox|radio)$/i );
4432
4433var rtagName = ( /<([\w:-]+)/ );
4434
4435var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4436
4437var rleadingWhitespace = ( /^\s+/ );
4438
4439var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|" +
4440		"details|dialog|figcaption|figure|footer|header|hgroup|main|" +
4441		"mark|meter|nav|output|picture|progress|section|summary|template|time|video";
4442
4443
4444
4445function createSafeFragment( document ) {
4446	var list = nodeNames.split( "|" ),
4447		safeFrag = document.createDocumentFragment();
4448
4449	if ( safeFrag.createElement ) {
4450		while ( list.length ) {
4451			safeFrag.createElement(
4452				list.pop()
4453			);
4454		}
4455	}
4456	return safeFrag;
4457}
4458
4459
4460( function() {
4461	var div = document.createElement( "div" ),
4462		fragment = document.createDocumentFragment(),
4463		input = document.createElement( "input" );
4464
4465	// Setup
4466	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
4467
4468	// IE strips leading whitespace when .innerHTML is used
4469	support.leadingWhitespace = div.firstChild.nodeType === 3;
4470
4471	// Make sure that tbody elements aren't automatically inserted
4472	// IE will insert them into empty tables
4473	support.tbody = !div.getElementsByTagName( "tbody" ).length;
4474
4475	// Make sure that link elements get serialized correctly by innerHTML
4476	// This requires a wrapper element in IE
4477	support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
4478
4479	// Makes sure cloning an html5 element does not cause problems
4480	// Where outerHTML is undefined, this still works
4481	support.html5Clone =
4482		document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
4483
4484	// Check if a disconnected checkbox will retain its checked
4485	// value of true after appended to the DOM (IE6/7)
4486	input.type = "checkbox";
4487	input.checked = true;
4488	fragment.appendChild( input );
4489	support.appendChecked = input.checked;
4490
4491	// Make sure textarea (and checkbox) defaultValue is properly cloned
4492	// Support: IE6-IE11+
4493	div.innerHTML = "<textarea>x</textarea>";
4494	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4495
4496	// #11217 - WebKit loses check when the name is after the checked attribute
4497	fragment.appendChild( div );
4498
4499	// Support: Windows Web Apps (WWA)
4500	// `name` and `type` must use .setAttribute for WWA (#14901)
4501	input = document.createElement( "input" );
4502	input.setAttribute( "type", "radio" );
4503	input.setAttribute( "checked", "checked" );
4504	input.setAttribute( "name", "t" );
4505
4506	div.appendChild( input );
4507
4508	// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
4509	// old WebKit doesn't clone checked state correctly in fragments
4510	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4511
4512	// Support: IE<9
4513	// Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
4514	support.noCloneEvent = !!div.addEventListener;
4515
4516	// Support: IE<9
4517	// Since attributes and properties are the same in IE,
4518	// cleanData must set properties to undefined rather than use removeAttribute
4519	div[ jQuery.expando ] = 1;
4520	support.attributes = !div.getAttribute( jQuery.expando );
4521} )();
4522
4523
4524// We have to close these tags to support XHTML (#13200)
4525var wrapMap = {
4526	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4527	legend: [ 1, "<fieldset>", "</fieldset>" ],
4528	area: [ 1, "<map>", "</map>" ],
4529
4530	// Support: IE8
4531	param: [ 1, "<object>", "</object>" ],
4532	thead: [ 1, "<table>", "</table>" ],
4533	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4534	col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
4535	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4536
4537	// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
4538	// unless wrapped in a div with non-breaking characters in front of it.
4539	_default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
4540};
4541
4542// Support: IE8-IE9
4543wrapMap.optgroup = wrapMap.option;
4544
4545wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4546wrapMap.th = wrapMap.td;
4547
4548
4549function getAll( context, tag ) {
4550	var elems, elem,
4551		i = 0,
4552		found = typeof context.getElementsByTagName !== "undefined" ?
4553			context.getElementsByTagName( tag || "*" ) :
4554			typeof context.querySelectorAll !== "undefined" ?
4555				context.querySelectorAll( tag || "*" ) :
4556				undefined;
4557
4558	if ( !found ) {
4559		for ( found = [], elems = context.childNodes || context;
4560			( elem = elems[ i ] ) != null;
4561			i++
4562		) {
4563			if ( !tag || jQuery.nodeName( elem, tag ) ) {
4564				found.push( elem );
4565			} else {
4566				jQuery.merge( found, getAll( elem, tag ) );
4567			}
4568		}
4569	}
4570
4571	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4572		jQuery.merge( [ context ], found ) :
4573		found;
4574}
4575
4576
4577// Mark scripts as having already been evaluated
4578function setGlobalEval( elems, refElements ) {
4579	var elem,
4580		i = 0;
4581	for ( ; ( elem = elems[ i ] ) != null; i++ ) {
4582		jQuery._data(
4583			elem,
4584			"globalEval",
4585			!refElements || jQuery._data( refElements[ i ], "globalEval" )
4586		);
4587	}
4588}
4589
4590
4591var rhtml = /<|&#?\w+;/,
4592	rtbody = /<tbody/i;
4593
4594function fixDefaultChecked( elem ) {
4595	if ( rcheckableType.test( elem.type ) ) {
4596		elem.defaultChecked = elem.checked;
4597	}
4598}
4599
4600function buildFragment( elems, context, scripts, selection, ignored ) {
4601	var j, elem, contains,
4602		tmp, tag, tbody, wrap,
4603		l = elems.length,
4604
4605		// Ensure a safe fragment
4606		safe = createSafeFragment( context ),
4607
4608		nodes = [],
4609		i = 0;
4610
4611	for ( ; i < l; i++ ) {
4612		elem = elems[ i ];
4613
4614		if ( elem || elem === 0 ) {
4615
4616			// Add nodes directly
4617			if ( jQuery.type( elem ) === "object" ) {
4618				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4619
4620			// Convert non-html into a text node
4621			} else if ( !rhtml.test( elem ) ) {
4622				nodes.push( context.createTextNode( elem ) );
4623
4624			// Convert html into DOM nodes
4625			} else {
4626				tmp = tmp || safe.appendChild( context.createElement( "div" ) );
4627
4628				// Deserialize a standard representation
4629				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4630				wrap = wrapMap[ tag ] || wrapMap._default;
4631
4632				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4633
4634				// Descend through wrappers to the right content
4635				j = wrap[ 0 ];
4636				while ( j-- ) {
4637					tmp = tmp.lastChild;
4638				}
4639
4640				// Manually add leading whitespace removed by IE
4641				if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
4642					nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
4643				}
4644
4645				// Remove IE's autoinserted <tbody> from table fragments
4646				if ( !support.tbody ) {
4647
4648					// String was a <table>, *may* have spurious <tbody>
4649					elem = tag === "table" && !rtbody.test( elem ) ?
4650						tmp.firstChild :
4651
4652						// String was a bare <thead> or <tfoot>
4653						wrap[ 1 ] === "<table>" && !rtbody.test( elem ) ?
4654							tmp :
4655							0;
4656
4657					j = elem && elem.childNodes.length;
4658					while ( j-- ) {
4659						if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
4660							!tbody.childNodes.length ) {
4661
4662							elem.removeChild( tbody );
4663						}
4664					}
4665				}
4666
4667				jQuery.merge( nodes, tmp.childNodes );
4668
4669				// Fix #12392 for WebKit and IE > 9
4670				tmp.textContent = "";
4671
4672				// Fix #12392 for oldIE
4673				while ( tmp.firstChild ) {
4674					tmp.removeChild( tmp.firstChild );
4675				}
4676
4677				// Remember the top-level container for proper cleanup
4678				tmp = safe.lastChild;
4679			}
4680		}
4681	}
4682
4683	// Fix #11356: Clear elements from fragment
4684	if ( tmp ) {
4685		safe.removeChild( tmp );
4686	}
4687
4688	// Reset defaultChecked for any radios and checkboxes
4689	// about to be appended to the DOM in IE 6/7 (#8060)
4690	if ( !support.appendChecked ) {
4691		jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
4692	}
4693
4694	i = 0;
4695	while ( ( elem = nodes[ i++ ] ) ) {
4696
4697		// Skip elements already in the context collection (trac-4087)
4698		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4699			if ( ignored ) {
4700				ignored.push( elem );
4701			}
4702
4703			continue;
4704		}
4705
4706		contains = jQuery.contains( elem.ownerDocument, elem );
4707
4708		// Append to fragment
4709		tmp = getAll( safe.appendChild( elem ), "script" );
4710
4711		// Preserve script evaluation history
4712		if ( contains ) {
4713			setGlobalEval( tmp );
4714		}
4715
4716		// Capture executables
4717		if ( scripts ) {
4718			j = 0;
4719			while ( ( elem = tmp[ j++ ] ) ) {
4720				if ( rscriptType.test( elem.type || "" ) ) {
4721					scripts.push( elem );
4722				}
4723			}
4724		}
4725	}
4726
4727	tmp = null;
4728
4729	return safe;
4730}
4731
4732
4733( function() {
4734	var i, eventName,
4735		div = document.createElement( "div" );
4736
4737	// Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
4738	for ( i in { submit: true, change: true, focusin: true } ) {
4739		eventName = "on" + i;
4740
vendor: 13,833 bytes, lines 4741-5220
4741		if ( !( support[ i ] = eventName in window ) ) {
4742
4743			// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
4744			div.setAttribute( eventName, "t" );
4745			support[ i ] = div.attributes[ eventName ].expando === false;
4746		}
4747	}
4748
4749	// Null elements to avoid leaks in IE.
4750	div = null;
4751} )();
4752
4753
4754var rformElems = /^(?:input|select|textarea)$/i,
4755	rkeyEvent = /^key/,
4756	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4757	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4758	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4759
4760function returnTrue() {
4761	return true;
4762}
4763
4764function returnFalse() {
4765	return false;
4766}
4767
4768// Support: IE9
4769// See #13393 for more info
4770function safeActiveElement() {
4771	try {
4772		return document.activeElement;
4773	} catch ( err ) { }
4774}
4775
4776function on( elem, types, selector, data, fn, one ) {
4777	var origFn, type;
4778
4779	// Types can be a map of types/handlers
4780	if ( typeof types === "object" ) {
4781
4782		// ( types-Object, selector, data )
4783		if ( typeof selector !== "string" ) {
4784
4785			// ( types-Object, data )
4786			data = data || selector;
4787			selector = undefined;
4788		}
4789		for ( type in types ) {
4790			on( elem, type, selector, data, types[ type ], one );
4791		}
4792		return elem;
4793	}
4794
4795	if ( data == null && fn == null ) {
4796
4797		// ( types, fn )
4798		fn = selector;
4799		data = selector = undefined;
4800	} else if ( fn == null ) {
4801		if ( typeof selector === "string" ) {
4802
4803			// ( types, selector, fn )
4804			fn = data;
4805			data = undefined;
4806		} else {
4807
4808			// ( types, data, fn )
4809			fn = data;
4810			data = selector;
4811			selector = undefined;
4812		}
4813	}
4814	if ( fn === false ) {
4815		fn = returnFalse;
4816	} else if ( !fn ) {
4817		return elem;
4818	}
4819
4820	if ( one === 1 ) {
4821		origFn = fn;
4822		fn = function( event ) {
4823
4824			// Can use an empty set, since event contains the info
4825			jQuery().off( event );
4826			return origFn.apply( this, arguments );
4827		};
4828
4829		// Use same guid so caller can remove using origFn
4830		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4831	}
4832	return elem.each( function() {
4833		jQuery.event.add( this, types, fn, data, selector );
4834	} );
4835}
4836
4837/*
4838 * Helper functions for managing events -- not part of the public interface.
4839 * Props to Dean Edwards' addEvent library for many of the ideas.
4840 */
4841jQuery.event = {
4842
4843	global: {},
4844
4845	add: function( elem, types, handler, data, selector ) {
4846		var tmp, events, t, handleObjIn,
4847			special, eventHandle, handleObj,
4848			handlers, type, namespaces, origType,
4849			elemData = jQuery._data( elem );
4850
4851		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4852		if ( !elemData ) {
4853			return;
4854		}
4855
4856		// Caller can pass in an object of custom data in lieu of the handler
4857		if ( handler.handler ) {
4858			handleObjIn = handler;
4859			handler = handleObjIn.handler;
4860			selector = handleObjIn.selector;
4861		}
4862
4863		// Make sure that the handler has a unique ID, used to find/remove it later
4864		if ( !handler.guid ) {
4865			handler.guid = jQuery.guid++;
4866		}
4867
4868		// Init the element's event structure and main handler, if this is the first
4869		if ( !( events = elemData.events ) ) {
4870			events = elemData.events = {};
4871		}
4872		if ( !( eventHandle = elemData.handle ) ) {
4873			eventHandle = elemData.handle = function( e ) {
4874
4875				// Discard the second event of a jQuery.event.trigger() and
4876				// when an event is called after a page has unloaded
4877				return typeof jQuery !== "undefined" &&
4878					( !e || jQuery.event.triggered !== e.type ) ?
4879					jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4880					undefined;
4881			};
4882
4883			// Add elem as a property of the handle fn to prevent a memory leak
4884			// with IE non-native events
4885			eventHandle.elem = elem;
4886		}
4887
4888		// Handle multiple events separated by a space
4889		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4890		t = types.length;
4891		while ( t-- ) {
4892			tmp = rtypenamespace.exec( types[ t ] ) || [];
4893			type = origType = tmp[ 1 ];
4894			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4895
4896			// There *must* be a type, no attaching namespace-only handlers
4897			if ( !type ) {
4898				continue;
4899			}
4900
4901			// If event changes its type, use the special event handlers for the changed type
4902			special = jQuery.event.special[ type ] || {};
4903
4904			// If selector defined, determine special event api type, otherwise given type
4905			type = ( selector ? special.delegateType : special.bindType ) || type;
4906
4907			// Update special based on newly reset type
4908			special = jQuery.event.special[ type ] || {};
4909
4910			// handleObj is passed to all event handlers
4911			handleObj = jQuery.extend( {
4912				type: type,
4913				origType: origType,
4914				data: data,
4915				handler: handler,
4916				guid: handler.guid,
4917				selector: selector,
4918				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4919				namespace: namespaces.join( "." )
4920			}, handleObjIn );
4921
4922			// Init the event handler queue if we're the first
4923			if ( !( handlers = events[ type ] ) ) {
4924				handlers = events[ type ] = [];
4925				handlers.delegateCount = 0;
4926
4927				// Only use addEventListener/attachEvent if the special events handler returns false
4928				if ( !special.setup ||
4929					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4930
4931					// Bind the global event handler to the element
4932					if ( elem.addEventListener ) {
4933						elem.addEventListener( type, eventHandle, false );
4934
4935					} else if ( elem.attachEvent ) {
4936						elem.attachEvent( "on" + type, eventHandle );
4937					}
4938				}
4939			}
4940
4941			if ( special.add ) {
4942				special.add.call( elem, handleObj );
4943
4944				if ( !handleObj.handler.guid ) {
4945					handleObj.handler.guid = handler.guid;
4946				}
4947			}
4948
4949			// Add to the element's handler list, delegates in front
4950			if ( selector ) {
4951				handlers.splice( handlers.delegateCount++, 0, handleObj );
4952			} else {
4953				handlers.push( handleObj );
4954			}
4955
4956			// Keep track of which events have ever been used, for event optimization
4957			jQuery.event.global[ type ] = true;
4958		}
4959
4960		// Nullify elem to prevent memory leaks in IE
4961		elem = null;
4962	},
4963
4964	// Detach an event or set of events from an element
4965	remove: function( elem, types, handler, selector, mappedTypes ) {
4966		var j, handleObj, tmp,
4967			origCount, t, events,
4968			special, handlers, type,
4969			namespaces, origType,
4970			elemData = jQuery.hasData( elem ) && jQuery._data( elem );
4971
4972		if ( !elemData || !( events = elemData.events ) ) {
4973			return;
4974		}
4975
4976		// Once for each type.namespace in types; type may be omitted
4977		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4978		t = types.length;
4979		while ( t-- ) {
4980			tmp = rtypenamespace.exec( types[ t ] ) || [];
4981			type = origType = tmp[ 1 ];
4982			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4983
4984			// Unbind all events (on this namespace, if provided) for the element
4985			if ( !type ) {
4986				for ( type in events ) {
4987					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4988				}
4989				continue;
4990			}
4991
4992			special = jQuery.event.special[ type ] || {};
4993			type = ( selector ? special.delegateType : special.bindType ) || type;
4994			handlers = events[ type ] || [];
4995			tmp = tmp[ 2 ] &&
4996				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4997
4998			// Remove matching events
4999			origCount = j = handlers.length;
5000			while ( j-- ) {
5001				handleObj = handlers[ j ];
5002
5003				if ( ( mappedTypes || origType === handleObj.origType ) &&
5004					( !handler || handler.guid === handleObj.guid ) &&
5005					( !tmp || tmp.test( handleObj.namespace ) ) &&
5006					( !selector || selector === handleObj.selector ||
5007						selector === "**" && handleObj.selector ) ) {
5008					handlers.splice( j, 1 );
5009
5010					if ( handleObj.selector ) {
5011						handlers.delegateCount--;
5012					}
5013					if ( special.remove ) {
5014						special.remove.call( elem, handleObj );
5015					}
5016				}
5017			}
5018
5019			// Remove generic event handler if we removed something and no more handlers exist
5020			// (avoids potential for endless recursion during removal of special event handlers)
5021			if ( origCount && !handlers.length ) {
5022				if ( !special.teardown ||
5023					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5024
5025					jQuery.removeEvent( elem, type, elemData.handle );
5026				}
5027
5028				delete events[ type ];
5029			}
5030		}
5031
5032		// Remove the expando if it's no longer used
5033		if ( jQuery.isEmptyObject( events ) ) {
5034			delete elemData.handle;
5035
5036			// removeData also checks for emptiness and clears the expando if empty
5037			// so use it instead of delete
5038			jQuery._removeData( elem, "events" );
5039		}
5040	},
5041
5042	trigger: function( event, data, elem, onlyHandlers ) {
5043		var handle, ontype, cur,
5044			bubbleType, special, tmp, i,
5045			eventPath = [ elem || document ],
5046			type = hasOwn.call( event, "type" ) ? event.type : event,
5047			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
5048
5049		cur = tmp = elem = elem || document;
5050
5051		// Don't do events on text and comment nodes
5052		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
5053			return;
5054		}
5055
5056		// focus/blur morphs to focusin/out; ensure we're not firing them right now
5057		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
5058			return;
5059		}
5060
5061		if ( type.indexOf( "." ) > -1 ) {
5062
5063			// Namespaced trigger; create a regexp to match event type in handle()
5064			namespaces = type.split( "." );
5065			type = namespaces.shift();
5066			namespaces.sort();
5067		}
5068		ontype = type.indexOf( ":" ) < 0 && "on" + type;
5069
5070		// Caller can pass in a jQuery.Event object, Object, or just an event type string
5071		event = event[ jQuery.expando ] ?
5072			event :
5073			new jQuery.Event( type, typeof event === "object" && event );
5074
5075		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
5076		event.isTrigger = onlyHandlers ? 2 : 3;
5077		event.namespace = namespaces.join( "." );
5078		event.rnamespace = event.namespace ?
5079			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
5080			null;
5081
5082		// Clean up the event in case it is being reused
5083		event.result = undefined;
5084		if ( !event.target ) {
5085			event.target = elem;
5086		}
5087
5088		// Clone any incoming data and prepend the event, creating the handler arg list
5089		data = data == null ?
5090			[ event ] :
5091			jQuery.makeArray( data, [ event ] );
5092
5093		// Allow special events to draw outside the lines
5094		special = jQuery.event.special[ type ] || {};
5095		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
5096			return;
5097		}
5098
5099		// Determine event propagation path in advance, per W3C events spec (#9951)
5100		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
5101		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
5102
5103			bubbleType = special.delegateType || type;
5104			if ( !rfocusMorph.test( bubbleType + type ) ) {
5105				cur = cur.parentNode;
5106			}
5107			for ( ; cur; cur = cur.parentNode ) {
5108				eventPath.push( cur );
5109				tmp = cur;
5110			}
5111
5112			// Only add window if we got to document (e.g., not plain obj or detached DOM)
5113			if ( tmp === ( elem.ownerDocument || document ) ) {
5114				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
5115			}
5116		}
5117
5118		// Fire handlers on the event path
5119		i = 0;
5120		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
5121
5122			event.type = i > 1 ?
5123				bubbleType :
5124				special.bindType || type;
5125
5126			// jQuery handler
5127			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
5128				jQuery._data( cur, "handle" );
5129
5130			if ( handle ) {
5131				handle.apply( cur, data );
5132			}
5133
5134			// Native handler
5135			handle = ontype && cur[ ontype ];
5136			if ( handle && handle.apply && acceptData( cur ) ) {
5137				event.result = handle.apply( cur, data );
5138				if ( event.result === false ) {
5139					event.preventDefault();
5140				}
5141			}
5142		}
5143		event.type = type;
5144
5145		// If nobody prevented the default action, do it now
5146		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
5147
5148			if (
5149				( !special._default ||
5150				 special._default.apply( eventPath.pop(), data ) === false
5151				) && acceptData( elem )
5152			) {
5153
5154				// Call a native DOM method on the target with the same name name as the event.
5155				// Can't use an .isFunction() check here because IE6/7 fails that test.
5156				// Don't do default actions on window, that's where global variables be (#6170)
5157				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
5158
5159					// Don't re-trigger an onFOO event when we call its FOO() method
5160					tmp = elem[ ontype ];
5161
5162					if ( tmp ) {
5163						elem[ ontype ] = null;
5164					}
5165
5166					// Prevent re-triggering of the same event, since we already bubbled it above
5167					jQuery.event.triggered = type;
5168					try {
5169						elem[ type ]();
5170					} catch ( e ) {
5171
5172						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
5173						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
5174					}
5175					jQuery.event.triggered = undefined;
5176
5177					if ( tmp ) {
5178						elem[ ontype ] = tmp;
5179					}
5180				}
5181			}
5182		}
5183
5184		return event.result;
5185	},
5186
5187	dispatch: function( event ) {
5188
5189		// Make a writable jQuery.Event from the native event object
5190		event = jQuery.event.fix( event );
5191
5192		var i, j, ret, matched, handleObj,
5193			handlerQueue = [],
5194			args = slice.call( arguments ),
5195			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
5196			special = jQuery.event.special[ event.type ] || {};
5197
5198		// Use the fix-ed jQuery.Event rather than the (read-only) native event
5199		args[ 0 ] = event;
5200		event.delegateTarget = this;
5201
5202		// Call the preDispatch hook for the mapped type, and let it bail if desired
5203		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5204			return;
5205		}
5206
5207		// Determine handlers
5208		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5209
5210		// Run delegates first; they may want to stop propagation beneath us
5211		i = 0;
5212		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5213			event.currentTarget = matched.elem;
5214
5215			j = 0;
5216			while ( ( handleObj = matched.handlers[ j++ ] ) &&
5217				!event.isImmediatePropagationStopped() ) {
5218
5219				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
5220				// a subset or equal to those in the bound event (both can have no namespace).
5221				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
5222
5223					event.handleObj = handleObj;
5224					event.data = handleObj.data;
5225
5226					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5227						handleObj.handler ).apply( matched.elem, args );
5228
5229					if ( ret !== undefined ) {
5230						if ( ( event.result = ret ) === false ) {
5231							event.preventDefault();
5232							event.stopPropagation();
5233						}
5234					}
5235				}
5236			}
5237		}
5238
5239		// Call the postDispatch hook for the mapped type
5240		if ( special.postDispatch ) {
5241			special.postDispatch.call( this, event );
5242		}
5243
5244		return event.result;
5245	},
5246
5247	handlers: function( event, handlers ) {
5248		var i, matches, sel, handleObj,
5249			handlerQueue = [],
5250			delegateCount = handlers.delegateCount,
5251			cur = event.target;
5252
5253		// Support (at least): Chrome, IE9
5254		// Find delegate handlers
5255		// Black-hole SVG <use> instance trees (#13180)
5256		//
5257		// Support: Firefox<=42+
5258		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
5259		if ( delegateCount && cur.nodeType &&
5260			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
5261
5262			/* jshint eqeqeq: false */
5263			for ( ; cur != this; cur = cur.parentNode || this ) {
5264				/* jshint eqeqeq: true */
5265
5266				// Don't check non-elements (#13208)
5267				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5268				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
5269					matches = [];
5270					for ( i = 0; i < delegateCount; i++ ) {
5271						handleObj = handlers[ i ];
5272
5273						// Don't conflict with Object.prototype properties (#13203)
5274						sel = handleObj.selector + " ";
5275
5276						if ( matches[ sel ] === undefined ) {
5277							matches[ sel ] = handleObj.needsContext ?
5278								jQuery( sel, this ).index( cur ) > -1 :
5279								jQuery.find( sel, this, null, [ cur ] ).length;
5280						}
5281						if ( matches[ sel ] ) {
5282							matches.push( handleObj );
5283						}
5284					}
5285					if ( matches.length ) {
5286						handlerQueue.push( { elem: cur, handlers: matches } );
5287					}
5288				}
5289			}
5290		}
5291
5292		// Add the remaining (directly-bound) handlers
5293		if ( delegateCount < handlers.length ) {
5294			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
5295		}
5296
5297		return handlerQueue;
5298	},
5299
5300	fix: function( event ) {
5301		if ( event[ jQuery.expando ] ) {
5302			return event;
5303		}
5304
5305		// Create a writable copy of the event object and normalize some properties
5306		var i, prop, copy,
5307			type = event.type,
5308			originalEvent = event,
5309			fixHook = this.fixHooks[ type ];
5310
5311		if ( !fixHook ) {
5312			this.fixHooks[ type ] = fixHook =
5313				rmouseEvent.test( type ) ? this.mouseHooks :
5314				rkeyEvent.test( type ) ? this.keyHooks :
5315				{};
5316		}
5317		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
5318
5319		event = new jQuery.Event( originalEvent );
5320
5321		i = copy.length;
5322		while ( i-- ) {
5323			prop = copy[ i ];
5324			event[ prop ] = originalEvent[ prop ];
5325		}
5326
5327		// Support: IE<9
5328		// Fix target property (#1925)
5329		if ( !event.target ) {
5330			event.target = originalEvent.srcElement || document;
5331		}
5332
5333		// Support: Safari 6-8+
5334		// Target should not be a text node (#504, #13143)
5335		if ( event.target.nodeType === 3 ) {
5336			event.target = event.target.parentNode;
5337		}
5338
5339		// Support: IE<9
5340		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
5341		event.metaKey = !!event.metaKey;
5342
5343		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
5344	},
5345
5346	// Includes some event props shared by KeyEvent and MouseEvent
5347	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
5348		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
5349
5350	fixHooks: {},
5351
5352	keyHooks: {
5353		props: "char charCode key keyCode".split( " " ),
5354		filter: function( event, original ) {
5355
5356			// Add which for key events
5357			if ( event.which == null ) {
5358				event.which = original.charCode != null ? original.charCode : original.keyCode;
5359			}
5360
5361			return event;
5362		}
5363	},
5364
5365	mouseHooks: {
5366		props: ( "button buttons clientX clientY fromElement offsetX offsetY " +
5367			"pageX pageY screenX screenY toElement" ).split( " " ),
5368		filter: function( event, original ) {
5369			var body, eventDoc, doc,
5370				button = original.button,
5371				fromElement = original.fromElement;
5372
5373			// Calculate pageX/Y if missing and clientX/Y available
5374			if ( event.pageX == null && original.clientX != null ) {
5375				eventDoc = event.target.ownerDocument || document;
5376				doc = eventDoc.documentElement;
5377				body = eventDoc.body;
5378
5379				event.pageX = original.clientX +
5380					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
5381					( doc && doc.clientLeft || body && body.clientLeft || 0 );
5382				event.pageY = original.clientY +
5383					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
5384					( doc && doc.clientTop  || body && body.clientTop  || 0 );
5385			}
5386
5387			// Add relatedTarget, if necessary
5388			if ( !event.relatedTarget && fromElement ) {
5389				event.relatedTarget = fromElement === event.target ?
5390					original.toElement :
5391					fromElement;
5392			}
5393
5394			// Add which for click: 1 === left; 2 === middle; 3 === right
5395			// Note: button is not normalized, so don't use it
5396			if ( !event.which && button !== undefined ) {
5397				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
5398			}
5399
5400			return event;
5401		}
5402	},
5403
5404	special: {
5405		load: {
5406
5407			// Prevent triggered image.load events from bubbling to window.load
5408			noBubble: true
5409		},
5410		focus: {
5411
5412			// Fire native event if possible so blur/focus sequence is correct
5413			trigger: function() {
5414				if ( this !== safeActiveElement() && this.focus ) {
5415					try {
5416						this.focus();
5417						return false;
5418					} catch ( e ) {
5419
5420						// Support: IE<9
5421						// If we error on focus to hidden element (#1486, #12518),
5422						// let .trigger() run the handlers
5423					}
5424				}
5425			},
5426			delegateType: "focusin"
5427		},
5428		blur: {
5429			trigger: function() {
5430				if ( this === safeActiveElement() && this.blur ) {
5431					this.blur();
5432					return false;
5433				}
5434			},
5435			delegateType: "focusout"
5436		},
5437		click: {
5438
5439			// For checkbox, fire native event so checked state will be right
5440			trigger: function() {
5441				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
5442					this.click();
5443					return false;
5444				}
5445			},
5446
5447			// For cross-browser consistency, don't fire native .click() on links
5448			_default: function( event ) {
5449				return jQuery.nodeName( event.target, "a" );
5450			}
5451		},
5452
5453		beforeunload: {
5454			postDispatch: function( event ) {
5455
5456				// Support: Firefox 20+
5457				// Firefox doesn't alert if the returnValue field is not set.
5458				if ( event.result !== undefined && event.originalEvent ) {
5459					event.originalEvent.returnValue = event.result;
5460				}
5461			}
5462		}
5463	},
5464
5465	// Piggyback on a donor event to simulate a different one
5466	simulate: function( type, elem, event ) {
5467		var e = jQuery.extend(
5468			new jQuery.Event(),
5469			event,
5470			{
5471				type: type,
5472				isSimulated: true
5473
5474				// Previously, `originalEvent: {}` was set here, so stopPropagation call
5475				// would not be triggered on donor event, since in our own
5476				// jQuery.event.stopPropagation function we had a check for existence of
5477				// originalEvent.stopPropagation method, so, consequently it would be a noop.
5478				//
5479				// Guard for simulated events was moved to jQuery.event.stopPropagation function
5480				// since `originalEvent` should point to the original event for the
5481				// constancy with other events and for more focused logic
5482			}
5483		);
5484
5485		jQuery.event.trigger( e, null, elem );
5486
5487		if ( e.isDefaultPrevented() ) {
5488			event.preventDefault();
5489		}
5490	}
5491};
5492
5493jQuery.removeEvent = document.removeEventListener ?
5494	function( elem, type, handle ) {
5495
5496		// This "if" is needed for plain objects
5497		if ( elem.removeEventListener ) {
5498			elem.removeEventListener( type, handle );
5499		}
5500	} :
5501	function( elem, type, handle ) {
5502		var name = "on" + type;
5503
5504		if ( elem.detachEvent ) {
5505
5506			// #8545, #7054, preventing memory leaks for custom events in IE6-8
5507			// detachEvent needed property on element, by name of that event,
5508			// to properly expose it to GC
5509			if ( typeof elem[ name ] === "undefined" ) {
5510				elem[ name ] = null;
5511			}
5512
5513			elem.detachEvent( name, handle );
5514		}
5515	};
5516
5517jQuery.Event = function( src, props ) {
5518
5519	// Allow instantiation without the 'new' keyword
5520	if ( !( this instanceof jQuery.Event ) ) {
5521		return new jQuery.Event( src, props );
5522	}
5523
5524	// Event object
5525	if ( src && src.type ) {
5526		this.originalEvent = src;
5527		this.type = src.type;
5528
5529		// Events bubbling up the document may have been marked as prevented
5530		// by a handler lower down the tree; reflect the correct value.
5531		this.isDefaultPrevented = src.defaultPrevented ||
5532				src.defaultPrevented === undefined &&
5533
5534				// Support: IE < 9, Android < 4.0
5535				src.returnValue === false ?
5536			returnTrue :
5537			returnFalse;
5538
5539	// Event type
5540	} else {
5541		this.type = src;
5542	}
5543
5544	// Put explicitly provided properties onto the event object
5545	if ( props ) {
5546		jQuery.extend( this, props );
5547	}
5548
5549	// Create a timestamp if incoming event doesn't have one
5550	this.timeStamp = src && src.timeStamp || jQuery.now();
5551
5552	// Mark it as fixed
5553	this[ jQuery.expando ] = true;
5554};
5555
5556// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5557// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5558jQuery.Event.prototype = {
5559	constructor: jQuery.Event,
5560	isDefaultPrevented: returnFalse,
5561	isPropagationStopped: returnFalse,
5562	isImmediatePropagationStopped: returnFalse,
5563
5564	preventDefault: function() {
5565		var e = this.originalEvent;
5566
5567		this.isDefaultPrevented = returnTrue;
5568		if ( !e ) {
5569			return;
5570		}
5571
5572		// If preventDefault exists, run it on the original event
5573		if ( e.preventDefault ) {
5574			e.preventDefault();
5575
5576		// Support: IE
5577		// Otherwise set the returnValue property of the original event to false
5578		} else {
5579			e.returnValue = false;
5580		}
5581	},
5582	stopPropagation: function() {
5583		var e = this.originalEvent;
5584
5585		this.isPropagationStopped = returnTrue;
5586
5587		if ( !e || this.isSimulated ) {
5588			return;
5589		}
5590
5591		// If stopPropagation exists, run it on the original event
5592		if ( e.stopPropagation ) {
5593			e.stopPropagation();
5594		}
5595
5596		// Support: IE
5597		// Set the cancelBubble property of the original event to true
5598		e.cancelBubble = true;
5599	},
5600	stopImmediatePropagation: function() {
5601		var e = this.originalEvent;
5602
5603		this.isImmediatePropagationStopped = returnTrue;
5604
5605		if ( e && e.stopImmediatePropagation ) {
5606			e.stopImmediatePropagation();
5607		}
5608
5609		this.stopPropagation();
5610	}
5611};
5612
5613// Create mouseenter/leave events using mouseover/out and event-time checks
5614// so that event delegation works in jQuery.
5615// Do the same for pointerenter/pointerleave and pointerover/pointerout
5616//
5617// Support: Safari 7 only
5618// Safari sends mouseenter too often; see:
5619// https://code.google.com/p/chromium/issues/detail?id=470258
5620// for the description of the bug (it existed in older Chrome versions as well).
5621jQuery.each( {
5622	mouseenter: "mouseover",
5623	mouseleave: "mouseout",
5624	pointerenter: "pointerover",
5625	pointerleave: "pointerout"
5626}, function( orig, fix ) {
5627	jQuery.event.special[ orig ] = {
5628		delegateType: fix,
5629		bindType: fix,
5630
5631		handle: function( event ) {
5632			var ret,
5633				target = this,
5634				related = event.relatedTarget,
5635				handleObj = event.handleObj;
5636
5637			// For mouseenter/leave call the handler if related is outside the target.
5638			// NB: No relatedTarget if the mouse left/entered the browser window
5639			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5640				event.type = handleObj.origType;
5641				ret = handleObj.handler.apply( this, arguments );
5642				event.type = fix;
5643			}
5644			return ret;
5645		}
5646	};
5647} );
5648
5649// IE submit delegation
5650if ( !support.submit ) {
5651
5652	jQuery.event.special.submit = {
5653		setup: function() {
5654
5655			// Only need this for delegated form submit events
5656			if ( jQuery.nodeName( this, "form" ) ) {
5657				return false;
5658			}
5659
5660			// Lazy-add a submit handler when a descendant form may potentially be submitted
5661			jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
5662
5663				// Node name check avoids a VML-related crash in IE (#9807)
5664				var elem = e.target,
5665					form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ?
5666
5667						// Support: IE <=8
5668						// We use jQuery.prop instead of elem.form
5669						// to allow fixing the IE8 delegated submit issue (gh-2332)
5670						// by 3rd party polyfills/workarounds.
5671						jQuery.prop( elem, "form" ) :
5672						undefined;
5673
5674				if ( form && !jQuery._data( form, "submit" ) ) {
5675					jQuery.event.add( form, "submit._submit", function( event ) {
5676						event._submitBubble = true;
5677					} );
5678					jQuery._data( form, "submit", true );
5679				}
5680			} );
5681
5682			// return undefined since we don't need an event listener
5683		},
5684
5685		postDispatch: function( event ) {
5686
5687			// If form was submitted by the user, bubble the event up the tree
5688			if ( event._submitBubble ) {
5689				delete event._submitBubble;
5690				if ( this.parentNode && !event.isTrigger ) {
5691					jQuery.event.simulate( "submit", this.parentNode, event );
5692				}
5693			}
5694		},
5695
5696		teardown: function() {
5697
5698			// Only need this for delegated form submit events
5699			if ( jQuery.nodeName( this, "form" ) ) {
5700				return false;
5701			}
5702
5703			// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
5704			jQuery.event.remove( this, "._submit" );
5705		}
5706	};
5707}
5708
5709// IE change delegation and checkbox/radio fix
5710if ( !support.change ) {
5711
5712	jQuery.event.special.change = {
5713
5714		setup: function() {
5715
5716			if ( rformElems.test( this.nodeName ) ) {
5717
5718				// IE doesn't fire change on a check/radio until blur; trigger it on click
5719				// after a propertychange. Eat the blur-change in special.change.handle.
5720				// This still fires onchange a second time for check/radio after blur.
5721				if ( this.type === "checkbox" || this.type === "radio" ) {
5722					jQuery.event.add( this, "propertychange._change", function( event ) {
5723						if ( event.originalEvent.propertyName === "checked" ) {
5724							this._justChanged = true;
5725						}
5726					} );
5727					jQuery.event.add( this, "click._change", function( event ) {
5728						if ( this._justChanged && !event.isTrigger ) {
5729							this._justChanged = false;
5730						}
5731
5732						// Allow triggered, simulated change events (#11500)
5733						jQuery.event.simulate( "change", this, event );
5734					} );
5735				}
5736				return false;
5737			}
5738
5739			// Delegated event; lazy-add a change handler on descendant inputs
5740			jQuery.event.add( this, "beforeactivate._change", function( e ) {
5741				var elem = e.target;
5742
5743				if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "change" ) ) {
5744					jQuery.event.add( elem, "change._change", function( event ) {
5745						if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
5746							jQuery.event.simulate( "change", this.parentNode, event );
5747						}
5748					} );
5749					jQuery._data( elem, "change", true );
5750				}
5751			} );
5752		},
5753
5754		handle: function( event ) {
5755			var elem = event.target;
5756
5757			// Swallow native change events from checkbox/radio, we already triggered them above
5758			if ( this !== elem || event.isSimulated || event.isTrigger ||
5759				( elem.type !== "radio" && elem.type !== "checkbox" ) ) {
5760
5761				return event.handleObj.handler.apply( this, arguments );
5762			}
5763		},
5764
5765		teardown: function() {
5766			jQuery.event.remove( this, "._change" );
5767
5768			return !rformElems.test( this.nodeName );
5769		}
5770	};
5771}
5772
5773// Support: Firefox
5774// Firefox doesn't have focus(in | out) events
5775// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
5776//
5777// Support: Chrome, Safari
5778// focus(in | out) events fire after focus & blur events,
5779// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
5780// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
5781if ( !support.focusin ) {
5782	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5783
5784		// Attach a single capturing handler on the document while someone wants focusin/focusout
5785		var handler = function( event ) {
5786			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
5787		};
5788
5789		jQuery.event.special[ fix ] = {
5790			setup: function() {
5791				var doc = this.ownerDocument || this,
5792					attaches = jQuery._data( doc, fix );
5793
5794				if ( !attaches ) {
5795					doc.addEventListener( orig, handler, true );
5796				}
5797				jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
5798			},
5799			teardown: function() {
5800				var doc = this.ownerDocument || this,
5801					attaches = jQuery._data( doc, fix ) - 1;
5802
5803				if ( !attaches ) {
5804					doc.removeEventListener( orig, handler, true );
5805					jQuery._removeData( doc, fix );
5806				} else {
5807					jQuery._data( doc, fix, attaches );
5808				}
5809			}
5810		};
5811	} );
5812}
5813
5814jQuery.fn.extend( {
5815
5816	on: function( types, selector, data, fn ) {
5817		return on( this, types, selector, data, fn );
5818	},
5819	one: function( types, selector, data, fn ) {
5820		return on( this, types, selector, data, fn, 1 );
5821	},
5822	off: function( types, selector, fn ) {
5823		var handleObj, type;
5824		if ( types && types.preventDefault && types.handleObj ) {
5825
5826			// ( event )  dispatched jQuery.Event
5827			handleObj = types.handleObj;
5828			jQuery( types.delegateTarget ).off(
5829				handleObj.namespace ?
5830					handleObj.origType + "." + handleObj.namespace :
5831					handleObj.origType,
5832				handleObj.selector,
5833				handleObj.handler
5834			);
5835			return this;
5836		}
5837		if ( typeof types === "object" ) {
5838
5839			// ( types-object [, selector] )
5840			for ( type in types ) {
5841				this.off( type, selector, types[ type ] );
5842			}
5843			return this;
5844		}
5845		if ( selector === false || typeof selector === "function" ) {
5846
5847			// ( types [, fn] )
5848			fn = selector;
5849			selector = undefined;
5850		}
5851		if ( fn === false ) {
5852			fn = returnFalse;
5853		}
5854		return this.each( function() {
5855			jQuery.event.remove( this, types, fn, selector );
5856		} );
5857	},
5858
5859	trigger: function( type, data ) {
5860		return this.each( function() {
5861			jQuery.event.trigger( type, data, this );
5862		} );
5863	},
5864	triggerHandler: function( type, data ) {
5865		var elem = this[ 0 ];
5866		if ( elem ) {
5867			return jQuery.event.trigger( type, data, elem, true );
5868		}
5869	}
5870} );
5871
5872
5873var rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
5874	rnoshimcache = new RegExp( "<(?:" + nodeNames + ")[\\s/>]", "i" ),
5875	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5876
5877	// Support: IE 10-11, Edge 10240+
5878	// In IE/Edge using regex groups here causes severe slowdowns.
5879	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5880	rnoInnerhtml = /<script|<style|<link/i,
5881
5882	// checked="checked" or checked
5883	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5884	rscriptTypeMasked = /^true\/(.*)/,
5885	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5886	safeFragment = createSafeFragment( document ),
5887	fragmentDiv = safeFragment.appendChild( document.createElement( "div" ) );
5888
5889// Support: IE<8
5890// Manipulating tables requires a tbody
5891function manipulationTarget( elem, content ) {
5892	return jQuery.nodeName( elem, "table" ) &&
5893		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
5894
5895		elem.getElementsByTagName( "tbody" )[ 0 ] ||
5896			elem.appendChild( elem.ownerDocument.createElement( "tbody" ) ) :
5897		elem;
5898}
5899
5900// Replace/restore the type attribute of script elements for safe DOM manipulation
5901function disableScript( elem ) {
5902	elem.type = ( jQuery.find.attr( elem, "type" ) !== null ) + "/" + elem.type;
5903	return elem;
5904}
5905function restoreScript( elem ) {
5906	var match = rscriptTypeMasked.exec( elem.type );
5907	if ( match ) {
5908		elem.type = match[ 1 ];
5909	} else {
5910		elem.removeAttribute( "type" );
5911	}
5912	return elem;
5913}
5914
5915function cloneCopyEvent( src, dest ) {
5916	if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5917		return;
5918	}
5919
5920	var type, i, l,
5921		oldData = jQuery._data( src ),
5922		curData = jQuery._data( dest, oldData ),
5923		events = oldData.events;
5924
5925	if ( events ) {
5926		delete curData.handle;
5927		curData.events = {};
5928
5929		for ( type in events ) {
5930			for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5931				jQuery.event.add( dest, type, events[ type ][ i ] );
5932			}
5933		}
5934	}
5935
5936	// make the cloned public data object a copy from the original
5937	if ( curData.data ) {
5938		curData.data = jQuery.extend( {}, curData.data );
5939	}
5940}
5941
5942function fixCloneNodeIssues( src, dest ) {
5943	var nodeName, e, data;
5944
5945	// We do not need to do anything for non-Elements
5946	if ( dest.nodeType !== 1 ) {
5947		return;
5948	}
5949
5950	nodeName = dest.nodeName.toLowerCase();
5951
5952	// IE6-8 copies events bound via attachEvent when using cloneNode.
5953	if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
5954		data = jQuery._data( dest );
5955
5956		for ( e in data.events ) {
5957			jQuery.removeEvent( dest, e, data.handle );
5958		}
5959
5960		// Event data gets referenced instead of copied if the expando gets copied too
5961		dest.removeAttribute( jQuery.expando );
5962	}
5963
5964	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
5965	if ( nodeName === "script" && dest.text !== src.text ) {
5966		disableScript( dest ).text = src.text;
5967		restoreScript( dest );
5968
5969	// IE6-10 improperly clones children of object elements using classid.
5970	// IE10 throws NoModificationAllowedError if parent is null, #12132.
5971	} else if ( nodeName === "object" ) {
5972		if ( dest.parentNode ) {
5973			dest.outerHTML = src.outerHTML;
5974		}
5975
5976		// This path appears unavoidable for IE9. When cloning an object
5977		// element in IE9, the outerHTML strategy above is not sufficient.
5978		// If the src has innerHTML and the destination does not,
5979		// copy the src.innerHTML into the dest.innerHTML. #10324
5980		if ( support.html5Clone && ( src.innerHTML && !jQuery.trim( dest.innerHTML ) ) ) {
5981			dest.innerHTML = src.innerHTML;
5982		}
5983
5984	} else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5985
5986		// IE6-8 fails to persist the checked state of a cloned checkbox
5987		// or radio button. Worse, IE6-7 fail to give the cloned element
5988		// a checked appearance if the defaultChecked value isn't also set
5989
5990		dest.defaultChecked = dest.checked = src.checked;
5991
5992		// IE6-7 get confused and end up setting the value of a cloned
5993		// checkbox/radio button to an empty string instead of "on"
5994		if ( dest.value !== src.value ) {
5995			dest.value = src.value;
5996		}
5997
5998	// IE6-8 fails to return the selected option to the default selected
5999	// state when cloning options
6000	} else if ( nodeName === "option" ) {
6001		dest.defaultSelected = dest.selected = src.defaultSelected;
6002
6003	// IE6-8 fails to set the defaultValue to the correct value when
6004	// cloning other types of input fields
6005	} else if ( nodeName === "input" || nodeName === "textarea" ) {
6006		dest.defaultValue = src.defaultValue;
6007	}
6008}
6009
6010function domManip( collection, args, callback, ignored ) {
6011
6012	// Flatten any nested arrays
6013	args = concat.apply( [], args );
6014
6015	var first, node, hasScripts,
6016		scripts, doc, fragment,
6017		i = 0,
6018		l = collection.length,
6019		iNoClone = l - 1,
6020		value = args[ 0 ],
6021		isFunction = jQuery.isFunction( value );
6022
6023	// We can't cloneNode fragments that contain checked, in WebKit
6024	if ( isFunction ||
6025			( l > 1 && typeof value === "string" &&
6026				!support.checkClone && rchecked.test( value ) ) ) {
6027		return collection.each( function( index ) {
6028			var self = collection.eq( index );
6029			if ( isFunction ) {
6030				args[ 0 ] = value.call( this, index, self.html() );
6031			}
6032			domManip( self, args, callback, ignored );
6033		} );
6034	}
6035
6036	if ( l ) {
6037		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6038		first = fragment.firstChild;
6039
6040		if ( fragment.childNodes.length === 1 ) {
6041			fragment = first;
6042		}
6043
6044		// Require either new content or an interest in ignored elements to invoke the callback
6045		if ( first || ignored ) {
6046			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6047			hasScripts = scripts.length;
6048
6049			// Use the original fragment for the last item
6050			// instead of the first because it can end up
6051			// being emptied incorrectly in certain situations (#8070).
6052			for ( ; i < l; i++ ) {
6053				node = fragment;
6054
6055				if ( i !== iNoClone ) {
6056					node = jQuery.clone( node, true, true );
6057
6058					// Keep references to cloned scripts for later restoration
6059					if ( hasScripts ) {
6060
6061						// Support: Android<4.1, PhantomJS<2
6062						// push.apply(_, arraylike) throws on ancient WebKit
6063						jQuery.merge( scripts, getAll( node, "script" ) );
6064					}
6065				}
6066
6067				callback.call( collection[ i ], node, i );
6068			}
6069
6070			if ( hasScripts ) {
6071				doc = scripts[ scripts.length - 1 ].ownerDocument;
6072
6073				// Reenable scripts
6074				jQuery.map( scripts, restoreScript );
6075
6076				// Evaluate executable scripts on first document insertion
6077				for ( i = 0; i < hasScripts; i++ ) {
6078					node = scripts[ i ];
6079					if ( rscriptType.test( node.type || "" ) &&
6080						!jQuery._data( node, "globalEval" ) &&
6081						jQuery.contains( doc, node ) ) {
6082
6083						if ( node.src ) {
6084
6085							// Optional AJAX dependency, but won't run scripts if not present
6086							if ( jQuery._evalUrl ) {
6087								jQuery._evalUrl( node.src );
6088							}
6089						} else {
6090							jQuery.globalEval(
6091								( node.text || node.textContent || node.innerHTML || "" )
6092									.replace( rcleanScript, "" )
6093							);
6094						}
6095					}
6096				}
6097			}
6098
6099			// Fix #11809: Avoid leaking memory
6100			fragment = first = null;
6101		}
6102	}
6103
6104	return collection;
6105}
6106
6107function remove( elem, selector, keepData ) {
6108	var node,
6109		elems = selector ? jQuery.filter( selector, elem ) : elem,
6110		i = 0;
6111
6112	for ( ; ( node = elems[ i ] ) != null; i++ ) {
6113
6114		if ( !keepData && node.nodeType === 1 ) {
6115			jQuery.cleanData( getAll( node ) );
6116		}
6117
6118		if ( node.parentNode ) {
6119			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
6120				setGlobalEval( getAll( node, "script" ) );
6121			}
6122			node.parentNode.removeChild( node );
6123		}
6124	}
6125
6126	return elem;
6127}
6128
6129jQuery.extend( {
6130	htmlPrefilter: function( html ) {
6131		return html.replace( rxhtmlTag, "<$1></$2>" );
6132	},
6133
6134	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6135		var destElements, node, clone, i, srcElements,
6136			inPage = jQuery.contains( elem.ownerDocument, elem );
6137
6138		if ( support.html5Clone || jQuery.isXMLDoc( elem ) ||
6139			!rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
6140
6141			clone = elem.cloneNode( true );
6142
6143		// IE<=8 does not properly clone detached, unknown element nodes
6144		} else {
6145			fragmentDiv.innerHTML = elem.outerHTML;
6146			fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
6147		}
6148
6149		if ( ( !support.noCloneEvent || !support.noCloneChecked ) &&
6150				( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
6151
6152			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
6153			destElements = getAll( clone );
6154			srcElements = getAll( elem );
6155
6156			// Fix all IE cloning issues
6157			for ( i = 0; ( node = srcElements[ i ] ) != null; ++i ) {
6158
6159				// Ensure that the destination node is not null; Fixes #9587
6160				if ( destElements[ i ] ) {
6161					fixCloneNodeIssues( node, destElements[ i ] );
6162				}
6163			}
6164		}
6165
6166		// Copy the events from the original to the clone
6167		if ( dataAndEvents ) {
6168			if ( deepDataAndEvents ) {
6169				srcElements = srcElements || getAll( elem );
6170				destElements = destElements || getAll( clone );
6171
6172				for ( i = 0; ( node = srcElements[ i ] ) != null; i++ ) {
6173					cloneCopyEvent( node, destElements[ i ] );
6174				}
6175			} else {
6176				cloneCopyEvent( elem, clone );
6177			}
6178		}
6179
6180		// Preserve script evaluation history
6181		destElements = getAll( clone, "script" );
6182		if ( destElements.length > 0 ) {
6183			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6184		}
6185
6186		destElements = srcElements = node = null;
6187
6188		// Return the cloned set
6189		return clone;
6190	},
6191
6192	cleanData: function( elems, /* internal */ forceAcceptData ) {
6193		var elem, type, id, data,
6194			i = 0,
6195			internalKey = jQuery.expando,
6196			cache = jQuery.cache,
6197			attributes = support.attributes,
6198			special = jQuery.event.special;
6199
6200		for ( ; ( elem = elems[ i ] ) != null; i++ ) {
6201			if ( forceAcceptData || acceptData( elem ) ) {
6202
6203				id = elem[ internalKey ];
6204				data = id && cache[ id ];
6205
6206				if ( data ) {
6207					if ( data.events ) {
6208						for ( type in data.events ) {
6209							if ( special[ type ] ) {
6210								jQuery.event.remove( elem, type );
6211
6212							// This is a shortcut to avoid jQuery.event.remove's overhead
6213							} else {
6214								jQuery.removeEvent( elem, type, data.handle );
6215							}
6216						}
6217					}
6218
6219					// Remove cache only if it was not already removed by jQuery.event.remove
6220					if ( cache[ id ] ) {
6221
6222						delete cache[ id ];
6223
6224						// Support: IE<9
6225						// IE does not allow us to delete expando properties from nodes
6226						// IE creates expando attributes along with the property
6227						// IE does not have a removeAttribute function on Document nodes
6228						if ( !attributes && typeof elem.removeAttribute !== "undefined" ) {
6229							elem.removeAttribute( internalKey );
6230
6231						// Webkit & Blink performance suffers when deleting properties
6232						// from DOM nodes, so set to undefined instead
6233						// https://code.google.com/p/chromium/issues/detail?id=378607
6234						} else {
6235							elem[ internalKey ] = undefined;
6236						}
6237
6238						deletedIds.push( id );
6239					}
6240				}
6241			}
6242		}
6243	}
6244} );
6245
6246jQuery.fn.extend( {
6247
6248	// Keep domManip exposed until 3.0 (gh-2225)
6249	domManip: domManip,
6250
6251	detach: function( selector ) {
6252		return remove( this, selector, true );
6253	},
6254
6255	remove: function( selector ) {
6256		return remove( this, selector );
6257	},
6258
6259	text: function( value ) {
6260		return access( this, function( value ) {
6261			return value === undefined ?
6262				jQuery.text( this ) :
6263				this.empty().append(
6264					( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value )
6265				);
6266		}, null, value, arguments.length );
6267	},
6268
6269	append: function() {
6270		return domManip( this, arguments, function( elem ) {
6271			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6272				var target = manipulationTarget( this, elem );
6273				target.appendChild( elem );
6274			}
6275		} );
6276	},
6277
6278	prepend: function() {
6279		return domManip( this, arguments, function( elem ) {
6280			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6281				var target = manipulationTarget( this, elem );
6282				target.insertBefore( elem, target.firstChild );
6283			}
6284		} );
6285	},
6286
6287	before: function() {
6288		return domManip( this, arguments, function( elem ) {
6289			if ( this.parentNode ) {
6290				this.parentNode.insertBefore( elem, this );
6291			}
6292		} );
6293	},
6294
6295	after: function() {
6296		return domManip( this, arguments, function( elem ) {
6297			if ( this.parentNode ) {
6298				this.parentNode.insertBefore( elem, this.nextSibling );
6299			}
6300		} );
6301	},
6302
6303	empty: function() {
6304		var elem,
6305			i = 0;
6306
6307		for ( ; ( elem = this[ i ] ) != null; i++ ) {
6308
6309			// Remove element nodes and prevent memory leaks
6310			if ( elem.nodeType === 1 ) {
6311				jQuery.cleanData( getAll( elem, false ) );
6312			}
6313
6314			// Remove any remaining nodes
6315			while ( elem.firstChild ) {
6316				elem.removeChild( elem.firstChild );
6317			}
6318
6319			// If this is a select, ensure that it displays empty (#12336)
6320			// Support: IE<9
6321			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
6322				elem.options.length = 0;
6323			}
6324		}
6325
6326		return this;
6327	},
6328
6329	clone: function( dataAndEvents, deepDataAndEvents ) {
6330		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6331		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6332
6333		return this.map( function() {
6334			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6335		} );
6336	},
6337
6338	html: function( value ) {
6339		return access( this, function( value ) {
6340			var elem = this[ 0 ] || {},
6341				i = 0,
6342				l = this.length;
6343
6344			if ( value === undefined ) {
6345				return elem.nodeType === 1 ?
6346					elem.innerHTML.replace( rinlinejQuery, "" ) :
6347					undefined;
6348			}
6349
6350			// See if we can take a shortcut and just use innerHTML
6351			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6352				( support.htmlSerialize || !rnoshimcache.test( value )  ) &&
6353				( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
6354				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6355
6356				value = jQuery.htmlPrefilter( value );
6357
6358				try {
6359					for ( ; i < l; i++ ) {
6360
6361						// Remove element nodes and prevent memory leaks
6362						elem = this[ i ] || {};
6363						if ( elem.nodeType === 1 ) {
6364							jQuery.cleanData( getAll( elem, false ) );
6365							elem.innerHTML = value;
6366						}
6367					}
6368
6369					elem = 0;
6370
6371				// If using innerHTML throws an exception, use the fallback method
6372				} catch ( e ) {}
6373			}
6374
6375			if ( elem ) {
6376				this.empty().append( value );
6377			}
6378		}, null, value, arguments.length );
6379	},
6380
6381	replaceWith: function() {
6382		var ignored = [];
6383
6384		// Make the changes, replacing each non-ignored context element with the new content
6385		return domManip( this, arguments, function( elem ) {
6386			var parent = this.parentNode;
6387
6388			if ( jQuery.inArray( this, ignored ) < 0 ) {
6389				jQuery.cleanData( getAll( this ) );
6390				if ( parent ) {
6391					parent.replaceChild( elem, this );
6392				}
6393			}
6394
6395		// Force callback invocation
6396		}, ignored );
6397	}
6398} );
6399
6400jQuery.each( {
6401	appendTo: "append",
6402	prependTo: "prepend",
6403	insertBefore: "before",
6404	insertAfter: "after",
6405	replaceAll: "replaceWith"
6406}, function( name, original ) {
6407	jQuery.fn[ name ] = function( selector ) {
6408		var elems,
6409			i = 0,
6410			ret = [],
6411			insert = jQuery( selector ),
6412			last = insert.length - 1;
6413
6414		for ( ; i <= last; i++ ) {
6415			elems = i === last ? this : this.clone( true );
6416			jQuery( insert[ i ] )[ original ]( elems );
6417
6418			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
6419			push.apply( ret, elems.get() );
6420		}
6421
6422		return this.pushStack( ret );
6423	};
6424} );
6425
6426
6427var iframe,
6428	elemdisplay = {
6429
6430		// Support: Firefox
6431		// We have to pre-define these values for FF (#10227)
6432		HTML: "block",
6433		BODY: "block"
6434	};
6435
6436/**
6437 * Retrieve the actual display of a element
6438 * @param {String} name nodeName of the element
6439 * @param {Object} doc Document object
6440 */
6441
6442// Called only from within defaultDisplay
6443function actualDisplay( name, doc ) {
6444	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6445
6446		display = jQuery.css( elem[ 0 ], "display" );
6447
6448	// We don't have any data stored on the element,
6449	// so use "detach" method as fast way to get rid of the element
6450	elem.detach();
6451
6452	return display;
6453}
6454
6455/**
6456 * Try to determine the default display value of an element
6457 * @param {String} nodeName
6458 */
6459function defaultDisplay( nodeName ) {
6460	var doc = document,
6461		display = elemdisplay[ nodeName ];
6462
6463	if ( !display ) {
6464		display = actualDisplay( nodeName, doc );
6465
6466		// If the simple way fails, read from inside an iframe
6467		if ( display === "none" || !display ) {
6468
6469			// Use the already-created iframe if possible
6470			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
6471				.appendTo( doc.documentElement );
6472
6473			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6474			doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
6475
6476			// Support: IE
6477			doc.write();
6478			doc.close();
6479
6480			display = actualDisplay( nodeName, doc );
6481			iframe.detach();
6482		}
6483
6484		// Store the correct default display
6485		elemdisplay[ nodeName ] = display;
6486	}
6487
6488	return display;
6489}
6490var rmargin = ( /^margin/ );
6491
6492var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6493
6494var swap = function( elem, options, callback, args ) {
6495	var ret, name,
6496		old = {};
6497
6498	// Remember the old values, and insert the new ones
6499	for ( name in options ) {
6500		old[ name ] = elem.style[ name ];
6501		elem.style[ name ] = options[ name ];
6502	}
6503
6504	ret = callback.apply( elem, args || [] );
6505
6506	// Revert the old values
6507	for ( name in options ) {
6508		elem.style[ name ] = old[ name ];
6509	}
6510
6511	return ret;
6512};
6513
6514
6515var documentElement = document.documentElement;
6516
6517
6518
6519( function() {
6520	var pixelPositionVal, pixelMarginRightVal, boxSizingReliableVal,
6521		reliableHiddenOffsetsVal, reliableMarginRightVal, reliableMarginLeftVal,
6522		container = document.createElement( "div" ),
6523		div = document.createElement( "div" );
6524
6525	// Finish early in limited (non-browser) environments
6526	if ( !div.style ) {
6527		return;
6528	}
6529
6530	div.style.cssText = "float:left;opacity:.5";
6531
6532	// Support: IE<9
6533	// Make sure that element opacity exists (as opposed to filter)
6534	support.opacity = div.style.opacity === "0.5";
6535
6536	// Verify style float existence
6537	// (IE uses styleFloat instead of cssFloat)
6538	support.cssFloat = !!div.style.cssFloat;
6539
6540	div.style.backgroundClip = "content-box";
6541	div.cloneNode( true ).style.backgroundClip = "";
6542	support.clearCloneStyle = div.style.backgroundClip === "content-box";
6543
6544	container = document.createElement( "div" );
6545	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
6546		"padding:0;margin-top:1px;position:absolute";
6547	div.innerHTML = "";
6548	container.appendChild( div );
6549
6550	// Support: Firefox<29, Android 2.3
6551	// Vendor-prefix box-sizing
6552	support.boxSizing = div.style.boxSizing === "" || div.style.MozBoxSizing === "" ||
6553		div.style.WebkitBoxSizing === "";
6554
6555	jQuery.extend( support, {
6556		reliableHiddenOffsets: function() {
6557			if ( pixelPositionVal == null ) {
6558				computeStyleTests();
6559			}
6560			return reliableHiddenOffsetsVal;
6561		},
6562
6563		boxSizingReliable: function() {
6564
6565			// We're checking for pixelPositionVal here instead of boxSizingReliableVal
6566			// since that compresses better and they're computed together anyway.
6567			if ( pixelPositionVal == null ) {
6568				computeStyleTests();
6569			}
6570			return boxSizingReliableVal;
6571		},
6572
6573		pixelMarginRight: function() {
6574
6575			// Support: Android 4.0-4.3
6576			if ( pixelPositionVal == null ) {
6577				computeStyleTests();
6578			}
6579			return pixelMarginRightVal;
6580		},
6581
6582		pixelPosition: function() {
6583			if ( pixelPositionVal == null ) {
6584				computeStyleTests();
6585			}
6586			return pixelPositionVal;
6587		},
6588
6589		reliableMarginRight: function() {
6590
6591			// Support: Android 2.3
6592			if ( pixelPositionVal == null ) {
6593				computeStyleTests();
6594			}
6595			return reliableMarginRightVal;
6596		},
6597
6598		reliableMarginLeft: function() {
6599
6600			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
6601			if ( pixelPositionVal == null ) {
6602				computeStyleTests();
6603			}
6604			return reliableMarginLeftVal;
6605		}
6606	} );
6607
6608	function computeStyleTests() {
6609		var contents, divStyle,
6610			documentElement = document.documentElement;
6611
6612		// Setup
6613		documentElement.appendChild( container );
6614
6615		div.style.cssText =
6616
6617			// Support: Android 2.3
6618			// Vendor-prefix box-sizing
6619			"-webkit-box-sizing:border-box;box-sizing:border-box;" +
6620			"position:relative;display:block;" +
6621			"margin:auto;border:1px;padding:1px;" +
6622			"top:1%;width:50%";
6623
6624		// Support: IE<9
6625		// Assume reasonable values in the absence of getComputedStyle
6626		pixelPositionVal = boxSizingReliableVal = reliableMarginLeftVal = false;
6627		pixelMarginRightVal = reliableMarginRightVal = true;
6628
6629		// Check for getComputedStyle so that this code is not run in IE<9.
6630		if ( window.getComputedStyle ) {
6631			divStyle = window.getComputedStyle( div );
6632			pixelPositionVal = ( divStyle || {} ).top !== "1%";
6633			reliableMarginLeftVal = ( divStyle || {} ).marginLeft === "2px";
6634			boxSizingReliableVal = ( divStyle || { width: "4px" } ).width === "4px";
6635
6636			// Support: Android 4.0 - 4.3 only
6637			// Some styles come back with percentage values, even though they shouldn't
6638			div.style.marginRight = "50%";
6639			pixelMarginRightVal = ( divStyle || { marginRight: "4px" } ).marginRight === "4px";
6640
6641			// Support: Android 2.3 only
6642			// Div with explicit width and no margin-right incorrectly
6643			// gets computed margin-right based on width of container (#3333)
6644			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6645			contents = div.appendChild( document.createElement( "div" ) );
6646
6647			// Reset CSS: box-sizing; display; margin; border; padding
6648			contents.style.cssText = div.style.cssText =
6649
6650				// Support: Android 2.3
6651				// Vendor-prefix box-sizing
6652				"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
6653				"box-sizing:content-box;display:block;margin:0;border:0;padding:0";
6654			contents.style.marginRight = contents.style.width = "0";
6655			div.style.width = "1px";
6656
6657			reliableMarginRightVal =
6658				!parseFloat( ( window.getComputedStyle( contents ) || {} ).marginRight );
6659
6660			div.removeChild( contents );
6661		}
6662
6663		// Support: IE6-8
6664		// First check that getClientRects works as expected
6665		// Check if table cells still have offsetWidth/Height when they are set
6666		// to display:none and there are still other visible table cells in a
6667		// table row; if so, offsetWidth/Height are not reliable for use when
6668		// determining if an element has been hidden directly using
6669		// display:none (it is still safe to use offsets if a parent element is
6670		// hidden; don safety goggles and see bug #4512 for more information).
6671		div.style.display = "none";
6672		reliableHiddenOffsetsVal = div.getClientRects().length === 0;
6673		if ( reliableHiddenOffsetsVal ) {
6674			div.style.display = "";
6675			div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
6676			div.childNodes[ 0 ].style.borderCollapse = "separate";
6677			contents = div.getElementsByTagName( "td" );
6678			contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
6679			reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6680			if ( reliableHiddenOffsetsVal ) {
6681				contents[ 0 ].style.display = "";
6682				contents[ 1 ].style.display = "none";
6683				reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
6684			}
6685		}
6686
6687		// Teardown
6688		documentElement.removeChild( container );
6689	}
6690
6691} )();
6692
6693
6694var getStyles, curCSS,
6695	rposition = /^(top|right|bottom|left)$/;
6696
6697if ( window.getComputedStyle ) {
6698	getStyles = function( elem ) {
6699
6700		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
6701		// IE throws on elements created in popups
6702		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6703		var view = elem.ownerDocument.defaultView;
6704
6705		if ( !view || !view.opener ) {
6706			view = window;
6707		}
6708
6709		return view.getComputedStyle( elem );
6710	};
6711
6712	curCSS = function( elem, name, computed ) {
6713		var width, minWidth, maxWidth, ret,
6714			style = elem.style;
6715
6716		computed = computed || getStyles( elem );
6717
6718		// getPropertyValue is only needed for .css('filter') in IE9, see #12537
6719		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
6720
6721		// Support: Opera 12.1x only
6722		// Fall back to style even without computed
6723		// computed is undefined for elems on document fragments
6724		if ( ( ret === "" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {
6725			ret = jQuery.style( elem, name );
6726		}
6727
6728		if ( computed ) {
6729
6730			// A tribute to the "awesome hack by Dean Edwards"
6731			// Chrome < 17 and Safari 5.0 uses "computed value"
6732			// instead of "used value" for margin-right
6733			// Safari 5.1.7 (at least) returns percentage for a larger set of values,
6734			// but width seems to be reliably pixels
6735			// this is against the CSSOM draft spec:
6736			// http://dev.w3.org/csswg/cssom/#resolved-values
6737			if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6738
6739				// Remember the original values
6740				width = style.width;
6741				minWidth = style.minWidth;
6742				maxWidth = style.maxWidth;
6743
6744				// Put in the new values to get a computed value out
6745				style.minWidth = style.maxWidth = style.width = ret;
6746				ret = computed.width;
6747
6748				// Revert the changed values
6749				style.width = width;
6750				style.minWidth = minWidth;
6751				style.maxWidth = maxWidth;
6752			}
6753		}
6754
6755		// Support: IE
6756		// IE returns zIndex value as an integer.
6757		return ret === undefined ?
6758			ret :
6759			ret + "";
6760	};
6761} else if ( documentElement.currentStyle ) {
6762	getStyles = function( elem ) {
6763		return elem.currentStyle;
6764	};
6765
6766	curCSS = function( elem, name, computed ) {
6767		var left, rs, rsLeft, ret,
6768			style = elem.style;
6769
6770		computed = computed || getStyles( elem );
6771		ret = computed ? computed[ name ] : undefined;
6772
6773		// Avoid setting ret to empty string here
6774		// so we don't default to auto
6775		if ( ret == null && style && style[ name ] ) {
6776			ret = style[ name ];
6777		}
6778
6779		// From the awesome hack by Dean Edwards
6780		// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6781
6782		// If we're not dealing with a regular pixel number
6783		// but a number that has a weird ending, we need to convert it to pixels
6784		// but not position css attributes, as those are
6785		// proportional to the parent element instead
6786		// and we can't measure the parent instead because it
6787		// might trigger a "stacking dolls" problem
6788		if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
6789
6790			// Remember the original values
6791			left = style.left;
6792			rs = elem.runtimeStyle;
6793			rsLeft = rs && rs.left;
6794
6795			// Put in the new values to get a computed value out
6796			if ( rsLeft ) {
6797				rs.left = elem.currentStyle.left;
6798			}
6799			style.left = name === "fontSize" ? "1em" : ret;
6800			ret = style.pixelLeft + "px";
6801
6802			// Revert the changed values
6803			style.left = left;
6804			if ( rsLeft ) {
6805				rs.left = rsLeft;
6806			}
6807		}
6808
6809		// Support: IE
6810		// IE returns zIndex value as an integer.
6811		return ret === undefined ?
6812			ret :
6813			ret + "" || "auto";
6814	};
6815}
6816
6817
6818
6819
6820function addGetHookIf( conditionFn, hookFn ) {
6821
6822	// Define the hook, we'll check on the first run if it's really needed.
6823	return {
6824		get: function() {
6825			if ( conditionFn() ) {
6826
6827				// Hook not needed (or it's not possible to use it due
6828				// to missing dependency), remove it.
6829				delete this.get;
6830				return;
6831			}
6832
6833			// Hook needed; redefine it so that the support test is not executed again.
6834			return ( this.get = hookFn ).apply( this, arguments );
6835		}
6836	};
6837}
6838
6839
6840var
6841
6842		ralpha = /alpha\([^)]*\)/i,
6843	ropacity = /opacity\s*=\s*([^)]*)/i,
6844
6845	// swappable if display is none or starts with table except
6846	// "table", "table-cell", or "table-caption"
6847	// see here for display values:
6848	// https://developer.mozilla.org/en-US/docs/CSS/display
6849	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6850	rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
6851
6852	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6853	cssNormalTransform = {
6854		letterSpacing: "0",
6855		fontWeight: "400"
6856	},
6857
6858	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
6859	emptyStyle = document.createElement( "div" ).style;
6860
6861
6862// return a css property mapped to a potentially vendor prefixed property
6863function vendorPropName( name ) {
6864
6865	// shortcut for names that are not vendor prefixed
6866	if ( name in emptyStyle ) {
6867		return name;
6868	}
6869
6870	// check for vendor prefixed names
6871	var capName = name.charAt( 0 ).toUpperCase() + name.slice( 1 ),
6872		i = cssPrefixes.length;
6873
6874	while ( i-- ) {
6875		name = cssPrefixes[ i ] + capName;
6876		if ( name in emptyStyle ) {
6877			return name;
6878		}
6879	}
6880}
6881
6882function showHide( elements, show ) {
6883	var display, elem, hidden,
6884		values = [],
6885		index = 0,
6886		length = elements.length;
6887
6888	for ( ; index < length; index++ ) {
6889		elem = elements[ index ];
6890		if ( !elem.style ) {
6891			continue;
6892		}
6893
6894		values[ index ] = jQuery._data( elem, "olddisplay" );
6895		display = elem.style.display;
6896		if ( show ) {
6897
6898			// Reset the inline display of this element to learn if it is
6899			// being hidden by cascaded rules or not
6900			if ( !values[ index ] && display === "none" ) {
6901				elem.style.display = "";
6902			}
6903
6904			// Set elements which have been overridden with display: none
6905			// in a stylesheet to whatever the default browser style is
6906			// for such an element
6907			if ( elem.style.display === "" && isHidden( elem ) ) {
6908				values[ index ] =
6909					jQuery._data( elem, "olddisplay", defaultDisplay( elem.nodeName ) );
6910			}
6911		} else {
6912			hidden = isHidden( elem );
6913
6914			if ( display && display !== "none" || !hidden ) {
6915				jQuery._data(
6916					elem,
6917					"olddisplay",
vendor: 6,043 bytes, lines 6918-7129
6918					hidden ? display : jQuery.css( elem, "display" )
6919				);
6920			}
6921		}
6922	}
6923
6924	// Set the display of most of the elements in a second loop
6925	// to avoid the constant reflow
6926	for ( index = 0; index < length; index++ ) {
6927		elem = elements[ index ];
6928		if ( !elem.style ) {
6929			continue;
6930		}
6931		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6932			elem.style.display = show ? values[ index ] || "" : "none";
6933		}
6934	}
6935
6936	return elements;
6937}
6938
6939function setPositiveNumber( elem, value, subtract ) {
6940	var matches = rnumsplit.exec( value );
6941	return matches ?
6942
6943		// Guard against undefined "subtract", e.g., when used as in cssHooks
6944		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6945		value;
6946}
6947
6948function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6949	var i = extra === ( isBorderBox ? "border" : "content" ) ?
6950
6951		// If we already have the right measurement, avoid augmentation
6952		4 :
6953
6954		// Otherwise initialize for horizontal or vertical properties
6955		name === "width" ? 1 : 0,
6956
6957		val = 0;
6958
6959	for ( ; i < 4; i += 2 ) {
6960
6961		// both box models exclude margin, so add it if we want it
6962		if ( extra === "margin" ) {
6963			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6964		}
6965
6966		if ( isBorderBox ) {
6967
6968			// border-box includes padding, so remove it if we want content
6969			if ( extra === "content" ) {
6970				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6971			}
6972
6973			// at this point, extra isn't border nor margin, so remove border
6974			if ( extra !== "margin" ) {
6975				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6976			}
6977		} else {
6978
6979			// at this point, extra isn't content, so add padding
6980			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6981
6982			// at this point, extra isn't content nor padding, so add border
6983			if ( extra !== "padding" ) {
6984				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6985			}
6986		}
6987	}
6988
6989	return val;
6990}
6991
6992function getWidthOrHeight( elem, name, extra ) {
6993
6994	// Start with offset property, which is equivalent to the border-box value
6995	var valueIsBorderBox = true,
6996		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6997		styles = getStyles( elem ),
6998		isBorderBox = support.boxSizing &&
6999			jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
7000
7001	// some non-html elements return undefined for offsetWidth, so check for null/undefined
7002	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
7003	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
7004	if ( val <= 0 || val == null ) {
7005
7006		// Fall back to computed then uncomputed css if necessary
7007		val = curCSS( elem, name, styles );
7008		if ( val < 0 || val == null ) {
7009			val = elem.style[ name ];
7010		}
7011
7012		// Computed unit is not pixels. Stop here and return.
7013		if ( rnumnonpx.test( val ) ) {
7014			return val;
7015		}
7016
7017		// we need the check for style in case a browser which returns unreliable values
7018		// for getComputedStyle silently falls back to the reliable elem.style
7019		valueIsBorderBox = isBorderBox &&
7020			( support.boxSizingReliable() || val === elem.style[ name ] );
7021
7022		// Normalize "", auto, and prepare for extra
7023		val = parseFloat( val ) || 0;
7024	}
7025
7026	// use the active box-sizing model to add/subtract irrelevant styles
7027	return ( val +
7028		augmentWidthOrHeight(
7029			elem,
7030			name,
7031			extra || ( isBorderBox ? "border" : "content" ),
7032			valueIsBorderBox,
7033			styles
7034		)
7035	) + "px";
7036}
7037
7038jQuery.extend( {
7039
7040	// Add in style property hooks for overriding the default
7041	// behavior of getting and setting a style property
7042	cssHooks: {
7043		opacity: {
7044			get: function( elem, computed ) {
7045				if ( computed ) {
7046
7047					// We should always get a number back from opacity
7048					var ret = curCSS( elem, "opacity" );
7049					return ret === "" ? "1" : ret;
7050				}
7051			}
7052		}
7053	},
7054
7055	// Don't automatically add "px" to these possibly-unitless properties
7056	cssNumber: {
7057		"animationIterationCount": true,
7058		"columnCount": true,
7059		"fillOpacity": true,
7060		"flexGrow": true,
7061		"flexShrink": true,
7062		"fontWeight": true,
7063		"lineHeight": true,
7064		"opacity": true,
7065		"order": true,
7066		"orphans": true,
7067		"widows": true,
7068		"zIndex": true,
7069		"zoom": true
7070	},
7071
7072	// Add in properties whose names you wish to fix before
7073	// setting or getting the value
7074	cssProps: {
7075
7076		// normalize float css property
7077		"float": support.cssFloat ? "cssFloat" : "styleFloat"
7078	},
7079
7080	// Get and set the style property on a DOM Node
7081	style: function( elem, name, value, extra ) {
7082
7083		// Don't set styles on text and comment nodes
7084		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7085			return;
7086		}
7087
7088		// Make sure that we're working with the right name
7089		var ret, type, hooks,
7090			origName = jQuery.camelCase( name ),
7091			style = elem.style;
7092
7093		name = jQuery.cssProps[ origName ] ||
7094			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7095
7096		// gets hook for the prefixed version
7097		// followed by the unprefixed version
7098		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7099
7100		// Check if we're setting a value
7101		if ( value !== undefined ) {
7102			type = typeof value;
7103
7104			// Convert "+=" or "-=" to relative numbers (#7345)
7105			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7106				value = adjustCSS( elem, name, ret );
7107
7108				// Fixes bug #9237
7109				type = "number";
7110			}
7111
7112			// Make sure that null and NaN values aren't set. See: #7116
7113			if ( value == null || value !== value ) {
7114				return;
7115			}
7116
7117			// If a number was passed in, add the unit (except for certain CSS properties)
7118			if ( type === "number" ) {
7119				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7120			}
7121
7122			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
7123			// but it would mean to define eight
7124			// (for every problematic property) identical functions
7125			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7126				style[ name ] = "inherit";
7127			}
7128
7129			// If a hook was provided, use that value, otherwise just set the specified value
7130			if ( !hooks || !( "set" in hooks ) ||
7131				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7132
7133				// Support: IE
7134				// Swallow errors from 'invalid' CSS values (#5509)
7135				try {
7136					style[ name ] = value;
7137				} catch ( e ) {}
7138			}
7139
7140		} else {
7141
7142			// If a hook was provided get the non-computed value from there
7143			if ( hooks && "get" in hooks &&
7144				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7145
7146				return ret;
7147			}
7148
7149			// Otherwise just get the value from the style object
7150			return style[ name ];
7151		}
7152	},
7153
7154	css: function( elem, name, extra, styles ) {
7155		var num, val, hooks,
7156			origName = jQuery.camelCase( name );
7157
7158		// Make sure that we're working with the right name
7159		name = jQuery.cssProps[ origName ] ||
7160			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
7161
7162		// gets hook for the prefixed version
7163		// followed by the unprefixed version
7164		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7165
7166		// If a hook was provided get the computed value from there
7167		if ( hooks && "get" in hooks ) {
7168			val = hooks.get( elem, true, extra );
7169		}
7170
7171		// Otherwise, if a way to get the computed value exists, use that
7172		if ( val === undefined ) {
7173			val = curCSS( elem, name, styles );
7174		}
7175
7176		//convert "normal" to computed value
7177		if ( val === "normal" && name in cssNormalTransform ) {
7178			val = cssNormalTransform[ name ];
7179		}
7180
7181		// Return, converting to number if forced or a qualifier was provided and val looks numeric
7182		if ( extra === "" || extra ) {
7183			num = parseFloat( val );
7184			return extra === true || isFinite( num ) ? num || 0 : val;
7185		}
7186		return val;
7187	}
7188} );
7189
7190jQuery.each( [ "height", "width" ], function( i, name ) {
7191	jQuery.cssHooks[ name ] = {
7192		get: function( elem, computed, extra ) {
7193			if ( computed ) {
7194
7195				// certain elements can have dimension info if we invisibly show them
7196				// however, it must have a current display style that would benefit from this
7197				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7198					elem.offsetWidth === 0 ?
7199						swap( elem, cssShow, function() {
7200							return getWidthOrHeight( elem, name, extra );
7201						} ) :
7202						getWidthOrHeight( elem, name, extra );
7203			}
7204		},
7205
7206		set: function( elem, value, extra ) {
7207			var styles = extra && getStyles( elem );
7208			return setPositiveNumber( elem, value, extra ?
7209				augmentWidthOrHeight(
7210					elem,
7211					name,
7212					extra,
7213					support.boxSizing &&
7214						jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7215					styles
7216				) : 0
7217			);
7218		}
7219	};
7220} );
7221
7222if ( !support.opacity ) {
7223	jQuery.cssHooks.opacity = {
7224		get: function( elem, computed ) {
7225
7226			// IE uses filters for opacity
7227			return ropacity.test( ( computed && elem.currentStyle ?
7228				elem.currentStyle.filter :
7229				elem.style.filter ) || "" ) ?
7230					( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
7231					computed ? "1" : "";
7232		},
7233
7234		set: function( elem, value ) {
7235			var style = elem.style,
7236				currentStyle = elem.currentStyle,
7237				opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
7238				filter = currentStyle && currentStyle.filter || style.filter || "";
7239
7240			// IE has trouble with opacity if it does not have layout
7241			// Force it by setting the zoom level
7242			style.zoom = 1;
7243
7244			// if setting opacity to 1, and no other filters exist -
7245			// attempt to remove filter attribute #6652
7246			// if value === "", then remove inline opacity #12685
7247			if ( ( value >= 1 || value === "" ) &&
7248					jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
7249					style.removeAttribute ) {
7250
7251				// Setting style.filter to null, "" & " " still leave "filter:" in the cssText
7252				// if "filter:" is present at all, clearType is disabled, we want to avoid this
7253				// style.removeAttribute is IE Only, but so apparently is this code path...
7254				style.removeAttribute( "filter" );
7255
7256				// if there is no filter style applied in a css rule
7257				// or unset inline opacity, we are done
7258				if ( value === "" || currentStyle && !currentStyle.filter ) {
7259					return;
7260				}
7261			}
7262
7263			// otherwise, set new filter values
7264			style.filter = ralpha.test( filter ) ?
7265				filter.replace( ralpha, opacity ) :
7266				filter + " " + opacity;
7267		}
7268	};
7269}
7270
7271jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
7272	function( elem, computed ) {
7273		if ( computed ) {
7274			return swap( elem, { "display": "inline-block" },
7275				curCSS, [ elem, "marginRight" ] );
7276		}
7277	}
7278);
7279
7280jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7281	function( elem, computed ) {
7282		if ( computed ) {
7283			return (
7284				parseFloat( curCSS( elem, "marginLeft" ) ) ||
7285
vendor: 4,625 bytes, lines 7286-7464
7286				// Support: IE<=11+
7287				// Running getBoundingClientRect on a disconnected node in IE throws an error
7288				// Support: IE8 only
7289				// getClientRects() errors on disconnected elems
7290				( jQuery.contains( elem.ownerDocument, elem ) ?
7291					elem.getBoundingClientRect().left -
7292						swap( elem, { marginLeft: 0 }, function() {
7293							return elem.getBoundingClientRect().left;
7294						} ) :
7295					0
7296				)
7297			) + "px";
7298		}
7299	}
7300);
7301
7302// These hooks are used by animate to expand properties
7303jQuery.each( {
7304	margin: "",
7305	padding: "",
7306	border: "Width"
7307}, function( prefix, suffix ) {
7308	jQuery.cssHooks[ prefix + suffix ] = {
7309		expand: function( value ) {
7310			var i = 0,
7311				expanded = {},
7312
7313				// assumes a single number if not a string
7314				parts = typeof value === "string" ? value.split( " " ) : [ value ];
7315
7316			for ( ; i < 4; i++ ) {
7317				expanded[ prefix + cssExpand[ i ] + suffix ] =
7318					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7319			}
7320
7321			return expanded;
7322		}
7323	};
7324
7325	if ( !rmargin.test( prefix ) ) {
7326		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7327	}
7328} );
7329
7330jQuery.fn.extend( {
7331	css: function( name, value ) {
7332		return access( this, function( elem, name, value ) {
7333			var styles, len,
7334				map = {},
7335				i = 0;
7336
7337			if ( jQuery.isArray( name ) ) {
7338				styles = getStyles( elem );
7339				len = name.length;
7340
7341				for ( ; i < len; i++ ) {
7342					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7343				}
7344
7345				return map;
7346			}
7347
7348			return value !== undefined ?
7349				jQuery.style( elem, name, value ) :
7350				jQuery.css( elem, name );
7351		}, name, value, arguments.length > 1 );
7352	},
7353	show: function() {
7354		return showHide( this, true );
7355	},
7356	hide: function() {
7357		return showHide( this );
7358	},
7359	toggle: function( state ) {
7360		if ( typeof state === "boolean" ) {
7361			return state ? this.show() : this.hide();
7362		}
7363
7364		return this.each( function() {
7365			if ( isHidden( this ) ) {
7366				jQuery( this ).show();
7367			} else {
7368				jQuery( this ).hide();
7369			}
7370		} );
7371	}
7372} );
7373
7374
7375function Tween( elem, options, prop, end, easing ) {
7376	return new Tween.prototype.init( elem, options, prop, end, easing );
7377}
7378jQuery.Tween = Tween;
7379
7380Tween.prototype = {
7381	constructor: Tween,
7382	init: function( elem, options, prop, end, easing, unit ) {
7383		this.elem = elem;
7384		this.prop = prop;
7385		this.easing = easing || jQuery.easing._default;
7386		this.options = options;
7387		this.start = this.now = this.cur();
7388		this.end = end;
7389		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7390	},
7391	cur: function() {
7392		var hooks = Tween.propHooks[ this.prop ];
7393
7394		return hooks && hooks.get ?
7395			hooks.get( this ) :
7396			Tween.propHooks._default.get( this );
7397	},
7398	run: function( percent ) {
7399		var eased,
7400			hooks = Tween.propHooks[ this.prop ];
7401
7402		if ( this.options.duration ) {
7403			this.pos = eased = jQuery.easing[ this.easing ](
7404				percent, this.options.duration * percent, 0, 1, this.options.duration
7405			);
7406		} else {
7407			this.pos = eased = percent;
7408		}
7409		this.now = ( this.end - this.start ) * eased + this.start;
7410
7411		if ( this.options.step ) {
7412			this.options.step.call( this.elem, this.now, this );
7413		}
7414
7415		if ( hooks && hooks.set ) {
7416			hooks.set( this );
7417		} else {
7418			Tween.propHooks._default.set( this );
7419		}
7420		return this;
7421	}
7422};
7423
7424Tween.prototype.init.prototype = Tween.prototype;
7425
7426Tween.propHooks = {
7427	_default: {
7428		get: function( tween ) {
7429			var result;
7430
7431			// Use a property on the element directly when it is not a DOM element,
7432			// or when there is no matching style property that exists.
7433			if ( tween.elem.nodeType !== 1 ||
7434				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7435				return tween.elem[ tween.prop ];
7436			}
7437
7438			// passing an empty string as a 3rd parameter to .css will automatically
7439			// attempt a parseFloat and fallback to a string if the parse fails
7440			// so, simple values such as "10px" are parsed to Float.
7441			// complex values such as "rotate(1rad)" are returned as is.
7442			result = jQuery.css( tween.elem, tween.prop, "" );
7443
7444			// Empty strings, null, undefined and "auto" are converted to 0.
7445			return !result || result === "auto" ? 0 : result;
7446		},
7447		set: function( tween ) {
7448
7449			// use step hook for back compat - use cssHook if its there - use .style if its
7450			// available and use plain properties where available
7451			if ( jQuery.fx.step[ tween.prop ] ) {
7452				jQuery.fx.step[ tween.prop ]( tween );
7453			} else if ( tween.elem.nodeType === 1 &&
7454				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
7455					jQuery.cssHooks[ tween.prop ] ) ) {
7456				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7457			} else {
7458				tween.elem[ tween.prop ] = tween.now;
7459			}
7460		}
7461	}
7462};
7463
7464// Support: IE <=9
7465// Panic based approach to setting things on disconnected nodes
7466
7467Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7468	set: function( tween ) {
7469		if ( tween.elem.nodeType && tween.elem.parentNode ) {
7470			tween.elem[ tween.prop ] = tween.now;
7471		}
7472	}
7473};
7474
7475jQuery.easing = {
7476	linear: function( p ) {
7477		return p;
7478	},
7479	swing: function( p ) {
7480		return 0.5 - Math.cos( p * Math.PI ) / 2;
7481	},
7482	_default: "swing"
7483};
7484
7485jQuery.fx = Tween.prototype.init;
7486
7487// Back Compat <1.8 extension point
7488jQuery.fx.step = {};
7489
7490
7491
7492
7493var
7494	fxNow, timerId,
7495	rfxtypes = /^(?:toggle|show|hide)$/,
7496	rrun = /queueHooks$/;
7497
7498// Animations created synchronously will run synchronously
7499function createFxNow() {
7500	window.setTimeout( function() {
7501		fxNow = undefined;
7502	} );
7503	return ( fxNow = jQuery.now() );
7504}
7505
7506// Generate parameters to create a standard animation
7507function genFx( type, includeWidth ) {
7508	var which,
7509		attrs = { height: type },
7510		i = 0;
7511
7512	// if we include width, step value is 1 to do all cssExpand values,
7513	// if we don't include width, step value is 2 to skip over Left and Right
7514	includeWidth = includeWidth ? 1 : 0;
7515	for ( ; i < 4 ; i += 2 - includeWidth ) {
7516		which = cssExpand[ i ];
7517		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7518	}
7519
7520	if ( includeWidth ) {
7521		attrs.opacity = attrs.width = type;
7522	}
7523
7524	return attrs;
7525}
7526
7527function createTween( value, prop, animation ) {
7528	var tween,
7529		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7530		index = 0,
7531		length = collection.length;
7532	for ( ; index < length; index++ ) {
7533		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7534
7535			// we're done with this property
7536			return tween;
7537		}
7538	}
7539}
7540
7541function defaultPrefilter( elem, props, opts ) {
7542	/* jshint validthis: true */
7543	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
7544		anim = this,
7545		orig = {},
7546		style = elem.style,
7547		hidden = elem.nodeType && isHidden( elem ),
7548		dataShow = jQuery._data( elem, "fxshow" );
7549
7550	// handle queue: false promises
7551	if ( !opts.queue ) {
7552		hooks = jQuery._queueHooks( elem, "fx" );
7553		if ( hooks.unqueued == null ) {
7554			hooks.unqueued = 0;
7555			oldfire = hooks.empty.fire;
7556			hooks.empty.fire = function() {
7557				if ( !hooks.unqueued ) {
7558					oldfire();
7559				}
7560			};
7561		}
7562		hooks.unqueued++;
7563
7564		anim.always( function() {
7565
7566			// doing this makes sure that the complete handler will be called
7567			// before this completes
7568			anim.always( function() {
7569				hooks.unqueued--;
7570				if ( !jQuery.queue( elem, "fx" ).length ) {
7571					hooks.empty.fire();
7572				}
7573			} );
7574		} );
7575	}
7576
7577	// height/width overflow pass
7578	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
7579
7580		// Make sure that nothing sneaks out
7581		// Record all 3 overflow attributes because IE does not
7582		// change the overflow attribute when overflowX and
7583		// overflowY are set to the same value
7584		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7585
7586		// Set display property to inline-block for height/width
7587		// animations on inline elements that are having width/height animated
7588		display = jQuery.css( elem, "display" );
7589
7590		// Test default display if display is currently "none"
7591		checkDisplay = display === "none" ?
7592			jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
7593
7594		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
7595
7596			// inline-level elements accept inline-block;
7597			// block-level elements need to be inline with layout
7598			if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
7599				style.display = "inline-block";
7600			} else {
7601				style.zoom = 1;
7602			}
7603		}
7604	}
7605
7606	if ( opts.overflow ) {
7607		style.overflow = "hidden";
7608		if ( !support.shrinkWrapBlocks() ) {
7609			anim.always( function() {
7610				style.overflow = opts.overflow[ 0 ];
7611				style.overflowX = opts.overflow[ 1 ];
7612				style.overflowY = opts.overflow[ 2 ];
7613			} );
7614		}
7615	}
7616
7617	// show/hide pass
7618	for ( prop in props ) {
7619		value = props[ prop ];
7620		if ( rfxtypes.exec( value ) ) {
7621			delete props[ prop ];
7622			toggle = toggle || value === "toggle";
7623			if ( value === ( hidden ? "hide" : "show" ) ) {
7624
7625				// If there is dataShow left over from a stopped hide or show
7626				// and we are going to proceed with show, we should pretend to be hidden
7627				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7628					hidden = true;
7629				} else {
7630					continue;
7631				}
7632			}
7633			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7634
7635		// Any non-fx value stops us from restoring the original display value
7636		} else {
7637			display = undefined;
7638		}
7639	}
7640
7641	if ( !jQuery.isEmptyObject( orig ) ) {
7642		if ( dataShow ) {
7643			if ( "hidden" in dataShow ) {
7644				hidden = dataShow.hidden;
7645			}
7646		} else {
7647			dataShow = jQuery._data( elem, "fxshow", {} );
7648		}
7649
7650		// store state if its toggle - enables .stop().toggle() to "reverse"
7651		if ( toggle ) {
7652			dataShow.hidden = !hidden;
7653		}
7654		if ( hidden ) {
7655			jQuery( elem ).show();
7656		} else {
7657			anim.done( function() {
7658				jQuery( elem ).hide();
7659			} );
7660		}
7661		anim.done( function() {
7662			var prop;
7663			jQuery._removeData( elem, "fxshow" );
7664			for ( prop in orig ) {
7665				jQuery.style( elem, prop, orig[ prop ] );
7666			}
7667		} );
7668		for ( prop in orig ) {
7669			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7670
7671			if ( !( prop in dataShow ) ) {
7672				dataShow[ prop ] = tween.start;
7673				if ( hidden ) {
7674					tween.end = tween.start;
7675					tween.start = prop === "width" || prop === "height" ? 1 : 0;
7676				}
7677			}
7678		}
7679
7680	// If this is a noop like .hide().hide(), restore an overwritten display value
7681	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : dis
vendor: 10,851 bytes, lines 7681-8113
7681play ) === "inline" ) {
7682		style.display = display;
7683	}
7684}
7685
7686function propFilter( props, specialEasing ) {
7687	var index, name, easing, value, hooks;
7688
7689	// camelCase, specialEasing and expand cssHook pass
7690	for ( index in props ) {
7691		name = jQuery.camelCase( index );
7692		easing = specialEasing[ name ];
7693		value = props[ index ];
7694		if ( jQuery.isArray( value ) ) {
7695			easing = value[ 1 ];
7696			value = props[ index ] = value[ 0 ];
7697		}
7698
7699		if ( index !== name ) {
7700			props[ name ] = value;
7701			delete props[ index ];
7702		}
7703
7704		hooks = jQuery.cssHooks[ name ];
7705		if ( hooks && "expand" in hooks ) {
7706			value = hooks.expand( value );
7707			delete props[ name ];
7708
7709			// not quite $.extend, this wont overwrite keys already present.
7710			// also - reusing 'index' from above because we have the correct "name"
7711			for ( index in value ) {
7712				if ( !( index in props ) ) {
7713					props[ index ] = value[ index ];
7714					specialEasing[ index ] = easing;
7715				}
7716			}
7717		} else {
7718			specialEasing[ name ] = easing;
7719		}
7720	}
7721}
7722
7723function Animation( elem, properties, options ) {
7724	var result,
7725		stopped,
7726		index = 0,
7727		length = Animation.prefilters.length,
7728		deferred = jQuery.Deferred().always( function() {
7729
7730			// don't match elem in the :animated selector
7731			delete tick.elem;
7732		} ),
7733		tick = function() {
7734			if ( stopped ) {
7735				return false;
7736			}
7737			var currentTime = fxNow || createFxNow(),
7738				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7739
7740				// Support: Android 2.3
7741				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7742				temp = remaining / animation.duration || 0,
7743				percent = 1 - temp,
7744				index = 0,
7745				length = animation.tweens.length;
7746
7747			for ( ; index < length ; index++ ) {
7748				animation.tweens[ index ].run( percent );
7749			}
7750
7751			deferred.notifyWith( elem, [ animation, percent, remaining ] );
7752
7753			if ( percent < 1 && length ) {
7754				return remaining;
7755			} else {
7756				deferred.resolveWith( elem, [ animation ] );
7757				return false;
7758			}
7759		},
7760		animation = deferred.promise( {
7761			elem: elem,
7762			props: jQuery.extend( {}, properties ),
7763			opts: jQuery.extend( true, {
7764				specialEasing: {},
7765				easing: jQuery.easing._default
7766			}, options ),
7767			originalProperties: properties,
7768			originalOptions: options,
7769			startTime: fxNow || createFxNow(),
7770			duration: options.duration,
7771			tweens: [],
7772			createTween: function( prop, end ) {
7773				var tween = jQuery.Tween( elem, animation.opts, prop, end,
7774						animation.opts.specialEasing[ prop ] || animation.opts.easing );
7775				animation.tweens.push( tween );
7776				return tween;
7777			},
7778			stop: function( gotoEnd ) {
7779				var index = 0,
7780
7781					// if we are going to the end, we want to run all the tweens
7782					// otherwise we skip this part
7783					length = gotoEnd ? animation.tweens.length : 0;
7784				if ( stopped ) {
7785					return this;
7786				}
7787				stopped = true;
7788				for ( ; index < length ; index++ ) {
7789					animation.tweens[ index ].run( 1 );
7790				}
7791
7792				// resolve when we played the last frame
7793				// otherwise, reject
7794				if ( gotoEnd ) {
7795					deferred.notifyWith( elem, [ animation, 1, 0 ] );
7796					deferred.resolveWith( elem, [ animation, gotoEnd ] );
7797				} else {
7798					deferred.rejectWith( elem, [ animation, gotoEnd ] );
7799				}
7800				return this;
7801			}
7802		} ),
7803		props = animation.props;
7804
7805	propFilter( props, animation.opts.specialEasing );
7806
7807	for ( ; index < length ; index++ ) {
7808		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
7809		if ( result ) {
7810			if ( jQuery.isFunction( result.stop ) ) {
7811				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
7812					jQuery.proxy( result.stop, result );
7813			}
7814			return result;
7815		}
7816	}
7817
7818	jQuery.map( props, createTween, animation );
7819
7820	if ( jQuery.isFunction( animation.opts.start ) ) {
7821		animation.opts.start.call( elem, animation );
7822	}
7823
7824	jQuery.fx.timer(
7825		jQuery.extend( tick, {
7826			elem: elem,
7827			anim: animation,
7828			queue: animation.opts.queue
7829		} )
7830	);
7831
7832	// attach callbacks from options
7833	return animation.progress( animation.opts.progress )
7834		.done( animation.opts.done, animation.opts.complete )
7835		.fail( animation.opts.fail )
7836		.always( animation.opts.always );
7837}
7838
7839jQuery.Animation = jQuery.extend( Animation, {
7840
7841	tweeners: {
7842		"*": [ function( prop, value ) {
7843			var tween = this.createTween( prop, value );
7844			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
7845			return tween;
7846		} ]
7847	},
7848
7849	tweener: function( props, callback ) {
7850		if ( jQuery.isFunction( props ) ) {
7851			callback = props;
7852			props = [ "*" ];
7853		} else {
7854			props = props.match( rnotwhite );
7855		}
7856
7857		var prop,
7858			index = 0,
7859			length = props.length;
7860
7861		for ( ; index < length ; index++ ) {
7862			prop = props[ index ];
7863			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
7864			Animation.tweeners[ prop ].unshift( callback );
7865		}
7866	},
7867
7868	prefilters: [ defaultPrefilter ],
7869
7870	prefilter: function( callback, prepend ) {
7871		if ( prepend ) {
7872			Animation.prefilters.unshift( callback );
7873		} else {
7874			Animation.prefilters.push( callback );
7875		}
7876	}
7877} );
7878
7879jQuery.speed = function( speed, easing, fn ) {
7880	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
7881		complete: fn || !fn && easing ||
7882			jQuery.isFunction( speed ) && speed,
7883		duration: speed,
7884		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
7885	};
7886
7887	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
7888		opt.duration in jQuery.fx.speeds ?
7889			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
7890
7891	// normalize opt.queue - true/undefined/null -> "fx"
7892	if ( opt.queue == null || opt.queue === true ) {
7893		opt.queue = "fx";
7894	}
7895
7896	// Queueing
7897	opt.old = opt.complete;
7898
7899	opt.complete = function() {
7900		if ( jQuery.isFunction( opt.old ) ) {
7901			opt.old.call( this );
7902		}
7903
7904		if ( opt.queue ) {
7905			jQuery.dequeue( this, opt.queue );
7906		}
7907	};
7908
7909	return opt;
7910};
7911
7912jQuery.fn.extend( {
7913	fadeTo: function( speed, to, easing, callback ) {
7914
7915		// show any hidden elements after setting opacity to 0
7916		return this.filter( isHidden ).css( "opacity", 0 ).show()
7917
7918			// animate to the value specified
7919			.end().animate( { opacity: to }, speed, easing, callback );
7920	},
7921	animate: function( prop, speed, easing, callback ) {
7922		var empty = jQuery.isEmptyObject( prop ),
7923			optall = jQuery.speed( speed, easing, callback ),
7924			doAnimation = function() {
7925
7926				// Operate on a copy of prop so per-property easing won't be lost
7927				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
7928
7929				// Empty animations, or finishing resolves immediately
7930				if ( empty || jQuery._data( this, "finish" ) ) {
7931					anim.stop( true );
7932				}
7933			};
7934			doAnimation.finish = doAnimation;
7935
7936		return empty || optall.queue === false ?
7937			this.each( doAnimation ) :
7938			this.queue( optall.queue, doAnimation );
7939	},
7940	stop: function( type, clearQueue, gotoEnd ) {
7941		var stopQueue = function( hooks ) {
7942			var stop = hooks.stop;
7943			delete hooks.stop;
7944			stop( gotoEnd );
7945		};
7946
7947		if ( typeof type !== "string" ) {
7948			gotoEnd = clearQueue;
7949			clearQueue = type;
7950			type = undefined;
7951		}
7952		if ( clearQueue && type !== false ) {
7953			this.queue( type || "fx", [] );
7954		}
7955
7956		return this.each( function() {
7957			var dequeue = true,
7958				index = type != null && type + "queueHooks",
7959				timers = jQuery.timers,
7960				data = jQuery._data( this );
7961
7962			if ( index ) {
7963				if ( data[ index ] && data[ index ].stop ) {
7964					stopQueue( data[ index ] );
7965				}
7966			} else {
7967				for ( index in data ) {
7968					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
7969						stopQueue( data[ index ] );
7970					}
7971				}
7972			}
7973
7974			for ( index = timers.length; index--; ) {
7975				if ( timers[ index ].elem === this &&
7976					( type == null || timers[ index ].queue === type ) ) {
7977
7978					timers[ index ].anim.stop( gotoEnd );
7979					dequeue = false;
7980					timers.splice( index, 1 );
7981				}
7982			}
7983
7984			// start the next in the queue if the last step wasn't forced
7985			// timers currently will call their complete callbacks, which will dequeue
7986			// but only if they were gotoEnd
7987			if ( dequeue || !gotoEnd ) {
7988				jQuery.dequeue( this, type );
7989			}
7990		} );
7991	},
7992	finish: function( type ) {
7993		if ( type !== false ) {
7994			type = type || "fx";
7995		}
7996		return this.each( function() {
7997			var index,
7998				data = jQuery._data( this ),
7999				queue = data[ type + "queue" ],
8000				hooks = data[ type + "queueHooks" ],
8001				timers = jQuery.timers,
8002				length = queue ? queue.length : 0;
8003
8004			// enable finishing flag on private data
8005			data.finish = true;
8006
8007			// empty the queue first
8008			jQuery.queue( this, type, [] );
8009
8010			if ( hooks && hooks.stop ) {
8011				hooks.stop.call( this, true );
8012			}
8013
8014			// look for any active animations, and finish them
8015			for ( index = timers.length; index--; ) {
8016				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8017					timers[ index ].anim.stop( true );
8018					timers.splice( index, 1 );
8019				}
8020			}
8021
8022			// look for any animations in the old queue and finish them
8023			for ( index = 0; index < length; index++ ) {
8024				if ( queue[ index ] && queue[ index ].finish ) {
8025					queue[ index ].finish.call( this );
8026				}
8027			}
8028
8029			// turn off finishing flag
8030			delete data.finish;
8031		} );
8032	}
8033} );
8034
8035jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
8036	var cssFn = jQuery.fn[ name ];
8037	jQuery.fn[ name ] = function( speed, easing, callback ) {
8038		return speed == null || typeof speed === "boolean" ?
8039			cssFn.apply( this, arguments ) :
8040			this.animate( genFx( name, true ), speed, easing, callback );
8041	};
8042} );
8043
8044// Generate shortcuts for custom animations
8045jQuery.each( {
8046	slideDown: genFx( "show" ),
8047	slideUp: genFx( "hide" ),
8048	slideToggle: genFx( "toggle" ),
8049	fadeIn: { opacity: "show" },
8050	fadeOut: { opacity: "hide" },
8051	fadeToggle: { opacity: "toggle" }
8052}, function( name, props ) {
8053	jQuery.fn[ name ] = function( speed, easing, callback ) {
8054		return this.animate( props, speed, easing, callback );
8055	};
8056} );
8057
8058jQuery.timers = [];
8059jQuery.fx.tick = function() {
8060	var timer,
8061		timers = jQuery.timers,
8062		i = 0;
8063
8064	fxNow = jQuery.now();
8065
8066	for ( ; i < timers.length; i++ ) {
8067		timer = timers[ i ];
8068
8069		// Checks the timer has not already been removed
8070		if ( !timer() && timers[ i ] === timer ) {
8071			timers.splice( i--, 1 );
8072		}
8073	}
8074
8075	if ( !timers.length ) {
8076		jQuery.fx.stop();
8077	}
8078	fxNow = undefined;
8079};
8080
8081jQuery.fx.timer = function( timer ) {
8082	jQuery.timers.push( timer );
8083	if ( timer() ) {
8084		jQuery.fx.start();
8085	} else {
8086		jQuery.timers.pop();
8087	}
8088};
8089
8090jQuery.fx.interval = 13;
8091
8092jQuery.fx.start = function() {
8093	if ( !timerId ) {
8094		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
8095	}
8096};
8097
8098jQuery.fx.stop = function() {
8099	window.clearInterval( timerId );
8100	timerId = null;
8101};
8102
8103jQuery.fx.speeds = {
8104	slow: 600,
8105	fast: 200,
8106
8107	// Default speed
8108	_default: 400
8109};
8110
8111
8112// Based off of the plugin by Clint Helfers, with permission.
8113// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8114jQuery.fn.delay = function( time, type ) {
8115	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8116	type = type || "fx";
8117
8118	return this.queue( type, function( next, hooks ) {
8119		var timeout = window.setTimeout( next, time );
8120		hooks.stop = function() {
8121			window.clearTimeout( timeout );
8122		};
8123	} );
8124};
8125
8126
8127( function() {
8128	var a,
8129		input = document.createElement( "input" ),
8130		div = document.createElement( "div" ),
8131		select = document.createElement( "select" ),
8132		opt = select.appendChild( document.createElement( "option" ) );
8133
8134	// Setup
8135	div = document.createElement( "div" );
8136	div.setAttribute( "className", "t" );
8137	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
8138	a = div.getElementsByTagName( "a" )[ 0 ];
8139
8140	// Support: Windows Web Apps (WWA)
8141	// `type` must use .setAttribute for WWA (#14901)
8142	input.setAttribute( "type", "checkbox" );
8143	div.appendChild( input );
8144
8145	a = div.getElementsByTagName( "a" )[ 0 ];
8146
8147	// First batch of tests.
8148	a.style.cssText = "top:1px";
8149
8150	// Test setAttribute on camelCase class.
8151	// If it works, we need attrFixes when doing get/setAttribute (ie6/7)
8152	support.getSetAttribute = div.className !== "t";
8153
8154	// Get the style information from getAttribute
8155	// (IE uses .cssText instead)
8156	support.style = /top/.test( a.getAttribute( "style" ) );
8157
8158	// Make sure that URLs aren't manipulated
8159	// (IE normalizes it by default)
8160	support.hrefNormalized = a.getAttribute( "href" ) === "/a";
8161
8162	// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
8163	support.checkOn = !!input.value;
8164
8165	// Make sure that a selected-by-default option has a working selected property.
8166	// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
8167	support.optSelected = opt.selected;
8168
8169	// Tests for enctype support on a form (#6743)
8170	support.enctype = !!document.createElement( "form" ).enctype;
8171
8172	// Make sure that the options inside disabled selects aren't marked as disabled
8173	// (WebKit marks them as disabled)
8174	select.disabled = true;
8175	support.optDisabled = !opt.disabled;
8176
8177	// Support: IE8 only
8178	// Check if we can trust getAttribute("value")
8179	input = document.createElement( "input" );
8180	input.setAttribute( "value", "" );
8181	support.input = input.getAttribute( "value" ) === "";
8182
8183	// Check if an input maintains its value after becoming a radio
8184	input.value = "t";
8185	input.setAttribute( "type", "radio" );
8186	support.radioValue = input.value === "t";
8187} )();
8188
8189
8190var rreturn = /\r/g,
8191	rspaces = /[\x20\t\r\n\f]+/g;
8192
8193jQuery.fn.extend( {
8194	val: function( value ) {
8195		var hooks, ret, isFunction,
8196			elem = this[ 0 ];
8197
8198		if ( !arguments.length ) {
8199			if ( elem ) {
8200				hooks = jQuery.valHooks[ elem.type ] ||
8201					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8202
8203				if (
8204					hooks &&
8205					"get" in hooks &&
8206					( ret = hooks.get( elem, "value" ) ) !== undefined
8207				) {
8208					return ret;
8209				}
8210
8211				ret = elem.value;
8212
8213				return typeof ret === "string" ?
8214
8215					// handle most common string cases
8216					ret.replace( rreturn, "" ) :
8217
8218					// handle cases where value is null/undef or number
8219					ret == null ? "" : ret;
8220			}
8221
8222			return;
8223		}
8224
8225		isFunction = jQuery.isFunction( value );
8226
8227		return this.each( function( i ) {
8228			var val;
8229
8230			if ( this.nodeType !== 1 ) {
8231				return;
8232			}
8233
8234			if ( isFunction ) {
8235				val = value.call( this, i, jQuery( this ).val() );
8236			} else {
8237				val = value;
8238			}
8239
8240			// Treat null/undefined as ""; convert numbers to string
8241			if ( val == null ) {
8242				val = "";
8243			} else if ( typeof val === "number" ) {
8244				val += "";
8245			} else if ( jQuery.isArray( val ) ) {
8246				val = jQuery.map( val, function( value ) {
8247					return value == null ? "" : value + "";
8248				} );
8249			}
8250
8251			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8252
8253			// If set returns undefined, fall back to normal setting
8254			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8255				this.value = val;
8256			}
8257		} );
8258	}
8259} );
8260
8261jQuery.extend( {
8262	valHooks: {
8263		option: {
8264			get: function( elem ) {
8265				var val = jQuery.find.attr( elem, "value" );
8266				return val != null ?
8267					val :
8268
8269					// Support: IE10-11+
8270					// option.text throws exceptions (#14686, #14858)
8271					// Strip and collapse whitespace
8272					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8273					jQuery.trim( jQuery.text( elem ) ).replace( rspaces, " " );
8274			}
8275		},
8276		select: {
8277			get: function( elem ) {
8278				var value, option,
8279					options = elem.options,
8280					index = elem.selectedIndex,
8281					one = elem.type === "select-one" || index < 0,
8282					values = one ? null : [],
8283					max = one ? index + 1 : options.length,
8284					i = index < 0 ?
8285						max :
8286						one ? index : 0;
8287
8288				// Loop through all the selected options
8289				for ( ; i < max; i++ ) {
8290					option = options[ i ];
8291
8292					// oldIE doesn't update selected after form reset (#2551)
8293					if ( ( option.selected || i === index ) &&
8294
8295							// Don't return options that are disabled or in a disabled optgroup
8296							( support.optDisabled ?
8297								!option.disabled :
8298								option.getAttribute( "disabled" ) === null ) &&
8299							( !option.parentNode.disabled ||
8300								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
8301
8302						// Get the specific value for the option
8303						value = jQuery( option ).val();
8304
8305						// We don't need an array for one selects
8306						if ( one ) {
8307							return value;
8308						}
8309
8310						// Multi-Selects return an array
8311						values.push( value );
8312					}
8313				}
8314
8315				return values;
8316			},
8317
8318			set: function( elem, value ) {
8319				var optionSet, option,
8320					options = elem.options,
8321					values = jQuery.makeArray( value ),
8322					i = options.length;
8323
8324				while ( i-- ) {
8325					option = options[ i ];
8326
8327					if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) {
8328
8329						// Support: IE6
8330						// When new option element is added to select box we need to
8331						// force reflow of newly added node in order to workaround delay
8332						// of initialization properties
8333						try {
8334							option.selected = optionSet = true;
8335
8336						} catch ( _ ) {
8337
8338							// Will be executed only in IE6
8339							option.scrollHeight;
8340						}
8341
8342					} else {
8343						option.selected = false;
8344					}
8345				}
8346
8347				// Force browsers to behave consistently when non-matching value is set
8348				if ( !optionSet ) {
8349					elem.selectedIndex = -1;
8350				}
8351
8352				return options;
8353			}
8354		}
8355	}
8356} );
8357
8358// Radios and checkboxes getter/setter
8359jQuery.each( [ "radio", "checkbox" ], function() {
8360	jQuery.valHooks[ this ] = {
8361		set: function( elem, value ) {
8362			if ( jQuery.isArray( value ) ) {
8363				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
8364			}
8365		}
8366	};
8367	if ( !support.checkOn ) {
8368		jQuery.valHooks[ this ].get = function( elem ) {
8369			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
8370		};
8371	}
8372} );
8373
8374
8375
8376
8377var nodeHook, boolHook,
8378	attrHandle = jQuery.expr.attrHandle,
8379	ruseDefault = /^(?:checked|selected)$/i,
8380	getSetAttribute = support.getSetAttribute,
8381	getSetInput = support.input;
8382
8383jQuery.fn.extend( {
8384	attr: function( name, value ) {
8385		return access( this, jQuery.attr, name, value, arguments.length > 1 );
8386	},
8387
8388	removeAttr: function( name ) {
8389		return this.each( function() {
8390			jQuery.removeAttr( this, name );
8391		} );
8392	}
8393} );
8394
8395jQuery.extend( {
8396	attr: function( elem, name, value ) {
8397		var ret, hooks,
8398			nType = elem.nodeType;
8399
8400		// Don't get/set attributes on text, comment and attribute nodes
8401		if ( nType === 3 || nType === 8 || nType === 2 ) {
8402			return;
8403		}
8404
8405		// Fallback to prop when attributes are not supported
8406		if ( typeof elem.getAttribute === "undefined" ) {
8407			return jQuery.prop( elem, name, value );
8408		}
8409
8410		// All attributes are lowercase
8411		// Grab necessary hook if one is defined
8412		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8413			name = name.toLowerCase();
8414			hooks = jQuery.attrHooks[ name ] ||
8415				( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
8416		}
8417
8418		if ( value !== undefined ) {
8419			if ( value === null ) {
8420				jQuery.removeAttr( elem, name );
8421				return;
8422			}
8423
8424			if ( hooks && "set" in hooks &&
8425				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8426				return ret;
8427			}
8428
8429			elem.setAttribute( name, value + "" );
8430			return value;
8431		}
8432
8433		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8434			return ret;
8435		}
8436
8437		ret = jQuery.find.attr( elem, name );
8438
8439		// Non-existent attributes return null, we normalize to undefined
8440		return ret == null ? undefined : ret;
8441	},
8442
8443	attrHooks: {
8444		type: {
8445			set: function( elem, value ) {
8446				if ( !support.radioValue && value === "radio" &&
8447					jQuery.nodeName( elem, "input" ) ) {
8448
8449					// Setting the type on a radio button after the value resets the value in IE8-9
8450					// Reset value to default in case type is set after value during creation
8451					var val = elem.value;
8452					elem.setAttribute( "type", value );
8453					if ( val ) {
8454						elem.value = val;
8455					}
8456					return value;
8457				}
8458			}
8459		}
8460	},
8461
8462	removeAttr: function( elem, value ) {
8463		var name, propName,
8464			i = 0,
8465			attrNames = value && value.match( rnotwhite );
8466
8467		if ( attrNames && elem.nodeType === 1 ) {
8468			while ( ( name = attrNames[ i++ ] ) ) {
8469				propName = jQuery.propFix[ name ] || name;
8470
8471				// Boolean attributes get special treatment (#10870)
8472				if ( jQuery.expr.match.bool.test( name ) ) {
8473
8474					// Set corresponding property to false
8475					if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8476						elem[ propName ] = false;
8477
8478					// Support: IE<9
8479					// Also clear defaultChecked/defaultSelected (if appropriate)
8480					} else {
8481						elem[ jQuery.camelCase( "default-" + name ) ] =
8482							elem[ propName ] = false;
8483					}
8484
8485				// See #9699 for explanation of this approach (setting first, then removal)
8486				} else {
8487					jQuery.attr( elem, name, "" );
8488				}
8489
8490				elem.removeAttribute( getSetAttribute ? name : propName );
8491			}
8492		}
8493	}
8494} );
8495
8496// Hooks for boolean attributes
8497boolHook = {
8498	set: function( elem, value, name ) {
8499		if ( value === false ) {
8500
8501			// Remove boolean attributes when set to false
8502			jQuery.removeAttr( elem, name );
8503		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8504
8505			// IE<8 needs the *property* name
8506			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
8507
8508		} else {
8509
8510			// Support: IE<9
8511			// Use defaultChecked and defaultSelected for oldIE
8512			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
8513		}
8514		return name;
8515	}
8516};
8517
8518jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
8519	var getter = attrHandle[ name ] || jQuery.find.attr;
8520
8521	if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
8522		attrHandle[ name ] = function( elem, name, isXML ) {
8523			var ret, handle;
8524			if ( !isXML ) {
8525
8526				// Avoid an infinite loop by temporarily removing this function from the getter
8527				handle = attrHandle[ name ];
8528				attrHandle[ name ] = ret;
8529				ret = getter( elem, name, isXML ) != null ?
8530					name.toLowerCase() :
8531					null;
8532				attrHandle[ name ] = handle;
8533			}
8534			return ret;
8535		};
8536	} else {
8537		attrHandle[ name ] = function( elem, name, isXML ) {
8538			if ( !isXML ) {
8539				return elem[ jQuery.camelCase( "default-" + name ) ] ?
8540					name.toLowerCase() :
8541					null;
8542			}
8543		};
8544	}
8545} );
8546
8547// fix oldIE attroperties
8548if ( !getSetInput || !getSetAttribute ) {
8549	jQuery.attrHooks.value = {
8550		set: function( elem, value, name ) {
8551			if ( jQuery.nodeName( elem, "input" ) ) {
8552
8553				// Does not return so that setAttribute is also used
8554				elem.defaultValue = value;
8555			} else {
8556
8557				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
8558				return nodeHook && nodeHook.set( elem, value, name );
8559			}
8560		}
8561	};
8562}
8563
8564// IE6/7 do not support getting/setting some attributes with get/setAttribute
8565if ( !getSetAttribute ) {
8566
8567	// Use this for any attribute in IE6/7
8568	// This fixes almost every IE6/7 issue
8569	nodeHook = {
8570		set: function( elem, value, name ) {
8571
8572			// Set the existing or create a new attribute node
8573			var ret = elem.getAttributeNode( name );
8574			if ( !ret ) {
8575				elem.setAttributeNode(
8576					( ret = elem.ownerDocument.createAttribute( name ) )
8577				);
8578			}
8579
8580			ret.value = value += "";
8581
8582			// Break association with cloned elements by also using setAttribute (#9646)
8583			if ( name === "value" || value === elem.getAttribute( name ) ) {
8584				return value;
8585			}
8586		}
8587	};
8588
8589	// Some attributes are constructed with empty-string values when not defined
8590	attrHandle.id = attrHandle.name = attrHandle.coords =
8591		function( elem, name, isXML ) {
8592			var ret;
8593			if ( !isXML ) {
8594				return ( ret = elem.getAttributeNode( name ) ) && ret.value !== "" ?
8595					ret.value :
8596					null;
8597			}
8598		};
8599
8600	// Fixing value retrieval on a button requires this module
8601	jQuery.valHooks.button = {
8602		get: function( elem, name ) {
8603			var ret = elem.getAttributeNode( name );
8604			if ( ret && ret.specified ) {
8605				return ret.value;
8606			}
8607		},
8608		set: nodeHook.set
8609	};
8610
8611	// Set contenteditable to false on removals(#10429)
8612	// Setting to empty string throws an error as an invalid value
8613	jQuery.attrHooks.contenteditable = {
8614		set: function( elem, value, name ) {
8615			nodeHook.set( elem, value === "" ? false : value, name );
8616		}
8617	};
8618
8619	// Set width and height to auto instead of 0 on empty string( Bug #8150 )
8620	// This is for removals
8621	jQuery.each( [ "width", "height" ], function( i, name ) {
8622		jQuery.attrHooks[ name ] = {
8623			set: function( elem, value ) {
8624				if ( value === "" ) {
8625					elem.setAttribute( name, "auto" );
8626					return value;
8627				}
8628			}
8629		};
8630	} );
8631}
8632
8633if ( !support.style ) {
8634	jQuery.attrHooks.style = {
8635		get: function( elem ) {
8636
8637			// Return undefined in the case of empty string
8638			// Note: IE uppercases css property names, but if we were to .toLowerCase()
8639			// .cssText, that would destroy case sensitivity in URL's, like in "background"
8640			return elem.style.cssText || undefined;
8641		},
8642		set: function( elem, value ) {
8643			return ( elem.style.cssText = value + "" );
8644		}
8645	};
8646}
8647
8648
8649
8650
8651var rfocusable = /^(?:input|select|textarea|button|object)$/i,
8652	rclickable = /^(?:a|area)$/i;
8653
8654jQuery.fn.extend( {
8655	prop: function( name, value ) {
8656		return access( this, jQuery.prop, name, value, arguments.length > 1 );
8657	},
8658
8659	removeProp: function( name ) {
8660		name = jQuery.propFix[ name ] || name;
8661		return this.each( function() {
8662
8663			// try/catch handles cases where IE balks (such as removing a property on window)
8664			try {
8665				this[ name ] = undefined;
8666				delete this[ name ];
8667			} catch ( e ) {}
8668		} );
8669	}
8670} );
8671
8672jQuery.extend( {
8673	prop: function( elem, name, value ) {
8674		var ret, hooks,
8675			nType = elem.nodeType;
8676
8677		// Don't get/set properties on text, comment and attribute nodes
8678		if ( nType === 3 || nType === 8 || nType === 2 ) {
8679			return;
8680		}
8681
8682		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8683
8684			// Fix name and attach hooks
8685			name = jQuery.propFix[ name ] || name;
8686			hooks = jQuery.propHooks[ name ];
8687		}
8688
8689		if ( value !== undefined ) {
8690			if ( hooks && "set" in hooks &&
8691				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8692				return ret;
8693			}
8694
8695			return ( elem[ name ] = value );
8696		}
8697
8698		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8699			return ret;
8700		}
8701
8702		return elem[ name ];
8703	},
8704
8705	propHooks: {
8706		tabIndex: {
8707			get: function( elem ) {
8708
8709				// elem.tabIndex doesn't always return the
8710				// correct value when it hasn't been explicitly set
8711				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8712				// Use proper attribute retrieval(#12072)
8713				var tabindex = jQuery.find.attr( elem, "tabindex" );
8714
8715				return tabindex ?
8716					parseInt( tabindex, 10 ) :
8717					rfocusable.test( elem.nodeName ) ||
8718						rclickable.test( elem.nodeName ) && elem.href ?
8719							0 :
8720							-1;
8721			}
8722		}
8723	},
8724
8725	propFix: {
8726		"for": "htmlFor",
8727		"class": "className"
8728	}
8729} );
8730
8731// Some attributes require a special call on IE
8732// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8733if ( !support.hrefNormalized ) {
8734
8735	// href/src property should get the full normalized URL (#10299/#12915)
8736	jQuery.each( [ "href", "src" ], function( i, name ) {
8737		jQuery.propHooks[ name ] = {
8738			get: function( elem ) {
8739				return elem.getAttribute( name, 4 );
8740			}
8741		};
8742	} );
8743}
8744
8745// Support: Safari, IE9+
8746// Accessing the selectedIndex property
8747// forces the browser to respect setting selected
8748// on the option
8749// The getter ensures a default option is selected
8750// when in an optgroup
8751if ( !support.optSelected ) {
8752	jQuery.propHooks.selected = {
8753		get: function( elem ) {
8754			var parent = elem.parentNode;
8755
8756			if ( parent ) {
8757				parent.selectedIndex;
8758
8759				// Make sure that it also works with optgroups, see #5701
8760				if ( parent.parentNode ) {
8761					parent.parentNode.selectedIndex;
8762				}
8763			}
8764			return null;
8765		},
8766		set: function( elem ) {
8767			var parent = elem.parentNode;
8768			if ( parent ) {
8769				parent.selectedIndex;
8770
8771				if ( parent.parentNode ) {
8772					parent.parentNode.selectedIndex;
8773				}
8774			}
8775		}
8776	};
8777}
8778
8779jQuery.each( [
8780	"tabIndex",
8781	"readOnly",
8782	"maxLength",
8783	"cellSpacing",
8784	"cellPadding",
8785	"rowSpan",
8786	"colSpan",
8787	"useMap",
8788	"frameBorder",
8789	"contentEditable"
8790], function() {
8791	jQuery.propFix[ this.toLowerCase() ] = this;
8792} );
8793
8794// IE6/7 call enctype encoding
8795if ( !support.enctype ) {
8796	jQuery.propFix.enctype = "encoding";
8797}
8798
8799
8800
8801
8802var rclass = /[\t\r\n\f]/g;
8803
8804function getClass( elem ) {
8805	return jQuery.attr( elem, "class" ) || "";
8806}
8807
8808jQuery.fn.extend( {
8809	addClass: function( value ) {
8810		var classes, elem, cur, curValue, clazz, j, finalValue,
8811			i = 0;
8812
8813		if ( jQuery.isFunction( value ) ) {
8814			return this.each( function( j ) {
8815				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8816			} );
8817		}
8818
8819		if ( typeof value === "string" && value ) {
8820			classes = value.match( rnotwhite ) || [];
8821
8822			while ( ( elem = this[ i++ ] ) ) {
8823				curValue = getClass( elem );
8824				cur = elem.nodeType === 1 &&
8825					( " " + curValue + " " ).replace( rclass, " " );
8826
8827				if ( cur ) {
8828					j = 0;
8829					while ( ( clazz = classes[ j++ ] ) ) {
8830						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8831							cur += clazz + " ";
8832						}
8833					}
8834
8835					// only assign if different to avoid unneeded rendering.
8836					finalValue = jQuery.trim( cur );
8837					if ( curValue !== finalValue ) {
8838						jQuery.attr( elem, "class", finalValue );
8839					}
8840				}
8841			}
8842		}
8843
8844		return this;
8845	},
8846
8847	removeClass: function( value ) {
8848		var classes, elem, cur, curValue, clazz, j, finalValue,
8849			i = 0;
8850
8851		if ( jQuery.isFunction( value ) ) {
8852			return this.each( function( j ) {
8853				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8854			} );
8855		}
8856
8857		if ( !arguments.length ) {
8858			return this.attr( "class", "" );
8859		}
8860
8861		if ( typeof value === "string" && value ) {
8862			classes = value.match( rnotwhite ) || [];
8863
8864			while ( ( elem = this[ i++ ] ) ) {
8865				curValue = getClass( elem );
8866
8867				// This expression is here for better compressibility (see addClass)
8868				cur = elem.nodeType === 1 &&
8869					( " " + curValue + " " ).replace( rclass, " " );
8870
8871				if ( cur ) {
8872					j = 0;
8873					while ( ( clazz = classes[ j++ ] ) ) {
8874
8875						// Remove *all* instances
8876						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8877							cur = cur.replace( " " + clazz + " ", " " );
8878						}
8879					}
8880
8881					// Only assign if different to avoid unneeded rendering.
8882					finalValue = jQuery.trim( cur );
8883					if ( curValue !== finalValue ) {
8884						jQuery.attr( elem, "class", finalValue );
8885					}
8886				}
8887			}
8888		}
8889
8890		return this;
8891	},
8892
8893	toggleClass: function( value, stateVal ) {
8894		var type = typeof value;
8895
8896		if ( typeof stateVal === "boolean" && type === "string" ) {
8897			return stateVal ? this.addClass( value ) : this.removeClass( value );
8898		}
8899
8900		if ( jQuery.isFunction( value ) ) {
8901			return this.each( function( i ) {
8902				jQuery( this ).toggleClass(
8903					value.call( this, i, getClass( this ), stateVal ),
8904					stateVal
8905				);
8906			} );
8907		}
8908
8909		return this.each( function() {
8910			var className, i, self, classNames;
8911
8912			if ( type === "string" ) {
8913
8914				// Toggle individual class names
8915				i = 0;
8916				self = jQuery( this );
8917				classNames = value.match( rnotwhite ) || [];
8918
8919				while ( ( className = classNames[ i++ ] ) ) {
8920
8921					// Check each className given, space separated list
8922					if ( self.hasClass( className ) ) {
8923						self.removeClass( className );
8924					} else {
8925						self.addClass( className );
8926					}
8927				}
8928
8929			// Toggle whole class name
8930			} else if ( value === undefined || type === "boolean" ) {
8931				className = getClass( this );
8932				if ( className ) {
8933
8934					// store className if set
8935					jQuery._data( this, "__className__", className );
8936				}
8937
8938				// If the element has a class name or if we're passed "false",
8939				// then remove the whole classname (if there was one, the above saved it).
8940				// Otherwise bring back whatever was previously saved (if anything),
8941				// falling back to the empty string if nothing was stored.
8942				jQuery.attr( this, "class",
8943					className || value === false ?
8944					"" :
8945					jQuery._data( this, "__className__" ) || ""
8946				);
8947			}
8948		} );
8949	},
8950
8951	hasClass: function( selector ) {
8952		var className, elem,
8953			i = 0;
8954
8955		className = " " + selector + " ";
8956		while ( ( elem = this[ i++ ] ) ) {
8957			if ( elem.nodeType === 1 &&
8958				( " " + getClass( elem ) + " " ).replace( rclass, " " )
8959					.indexOf( className ) > -1
8960			) {
8961				return true;
8962			}
8963		}
8964
8965		return false;
8966	}
8967} );
8968
8969
8970
8971
8972// Return jQuery for attributes-only inclusion
8973
8974
8975jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
8976	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
8977	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
8978	function( i, name ) {
8979
8980	// Handle event binding
8981	jQuery.fn[ name ] = function( data, fn ) {
8982		return arguments.length > 0 ?
8983			this.on( name, null, data, fn ) :
8984			this.trigger( name );
8985	};
8986} );
8987
8988jQuery.fn.extend( {
8989	hover: function( fnOver, fnOut ) {
8990		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
8991	}
8992} );
8993
8994
8995var location = window.location;
8996
8997var nonce = jQuery.now();
8998
8999var rquery = ( /\?/ );
9000
9001
9002
9003var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
9004
9005jQuery.parseJSON = function( data ) {
9006
9007	// Attempt to parse using the native JSON parser first
9008	if ( window.JSON && window.JSON.parse ) {
9009
9010		// Support: Android 2.3
9011		// Workaround failure to string-cast null input
9012		return window.JSON.parse( data + "" );
9013	}
9014
9015	var requireNonComma,
9016		depth = null,
9017		str = jQuery.trim( data + "" );
9018
9019	// Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
9020	// after removing valid tokens
9021	return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
9022
9023		// Force termination if we see a misplaced comma
9024		if ( requireNonComma && comma ) {
9025			depth = 0;
9026		}
9027
9028		// Perform no more replacements after returning to outermost depth
9029		if ( depth === 0 ) {
9030			return token;
9031		}
9032
9033		// Commas must not follow "[", "{", or ","
9034		requireNonComma = open || comma;
9035
9036		// Determine new depth
9037		// array/object open ("[" or "{"): depth += true - false (increment)
9038		// array/object close ("]" or "}"): depth += false - true (decrement)
9039		// other cases ("," or primitive): depth += true - true (numeric cast)
9040		depth += !close - !open;
9041
9042		// Remove this token
9043		return "";
9044	} ) ) ?
9045		( Function( "return " + str ) )() :
9046		jQuery.error( "Invalid JSON: " + data );
9047};
9048
9049
9050// Cross-browser xml parsing
9051jQuery.parseXML = function( data ) {
9052	var xml, tmp;
9053	if ( !data || typeof data !== "string" ) {
9054		return null;
9055	}
9056	try {
9057		if ( window.DOMParser ) { // Standard
9058			tmp = new window.DOMParser();
9059			xml = tmp.parseFromString( data, "text/xml" );
9060		} else { // IE
9061			xml = new window.ActiveXObject( "Microsoft.XMLDOM" );
9062			xml.async = "false";
9063			xml.loadXML( data );
9064		}
9065	} catch ( e ) {
9066		xml = undefined;
9067	}
9068	if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
9069		jQuery.error( "Invalid XML: " + data );
9070	}
9071	return xml;
9072};
9073
9074
9075var
9076	rhash = /#.*$/,
9077	rts = /([?&])_=[^&]*/,
9078
9079	// IE leaves an \r character at EOL
9080	rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg,
9081
9082	// #7653, #8125, #8152: local protocol detection
9083	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9084	rnoContent = /^(?:GET|HEAD)$/,
9085	rprotocol = /^\/\//,
9086	rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
9087
9088	/* Prefilters
9089	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9090	 * 2) These are called:
9091	 *    - BEFORE asking for a transport
9092	 *    - AFTER param serialization (s.data is a string if s.processData is true)
9093	 * 3) key is the dataType
9094	 * 4) the catchall symbol "*" can be used
9095	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9096	 */
9097	prefilters = {},
9098
9099	/* Transports bindings
9100	 * 1) key is the dataType
9101	 * 2) the catchall symbol "*" can be used
9102	 * 3) selection will start with transport dataType and THEN go to "*" if needed
9103	 */
9104	transports = {},
9105
9106	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9107	allTypes = "*/".concat( "*" ),
9108
9109	// Document location
9110	ajaxLocation = location.href,
9111
9112	// Segment location into parts
9113	ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
9114
9115// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9116function addToPrefiltersOrTransports( structure ) {
9117
9118	// dataTypeExpression is optional and defaults to "*"
9119	return function( dataTypeExpression, func ) {
9120
9121		if ( typeof dataTypeExpression !== "string" ) {
9122			func = dataTypeExpression;
9123			dataTypeExpression = "*";
9124		}
9125
9126		var dataType,
9127			i = 0,
9128			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
9129
9130		if ( jQuery.isFunction( func ) ) {
9131
9132			// For each dataType in the dataTypeExpression
9133			while ( ( dataType = dataTypes[ i++ ] ) ) {
9134
9135				// Prepend if requested
9136				if ( dataType.charAt( 0 ) === "+" ) {
9137					dataType = dataType.slice( 1 ) || "*";
9138					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9139
9140				// Otherwise append
9141				} else {
9142					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9143				}
9144			}
9145		}
9146	};
9147}
9148
9149// Base inspection function for prefilters and transports
9150function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9151
9152	var inspected = {},
9153		seekingTransport = ( structure === transports );
9154
9155	function inspect( dataType ) {
9156		var selected;
9157		inspected[ dataType ] = true;
9158		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9159			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9160			if ( typeof dataTypeOrTransport === "string" &&
9161				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9162
9163				options.dataTypes.unshift( dataTypeOrTransport );
9164				inspect( dataTypeOrTransport );
9165				return false;
9166			} else if ( seekingTransport ) {
9167				return !( selected = dataTypeOrTransport );
9168			}
9169		} );
9170		return selected;
9171	}
9172
9173	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9174}
9175
9176// A special extend for ajax options
9177// that takes "flat" options (not to be deep extended)
9178// Fixes #9887
9179function ajaxExtend( target, src ) {
9180	var deep, key,
9181		flatOptions = jQuery.ajaxSettings.flatOptions || {};
9182
9183	for ( key in src ) {
9184		if ( src[ key ] !== undefined ) {
9185			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9186		}
9187	}
9188	if ( deep ) {
9189		jQuery.extend( true, target, deep );
9190	}
9191
9192	return target;
9193}
9194
9195/* Handles responses to an ajax request:
9196 * - finds the right dataType (mediates between content-type and expected dataType)
9197 * - returns the corresponding response
9198 */
9199function ajaxHandleResponses( s, jqXHR, responses ) {
9200	var firstDataType, ct, finalDataType, type,
9201		contents = s.contents,
9202		dataTypes = s.dataTypes;
9203
9204	// Remove auto dataType and get content-type in the process
9205	while ( dataTypes[ 0 ] === "*" ) {
9206		dataTypes.shift();
9207		if ( ct === undefined ) {
9208			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9209		}
9210	}
9211
9212	// Check if we're dealing with a known content-type
9213	if ( ct ) {
9214		for ( type in contents ) {
9215			if ( contents[ type ] && contents[ type ].test( ct ) ) {
9216				dataTypes.unshift( type );
9217				break;
9218			}
9219		}
9220	}
9221
9222	// Check to see if we have a response for the expected dataType
9223	if ( dataTypes[ 0 ] in responses ) {
9224		finalDataType = dataTypes[ 0 ];
9225	} else {
9226
vendor: 5,407 bytes, lines 9227-9456
9227		// Try convertible dataTypes
9228		for ( type in responses ) {
9229			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9230				finalDataType = type;
9231				break;
9232			}
9233			if ( !firstDataType ) {
9234				firstDataType = type;
9235			}
9236		}
9237
9238		// Or just use first one
9239		finalDataType = finalDataType || firstDataType;
9240	}
9241
9242	// If we found a dataType
9243	// We add the dataType to the list if needed
9244	// and return the corresponding response
9245	if ( finalDataType ) {
9246		if ( finalDataType !== dataTypes[ 0 ] ) {
9247			dataTypes.unshift( finalDataType );
9248		}
9249		return responses[ finalDataType ];
9250	}
9251}
9252
9253/* Chain conversions given the request and the original response
9254 * Also sets the responseXXX fields on the jqXHR instance
9255 */
9256function ajaxConvert( s, response, jqXHR, isSuccess ) {
9257	var conv2, current, conv, tmp, prev,
9258		converters = {},
9259
9260		// Work with a copy of dataTypes in case we need to modify it for conversion
9261		dataTypes = s.dataTypes.slice();
9262
9263	// Create converters map with lowercased keys
9264	if ( dataTypes[ 1 ] ) {
9265		for ( conv in s.converters ) {
9266			converters[ conv.toLowerCase() ] = s.converters[ conv ];
9267		}
9268	}
9269
9270	current = dataTypes.shift();
9271
9272	// Convert to each sequential dataType
9273	while ( current ) {
9274
9275		if ( s.responseFields[ current ] ) {
9276			jqXHR[ s.responseFields[ current ] ] = response;
9277		}
9278
9279		// Apply the dataFilter if provided
9280		if ( !prev && isSuccess && s.dataFilter ) {
9281			response = s.dataFilter( response, s.dataType );
9282		}
9283
9284		prev = current;
9285		current = dataTypes.shift();
9286
9287		if ( current ) {
9288
9289			// There's only work to do if current dataType is non-auto
9290			if ( current === "*" ) {
9291
9292				current = prev;
9293
9294			// Convert response if prev dataType is non-auto and differs from current
9295			} else if ( prev !== "*" && prev !== current ) {
9296
9297				// Seek a direct converter
9298				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9299
9300				// If none found, seek a pair
9301				if ( !conv ) {
9302					for ( conv2 in converters ) {
9303
9304						// If conv2 outputs current
9305						tmp = conv2.split( " " );
9306						if ( tmp[ 1 ] === current ) {
9307
9308							// If prev can be converted to accepted input
9309							conv = converters[ prev + " " + tmp[ 0 ] ] ||
9310								converters[ "* " + tmp[ 0 ] ];
9311							if ( conv ) {
9312
9313								// Condense equivalence converters
9314								if ( conv === true ) {
9315									conv = converters[ conv2 ];
9316
9317								// Otherwise, insert the intermediate dataType
9318								} else if ( converters[ conv2 ] !== true ) {
9319									current = tmp[ 0 ];
9320									dataTypes.unshift( tmp[ 1 ] );
9321								}
9322								break;
9323							}
9324						}
9325					}
9326				}
9327
9328				// Apply converter (if not an equivalence)
9329				if ( conv !== true ) {
9330
9331					// Unless errors are allowed to bubble, catch and return them
9332					if ( conv && s[ "throws" ] ) { // jscs:ignore requireDotNotation
9333						response = conv( response );
9334					} else {
9335						try {
9336							response = conv( response );
9337						} catch ( e ) {
9338							return {
9339								state: "parsererror",
9340								error: conv ? e : "No conversion from " + prev + " to " + current
9341							};
9342						}
9343					}
9344				}
9345			}
9346		}
9347	}
9348
9349	return { state: "success", data: response };
9350}
9351
9352jQuery.extend( {
9353
9354	// Counter for holding the number of active queries
9355	active: 0,
9356
9357	// Last-Modified header cache for next request
9358	lastModified: {},
9359	etag: {},
9360
9361	ajaxSettings: {
9362		url: ajaxLocation,
9363		type: "GET",
9364		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
9365		global: true,
9366		processData: true,
9367		async: true,
9368		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9369		/*
9370		timeout: 0,
9371		data: null,
9372		dataType: null,
9373		username: null,
9374		password: null,
9375		cache: null,
9376		throws: false,
9377		traditional: false,
9378		headers: {},
9379		*/
9380
9381		accepts: {
9382			"*": allTypes,
9383			text: "text/plain",
9384			html: "text/html",
9385			xml: "application/xml, text/xml",
9386			json: "application/json, text/javascript"
9387		},
9388
9389		contents: {
9390			xml: /\bxml\b/,
9391			html: /\bhtml/,
9392			json: /\bjson\b/
9393		},
9394
9395		responseFields: {
9396			xml: "responseXML",
9397			text: "responseText",
9398			json: "responseJSON"
9399		},
9400
9401		// Data converters
9402		// Keys separate source (or catchall "*") and destination types with a single space
9403		converters: {
9404
9405			// Convert anything to text
9406			"* text": String,
9407
9408			// Text to html (true = no transformation)
9409			"text html": true,
9410
9411			// Evaluate text as a json expression
9412			"text json": jQuery.parseJSON,
9413
9414			// Parse text as xml
9415			"text xml": jQuery.parseXML
9416		},
9417
9418		// For options that shouldn't be deep extended:
9419		// you can add your own custom options here if
9420		// and when you create one that shouldn't be
9421		// deep extended (see ajaxExtend)
9422		flatOptions: {
9423			url: true,
9424			context: true
9425		}
9426	},
9427
9428	// Creates a full fledged settings object into target
9429	// with both ajaxSettings and settings fields.
9430	// If target is omitted, writes into ajaxSettings.
9431	ajaxSetup: function( target, settings ) {
9432		return settings ?
9433
9434			// Building a settings object
9435			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9436
9437			// Extending ajaxSettings
9438			ajaxExtend( jQuery.ajaxSettings, target );
9439	},
9440
9441	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9442	ajaxTransport: addToPrefiltersOrTransports( transports ),
9443
9444	// Main method
9445	ajax: function( url, options ) {
9446
9447		// If url is an object, simulate pre-1.5 signature
9448		if ( typeof url === "object" ) {
9449			options = url;
9450			url = undefined;
9451		}
9452
9453		// Force options to be an object
9454		options = options || {};
9455
9456		var
9457
9458			// Cross-domain detection vars
9459			parts,
9460
9461			// Loop variable
9462			i,
9463
9464			// URL without anti-cache param
9465			cacheURL,
9466
9467			// Response headers as string
9468			responseHeadersString,
9469
9470			// timeout handle
9471			timeoutTimer,
9472
9473			// To know if global events are to be dispatched
9474			fireGlobals,
9475
9476			transport,
9477
9478			// Response headers
9479			responseHeaders,
9480
9481			// Create the final options object
9482			s = jQuery.ajaxSetup( {}, options ),
9483
9484			// Callbacks context
9485			callbackContext = s.context || s,
9486
9487			// Context for global events is callbackContext if it is a DOM node or jQuery collection
9488			globalEventContext = s.context &&
9489				( callbackContext.nodeType || callbackContext.jquery ) ?
9490					jQuery( callbackContext ) :
9491					jQuery.event,
9492
9493			// Deferreds
9494			deferred = jQuery.Deferred(),
9495			completeDeferred = jQuery.Callbacks( "once memory" ),
9496
9497			// Status-dependent callbacks
9498			statusCode = s.statusCode || {},
9499
9500			// Headers (they are sent all at once)
9501			requestHeaders = {},
9502			requestHeadersNames = {},
9503
9504			// The jqXHR state
9505			state = 0,
9506
9507			// Default abort message
9508			strAbort = "canceled",
9509
9510			// Fake xhr
9511			jqXHR = {
9512				readyState: 0,
9513
9514				// Builds headers hashtable if needed
9515				getResponseHeader: function( key ) {
9516					var match;
9517					if ( state === 2 ) {
9518						if ( !responseHeaders ) {
9519							responseHeaders = {};
9520							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9521								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
9522							}
9523						}
9524						match = responseHeaders[ key.toLowerCase() ];
9525					}
9526					return match == null ? null : match;
9527				},
9528
9529				// Raw string
9530				getAllResponseHeaders: function() {
9531					return state === 2 ? responseHeadersString : null;
9532				},
9533
9534				// Caches the header
9535				setRequestHeader: function( name, value ) {
9536					var lname = name.toLowerCase();
9537					if ( !state ) {
9538						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
9539						requestHeaders[ name ] = value;
9540					}
9541					return this;
9542				},
9543
9544				// Overrides response content-type header
9545				overrideMimeType: function( type ) {
9546					if ( !state ) {
9547						s.mimeType = type;
9548					}
9549					return this;
9550				},
9551
9552				// Status-dependent callbacks
9553				statusCode: function( map ) {
9554					var code;
9555					if ( map ) {
9556						if ( state < 2 ) {
9557							for ( code in map ) {
9558
9559								// Lazy-add the new callback in a way that preserves old ones
9560								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9561							}
9562						} else {
9563
9564							// Execute the appropriate callbacks
9565							jqXHR.always( map[ jqXHR.status ] );
9566						}
9567					}
9568					return this;
9569				},
9570
9571				// Cancel the request
9572				abort: function( statusText ) {
9573					var finalText = statusText || strAbort;
9574					if ( transport ) {
9575						transport.abort( finalText );
9576					}
9577					done( 0, finalText );
9578					return this;
9579				}
9580			};
9581
9582		// Attach deferreds
9583		deferred.promise( jqXHR ).complete = completeDeferred.add;
9584		jqXHR.success = jqXHR.done;
9585		jqXHR.error = jqXHR.fail;
9586
9587		// Remove hash character (#7531: and string promotion)
9588		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
9589		// Handle falsy url in the settings object (#10093: consistency with old signature)
9590		// We also use the url parameter if available
9591		s.url = ( ( url || s.url || ajaxLocation ) + "" )
9592			.replace( rhash, "" )
9593			.replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
9594
9595		// Alias method option to type as per ticket #12004
9596		s.type = options.method || options.type || s.method || s.type;
9597
9598		// Extract dataTypes list
9599		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
9600
9601		// A cross-domain request is in order when we have a protocol:host:port mismatch
9602		if ( s.crossDomain == null ) {
9603			parts = rurl.exec( s.url.toLowerCase() );
9604			s.crossDomain = !!( parts &&
9605				( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
9606					( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
9607						( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
9608			);
9609		}
9610
9611		// Convert data if not already a string
9612		if ( s.data && s.processData && typeof s.data !== "string" ) {
9613			s.data = jQuery.param( s.data, s.traditional );
9614		}
9615
9616		// Apply prefilters
9617		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9618
9619		// If request was aborted inside a prefilter, stop there
9620		if ( state === 2 ) {
9621			return jqXHR;
9622		}
9623
9624		// We can fire global events as of now if asked to
9625		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
9626		fireGlobals = jQuery.event && s.global;
9627
9628		// Watch for a new set of requests
9629		if ( fireGlobals && jQuery.active++ === 0 ) {
9630			jQuery.event.trigger( "ajaxStart" );
9631		}
9632
9633		// Uppercase the type
9634		s.type = s.type.toUpperCase();
9635
9636		// Determine if request has content
9637		s.hasContent = !rnoContent.test( s.type );
9638
9639		// Save the URL in case we're toying with the If-Modified-Since
9640		// and/or If-None-Match header later on
9641		cacheURL = s.url;
9642
9643		// More options handling for requests with no content
9644		if ( !s.hasContent ) {
9645
9646			// If data is available, append data to url
9647			if ( s.data ) {
9648				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
9649
9650				// #9682: remove data so that it's not used in an eventual retry
9651				delete s.data;
9652			}
9653
9654			// Add anti-cache in url if needed
9655			if ( s.cache === false ) {
9656				s.url = rts.test( cacheURL ) ?
9657
9658					// If there is already a '_' parameter, set its value
9659					cacheURL.replace( rts, "$1_=" + nonce++ ) :
9660
9661					// Otherwise add one to the end
9662					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
9663			}
9664		}
9665
9666		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9667		if ( s.ifModified ) {
9668			if ( jQuery.lastModified[ cacheURL ] ) {
9669				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
9670			}
9671			if ( jQuery.etag[ cacheURL ] ) {
9672				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
9673			}
9674		}
9675
9676		// Set the correct header, if data is being sent
9677		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
9678			jqXHR.setRequestHeader( "Content-Type", s.contentType );
9679		}
9680
9681		// Set the Accepts header for the server, depending on the dataType
9682		jqXHR.setRequestHeader(
9683			"Accept",
9684			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
9685				s.accepts[ s.dataTypes[ 0 ] ] +
9686					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
9687				s.accepts[ "*" ]
9688		);
9689
9690		// Check for headers option
9691		for ( i in s.headers ) {
9692			jqXHR.setRequestHeader( i, s.headers[ i ] );
9693		}
9694
9695		// Allow custom headers/mimetypes and early abort
9696		if ( s.beforeSend &&
9697			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
9698
9699			// Abort if not done already and return
9700			return jqXHR.abort();
9701		}
9702
9703		// aborting is no longer a cancellation
9704		strAbort = "abort";
9705
9706		// Install callbacks on deferreds
9707		for ( i in { success: 1, error: 1, complete: 1 } ) {
9708			jqXHR[ i ]( s[ i ] );
9709		}
9710
9711		// Get transport
9712		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
9713
9714		// If no transport, we auto-abort
9715		if ( !transport ) {
9716			done( -1, "No Transport" );
9717		} else {
9718			jqXHR.readyState = 1;
9719
9720			// Send global event
9721			if ( fireGlobals ) {
9722				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
9723			}
9724
9725			// If request was aborted inside ajaxSend, stop there
9726			if ( state === 2 ) {
9727				return jqXHR;
9728			}
9729
9730			// Timeout
9731			if ( s.async && s.timeout > 0 ) {
9732				timeoutTimer = window.setTimeout( function() {
9733					jqXHR.abort( "timeout" );
9734				}, s.timeout );
9735			}
9736
9737			try {
9738				state = 1;
9739				transport.send( requestHeaders, done );
9740			} catch ( e ) {
9741
9742				// Propagate exception as error if not done
9743				if ( state < 2 ) {
9744					done( -1, e );
9745
9746				// Simply rethrow otherwise
9747				} else {
9748					throw e;
9749				}
9750			}
9751		}
9752
9753		// Callback for when everything is done
9754		function done( status, nativeStatusText, responses, headers ) {
9755			var isSuccess, success, error, response, modified,
9756				statusText = nativeStatusText;
9757
9758			// Called once
9759			if ( state === 2 ) {
9760				return;
9761			}
9762
9763			// State is "done" now
9764			state = 2;
9765
9766			// Clear timeout if it exists
9767			if ( timeoutTimer ) {
9768				window.clearTimeout( timeoutTimer );
9769			}
9770
9771			// Dereference transport for early garbage collection
9772			// (no matter how long the jqXHR object will be used)
9773			transport = undefined;
9774
9775			// Cache response headers
9776			responseHeadersString = headers || "";
9777
9778			// Set readyState
9779			jqXHR.readyState = status > 0 ? 4 : 0;
9780
9781			// Determine if successful
9782			isSuccess = status >= 200 && status < 300 || status === 304;
9783
9784			// Get response data
9785			if ( responses ) {
9786				response = ajaxHandleResponses( s, jqXHR, responses );
9787			}
9788
9789			// Convert no matter what (that way responseXXX fields are always set)
9790			response = ajaxConvert( s, response, jqXHR, isSuccess );
9791
9792			// If successful, handle type chaining
9793			if ( isSuccess ) {
9794
9795				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
9796				if ( s.ifModified ) {
9797					modified = jqXHR.getResponseHeader( "Last-Modified" );
9798					if ( modified ) {
9799						jQuery.lastModified[ cacheURL ] = modified;
9800					}
9801					modified = jqXHR.getResponseHeader( "etag" );
9802					if ( modified ) {
9803						jQuery.etag[ cacheURL ] = modified;
9804					}
9805				}
9806
9807				// if no content
9808				if ( status === 204 || s.type === "HEAD" ) {
9809					statusText = "nocontent";
9810
9811				// if not modified
9812				} else if ( status === 304 ) {
9813					statusText = "notmodified";
9814
9815				// If we have data, let's convert it
9816				} else {
9817					statusText = response.state;
9818					success = response.data;
9819					error = response.error;
9820					isSuccess = !error;
9821				}
9822			} else {
9823
9824				// We extract error from statusText
9825				// then normalize statusText and status for non-aborts
9826				error = statusText;
9827				if ( status || !statusText ) {
9828					statusText = "error";
9829					if ( status < 0 ) {
9830						status = 0;
9831					}
9832				}
9833			}
9834
9835			// Set data for the fake xhr object
9836			jqXHR.status = status;
9837			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
9838
9839			// Success/Error
9840			if ( isSuccess ) {
9841				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
9842			} else {
9843				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
9844			}
9845
9846			// Status-dependent callbacks
9847			jqXHR.statusCode( statusCode );
9848			statusCode = undefined;
9849
9850			if ( fireGlobals ) {
9851				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
9852					[ jqXHR, s, isSuccess ? success : error ] );
9853			}
9854
9855			// Complete
9856			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
9857
9858			if ( fireGlobals ) {
9859				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
9860
9861				// Handle the global AJAX counter
9862				if ( !( --jQuery.active ) ) {
9863					jQuery.event.trigger( "ajaxStop" );
9864				}
9865			}
9866		}
9867
9868		return jqXHR;
9869	},
9870
9871	getJSON: function( url, data, callback ) {
9872		return jQuery.get( url, data, callback, "json" );
9873	},
9874
9875	getScript: function( url, callback ) {
9876		return jQuery.get( url, undefined, callback, "script" );
9877	}
9878} );
9879
9880jQuery.each( [ "get", "post" ], function( i, method ) {
9881	jQuery[ method ] = function( url, data, callback, type ) {
9882
9883		// shift arguments if data argument was omitted
9884		if ( jQuery.isFunction( data ) ) {
9885			type = type || callback;
9886			callback = data;
9887			data = undefined;
9888		}
9889
9890		// The url can be an options object (which then must have .url)
9891		return jQuery.ajax( jQuery.extend( {
9892			url: url,
9893			type: method,
9894			dataType: type,
9895			data: data,
9896			success: callback
9897		}, jQuery.isPlainObject( url ) && url ) );
9898	};
9899} );
9900
9901
9902jQuery._evalUrl = function( url ) {
9903	return jQuery.ajax( {
9904		url: url,
9905
9906		// Make this explicit, since user can override this through ajaxSetup (#11264)
9907		type: "GET",
9908		dataType: "script",
9909		cache: true,
9910		async: false,
9911		global: false,
9912		"throws": true
9913	} );
9914};
9915
9916
9917jQuery.fn.extend( {
9918	wrapAll: function( html ) {
9919		if ( jQuery.isFunction( html ) ) {
9920			return this.each( function( i ) {
9921				jQuery( this ).wrapAll( html.call( this, i ) );
9922			} );
9923		}
9924
9925		if ( this[ 0 ] ) {
9926
9927			// The elements to wrap the target around
9928			var wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
9929
9930			if ( this[ 0 ].parentNode ) {
9931				wrap.insertBefore( this[ 0 ] );
9932			}
9933
9934			wrap.map( function() {
9935				var elem = this;
9936
9937				while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
9938					elem = elem.firstChild;
9939				}
9940
9941				return elem;
9942			} ).append( this );
9943		}
9944
9945		return this;
9946	},
9947
9948	wrapInner: function( html ) {
9949		if ( jQuery.isFunction( html ) ) {
9950			return this.each( function( i ) {
9951				jQuery( this ).wrapInner( html.call( this, i ) );
9952			} );
9953		}
9954
9955		return this.each( function() {
9956			var self = jQuery( this ),
9957				contents = self.contents();
9958
9959			if ( contents.length ) {
9960				contents.wrapAll( html );
9961
9962			} else {
9963				self.append( html );
9964			}
9965		} );
9966	},
9967
9968	wrap: function( html ) {
9969		var isFunction = jQuery.isFunction( html );
9970
9971		return this.each( function( i ) {
9972			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
9973		} );
9974	},
9975
9976	unwrap: function() {
9977		return this.parent().each( function() {
9978			if ( !jQuery.nodeName( this, "body" ) ) {
9979				jQuery( this ).replaceWith( this.childNodes );
9980			}
9981		} ).end();
9982	}
9983} );
9984
9985
9986function getDisplay( elem ) {
9987	return elem.style && elem.style.display || jQuery.css( elem, "dis
9987play" );
9988}
9989
9990function filterHidden( elem ) {
9991
9992	// Disconnected elements are considered hidden
9993	if ( !jQuery.contains( elem.ownerDocument || document, elem ) ) {
9994		return true;
9995	}
9996	while ( elem && elem.nodeType === 1 ) {
9997		if ( getDisplay( elem ) === "none" || elem.type === "hidden" ) {
9998			return true;
9999		}
10000		elem = elem.parentNode;
10001	}
10002	return false;
10003}
10004
10005jQuery.expr.filters.hidden = function( elem ) {
10006
10007	// Support: Opera <= 12.12
10008	// Opera reports offsetWidths and offsetHeights less than zero on some elements
10009	return support.reliableHiddenOffsets() ?
10010		( elem.offsetWidth <= 0 && elem.offsetHeight <= 0 &&
10011			!elem.getClientRects().length ) :
10012			filterHidden( elem );
10013};
10014
10015jQuery.expr.filters.visible = function( elem ) {
10016	return !jQuery.expr.filters.hidden( elem );
10017};
10018
10019
10020
10021
10022var r20 = /%20/g,
10023	rbracket = /\[\]$/,
10024	rCRLF = /\r?\n/g,
10025	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
10026	rsubmittable = /^(?:input|select|textarea|keygen)/i;
10027
10028function buildParams( prefix, obj, traditional, add ) {
10029	var name;
10030
10031	if ( jQuery.isArray( obj ) ) {
10032
10033		// Serialize array item.
10034		jQuery.each( obj, function( i, v ) {
10035			if ( traditional || rbracket.test( prefix ) ) {
10036
10037				// Treat each array item as a scalar.
10038				add( prefix, v );
10039
10040			} else {
10041
10042				// Item is non-scalar (array or object), encode its numeric index.
10043				buildParams(
10044					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
10045					v,
10046					traditional,
10047					add
10048				);
10049			}
10050		} );
10051
10052	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
10053
10054		// Serialize object item.
10055		for ( name in obj ) {
10056			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
10057		}
10058
10059	} else {
10060
10061		// Serialize scalar item.
10062		add( prefix, obj );
10063	}
10064}
10065
10066// Serialize an array of form elements or a set of
10067// key/values into a query string
10068jQuery.param = function( a, traditional ) {
10069	var prefix,
10070		s = [],
10071		add = function( key, value ) {
10072
10073			// If value is a function, invoke it and return its value
10074			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
10075			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
10076		};
10077
10078	// Set traditional to true for jQuery <= 1.3.2 behavior.
10079	if ( traditional === undefined ) {
10080		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
10081	}
10082
10083	// If an array was passed in, assume that it is an array of form elements.
10084	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
10085
10086		// Serialize the form elements
10087		jQuery.each( a, function() {
10088			add( this.name, this.value );
10089		} );
10090
10091	} else {
10092
10093		// If traditional, encode the "old" way (the way 1.3.2 or older
10094		// did it), otherwise encode params recursively.
10095		for ( prefix in a ) {
10096			buildParams( prefix, a[ prefix ], traditional, add );
10097		}
10098	}
10099
10100	// Return the resulting serialization
10101	return s.join( "&" ).replace( r20, "+" );
10102};
10103
10104jQuery.fn.extend( {
10105	serialize: function() {
10106		return jQuery.param( this.serializeArray() );
10107	},
10108	serializeArray: function() {
10109		return this.map( function() {
10110
10111			// Can add propHook for "elements" to filter or add form elements
10112			var elements = jQuery.prop( this, "elements" );
10113			return elements ? jQuery.makeArray( elements ) : this;
10114		} )
10115		.filter( function() {
10116			var type = this.type;
10117
10118			// Use .is(":disabled") so that fieldset[disabled] works
10119			return this.name && !jQuery( this ).is( ":disabled" ) &&
10120				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
10121				( this.checked || !rcheckableType.test( type ) );
10122		} )
10123		.map( function( i, elem ) {
10124			var val = jQuery( this ).val();
10125
10126			return val == null ?
10127				null :
10128				jQuery.isArray( val ) ?
10129					jQuery.map( val, function( val ) {
10130						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10131					} ) :
10132					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
10133		} ).get();
10134	}
10135} );
10136
10137
10138// Create the request object
10139// (This is still attached to ajaxSettings for backward compatibility)
10140jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
10141
10142	// Support: IE6-IE8
10143	function() {
10144
10145		// XHR cannot access local files, always use ActiveX for that case
10146		if ( this.isLocal ) {
10147			return createActiveXHR();
10148		}
10149
10150		// Support: IE 9-11
10151		// IE seems to error on cross-domain PATCH requests when ActiveX XHR
10152		// is used. In IE 9+ always use the native XHR.
10153		// Note: this condition won't catch Edge as it doesn't define
10154		// document.documentMode but it also doesn't support ActiveX so it won't
10155		// reach this code.
10156		if ( document.documentMode > 8 ) {
10157			return createStandardXHR();
10158		}
10159
10160		// Support: IE<9
10161		// oldIE XHR does not support non-RFC2616 methods (#13240)
10162		// See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
10163		// and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
10164		// Although this check for six methods instead of eight
10165		// since IE also does not support "trace" and "connect"
10166		return /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
10167			createStandardXHR() || createActiveXHR();
10168	} :
10169
10170	// For all other browsers, use the standard XMLHttpRequest object
10171	createStandardXHR;
10172
10173var xhrId = 0,
10174	xhrCallbacks = {},
10175	xhrSupported = jQuery.ajaxSettings.xhr();
10176
10177// Support: IE<10
10178// Open requests must be manually aborted on unload (#5280)
10179// See https://support.microsoft.com/kb/2856746 for more info
10180if ( window.attachEvent ) {
10181	window.attachEvent( "onunload", function() {
10182		for ( var key in xhrCallbacks ) {
10183			xhrCallbacks[ key ]( undefined, true );
10184		}
10185	} );
10186}
10187
10188// Determine support properties
10189support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10190xhrSupported = support.ajax = !!xhrSupported;
10191
10192// Create transport if the browser can provide an xhr
10193if ( xhrSupported ) {
10194
10195	jQuery.ajaxTransport( function( options ) {
10196
10197		// Cross domain only allowed if supported through XMLHttpRequest
10198		if ( !options.crossDomain || support.cors ) {
10199
10200			var callback;
10201
10202			return {
10203				send: function( headers, complete ) {
10204					var i,
10205						xhr = options.xhr(),
10206						id = ++xhrId;
10207
10208					// Open the socket
10209					xhr.open(
10210						options.type,
10211						options.url,
10212						options.async,
10213						options.username,
10214						options.password
10215					);
10216
10217					// Apply custom fields if provided
10218					if ( options.xhrFields ) {
10219						for ( i in options.xhrFields ) {
10220							xhr[ i ] = options.xhrFields[ i ];
10221						}
10222					}
10223
10224					// Override mime type if needed
10225					if ( options.mimeType && xhr.overrideMimeType ) {
10226						xhr.overrideMimeType( options.mimeType );
10227					}
10228
10229					// X-Requested-With header
10230					// For cross-domain requests, seeing as conditions for a preflight are
10231					// akin to a jigsaw puzzle, we simply never set it to be sure.
10232					// (it can always be set on a per-request basis or even using ajaxSetup)
10233					// For same-domain requests, won't change header if already provided.
10234					if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10235						headers[ "X-Requested-With" ] = "XMLHttpRequest";
10236					}
10237
10238					// Set headers
10239					for ( i in headers ) {
10240
10241						// Support: IE<9
10242						// IE's ActiveXObject throws a 'Type Mismatch' exception when setting
10243						// request header to a null-value.
10244						//
10245						// To keep consistent with other XHR implementations, cast the value
10246						// to string and ignore `undefined`.
10247						if ( headers[ i ] !== undefined ) {
10248							xhr.setRequestHeader( i, headers[ i ] + "" );
10249						}
10250					}
10251
10252					// Do send the request
10253					// This may raise an exception which is actually
10254					// handled in jQuery.ajax (so no try/catch here)
10255					xhr.send( ( options.hasContent && options.data ) || null );
10256
10257					// Listener
10258					callback = function( _, isAbort ) {
10259						var status, statusText, responses;
10260
10261						// Was never called and is aborted or complete
10262						if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
10263
10264							// Clean up
10265							delete xhrCallbacks[ id ];
10266							callback = undefined;
10267							xhr.onreadystatechange = jQuery.noop;
10268
10269							// Abort manually if needed
10270							if ( isAbort ) {
10271								if ( xhr.readyState !== 4 ) {
10272									xhr.abort();
10273								}
10274							} else {
10275								responses = {};
10276								status = xhr.status;
10277
10278								// Support: IE<10
10279								// Accessing binary-data responseText throws an exception
10280								// (#11426)
10281								if ( typeof xhr.responseText === "string" ) {
10282									responses.text = xhr.responseText;
10283								}
10284
10285								// Firefox throws an exception when accessing
10286								// statusText for faulty cross-domain requests
10287								try {
10288									statusText = xhr.statusText;
10289								} catch ( e ) {
10290
10291									// We normalize with Webkit giving an empty statusText
10292									statusText = "";
10293								}
10294
10295								// Filter status for non standard behaviors
10296
10297								// If the request is local and we have data: assume a success
10298								// (success with no data won't get notified, that's the best we
10299								// can do given current implementations)
10300								if ( !status && options.isLocal && !options.crossDomain ) {
10301									status = responses.text ? 200 : 404;
10302
10303								// IE - #1450: sometimes returns 1223 when it should be 204
10304								} else if ( status === 1223 ) {
10305									status = 204;
10306								}
10307							}
10308						}
10309
10310						// Call complete if needed
10311						if ( responses ) {
10312							complete( status, statusText, responses, xhr.getAllResponseHeaders() );
10313						}
10314					};
10315
10316					// Do send the request
10317					// `xhr.send` may raise an exception, but it will be
10318					// handled in jQuery.ajax (so no try/catch here)
10319					if ( !options.async ) {
10320
10321						// If we're in sync mode we fire the callback
10322						callback();
10323					} else if ( xhr.readyState === 4 ) {
10324
10325						// (IE6 & IE7) if it's in cache and has been
10326						// retrieved directly we need to fire the callback
10327						window.setTimeout( callback );
10328					} else {
10329
10330						// Register the callback, but delay it in case `xhr.send` throws
10331						// Add to the list of active xhr callbacks
10332						xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
10333					}
10334				},
10335
10336				abort: function() {
10337					if ( callback ) {
10338						callback( undefined, true );
10339					}
10340				}
10341			};
10342		}
10343	} );
10344}
10345
10346// Functions to create xhrs
10347function createStandardXHR() {
10348	try {
10349		return new window.XMLHttpRequest();
10350	} catch ( e ) {}
10351}
10352
10353function createActiveXHR() {
10354	try {
10355		return new window.ActiveXObject( "Microsoft.XMLHTTP" );
10356	} catch ( e ) {}
10357}
10358
10359
10360
10361
10362// Install script dataType
10363jQuery.ajaxSetup( {
10364	accepts: {
10365		script: "text/javascript, application/javascript, " +
10366			"application/ecmascript, application/x-ecmascript"
10367	},
10368	contents: {
10369		script: /\b(?:java|ecma)script\b/
10370	},
10371	converters: {
10372		"text script": function( text ) {
10373			jQuery.globalEval( text );
10374			return text;
10375		}
10376	}
10377} );
10378
10379// Handle cache's special case and global
10380jQuery.ajaxPrefilter( "script", function( s ) {
10381	if ( s.cache === undefined ) {
10382		s.cache = false;
10383	}
10384	if ( s.crossDomain ) {
10385		s.type = "GET";
10386		s.global = false;
10387	}
10388} );
10389
10390// Bind script tag hack transport
10391jQuery.ajaxTransport( "script", function( s ) {
10392
10393	// This transport only deals with cross domain requests
10394	if ( s.crossDomain ) {
10395
10396		var script,
10397			head = document.head || jQuery( "head" )[ 0 ] || document.documentElement;
10398
10399		return {
10400
10401			send: function( _, callback ) {
10402
10403				script = document.createElement( "script" );
10404
10405				script.async = true;
10406
10407				if ( s.scriptCharset ) {
10408					script.charset = s.scriptCharset;
10409				}
10410
10411				script.src = s.url;
10412
10413				// Attach handlers for all browsers
10414				script.onload = script.onreadystatechange = function( _, isAbort ) {
10415
10416					if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
10417
10418						// Handle memory leak in IE
10419						script.onload = script.onreadystatechange = null;
10420
10421						// Remove the script
10422						if ( script.parentNode ) {
10423							script.parentNode.removeChild( script );
10424						}
10425
10426						// Dereference the script
10427						script = null;
10428
10429						// Callback if not abort
10430						if ( !isAbort ) {
10431							callback( 200, "success" );
10432						}
10433					}
10434				};
10435
10436				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
10437				// Use native DOM manipulation to avoid our domManip AJAX trickery
10438				head.insertBefore( script, head.firstChild );
10439			},
10440
10441			abort: function() {
10442				if ( script ) {
10443					script.onload( undefined, true );
10444				}
10445			}
10446		};
10447	}
10448} );
10449
10450
10451
10452
10453var oldCallbacks = [],
10454	rjsonp = /(=)\?(?=&|$)|\?\?/;
10455
10456// Default jsonp settings
10457jQuery.ajaxSetup( {
10458	jsonp: "callback",
10459	jsonpCallback: function() {
10460		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
10461		this[ callback ] = true;
10462		return callback;
10463	}
10464} );
10465
10466// Detect, normalize options and install callbacks for jsonp requests
10467jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10468
10469	var callbackName, overwritten, responseContainer,
10470		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10471			"url" :
10472			typeof s.data === "string" &&
10473				( s.contentType || "" )
10474					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10475				rjsonp.test( s.data ) && "data"
10476		);
10477
10478	// Handle iff the expected data type is "jsonp" or we have a parameter to set
10479	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10480
10481		// Get callback name, remembering preexisting value associated with it
10482		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
10483			s.jsonpCallback() :
10484			s.jsonpCallback;
10485
10486		// Insert callback into url or form data
10487		if ( jsonProp ) {
10488			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10489		} else if ( s.jsonp !== false ) {
10490			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10491		}
10492
10493		// Use data converter to retrieve json after script execution
10494		s.converters[ "script json" ] = function() {
10495			if ( !responseContainer ) {
10496				jQuery.error( callbackName + " was not called" );
10497			}
10498			return responseContainer[ 0 ];
10499		};
10500
10501		// force json dataType
10502		s.dataTypes[ 0 ] = "json";
10503
10504		// Install callback
10505		overwritten = window[ callbackName ];
10506		window[ callbackName ] = function() {
10507			responseContainer = arguments;
10508		};
10509
10510		// Clean-up function (fires after converters)
10511		jqXHR.always( function() {
10512
10513			// If previous value didn't exist - remove it
10514			if ( overwritten === undefined ) {
10515				jQuery( window ).removeProp( callbackName );
10516
10517			// Otherwise restore preexisting value
10518			} else {
10519				window[ callbackName ] = overwritten;
10520			}
10521
10522			// Save back as free
10523			if ( s[ callbackName ] ) {
10524
10525				// make sure that re-using the options doesn't screw things around
10526				s.jsonpCallback = originalSettings.jsonpCallback;
10527
10528				// save the callback name for future use
10529				oldCallbacks.push( callbackName );
10530			}
10531
10532			// Call if it was a function and we have a response
10533			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
10534				overwritten( responseContainer[ 0 ] );
10535			}
10536
10537			responseContainer = overwritten = undefined;
10538		} );
10539
10540		// Delegate to script
10541		return "script";
10542	}
10543} );
10544
10545
10546
10547
10548// data: string of html
10549// context (optional): If specified, the fragment will be created in this context,
10550// defaults to document
10551// keepScripts (optional): If true, will include scripts passed in the html string
10552jQuery.parseHTML = function( data, context, keepScripts ) {
10553	if ( !data || typeof data !== "string" ) {
10554		return null;
10555	}
10556	if ( typeof context === "boolean" ) {
10557		keepScripts = context;
10558		context = false;
10559	}
10560	context = context || document;
10561
10562	var parsed = rsingleTag.exec( data ),
10563		scripts = !keepScripts && [];
10564
10565	// Single tag
10566	if ( parsed ) {
10567		return [ context.createElement( parsed[ 1 ] ) ];
10568	}
10569
10570	parsed = buildFragment( [ data ], context, scripts );
10571
10572	if ( scripts && scripts.length ) {
10573		jQuery( scripts ).remove();
10574	}
10575
10576	return jQuery.merge( [], parsed.childNodes );
10577};
10578
10579
10580// Keep a copy of the old load method
10581var _load = jQuery.fn.load;
10582
10583/**
10584 * Load a url into a page
10585 */
10586jQuery.fn.load = function( url, params, callback ) {
10587	if ( typeof url !== "string" && _load ) {
10588		return _load.apply( this, arguments );
10589	}
10590
10591	var selector, type, response,
10592		self = this,
10593		off = url.indexOf( " " );
10594
10595	if ( off > -1 ) {
10596		selector = jQuery.trim( url.slice( off, url.length ) );
10597		url = url.slice( 0, off );
10598	}
10599
10600	// If it's a function
10601	if ( jQuery.isFunction( params ) ) {
10602
10603		// We assume that it's the callback
10604		callback = params;
10605		params = undefined;
10606
10607	// Otherwise, build a param string
10608	} else if ( params && typeof params === "object" ) {
10609		type = "POST";
10610	}
10611
10612	// If we have elements to modify, make the request
10613	if ( self.length > 0 ) {
10614		jQuery.ajax( {
10615			url: url,
10616
10617			// If "type" variable is undefined, then "GET" method will be used.
10618			// Make value of this field explicit since
10619			// user can override it through ajaxSetup method
10620			type: type || "GET",
10621			dataType: "html",
10622			data: params
10623		} ).done( function( responseText ) {
10624
10625			// Save response for use in complete callback
10626			response = arguments;
10627
10628			self.html( selector ?
10629
10630				// If a selector was specified, locate the right elements in a dummy div
10631				// Exclude scripts to avoid IE 'Permission Denied' errors
10632				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10633
10634				// Otherwise use the full result
10635				responseText );
10636
10637		// If the request succeeds, this function gets "data", "status", "jqXHR"
10638		// but they are ignored because response was set above.
10639		// If it fails, this function gets "jqXHR", "status", "error"
10640		} ).always( callback && function( jqXHR, status ) {
10641			self.each( function() {
10642				callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10643			} );
10644		} );
10645	}
10646
10647	return this;
10648};
10649
10650
10651
10652
10653// Attach a bunch of functions for handling common AJAX events
10654jQuery.each( [
10655	"ajaxStart",
10656	"ajaxStop",
10657	"ajaxComplete",
10658	"ajaxError",
10659	"ajaxSuccess",
10660	"ajaxSend"
10661], function( i, type ) {
10662	jQuery.fn[ type ] = function( fn ) {
10663		return this.on( type, fn );
10664	};
10665} );
10666
10667
10668
10669
10670jQuery.expr.filters.animated = function( elem ) {
10671	return jQuery.grep( jQuery.timers, function( fn ) {
10672		return elem === fn.elem;
10673	} ).length;
10674};
10675
10676
10677
10678
10679
10680/**
10681 * Gets a window from an element
10682 */
10683function getWindow( elem ) {
10684	return jQuery.isWindow( elem ) ?
10685		elem :
10686		elem.nodeType === 9 ?
10687			elem.defaultView || elem.parentWindow :
10688			false;
10689}
10690
10691jQuery.offset = {
10692	setOffset: function( elem, options, i ) {
10693		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10694			position = jQuery.css( elem, "position" ),
10695			curElem = jQuery( elem ),
10696			props = {};
10697
10698		// set position first, in-case top/left are set even on static elem
10699		if ( position === "static" ) {
10700			elem.style.position = "relative";
10701		}
10702
10703		curOffset = curElem.offset();
10704		curCSSTop = jQuery.css( elem, "top" );
10705		curCSSLeft = jQuery.css( elem, "left" );
10706		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10707			jQuery.inArray( "auto", [ curCSSTop, curCSSLeft ] ) > -1;
10708
10709		// need to be able to calculate position if either top or left
10710		// is auto and position is either absolute or fixed
10711		if ( calculatePosition ) {
10712			curPosition = curElem.position();
10713			curTop = curPosition.top;
10714			curLeft = curPosition.left;
10715		} else {
10716			curTop = parseFloat( curCSSTop ) || 0;
10717			curLeft = parseFloat( curCSSLeft ) || 0;
10718		}
10719
10720		if ( jQuery.isFunction( options ) ) {
10721
10722			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10723			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10724		}
10725
10726		if ( options.top != null ) {
10727			props.top = ( options.top - curOffset.top ) + curTop;
10728		}
10729		if ( options.left != null ) {
10730			props.left = ( options.left - curOffset.left ) + curLeft;
10731		}
10732
10733		if ( "using" in options ) {
10734			options.using.call( elem, props );
10735		} else {
10736			curElem.css( props );
10737		}
10738	}
10739};
10740
10741jQuery.fn.extend( {
10742	offset: function( options ) {
10743		if ( arguments.length ) {
10744			return options === undefined ?
10745				this :
10746				this.each( function( i ) {
10747					jQuery.offset.setOffset( this, options, i );
10748				} );
10749		}
10750
10751		var docElem, win,
10752			box = { top: 0, left: 0 },
10753			elem = this[ 0 ],
10754			doc = elem && elem.ownerDocument;
10755
10756		if ( !doc ) {
10757			return;
10758		}
10759
10760		docElem = doc.documentElement;
10761
10762		// Make sure it's not a disconnected DOM node
10763		if ( !jQuery.contains( docElem, elem ) ) {
10764			return box;
10765		}
10766
10767		// If we don't have gBCR, just use 0,0 rather than error
10768		// BlackBerry 5, iOS 3 (original iPhone)
10769		if ( typeof elem.getBoundingClientRect !== "undefined" ) {
10770			box = elem.getBoundingClientRect();
10771		}
10772		win = getWindow( doc );
10773		return {
10774			top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
10775			left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
10776		};
10777	},
10778
10779	position: function() {
10780		if ( !this[ 0 ] ) {
10781			return;
10782		}
10783
10784		var offsetParent, offset,
10785			parentOffset = { top: 0, left: 0 },
10786			elem = this[ 0 ];
10787
10788		// Fixed elements are offset from window (parentOffset = {top:0, left
10788: 0},
10789		// because it is its only offset parent
10790		if ( jQuery.css( elem, "position" ) === "fixed" ) {
10791
10792			// we assume that getBoundingClientRect is available when computed position is fixed
10793			offset = elem.getBoundingClientRect();
10794		} else {
10795
10796			// Get *real* offsetParent
10797			offsetParent = this.offsetParent();
10798
10799			// Get correct offsets
10800			offset = this.offset();
10801			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
10802				parentOffset = offsetParent.offset();
10803			}
10804
10805			// Add offsetParent borders
10806			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
10807			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
10808		}
10809
10810		// Subtract parent offsets and element margins
10811		// note: when an element has margin: auto the offsetLeft and marginLeft
10812		// are the same in Safari causing offset.left to incorrectly be 0
10813		return {
10814			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
10815			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
10816		};
10817	},
10818
10819	offsetParent: function() {
10820		return this.map( function() {
10821			var offsetParent = this.offsetParent;
10822
10823			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) &&
10824				jQuery.css( offsetParent, "position" ) === "static" ) ) {
10825				offsetParent = offsetParent.offsetParent;
10826			}
10827			return offsetParent || documentElement;
10828		} );
10829	}
10830} );
10831
10832// Create scrollLeft and scrollTop methods
10833jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
10834	var top = /Y/.test( prop );
10835
10836	jQuery.fn[ method ] = function( val ) {
10837		return access( this, function( elem, method, val ) {
10838			var win = getWindow( elem );
10839
10840			if ( val === undefined ) {
10841				return win ? ( prop in win ) ? win[ prop ] :
10842					win.document.documentElement[ method ] :
10843					elem[ method ];
10844			}
10845
10846			if ( win ) {
10847				win.scrollTo(
10848					!top ? val : jQuery( win ).scrollLeft(),
10849					top ? val : jQuery( win ).scrollTop()
10850				);
10851
10852			} else {
10853				elem[ method ] = val;
10854			}
10855		}, method, val, arguments.length, null );
10856	};
10857} );
10858
10859// Support: Safari<7-8+, Chrome<37-44+
10860// Add the top/left cssHooks using jQuery.fn.position
10861// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
10862// getComputedStyle returns percent when specified for top/left/bottom/right
10863// rather than make the css module depend on the offset module, we just check for it here
10864jQuery.each( [ "top", "left" ], function( i, prop ) {
10865	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
10866		function( elem, computed ) {
10867			if ( computed ) {
10868				computed = curCSS( elem, prop );
10869
10870				// if curCSS returns percentage, fallback to offset
10871				return rnumnonpx.test( computed ) ?
10872					jQuery( elem ).position()[ prop ] + "px" :
10873					computed;
10874			}
10875		}
10876	);
10877} );
10878
10879
10880// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
10881jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
10882	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
10883	function( defaultExtra, funcName ) {
10884
10885		// margin is only for outerHeight, outerWidth
10886		jQuery.fn[ funcName ] = function( margin, value ) {
10887			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
10888				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
10889
10890			return access( this, function( elem, type, value ) {
10891				var doc;
10892
10893				if ( jQuery.isWindow( elem ) ) {
10894
10895					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
10896					// isn't a whole lot we can do. See pull request at this URL for discussion:
10897					// https://github.com/jquery/jquery/pull/764
10898					return elem.document.documentElement[ "client" + name ];
10899				}
10900
10901				// Get document width or height
10902				if ( elem.nodeType === 9 ) {
10903					doc = elem.documentElement;
10904
10905					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
10906					// whichever is greatest
10907					// unfortunately, this causes bug #3838 in IE6/8 only,
10908					// but there is currently no good, small way to fix it.
10909					return Math.max(
10910						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
10911						elem.body[ "offset" + name ], doc[ "offset" + name ],
10912						doc[ "client" + name ]
10913					);
10914				}
10915
10916				return value === undefined ?
10917
10918					// Get width or height on the element, requesting but not forcing parseFloat
10919					jQuery.css( elem, type, extra ) :
10920
10921					// Set width or height on the element
10922					jQuery.style( elem, type, value, extra );
10923			}, type, chainable ? margin : undefined, chainable, null );
10924		};
10925	} );
10926} );
10927
10928
10929jQuery.fn.extend( {
10930
10931	bind: function( types, data, fn ) {
10932		return this.on( types, null, data, fn );
10933	},
10934	unbind: function( types, fn ) {
10935		return this.off( types, null, fn );
10936	},
10937
10938	delegate: function( selector, types, data, fn ) {
10939		return this.on( types, selector, data, fn );
10940	},
10941	undelegate: function( selector, types, fn ) {
10942
10943		// ( namespace ) or ( selector, types [, fn] )
10944		return arguments.length === 1 ?
10945			this.off( selector, "**" ) :
10946			this.off( types, selector || "**", fn );
10947	}
10948} );
10949
10950// The number of elements contained in the matched element set
10951jQuery.fn.size = function() {
10952	return this.length;
10953};
10954
10955jQuery.fn.andSelf = jQuery.fn.addBack;
10956
10957
10958
10959
10960// Register as a named AMD module, since jQuery can be concatenated with other
10961// files that may use define, but not via a proper concatenation script that
10962// understands anonymous AMD modules. A named AMD is safest and most robust
10963// way to register. Lowercase jquery is used because AMD module names are
10964// derived from file names, and jQuery is normally delivered in a lowercase
10965// file name. Do this after creating the global so that if an AMD module wants
10966// to call noConflict to hide this version of jQuery, it will work.
10967
10968// Note that for maximum portability, libraries that are not jQuery should
10969// declare themselves as anonymous modules, and avoid setting a global if an
10970// AMD loader is present. jQuery is a special case. For more information, see
10971// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
10972
10973if ( typeof define === "function" && define.amd ) {
10974	define( "jquery", [], function() {
10975		return jQuery;
10976	} );
10977}
10978
10979
10980
10981var
10982
10983	// Map over jQuery in case of overwrite
10984	_jQuery = window.jQuery,
10985
10986	// Map over the $ in case of overwrite
10987	_$ = window.$;
10988
10989jQuery.noConflict = function( deep ) {
10990	if ( window.$ === jQuery ) {
10991		window.$ = _$;
10992	}
10993
10994	if ( deep && window.jQuery === jQuery ) {
10995		window.jQuery = _jQuery;
10996	}
10997
10998	return jQuery;
10999};
11000
11001// Expose jQuery and $ identifiers, even in
11002// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11003// and CommonJS for browser emulators (#13566)
11004if ( !noGlobal ) {
11005	window.jQuery = window.$ = jQuery;
11006}
11007
11008return jQuery;
11009}));
11010( function( factory ) {
11011	"use strict";
11012
11013	if ( typeof define === "function" && define.amd ) {
11014
11015		// AMD. Register as an anonymous module.
11016		define( [ "jquery" ], factory );
11017	} else {
11018
11019		// Browser globals
11020		factory( jQuery );
11021	}
11022} )( function( $ ) {
11023"use strict";
11024
11025$.ui = $.ui || {};
11026
11027return $.ui.version = "1.13.0";
11028
11029} );
11030
11031
11032/*!
11033 * jQuery UI :data 1.13.0
11034 * http://jqueryui.com
11035 *
11036 * Copyright jQuery Foundation and other contributors
11037 * Released under the MIT license.
11038 * http://jquery.org/license
11039 */
11040
11041//>>label: :data Selector
11042//>>group: Core
11043//>>description: Selects elements which have data stored under the specified key.
11044//>>docs: http://api.jqueryui.com/data-selector/
11045
11046( function( factory ) {
11047	"use strict";
11048
11049	if ( typeof define === "function" && define.amd ) {
11050
11051		// AMD. Register as an anonymous module.
11052		define( [ "jquery", "./version" ], factory );
11053	} else {
11054
11055		// Browser globals
11056		factory( jQuery );
11057	}
11058} )( function( $ ) {
11059"use strict";
11060
11061return $.extend( $.expr.pseudos, {
11062	data: $.expr.createPseudo ?
11063		$.expr.createPseudo( function( dataName ) {
11064			return function( elem ) {
11065				return !!$.data( elem, dataName );
11066			};
11067		} ) :
11068
11069		// Support: jQuery <1.8
11070		function( elem, i, match ) {
11071			return !!$.data( elem, match[ 3 ] );
11072		}
11073} );
11074} );
11075
11076
11077/*!
11078 * jQuery UI Disable Selection 1.13.0
11079 * http://jqueryui.com
11080 *
11081 * Copyright jQuery Foundation and other contributors
11082 * Released under the MIT license.
11083 * http://jquery.org/license
11084 */
11085
11086//>>label: disableSelection
11087//>>group: Core
11088//>>description: Disable selection of text content within the set of matched elements.
11089//>>docs: http://api.jqueryui.com/disableSelection/
11090
11091// This file is deprecated
11092( function( factory ) {
11093	"use strict";
11094
11095	if ( typeof define === "function" && define.amd ) {
11096
11097		// AMD. Register as an anonymous module.
11098		define( [ "jquery", "./version" ], factory );
11099	} else {
11100
11101		// Browser globals
11102		factory( jQuery );
11103	}
11104} )( function( $ ) {
11105"use strict";
11106
11107return $.fn.extend( {
11108	disableSelection: ( function() {
11109		var eventType = "onselectstart" in document.createElement( "div" ) ?
11110			"selectstart" :
11111			"mousedown";
11112
11113		return function() {
11114			return this.on( eventType + ".ui-disableSelection", function( event ) {
11115				event.preventDefault();
11116			} );
11117		};
11118	} )(),
11119
11120	enableSelection: function() {
11121		return this.off( ".ui-disableSelection" );
11122	}
11123} );
11124
11125} );
11126
11127
11128/*!
11129 * jQuery UI Focusable 1.13.0
11130 * http://jqueryui.com
11131 *
11132 * Copyright jQuery Foundation and other contributors
11133 * Released under the MIT license.
11134 * http://jquery.org/license
11135 */
11136
11137//>>label: :focusable Selector
11138//>>group: Core
11139//>>description: Selects elements which can be focused.
11140//>>docs: http://api.jqueryui.com/focusable-selector/
11141
11142( function( factory ) {
11143	"use strict";
11144
11145	if ( typeof define === "function" && define.amd ) {
11146
11147		// AMD. Register as an anonymous module.
11148		define( [ "jquery", "./version" ], factory );
11149	} else {
11150
11151		// Browser globals
11152		factory( jQuery );
11153	}
11154} )( function( $ ) {
11155"use strict";
11156
11157// Selectors
11158$.ui.focusable = function( element, hasTabindex ) {
11159	var map, mapName, img, focusableIfVisible, fieldset,
11160		nodeName = element.nodeName.toLowerCase();
11161
11162	if ( "area" === nodeName ) {
11163		map = element.parentNode;
11164		mapName = map.name;
11165		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
11166			return false;
11167		}
11168		img = $( "img[usemap='#" + mapName + "']" );
11169		return img.length > 0 && img.is( ":visible" );
11170	}
11171
11172	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
11173		focusableIfVisible = !element.disabled;
11174
11175		if ( focusableIfVisible ) {
11176
11177			// Form controls within a disabled fieldset are disabled.
11178			// However, controls within the fieldset's legend do not get disabled.
11179			// Since controls generally aren't placed inside legends, we skip
11180			// this portion of the check.
11181			fieldset = $( element ).closest( "fieldset" )[ 0 ];
11182			if ( fieldset ) {
11183				focusableIfVisible = !fieldset.disabled;
11184			}
11185		}
11186	} else if ( "a" === nodeName ) {
11187		focusableIfVisible = element.href || hasTabindex;
11188	} else {
11189		focusableIfVisible = hasTabindex;
11190	}
11191
11192	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
11193};
11194
11195// Support: IE 8 only
11196// IE 8 doesn't resolve inherit to visible/hidden for computed values
11197function visible( element ) {
11198	var visibility = element.css( "visibility" );
11199	while ( visibility === "inherit" ) {
11200		element = element.parent();
11201		visibility = element.css( "visibility" );
11202	}
11203	return visibility === "visible";
11204}
11205
11206$.extend( $.expr.pseudos, {
11207	focusable: function( element ) {
11208		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
11209	}
11210} );
11211
11212return $.ui.focusable;
11213
11214} );
11215
11216( function( factory ) {
11217	"use strict";
11218
11219	if ( typeof define === "function" && define.amd ) {
11220
11221		// AMD. Register as an anonymous module.
11222		define( [ "jquery", "./version" ], factory );
11223	} else {
11224
11225		// Browser globals
11226		factory( jQuery );
11227	}
11228} )( function( $ ) {
11229"use strict";
11230
11231// Support: IE8 Only
11232// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
11233// with a string, so we need to find the proper form.
11234return $.fn._form = function() {
11235	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
11236};
11237
11238} );
11239
11240( function( factory ) {
11241	"use strict";
11242
11243	if ( typeof define === "function" && define.amd ) {
11244
11245		// AMD. Register as an anonymous module.
11246		define( [ "jquery", "./version" ], factory );
11247	} else {
11248
11249		// Browser globals
11250		factory( jQuery );
11251	}
11252} )( function( $ ) {
11253"use strict";
11254
11255// This file is deprecated
11256return $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
11257} );
11258
11259
11260/*!
11261 * jQuery UI Keycode 1.13.0
11262 * http://jqueryui.com
11263 *
11264 * Copyright jQuery Foundation and other contributors
11265 * Released under the MIT license.
11266 * http://jquery.org/license
11267 */
11268
11269//>>label: Keycode
11270//>>group: Core
11271//>>description: Provide keycodes as keynames
11272//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
11273
11274( function( factory ) {
11275	"use strict";
11276
11277	if ( typeof define === "function" && define.amd ) {
11278
11279		// AMD. Register as an anonymous module.
11280		define( [ "jquery", "./version" ], factory );
11281	} else {
11282
11283		// Browser globals
11284		factory( jQuery );
11285	}
11286} )( function( $ ) {
11287"use strict";
11288
11289return $.ui.keyCode = {
11290	BACKSPACE: 8,
11291	COMMA: 188,
11292	DELETE: 46,
11293	DOWN: 40,
11294	END: 35,
11295	ENTER: 13,
11296	ESCAPE: 27,
11297	HOME: 36,
11298	LEFT: 37,
11299	PAGE_DOWN: 34,
11300	PAGE_UP: 33,
11301	PERIOD: 190,
11302	RIGHT: 39,
11303	SPACE: 32,
11304	TAB: 9,
11305	UP: 38
11306};
11307
11308} );
11309
11310
11311/*!
11312 * jQuery UI Labels 1.13.0
11313 * http://jqueryui.com
11314 *
11315 * Copyright jQuery Foundation and other contributors
11316 * Released under the MIT license.
11317 * http://jquery.org/license
11318 */
11319
11320//>>label: labels
11321//>>group: Core
11322//>>description: Find all the labels associated with a given input
11323//>>docs: http://api.jqueryui.com/labels/
11324
11325( function( factory ) {
11326	"use strict";
11327
11328	if ( typeof define === "function" && define.amd ) {
11329
11330		// AMD. Register as an anonymous module.
11331		define( [ "jquery", "./version" ], factory );
11332	} else {
11333
11334		// Browser globals
11335		factory( jQuery );
11336	}
11337} )( function( $ ) {
11338"use strict";
11339
11340return $.fn.labels = function() {
11341	var ancestor, selector, id, labels, ancestors;
11342
11343	if ( !this.length ) {
11344		return this.pushStack( [] );
11345	}
11346
11347	// Check control.labels first
11348	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
11349		return this.pushStack( this[ 0 ].labels );
11350	}
11351
11352	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
11353	// Above browsers do not support control.labels. Everything below is to support them
11354	// as well as document fragments. control.labels does not work on document fragments
11355	labels = this.eq( 0 ).parents( "label" );
11356
11357	// Look for the label based on the id
11358	id = this.attr( "id" );
11359	if ( id ) {
11360
11361		// We don't search against the document in case the element
11362		// is disconnected from the DOM
vendor: 6,202 bytes, lines 11363-11628
11363		ancestor = this.eq( 0 ).parents().last();
11364
11365		// Get a full set of top level ancestors
11366		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
11367
11368		// Create a selector for the label based on the id
11369		selector = "label[for='" + $.escapeSelector( id ) + "']";
11370
11371		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
11372
11373	}
11374
11375	// Return whatever we have found for labels
11376	return this.pushStack( labels );
11377};
11378
11379} );
11380
11381
11382/*!
11383 * jQuery UI Support for jQuery core 1.8.x and newer 1.13.0
11384 * http://jqueryui.com
11385 *
11386 * Copyright jQuery Foundation and other contributors
11387 * Released under the MIT license.
11388 * http://jquery.org/license
11389 *
11390 */
11391
11392//>>label: jQuery 1.8+ Support
11393//>>group: Core
11394//>>description: Support version 1.8.x and newer of jQuery core
11395
11396( function( factory ) {
11397"use strict";
11398
11399	if ( typeof define === "function" && define.amd ) {
11400
11401		// AMD. Register as an anonymous module.
11402		define( [ "jquery", "./version" ], factory );
11403	} else {
11404
11405		// Browser globals
11406		factory( jQuery );
11407	}
11408} )( function( $ ) {
11409"use strict";
11410
11411// Support: jQuery 1.9.x or older
11412// $.expr[ ":" ] is deprecated.
11413if ( !$.expr.pseudos ) {
11414	$.expr.pseudos = $.expr[ ":" ];
11415}
11416
11417// Support: jQuery 1.11.x or older
11418// $.unique has been renamed to $.uniqueSort
11419if ( !$.uniqueSort ) {
11420	$.uniqueSort = $.unique;
11421}
11422
11423// Support: jQuery 2.2.x or older.
11424// This method has been defined in jQuery 3.0.0.
11425// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
11426if ( !$.escapeSelector ) {
11427
11428	// CSS string/identifier serialization
11429	// https://drafts.csswg.org/cssom/#common-serializing-idioms
11430	var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
11431
11432	var fcssescape = function( ch, asCodePoint ) {
11433		if ( asCodePoint ) {
11434
11435			// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
11436			if ( ch === "\0" ) {
11437				return "\uFFFD";
11438			}
11439
11440			// Control characters and (dependent upon position) numbers get escaped as code points
11441			return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
11442		}
11443
11444		// Other potentially-special ASCII characters get backslash-escaped
11445		return "\\" + ch;
11446	};
11447
11448	$.escapeSelector = function( sel ) {
11449		return ( sel + "" ).replace( rcssescape, fcssescape );
11450	};
11451}
11452
11453// Support: jQuery 3.4.x or older
11454// These methods have been defined in jQuery 3.5.0.
11455if ( !$.fn.even || !$.fn.odd ) {
11456	$.fn.extend( {
11457		even: function() {
11458			return this.filter( function( i ) {
11459				return i % 2 === 0;
11460			} );
11461		},
11462		odd: function() {
11463			return this.filter( function( i ) {
11464				return i % 2 === 1;
11465			} );
11466		}
11467	} );
11468}
11469
11470} );
11471
11472( function( factory ) {
11473	"use strict";
11474
11475	if ( typeof define === "function" && define.amd ) {
11476
11477		// AMD. Register as an anonymous module.
11478		define( [ "jquery", "./version" ], factory );
11479	} else {
11480
11481		// Browser globals
11482		factory( jQuery );
11483	}
11484} )( function( $ ) {
11485"use strict";
11486
11487// $.ui.plugin is deprecated. Use $.widget() extensions instead.
11488return $.ui.plugin = {
11489	add: function( module, option, set ) {
11490		var i,
11491			proto = $.ui[ module ].prototype;
11492		for ( i in set ) {
11493			proto.plugins[ i ] = proto.plugins[ i ] || [];
11494			proto.plugins[ i ].push( [ option, set[ i ] ] );
11495		}
11496	},
11497	call: function( instance, name, args, allowDisconnected ) {
11498		var i,
11499			set = instance.plugins[ name ];
11500
11501		if ( !set ) {
11502			return;
11503		}
11504
11505		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
11506				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
11507			return;
11508		}
11509
11510		for ( i = 0; i < set.length; i++ ) {
11511			if ( instance.options[ set[ i ][ 0 ] ] ) {
11512				set[ i ][ 1 ].apply( instance.element, args );
11513			}
11514		}
11515	}
11516};
11517
11518} );
11519
11520( function( factory ) {
11521	"use strict";
11522
11523	if ( typeof define === "function" && define.amd ) {
11524
11525		// AMD. Register as an anonymous module.
11526		define( [ "jquery", "./version" ], factory );
11527	} else {
11528
11529		// Browser globals
11530		factory( jQuery );
11531	}
11532} )( function( $ ) {
11533"use strict";
11534
11535return $.ui.safeActiveElement = function( document ) {
11536	var activeElement;
11537
11538	// Support: IE 9 only
11539	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
11540	try {
11541		activeElement = document.activeElement;
11542	} catch ( error ) {
11543		activeElement = document.body;
11544	}
11545
11546	// Support: IE 9 - 11 only
11547	// IE may return null instead of an element
11548	// Interestingly, this only seems to occur when NOT in an iframe
11549	if ( !activeElement ) {
11550		activeElement = document.body;
11551	}
11552
11553	// Support: IE 11 only
11554	// IE11 returns a seemingly empty object in some cases when accessing
11555	// document.activeElement from an <iframe>
11556	if ( !activeElement.nodeName ) {
11557		activeElement = document.body;
11558	}
11559
11560	return activeElement;
11561};
11562
11563} );
11564
11565( function( factory ) {
11566	"use strict";
11567
11568	if ( typeof define === "function" && define.amd ) {
11569
11570		// AMD. Register as an anonymous module.
11571		define( [ "jquery", "./version" ], factory );
11572	} else {
11573
11574		// Browser globals
11575		factory( jQuery );
11576	}
11577} )( function( $ ) {
11578"use strict";
11579
11580return $.ui.safeBlur = function( element ) {
11581
11582	// Support: IE9 - 10 only
11583	// If the <body> is blurred, IE will switch windows, see #9420
11584	if ( element && element.nodeName.toLowerCase() !== "body" ) {
11585		$( element ).trigger( "blur" );
11586	}
11587};
11588
11589} );
11590
11591
11592/*!
11593 * jQuery UI Scroll Parent 1.13.0
11594 * http://jqueryui.com
11595 *
11596 * Copyright jQuery Foundation and other contributors
11597 * Released under the MIT license.
11598 * http://jquery.org/license
11599 */
11600
11601//>>label: scrollParent
11602//>>group: Core
11603//>>description: Get the closest ancestor element that is scrollable.
11604//>>docs: http://api.jqueryui.com/scrollParent/
11605
11606( function( factory ) {
11607	"use strict";
11608
11609	if ( typeof define === "function" && define.amd ) {
11610
11611		// AMD. Register as an anonymous module.
11612		define( [ "jquery", "./version" ], factory );
11613	} else {
11614
11615		// Browser globals
11616		factory( jQuery );
11617	}
11618} )( function( $ ) {
11619"use strict";
11620
11621return $.fn.scrollParent = function( includeHidden ) {
11622	var position = this.css( "position" ),
11623		excludeStaticParent = position === "absolute",
11624		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
11625		scrollParent = this.parents().filter( function() {
11626			var parent = $( this );
11627			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
11628				return false;
11629			}
11630			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
11631				parent.css( "overflow-x" ) );
11632		} ).eq( 0 );
11633
11634	return position === "fixed" || !scrollParent.length ?
11635		$( this[ 0 ].ownerDocument || document ) :
11636		scrollParent;
11637};
11638
11639} );
11640
11641
11642
11643/*!
11644 * jQuery UI Tabbable 1.13.0
11645 * http://jqueryui.com
11646 *
11647 * Copyright jQuery Foundation and other contributors
11648 * Released under the MIT license.
11649 * http://jquery.org/license
11650 */
11651
11652//>>label: :tabbable Selector
11653//>>group: Core
11654//>>description: Selects elements which can be tabbed to.
11655//>>docs: http://api.jqueryui.com/tabbable-selector/
11656
11657( function( factory ) {
11658	"use strict";
11659
11660	if ( typeof define === "function" && define.amd ) {
11661
11662		// AMD. Register as an anonymous module.
11663		define( [ "jquery", "./version", "./focusable" ], factory );
11664	} else {
11665
11666		// Browser globals
11667		factory( jQuery );
11668	}
11669} )( function( $ ) {
11670"use strict";
11671
11672return $.extend( $.expr.pseudos, {
11673	tabbable: function( element ) {
11674		var tabIndex = $.attr( element, "tabindex" ),
11675			hasTabindex = tabIndex != null;
11676		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
11677	}
11678} );
11679
11680} );
11681
11682
11683/*!
11684 * jQuery UI Unique ID 1.13.0
11685 * http://jqueryui.com
11686 *
11687 * Copyright jQuery Foundation and other contributors
11688 * Released under the MIT license.
11689 * http://jquery.org/license
11690 */
11691
11692//>>label: uniqueId
11693//>>group: Core
11694//>>description: Functions to generate and remove uniqueId's
11695//>>docs: http://api.jqueryui.com/uniqueId/
11696
11697( function( factory ) {
11698	"use strict";
11699
11700	if ( typeof define === "function" && define.amd ) {
11701
11702		// AMD. Register as an anonymous module.
11703		define( [ "jquery", "./version" ], factory );
11704	} else {
11705
11706		// Browser globals
11707		factory( jQuery );
11708	}
11709} )( function( $ ) {
11710"use strict";
11711
11712return $.fn.extend( {
11713	uniqueId: ( function() {
11714		var uuid = 0;
11715
11716		return function() {
11717			return this.each( function() {
11718				if ( !this.id ) {
11719					this.id = "ui-id-" + ( ++uuid );
11720				}
11721			} );
11722		};
11723	} )(),
11724
11725	removeUniqueId: function() {
11726		return this.each( function() {
11727			if ( /^ui-id-\d+$/.test( this.id ) ) {
11728				$( this ).removeAttr( "id" );
11729			}
11730		} );
11731	}
11732} );
11733
11734} );
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751( function( factory ) {
11752	"use strict";
11753
11754	if ( typeof define === "function" && define.amd ) {
11755
11756		// AMD. Register as an anonymous module.
11757		define( [ "jquery", "./version" ], factory );
11758	} else {
11759
11760		// Browser globals
11761		factory( jQuery );
11762	}
11763} )( function( $ ) {
11764	"use strict";
11765
11766// Create a local jQuery because jQuery Color relies on it and the
11767// global may not exist with AMD and a custom build (#10199).
11768// This module is a noop if used as a regular AMD module.
11769// eslint-disable-next-line no-unused-vars
11770var jQuery = $;
11771
11772} );
11773/*!
11774 * jQuery Color Animations v2.2.0
11775 * https://github.com/jquery/jquery-color
11776 *
11777 * Copyright OpenJS Foundation and other contributors
11778 * Released under the MIT license.
11779 * http://jquery.org/license
11780 *
11781 * Date: Sun May 10 09:02:36 2020 +0200
11782 */
11783
11784
11785( function( root, factory ) {
11786	if ( typeof define === "function" && define.amd ) {
11787
11788		// AMD. Register as an anonymous module.
11789		define( [ "jquery" ], factory );
11790	} else if ( typeof exports === "object" ) {
11791		module.exports = factory( require( "jquery" ) );
11792	} else {
11793		factory( root.jQuery );
11794	}
11795} )( this, function( jQuery, undefined ) {
vendor: 16,825 bytes, lines 11795-12494
11795
11796
11797	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
11798		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
11799
11800	class2type = {},
11801	toString = class2type.toString,
11802
11803	// plusequals test for += 100 -= 100
11804	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
11805
11806	// a set of RE's that can match strings and generate color tuples.
11807	stringParsers = [ {
11808			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11809			parse: function( execResult ) {
11810				return [
11811					execResult[ 1 ],
11812					execResult[ 2 ],
11813					execResult[ 3 ],
11814					execResult[ 4 ]
11815				];
11816			}
11817		}, {
11818			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11819			parse: function( execResult ) {
11820				return [
11821					execResult[ 1 ] * 2.55,
11822					execResult[ 2 ] * 2.55,
11823					execResult[ 3 ] * 2.55,
11824					execResult[ 4 ]
11825				];
11826			}
11827		}, {
11828
11829			// this regex ignores A-F because it's compared against an already lowercased string
11830			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
11831			parse: function( execResult ) {
11832				return [
11833					parseInt( execResult[ 1 ], 16 ),
11834					parseInt( execResult[ 2 ], 16 ),
11835					parseInt( execResult[ 3 ], 16 ),
11836					execResult[ 4 ] ?
11837						( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
11838						1
11839				];
11840			}
11841		}, {
11842
11843			// this regex ignores A-F because it's compared against an already lowercased string
11844			re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
11845			parse: function( execResult ) {
11846				return [
11847					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
11848					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
11849					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
11850					execResult[ 4 ] ?
11851						( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
11852							.toFixed( 2 ) :
11853						1
11854				];
11855			}
11856		}, {
11857			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
11858			space: "hsla",
11859			parse: function( execResult ) {
11860				return [
11861					execResult[ 1 ],
11862					execResult[ 2 ] / 100,
11863					execResult[ 3 ] / 100,
11864					execResult[ 4 ]
11865				];
11866			}
11867		} ],
11868
11869	// jQuery.Color( )
11870	color = jQuery.Color = function( color, green, blue, alpha ) {
11871		return new jQuery.Color.fn.parse( color, green, blue, alpha );
11872	},
11873	spaces = {
11874		rgba: {
11875			props: {
11876				red: {
11877					idx: 0,
11878					type: "byte"
11879				},
11880				green: {
11881					idx: 1,
11882					type: "byte"
11883				},
11884				blue: {
11885					idx: 2,
11886					type: "byte"
11887				}
11888			}
11889		},
11890
11891		hsla: {
11892			props: {
11893				hue: {
11894					idx: 0,
11895					type: "degrees"
11896				},
11897				saturation: {
11898					idx: 1,
11899					type: "percent"
11900				},
11901				lightness: {
11902					idx: 2,
11903					type: "percent"
11904				}
11905			}
11906		}
11907	},
11908	propTypes = {
11909		"byte": {
11910			floor: true,
11911			max: 255
11912		},
11913		"percent": {
11914			max: 1
11915		},
11916		"degrees": {
11917			mod: 360,
11918			floor: true
11919		}
11920	},
11921	support = color.support = {},
11922
11923	// element for support tests
11924	supportElem = jQuery( "<p>" )[ 0 ],
11925
11926	// colors = jQuery.Color.names
11927	colors,
11928
11929	// local aliases of functions called often
11930	each = jQuery.each;
11931
11932// determine rgba support immediately
11933supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
11934support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
11935
11936// define cache name and alpha properties
11937// for rgba and hsla spaces
11938each( spaces, function( spaceName, space ) {
11939	space.cache = "_" + spaceName;
11940	space.props.alpha = {
11941		idx: 3,
11942		type: "percent",
11943		def: 1
11944	};
11945} );
11946
11947// Populate the class2type map
11948jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
11949	function( _i, name ) {
11950		class2type[ "[object " + name + "]" ] = name.toLowerCase();
11951	} );
11952
11953function getType( obj ) {
11954	if ( obj == null ) {
11955		return obj + "";
11956	}
11957
11958	return typeof obj === "object" ?
11959		class2type[ toString.call( obj ) ] || "object" :
11960		typeof obj;
11961}
11962
11963function clamp( value, prop, allowEmpty ) {
11964	var type = propTypes[ prop.type ] || {};
11965
11966	if ( value == null ) {
11967		return ( allowEmpty || !prop.def ) ? null : prop.def;
11968	}
11969
11970	// ~~ is an short way of doing floor for positive numbers
11971	value = type.floor ? ~~value : parseFloat( value );
11972
11973	// IE will pass in empty strings as value for alpha,
11974	// which will hit this case
11975	if ( isNaN( value ) ) {
11976		return prop.def;
11977	}
11978
11979	if ( type.mod ) {
11980
11981		// we add mod before modding to make sure that negatives values
11982		// get converted properly: -10 -> 350
11983		return ( value + type.mod ) % type.mod;
11984	}
11985
11986	// for now all property types without mod have min and max
11987	return Math.min( type.max, Math.max( 0, value ) );
11988}
11989
11990function stringParse( string ) {
11991	var inst = color(),
11992		rgba = inst._rgba = [];
11993
11994	string = string.toLowerCase();
11995
11996	each( stringParsers, function( _i, parser ) {
11997		var parsed,
11998			match = parser.re.exec( string ),
11999			values = match && parser.parse( match ),
12000			spaceName = parser.space || "rgba";
12001
12002		if ( values ) {
12003			parsed = inst[ spaceName ]( values );
12004
12005			// if this was an rgba parse the assignment might happen twice
12006			// oh well....
12007			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
12008			rgba = inst._rgba = parsed._rgba;
12009
12010			// exit each( stringParsers ) here because we matched
12011			return false;
12012		}
12013	} );
12014
12015	// Found a stringParser that handled it
12016	if ( rgba.length ) {
12017
12018		// if this came from a parsed string, force "transparent" when alpha is 0
12019		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
12020		if ( rgba.join() === "0,0,0,0" ) {
12021			jQuery.extend( rgba, colors.transparent );
12022		}
12023		return inst;
12024	}
12025
12026	// named colors
12027	return colors[ string ];
12028}
12029
12030color.fn = jQuery.extend( color.prototype, {
12031	parse: function( red, green, blue, alpha ) {
12032		if ( red === undefined ) {
12033			this._rgba = [ null, null, null, null ];
12034			return this;
12035		}
12036		if ( red.jquery || red.nodeType ) {
12037			red = jQuery( red ).css( green );
12038			green = undefined;
12039		}
12040
12041		var inst = this,
12042			type = getType( red ),
12043			rgba = this._rgba = [];
12044
12045		// more than 1 argument specified - assume ( red, green, blue, alpha )
12046		if ( green !== undefined ) {
12047			red = [ red, green, blue, alpha ];
12048			type = "array";
12049		}
12050
12051		if ( type === "string" ) {
12052			return this.parse( stringParse( red ) || colors._default );
12053		}
12054
12055		if ( type === "array" ) {
12056			each( spaces.rgba.props, function( _key, prop ) {
12057				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
12058			} );
12059			return this;
12060		}
12061
12062		if ( type === "object" ) {
12063			if ( red instanceof color ) {
12064				each( spaces, function( _spaceName, space ) {
12065					if ( red[ space.cache ] ) {
12066						inst[ space.cache ] = red[ space.cache ].slice();
12067					}
12068				} );
12069			} else {
12070				each( spaces, function( _spaceName, space ) {
12071					var cache = space.cache;
12072					each( space.props, function( key, prop ) {
12073
12074						// if the cache doesn't exist, and we know how to convert
12075						if ( !inst[ cache ] && space.to ) {
12076
12077							// if the value was null, we don't need to copy it
12078							// if the key was alpha, we don't need to copy it either
12079							if ( key === "alpha" || red[ key ] == null ) {
12080								return;
12081							}
12082							inst[ cache ] = space.to( inst._rgba );
12083						}
12084
12085						// this is the only case where we allow nulls for ALL properties.
12086						// call clamp with alwaysAllowEmpty
12087						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
12088					} );
12089
12090					// everything defined but alpha?
12091					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
12092
12093						// use the default of 1
12094						if ( inst[ cache ][ 3 ] == null ) {
12095							inst[ cache ][ 3 ] = 1;
12096						}
12097
12098						if ( space.from ) {
12099							inst._rgba = space.from( inst[ cache ] );
12100						}
12101					}
12102				} );
12103			}
12104			return this;
12105		}
12106	},
12107	is: function( compare ) {
12108		var is = color( compare ),
12109			same = true,
12110			inst = this;
12111
12112		each( spaces, function( _, space ) {
12113			var localCache,
12114				isCache = is[ space.cache ];
12115			if ( isCache ) {
12116				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
12117				each( space.props, function( _, prop ) {
12118					if ( isCache[ prop.idx ] != null ) {
12119						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
12120						return same;
12121					}
12122				} );
12123			}
12124			return same;
12125		} );
12126		return same;
12127	},
12128	_space: function() {
12129		var used = [],
12130			inst = this;
12131		each( spaces, function( spaceName, space ) {
12132			if ( inst[ space.cache ] ) {
12133				used.push( spaceName );
12134			}
12135		} );
12136		return used.pop();
12137	},
12138	transition: function( other, distance ) {
12139		var end = color( other ),
12140			spaceName = end._space(),
12141			space = spaces[ spaceName ],
12142			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
12143			start = startColor[ space.cache ] || space.to( startColor._rgba ),
12144			result = start.slice();
12145
12146		end = end[ space.cache ];
12147		each( space.props, function( _key, prop ) {
12148			var index = prop.idx,
12149				startValue = start[ index ],
12150				endValue = end[ index ],
12151				type = propTypes[ prop.type ] || {};
12152
12153			// if null, don't override start value
12154			if ( endValue === null ) {
12155				return;
12156			}
12157
12158			// if null - use end
12159			if ( startValue === null ) {
12160				result[ index ] = endValue;
12161			} else {
12162				if ( type.mod ) {
12163					if ( endValue - startValue > type.mod / 2 ) {
12164						startValue += type.mod;
12165					} else if ( startValue - endValue > type.mod / 2 ) {
12166						startValue -= type.mod;
12167					}
12168				}
12169				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
12170			}
12171		} );
12172		return this[ spaceName ]( result );
12173	},
12174	blend: function( opaque ) {
12175
12176		// if we are already opaque - return ourself
12177		if ( this._rgba[ 3 ] === 1 ) {
12178			return this;
12179		}
12180
12181		var rgb = this._rgba.slice(),
12182			a = rgb.pop(),
12183			blend = color( opaque )._rgba;
12184
12185		return color( jQuery.map( rgb, function( v, i ) {
12186			return ( 1 - a ) * blend[ i ] + a * v;
12187		} ) );
12188	},
12189	toRgbaString: function() {
12190		var prefix = "rgba(",
12191			rgba = jQuery.map( this._rgba, function( v, i ) {
12192				if ( v != null ) {
12193					return v;
12194				}
12195				return i > 2 ? 1 : 0;
12196			} );
12197
12198		if ( rgba[ 3 ] === 1 ) {
12199			rgba.pop();
12200			prefix = "rgb(";
12201		}
12202
12203		return prefix + rgba.join() + ")";
12204	},
12205	toHslaString: function() {
12206		var prefix = "hsla(",
12207			hsla = jQuery.map( this.hsla(), function( v, i ) {
12208				if ( v == null ) {
12209					v = i > 2 ? 1 : 0;
12210				}
12211
12212				// catch 1 and 2
12213				if ( i && i < 3 ) {
12214					v = Math.round( v * 100 ) + "%";
12215				}
12216				return v;
12217			} );
12218
12219		if ( hsla[ 3 ] === 1 ) {
12220			hsla.pop();
12221			prefix = "hsl(";
12222		}
12223		return prefix + hsla.join() + ")";
12224	},
12225	toHexString: function( includeAlpha ) {
12226		var rgba = this._rgba.slice(),
12227			alpha = rgba.pop();
12228
12229		if ( includeAlpha ) {
12230			rgba.push( ~~( alpha * 255 ) );
12231		}
12232
12233		return "#" + jQuery.map( rgba, function( v ) {
12234
12235			// default to 0 when nulls exist
12236			v = ( v || 0 ).toString( 16 );
12237			return v.length === 1 ? "0" + v : v;
12238		} ).join( "" );
12239	},
12240	toString: function() {
12241		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
12242	}
12243} );
12244color.fn.parse.prototype = color.fn;
12245
12246// hsla conversions adapted from:
12247// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
12248
12249function hue2rgb( p, q, h ) {
12250	h = ( h + 1 ) % 1;
12251	if ( h * 6 < 1 ) {
12252		return p + ( q - p ) * h * 6;
12253	}
12254	if ( h * 2 < 1 ) {
12255		return q;
12256	}
12257	if ( h * 3 < 2 ) {
12258		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
12259	}
12260	return p;
12261}
12262
12263spaces.hsla.to = function( rgba ) {
12264	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
12265		return [ null, null, null, rgba[ 3 ] ];
12266	}
12267	var r = rgba[ 0 ] / 255,
12268		g = rgba[ 1 ] / 255,
12269		b = rgba[ 2 ] / 255,
12270		a = rgba[ 3 ],
12271		max = Math.max( r, g, b ),
12272		min = Math.min( r, g, b ),
12273		diff = max - min,
12274		add = max + min,
12275		l = add * 0.5,
12276		h, s;
12277
12278	if ( min === max ) {
12279		h = 0;
12280	} else if ( r === max ) {
12281		h = ( 60 * ( g - b ) / diff ) + 360;
12282	} else if ( g === max ) {
12283		h = ( 60 * ( b - r ) / diff ) + 120;
12284	} else {
12285		h = ( 60 * ( r - g ) / diff ) + 240;
12286	}
12287
12288	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
12289	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
12290	if ( diff === 0 ) {
12291		s = 0;
12292	} else if ( l <= 0.5 ) {
12293		s = diff / add;
12294	} else {
12295		s = diff / ( 2 - add );
12296	}
12297	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
12298};
12299
12300spaces.hsla.from = function( hsla ) {
12301	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
12302		return [ null, null, null, hsla[ 3 ] ];
12303	}
12304	var h = hsla[ 0 ] / 360,
12305		s = hsla[ 1 ],
12306		l = hsla[ 2 ],
12307		a = hsla[ 3 ],
12308		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
12309		p = 2 * l - q;
12310
12311	return [
12312		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
12313		Math.round( hue2rgb( p, q, h ) * 255 ),
12314		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
12315		a
12316	];
12317};
12318
12319
12320each( spaces, function( spaceName, space ) {
12321	var props = space.props,
12322		cache = space.cache,
12323		to = space.to,
12324		from = space.from;
12325
12326	// makes rgba() and hsla()
12327	color.fn[ spaceName ] = function( value ) {
12328
12329		// generate a cache for this space if it doesn't exist
12330		if ( to && !this[ cache ] ) {
12331			this[ cache ] = to( this._rgba );
12332		}
12333		if ( value === undefined ) {
12334			return this[ cache ].slice();
12335		}
12336
12337		var ret,
12338			type = getType( value ),
12339			arr = ( type === "array" || type === "object" ) ? value : arguments,
12340			local = this[ cache ].slice();
12341
12342		each( props, function( key, prop ) {
12343			var val = arr[ type === "object" ? key : prop.idx ];
12344			if ( val == null ) {
12345				val = local[ prop.idx ];
12346			}
12347			local[ prop.idx ] = clamp( val, prop );
12348		} );
12349
12350		if ( from ) {
12351			ret = color( from( local ) );
12352			ret[ cache ] = local;
12353			return ret;
12354		} else {
12355			return color( local );
12356		}
12357	};
12358
12359	// makes red() green() blue() alpha() hue() saturation() lightness()
12360	each( props, function( key, prop ) {
12361
12362		// alpha is included in more than one space
12363		if ( color.fn[ key ] ) {
12364			return;
12365		}
12366		color.fn[ key ] = function( value ) {
12367			var local, cur, match, fn,
12368				vtype = getType( value );
12369
12370			if ( key === "alpha" ) {
12371				fn = this._hsla ? "hsla" : "rgba";
12372			} else {
12373				fn = spaceName;
12374			}
12375			local = this[ fn ]();
12376			cur = local[ prop.idx ];
12377
12378			if ( vtype === "undefined" ) {
12379				return cur;
12380			}
12381
12382			if ( vtype === "function" ) {
12383				value = value.call( this, cur );
12384				vtype = getType( value );
12385			}
12386			if ( value == null && prop.empty ) {
12387				return this;
12388			}
12389			if ( vtype === "string" ) {
12390				match = rplusequals.exec( value );
12391				if ( match ) {
12392					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
12393				}
12394			}
12395			local[ prop.idx ] = value;
12396			return this[ fn ]( local );
12397		};
12398	} );
12399} );
12400
12401// add cssHook and .fx.step function for each named hook.
12402// accept a space separated string of properties
12403color.hook = function( hook ) {
12404	var hooks = hook.split( " " );
12405	each( hooks, function( _i, hook ) {
12406		jQuery.cssHooks[ hook ] = {
12407			set: function( elem, value ) {
12408				var parsed, curElem,
12409					backgroundColor = "";
12410
12411				if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
12412					value = color( parsed || value );
12413					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
12414						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
12415						while (
12416							( backgroundColor === "" || backgroundColor === "transparent" ) &&
12417							curElem && curElem.style
12418						) {
12419							try {
12420								backgroundColor = jQuery.css( curElem, "backgroundColor" );
12421								curElem = curElem.parentNode;
12422							} catch ( e ) {
12423							}
12424						}
12425
12426						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
12427							backgroundColor :
12428							"_default" );
12429					}
12430
12431					value = value.toRgbaString();
12432				}
12433				try {
12434					elem.style[ hook ] = value;
12435				} catch ( e ) {
12436
12437					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
12438				}
12439			}
12440		};
12441		jQuery.fx.step[ hook ] = function( fx ) {
12442			if ( !fx.colorInit ) {
12443				fx.start = color( fx.elem, hook );
12444				fx.end = color( fx.end );
12445				fx.colorInit = true;
12446			}
12447			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
12448		};
12449	} );
12450
12451};
12452
12453color.hook( stepHooks );
12454
12455jQuery.cssHooks.borderColor = {
12456	expand: function( value ) {
12457		var expanded = {};
12458
12459		each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
12460			expanded[ "border" + part + "Color" ] = value;
12461		} );
12462		return expanded;
12463	}
12464};
12465
12466// Basic color names only.
12467// Usage of any of the other color names requires adding yourself or including
12468// jquery.color.svg-names.js.
12469colors = jQuery.Color.names = {
12470
12471	// 4.1. Basic color keywords
12472	aqua: "#00ffff",
12473	black: "#000000",
12474	blue: "#0000ff",
12475	fuchsia: "#ff00ff",
12476	gray: "#808080",
12477	green: "#008000",
12478	lime: "#00ff00",
12479	maroon: "#800000",
12480	navy: "#000080",
12481	olive: "#808000",
12482	purple: "#800080",
12483	red: "#ff0000",
12484	silver: "#c0c0c0",
12485	teal: "#008080",
12486	white: "#ffffff",
12487	yellow: "#ffff00",
12488
12489	// 4.2.3. "transparent" color keyword
12490	transparent: [ null, null, null, 0 ],
12491
12492	_default: "#ffffff"
12493};
12494
12495} );
12496
12497
12498
12499
12500/*!
12501 * jQuery UI Effects 1.13.0
12502 * http://jqueryui.com
12503 *
12504 * Copyright jQuery Foundation and other contributors
12505 * Released under the MIT license.
12506 * http://jquery.org/license
12507 */
12508
12509//>>label: Effects Core
12510//>>group: Effects
12511/* eslint-disable max-len */
12512//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
12513/* eslint-enable max-len */
12514//>>docs: http://api.jqueryui.com/category/effects-core/
12515//>>demos: http://jqueryui.com/effect/
12516
12517( function( factory ) {
12518	"use strict";
12519
12520	if ( typeof define === "function" && define.amd ) {
12521
12522		// AMD. Register as an anonymous module.
12523		define( [
12524			"jquery",
12525			"./jquery-var-for-color",
12526			"./vendor/jquery-color/jquery.color",
12527			"./version"
12528		], factory );
12529	} else {
12530
12531		// Browser globals
12532		factory( jQuery );
12533	}
12534} )( function( $ ) {
12535"use strict";
vendor: 9,460 bytes, lines 12535-12904
12535
12536
12537var dataSpace = "ui-effects-",
12538	dataSpaceStyle = "ui-effects-style",
12539	dataSpaceAnimated = "ui-effects-animated";
12540
12541$.effects = {
12542	effect: {}
12543};
12544
12545/******************************************************************************/
12546/****************************** CLASS ANIMATIONS ******************************/
12547/******************************************************************************/
12548( function() {
12549
12550var classAnimationActions = [ "add", "remove", "toggle" ],
12551	shorthandStyles = {
12552		border: 1,
12553		borderBottom: 1,
12554		borderColor: 1,
12555		borderLeft: 1,
12556		borderRight: 1,
12557		borderTop: 1,
12558		borderWidth: 1,
12559		margin: 1,
12560		padding: 1
12561	};
12562
12563$.each(
12564	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
12565	function( _, prop ) {
12566		$.fx.step[ prop ] = function( fx ) {
12567			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
12568				jQuery.style( fx.elem, prop, fx.end );
12569				fx.setAttr = true;
12570			}
12571		};
12572	}
12573);
12574
12575function camelCase( string ) {
12576	return string.replace( /-([\da-z])/gi, function( all, letter ) {
12577		return letter.toUpperCase();
12578	} );
12579}
12580
12581function getElementStyles( elem ) {
12582	var key, len,
12583		style = elem.ownerDocument.defaultView ?
12584			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
12585			elem.currentStyle,
12586		styles = {};
12587
12588	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
12589		len = style.length;
12590		while ( len-- ) {
12591			key = style[ len ];
12592			if ( typeof style[ key ] === "string" ) {
12593				styles[ camelCase( key ) ] = style[ key ];
12594			}
12595		}
12596
12597	// Support: Opera, IE <9
12598	} else {
12599		for ( key in style ) {
12600			if ( typeof style[ key ] === "string" ) {
12601				styles[ key ] = style[ key ];
12602			}
12603		}
12604	}
12605
12606	return styles;
12607}
12608
12609function styleDifference( oldStyle, newStyle ) {
12610	var diff = {},
12611		name, value;
12612
12613	for ( name in newStyle ) {
12614		value = newStyle[ name ];
12615		if ( oldStyle[ name ] !== value ) {
12616			if ( !shorthandStyles[ name ] ) {
12617				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
12618					diff[ name ] = value;
12619				}
12620			}
12621		}
12622	}
12623
12624	return diff;
12625}
12626
12627// Support: jQuery <1.8
12628if ( !$.fn.addBack ) {
12629	$.fn.addBack = function( selector ) {
12630		return this.add( selector == null ?
12631			this.prevObject : this.prevObject.filter( selector )
12632		);
12633	};
12634}
12635
12636$.effects.animateClass = function( value, duration, easing, callback ) {
12637	var o = $.speed( duration, easing, callback );
12638
12639	return this.queue( function() {
12640		var animated = $( this ),
12641			baseClass = animated.attr( "class" ) || "",
12642			applyClassChange,
12643			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
12644
12645		// Map the animated objects to store the original styles.
12646		allAnimations = allAnimations.map( function() {
12647			var el = $( this );
12648			return {
12649				el: el,
12650				start: getElementStyles( this )
12651			};
12652		} );
12653
12654		// Apply class change
12655		applyClassChange = function() {
12656			$.each( classAnimationActions, function( i, action ) {
12657				if ( value[ action ] ) {
12658					animated[ action + "Class" ]( value[ action ] );
12659				}
12660			} );
12661		};
12662		applyClassChange();
12663
12664		// Map all animated objects again - calculate new styles and diff
12665		allAnimations = allAnimations.map( function() {
12666			this.end = getElementStyles( this.el[ 0 ] );
12667			this.diff = styleDifference( this.start, this.end );
12668			return this;
12669		} );
12670
12671		// Apply original class
12672		animated.attr( "class", baseClass );
12673
12674		// Map all animated objects again - this time collecting a promise
12675		allAnimations = allAnimations.map( function() {
12676			var styleInfo = this,
12677				dfd = $.Deferred(),
12678				opts = $.extend( {}, o, {
12679					queue: false,
12680					complete: function() {
12681						dfd.resolve( styleInfo );
12682					}
12683				} );
12684
12685			this.el.animate( this.diff, opts );
12686			return dfd.promise();
12687		} );
12688
12689		// Once all animations have completed:
12690		$.when.apply( $, allAnimations.get() ).done( function() {
12691
12692			// Set the final class
12693			applyClassChange();
12694
12695			// For each animated element,
12696			// clear all css properties that were animated
12697			$.each( arguments, function() {
12698				var el = this.el;
12699				$.each( this.diff, function( key ) {
12700					el.css( key, "" );
12701				} );
12702			} );
12703
12704			// This is guarnteed to be there if you use jQuery.speed()
12705			// it also handles dequeuing the next anim...
12706			o.complete.call( animated[ 0 ] );
12707		} );
12708	} );
12709};
12710
12711$.fn.extend( {
12712	addClass: ( function( orig ) {
12713		return function( classNames, speed, easing, callback ) {
12714			return speed ?
12715				$.effects.animateClass.call( this,
12716					{ add: classNames }, speed, easing, callback ) :
12717				orig.apply( this, arguments );
12718		};
12719	} )( $.fn.addClass ),
12720
12721	removeClass: ( function( orig ) {
12722		return function( classNames, speed, easing, callback ) {
12723			return arguments.length > 1 ?
12724				$.effects.animateClass.call( this,
12725					{ remove: classNames }, speed, easing, callback ) :
12726				orig.apply( this, arguments );
12727		};
12728	} )( $.fn.removeClass ),
12729
12730	toggleClass: ( function( orig ) {
12731		return function( classNames, force, speed, easing, callback ) {
12732			if ( typeof force === "boolean" || force === undefined ) {
12733				if ( !speed ) {
12734
12735					// Without speed parameter
12736					return orig.apply( this, arguments );
12737				} else {
12738					return $.effects.animateClass.call( this,
12739						( force ? { add: classNames } : { remove: classNames } ),
12740						speed, easing, callback );
12741				}
12742			} else {
12743
12744				// Without force parameter
12745				return $.effects.animateClass.call( this,
12746					{ toggle: classNames }, force, speed, easing );
12747			}
12748		};
12749	} )( $.fn.toggleClass ),
12750
12751	switchClass: function( remove, add, speed, easing, callback ) {
12752		return $.effects.animateClass.call( this, {
12753			add: add,
12754			remove: remove
12755		}, speed, easing, callback );
12756	}
12757} );
12758
12759} )();
12760
12761/******************************************************************************/
12762/*********************************** EFFECTS **********************************/
12763/******************************************************************************/
12764
12765( function() {
12766
12767if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
12768	$.expr.pseudos.animated = ( function( orig ) {
12769		return function( elem ) {
12770			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
12771		};
12772	} )( $.expr.pseudos.animated );
12773}
12774
12775if ( $.uiBackCompat !== false ) {
12776	$.extend( $.effects, {
12777
12778		// Saves a set of properties in a data storage
12779		save: function( element, set ) {
12780			var i = 0, length = set.length;
12781			for ( ; i < length; i++ ) {
12782				if ( set[ i ] !== null ) {
12783					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
12784				}
12785			}
12786		},
12787
12788		// Restores a set of previously saved properties from a data storage
12789		restore: function( element, set ) {
12790			var val, i = 0, length = set.length;
12791			for ( ; i < length; i++ ) {
12792				if ( set[ i ] !== null ) {
12793					val = element.data( dataSpace + set[ i ] );
12794					element.css( set[ i ], val );
12795				}
12796			}
12797		},
12798
12799		setMode: function( el, mode ) {
12800			if ( mode === "toggle" ) {
12801				mode = el.is( ":hidden" ) ? "show" : "hide";
12802			}
12803			return mode;
12804		},
12805
12806		// Wraps the element around a wrapper that copies position properties
12807		createWrapper: function( element ) {
12808
12809			// If the element is already wrapped, return it
12810			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
12811				return element.parent();
12812			}
12813
12814			// Wrap the element
12815			var props = {
12816					width: element.outerWidth( true ),
12817					height: element.outerHeight( true ),
12818					"float": element.css( "float" )
12819				},
12820				wrapper = $( "<div></div>" )
12821					.addClass( "ui-effects-wrapper" )
12822					.css( {
12823						fontSize: "100%",
12824						background: "transparent",
12825						border: "none",
12826						margin: 0,
12827						padding: 0
12828					} ),
12829
12830				// Store the size in case width/height are defined in % - Fixes #5245
12831				size = {
12832					width: element.width(),
12833					height: element.height()
12834				},
12835				active = document.activeElement;
12836
12837			// Support: Firefox
12838			// Firefox incorrectly exposes anonymous content
12839			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
12840			try {
12841				// eslint-disable-next-line no-unused-expressions
12842				active.id;
12843			} catch ( e ) {
12844				active = document.body;
12845			}
12846
12847			element.wrap( wrapper );
12848
12849			// Fixes #7595 - Elements lose focus when wrapped.
12850			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
12851				$( active ).trigger( "focus" );
12852			}
12853
12854			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
12855			// lose the reference to the wrapped element
12856			wrapper = element.parent();
12857
12858			// Transfer positioning properties to the wrapper
12859			if ( element.css( "position" ) === "static" ) {
12860				wrapper.css( { position: "relative" } );
12861				element.css( { position: "relative" } );
12862			} else {
12863				$.extend( props, {
12864					position: element.css( "position" ),
12865					zIndex: element.css( "z-index" )
12866				} );
12867				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
12868					props[ pos ] = element.css( pos );
12869					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
12870						props[ pos ] = "auto";
12871					}
12872				} );
12873				element.css( {
12874					position: "relative",
12875					top: 0,
12876					left: 0,
12877					right: "auto",
12878					bottom: "auto"
12879				} );
12880			}
12881			element.css( size );
12882
12883			return wrapper.css( props ).show();
12884		},
12885
12886		removeWrapper: function( element ) {
12887			var active = document.activeElement;
12888
12889			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
12890				element.parent().replaceWith( element );
12891
12892				// Fixes #7595 - Elements lose focus when wrapped.
12893				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
12894					$( active ).trigger( "focus" );
12895				}
12896			}
12897
12898			return element;
12899		}
12900	} );
12901}
12902
12903$.extend( $.effects, {
12904	version: "1.13.
vendor: 2,055 bytes, lines 12904-12999
129040",
12905
12906	define: function( name, mode, effect ) {
12907		if ( !effect ) {
12908			effect = mode;
12909			mode = "effect";
12910		}
12911
12912		$.effects.effect[ name ] = effect;
12913		$.effects.effect[ name ].mode = mode;
12914
12915		return effect;
12916	},
12917
12918	scaledDimensions: function( element, percent, direction ) {
12919		if ( percent === 0 ) {
12920			return {
12921				height: 0,
12922				width: 0,
12923				outerHeight: 0,
12924				outerWidth: 0
12925			};
12926		}
12927
12928		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
12929			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
12930
12931		return {
12932			height: element.height() * y,
12933			width: element.width() * x,
12934			outerHeight: element.outerHeight() * y,
12935			outerWidth: element.outerWidth() * x
12936		};
12937
12938	},
12939
12940	clipToBox: function( animation ) {
12941		return {
12942			width: animation.clip.right - animation.clip.left,
12943			height: animation.clip.bottom - animation.clip.top,
12944			left: animation.clip.left,
12945			top: animation.clip.top
12946		};
12947	},
12948
12949	// Injects recently queued functions to be first in line (after "inprogress")
12950	unshift: function( element, queueLength, count ) {
12951		var queue = element.queue();
12952
12953		if ( queueLength > 1 ) {
12954			queue.splice.apply( queue,
12955				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
12956		}
12957		element.dequeue();
12958	},
12959
12960	saveStyle: function( element ) {
12961		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
12962	},
12963
12964	restoreStyle: function( element ) {
12965		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
12966		element.removeData( dataSpaceStyle );
12967	},
12968
12969	mode: function( element, mode ) {
12970		var hidden = element.is( ":hidden" );
12971
12972		if ( mode === "toggle" ) {
12973			mode = hidden ? "show" : "hide";
12974		}
12975		if ( hidden ? mode === "hide" : mode === "show" ) {
12976			mode = "none";
12977		}
12978		return mode;
12979	},
12980
12981	// Translates a [top,left] array into a baseline value
12982	getBaseline: function( origin, original ) {
12983		var y, x;
12984
12985		switch ( origin[ 0 ] ) {
12986		case "top":
12987			y = 0;
12988			break;
12989		case "middle":
12990			y = 0.5;
12991			break;
12992		case "bottom":
12993			y = 1;
12994			break;
12995		default:
12996			y = origin[ 0 ] / original.height;
12997		}
12998
12999		switch ( origin[ 1 ] ) {
13000		case "left":
13001			x = 0;
13002			break;
13003		case "center":
13004			x = 0.5;
13005			break;
13006		case "right":
13007			x = 1;
13008			break;
13009		default:
13010			x = origin[ 1 ] / original.width;
13011		}
13012
13013		return {
13014			x: x,
13015			y: y
13016		};
13017	},
13018
13019	// Creates a placeholder element so that the original element can be made absolute
13020	createPlaceholder: function( element ) {
13021		var placeholder,
13022			cssPosition = element.css( "position" ),
13023			position = element.position();
13024
13025		// Lock in margins first to account for form elements, which
13026		// will change margin if you explicitly set height
13027		// see: http
vendor: 10,558 bytes, lines 13027-13421
13027://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
13028		// Support: Safari
13029		element.css( {
13030			marginTop: element.css( "marginTop" ),
13031			marginBottom: element.css( "marginBottom" ),
13032			marginLeft: element.css( "marginLeft" ),
13033			marginRight: element.css( "marginRight" )
13034		} )
13035		.outerWidth( element.outerWidth() )
13036		.outerHeight( element.outerHeight() );
13037
13038		if ( /^(static|relative)/.test( cssPosition ) ) {
13039			cssPosition = "absolute";
13040
13041			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
13042
13043				// Convert inline to inline block to account for inline elements
13044				// that turn to inline block based on content (like img)
13045				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
13046					"inline-block" :
13047					"block",
13048				visibility: "hidden",
13049
13050				// Margins need to be set to account for margin collapse
13051				marginTop: element.css( "marginTop" ),
13052				marginBottom: element.css( "marginBottom" ),
13053				marginLeft: element.css( "marginLeft" ),
13054				marginRight: element.css( "marginRight" ),
13055				"float": element.css( "float" )
13056			} )
13057			.outerWidth( element.outerWidth() )
13058			.outerHeight( element.outerHeight() )
13059			.addClass( "ui-effects-placeholder" );
13060
13061			element.data( dataSpace + "placeholder", placeholder );
13062		}
13063
13064		element.css( {
13065			position: cssPosition,
13066			left: position.left,
13067			top: position.top
13068		} );
13069
13070		return placeholder;
13071	},
13072
13073	removePlaceholder: function( element ) {
13074		var dataKey = dataSpace + "placeholder",
13075				placeholder = element.data( dataKey );
13076
13077		if ( placeholder ) {
13078			placeholder.remove();
13079			element.removeData( dataKey );
13080		}
13081	},
13082
13083	// Removes a placeholder if it exists and restores
13084	// properties that were modified during placeholder creation
13085	cleanUp: function( element ) {
13086		$.effects.restoreStyle( element );
13087		$.effects.removePlaceholder( element );
13088	},
13089
13090	setTransition: function( element, list, factor, value ) {
13091		value = value || {};
13092		$.each( list, function( i, x ) {
13093			var unit = element.cssUnit( x );
13094			if ( unit[ 0 ] > 0 ) {
13095				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
13096			}
13097		} );
13098		return value;
13099	}
13100} );
13101
13102// Return an effect options object for the given parameters:
13103function _normalizeArguments( effect, options, speed, callback ) {
13104
13105	// Allow passing all options as the first parameter
13106	if ( $.isPlainObject( effect ) ) {
13107		options = effect;
13108		effect = effect.effect;
13109	}
13110
13111	// Convert to an object
13112	effect = { effect: effect };
13113
13114	// Catch (effect, null, ...)
13115	if ( options == null ) {
13116		options = {};
13117	}
13118
13119	// Catch (effect, callback)
13120	if ( typeof options === "function" ) {
13121		callback = options;
13122		speed = null;
13123		options = {};
13124	}
13125
13126	// Catch (effect, speed, ?)
13127	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
13128		callback = speed;
13129		speed = options;
13130		options = {};
13131	}
13132
13133	// Catch (effect, options, callback)
13134	if ( typeof speed === "function" ) {
13135		callback = speed;
13136		speed = null;
13137	}
13138
13139	// Add options to effect
13140	if ( options ) {
13141		$.extend( effect, options );
13142	}
13143
13144	speed = speed || options.duration;
13145	effect.duration = $.fx.off ? 0 :
13146		typeof speed === "number" ? speed :
13147		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
13148		$.fx.speeds._default;
13149
13150	effect.complete = callback || options.complete;
13151
13152	return effect;
13153}
13154
13155function standardAnimationOption( option ) {
13156
13157	// Valid standard speeds (nothing, number, named speed)
13158	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
13159		return true;
13160	}
13161
13162	// Invalid strings - treat as "normal" speed
13163	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
13164		return true;
13165	}
13166
13167	// Complete callback
13168	if ( typeof option === "function" ) {
13169		return true;
13170	}
13171
13172	// Options hash (but not naming an effect)
13173	if ( typeof option === "object" && !option.effect ) {
13174		return true;
13175	}
13176
13177	// Didn't match any standard API
13178	return false;
13179}
13180
13181$.fn.extend( {
13182	effect: function( /* effect, options, speed, callback */ ) {
13183		var args = _normalizeArguments.apply( this, arguments ),
13184			effectMethod = $.effects.effect[ args.effect ],
13185			defaultMode = effectMethod.mode,
13186			queue = args.queue,
13187			queueName = queue || "fx",
13188			complete = args.complete,
13189			mode = args.mode,
13190			modes = [],
13191			prefilter = function( next ) {
13192				var el = $( this ),
13193					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
13194
13195				// Sentinel for duck-punching the :animated pseudo-selector
13196				el.data( dataSpaceAnimated, true );
13197
13198				// Save effect mode for later use,
13199				// we can't just call $.effects.mode again later,
13200				// as the .show() below destroys the initial state
13201				modes.push( normalizedMode );
13202
13203				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
13204				if ( defaultMode && ( normalizedMode === "show" ||
13205						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
13206					el.show();
13207				}
13208
13209				if ( !defaultMode || normalizedMode !== "none" ) {
13210					$.effects.saveStyle( el );
13211				}
13212
13213				if ( typeof next === "function" ) {
13214					next();
13215				}
13216			};
13217
13218		if ( $.fx.off || !effectMethod ) {
13219
13220			// Delegate to the original method (e.g., .show()) if possible
13221			if ( mode ) {
13222				return this[ mode ]( args.duration, complete );
13223			} else {
13224				return this.each( function() {
13225					if ( complete ) {
13226						complete.call( this );
13227					}
13228				} );
13229			}
13230		}
13231
13232		function run( next ) {
13233			var elem = $( this );
13234
13235			function cleanup() {
13236				elem.removeData( dataSpaceAnimated );
13237
13238				$.effects.cleanUp( elem );
13239
13240				if ( args.mode === "hide" ) {
13241					elem.hide();
13242				}
13243
13244				done();
13245			}
13246
13247			function done() {
13248				if ( typeof complete === "function" ) {
13249					complete.call( elem[ 0 ] );
13250				}
13251
13252				if ( typeof next === "function" ) {
13253					next();
13254				}
13255			}
13256
13257			// Override mode option on a per element basis,
13258			// as toggle can be either show or hide depending on element state
13259			args.mode = modes.shift();
13260
13261			if ( $.uiBackCompat !== false && !defaultMode ) {
13262				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
13263
13264					// Call the core method to track "olddisplay" properly
13265					elem[ mode ]();
13266					done();
13267				} else {
13268					effectMethod.call( elem[ 0 ], args, done );
13269				}
13270			} else {
13271				if ( args.mode === "none" ) {
13272
13273					// Call the core method to track "olddisplay" properly
13274					elem[ mode ]();
13275					done();
13276				} else {
13277					effectMethod.call( elem[ 0 ], args, cleanup );
13278				}
13279			}
13280		}
13281
13282		// Run prefilter on all elements first to ensure that
13283		// any showing or hiding happens before placeholder creation,
13284		// which ensures that any layout changes are correctly captured.
13285		return queue === false ?
13286			this.each( prefilter ).each( run ) :
13287			this.queue( queueName, prefilter ).queue( queueName, run );
13288	},
13289
13290	show: ( function( orig ) {
13291		return function( option ) {
13292			if ( standardAnimationOption( option ) ) {
13293				return orig.apply( this, arguments );
13294			} else {
13295				var args = _normalizeArguments.apply( this, arguments );
13296				args.mode = "show";
13297				return this.effect.call( this, args );
13298			}
13299		};
13300	} )( $.fn.show ),
13301
13302	hide: ( function( orig ) {
13303		return function( option ) {
13304			if ( standardAnimationOption( option ) ) {
13305				return orig.apply( this, arguments );
13306			} else {
13307				var args = _normalizeArguments.apply( this, arguments );
13308				args.mode = "hide";
13309				return this.effect.call( this, args );
13310			}
13311		};
13312	} )( $.fn.hide ),
13313
13314	toggle: ( function( orig ) {
13315		return function( option ) {
13316			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
13317				return orig.apply( this, arguments );
13318			} else {
13319				var args = _normalizeArguments.apply( this, arguments );
13320				args.mode = "toggle";
13321				return this.effect.call( this, args );
13322			}
13323		};
13324	} )( $.fn.toggle ),
13325
13326	cssUnit: function( key ) {
13327		var style = this.css( key ),
13328			val = [];
13329
13330		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
13331			if ( style.indexOf( unit ) > 0 ) {
13332				val = [ parseFloat( style ), unit ];
13333			}
13334		} );
13335		return val;
13336	},
13337
13338	cssClip: function( clipObj ) {
13339		if ( clipObj ) {
13340			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
13341				clipObj.bottom + "px " + clipObj.left + "px)" );
13342		}
13343		return parseClip( this.css( "clip" ), this );
13344	},
13345
13346	transfer: function( options, done ) {
13347		var element = $( this ),
13348			target = $( options.to ),
13349			targetFixed = target.css( "position" ) === "fixed",
13350			body = $( "body" ),
13351			fixTop = targetFixed ? body.scrollTop() : 0,
13352			fixLeft = targetFixed ? body.scrollLeft() : 0,
13353			endPosition = target.offset(),
13354			animation = {
13355				top: endPosition.top - fixTop,
13356				left: endPosition.left - fixLeft,
13357				height: target.innerHeight(),
13358				width: target.innerWidth()
13359			},
13360			startPosition = element.offset(),
13361			transfer = $( "<div class='ui-effects-transfer'></div>" );
13362
13363		transfer
13364			.appendTo( "body" )
13365			.addClass( options.className )
13366			.css( {
13367				top: startPosition.top - fixTop,
13368				left: startPosition.left - fixLeft,
13369				height: element.innerHeight(),
13370				width: element.innerWidth(),
13371				position: targetFixed ? "fixed" : "absolute"
13372			} )
13373			.animate( animation, options.duration, options.easing, function() {
13374				transfer.remove();
13375				if ( typeof done === "function" ) {
13376					done();
13377				}
13378			} );
13379	}
13380} );
13381
13382function parseClip( str, element ) {
13383		var outerWidth = element.outerWidth(),
13384			outerHeight = element.outerHeight(),
13385			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
13386			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
13387
13388		return {
13389			top: parseFloat( values[ 1 ] ) || 0,
13390			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
13391			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
13392			left: parseFloat( values[ 4 ] ) || 0
13393		};
13394}
13395
13396$.fx.step.clip = function( fx ) {
13397	if ( !fx.clipInit ) {
13398		fx.start = $( fx.elem ).cssClip();
13399		if ( typeof fx.end === "string" ) {
13400			fx.end = parseClip( fx.end, fx.elem );
13401		}
13402		fx.clipInit = true;
13403	}
13404
13405	$( fx.elem ).cssClip( {
13406		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
13407		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
13408		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
13409		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
13410	} );
13411};
13412
13413} )();
13414
13415/******************************************************************************/
13416/*********************************** EASING ***********************************/
13417/******************************************************************************/
13418
13419( function() {
13420
13421// Based on easing equations from Robert Penner (http://
vendor: 9,574 bytes, lines 13421-13795
13421www.robertpenner.com/easing)
13422
13423var baseEasings = {};
13424
13425$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
13426	baseEasings[ name ] = function( p ) {
13427		return Math.pow( p, i + 2 );
13428	};
13429} );
13430
13431$.extend( baseEasings, {
13432	Sine: function( p ) {
13433		return 1 - Math.cos( p * Math.PI / 2 );
13434	},
13435	Circ: function( p ) {
13436		return 1 - Math.sqrt( 1 - p * p );
13437	},
13438	Elastic: function( p ) {
13439		return p === 0 || p === 1 ? p :
13440			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
13441	},
13442	Back: function( p ) {
13443		return p * p * ( 3 * p - 2 );
13444	},
13445	Bounce: function( p ) {
13446		var pow2,
13447			bounce = 4;
13448
13449		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
13450		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
13451	}
13452} );
13453
13454$.each( baseEasings, function( name, easeIn ) {
13455	$.easing[ "easeIn" + name ] = easeIn;
13456	$.easing[ "easeOut" + name ] = function( p ) {
13457		return 1 - easeIn( 1 - p );
13458	};
13459	$.easing[ "easeInOut" + name ] = function( p ) {
13460		return p < 0.5 ?
13461			easeIn( p * 2 ) / 2 :
13462			1 - easeIn( p * -2 + 2 ) / 2;
13463	};
13464} );
13465
13466} )();
13467
13468return $.effects;
13469
13470} );
13471
13472
13473
13474/*!
13475 * jQuery UI Form Reset Mixin 1.13.0
13476 * http://jqueryui.com
13477 *
13478 * Copyright jQuery Foundation and other contributors
13479 * Released under the MIT license.
13480 * http://jquery.org/license
13481 */
13482
13483//>>label: Form Reset Mixin
13484//>>group: Core
13485//>>description: Refresh input widgets when their form is reset
13486//>>docs: http://api.jqueryui.com/form-reset-mixin/
13487
13488( function( factory ) {
13489	"use strict";
13490
13491	if ( typeof define === "function" && define.amd ) {
13492
13493		// AMD. Register as an anonymous module.
13494		define( [
13495			"jquery",
13496			"./form",
13497			"./version"
13498		], factory );
13499	} else {
13500
13501		// Browser globals
13502		factory( jQuery );
13503	}
13504} )( function( $ ) {
13505"use strict";
13506
13507return $.ui.formResetMixin = {
13508	_formResetHandler: function() {
13509		var form = $( this );
13510
13511		// Wait for the form reset to actually happen before refreshing
13512		setTimeout( function() {
13513			var instances = form.data( "ui-form-reset-instances" );
13514			$.each( instances, function() {
13515				this.refresh();
13516			} );
13517		} );
13518	},
13519
13520	_bindFormResetHandler: function() {
13521		this.form = this.element._form();
13522		if ( !this.form.length ) {
13523			return;
13524		}
13525
13526		var instances = this.form.data( "ui-form-reset-instances" ) || [];
13527		if ( !instances.length ) {
13528
13529			// We don't use _on() here because we use a single event handler per form
13530			this.form.on( "reset.ui-form-reset", this._formResetHandler );
13531		}
13532		instances.push( this );
13533		this.form.data( "ui-form-reset-instances", instances );
13534	},
13535
13536	_unbindFormResetHandler: function() {
13537		if ( !this.form.length ) {
13538			return;
13539		}
13540
13541		var instances = this.form.data( "ui-form-reset-instances" );
13542		instances.splice( $.inArray( this, instances ), 1 );
13543		if ( instances.length ) {
13544			this.form.data( "ui-form-reset-instances", instances );
13545		} else {
13546			this.form
13547				.removeData( "ui-form-reset-instances" )
13548				.off( "reset.ui-form-reset" );
13549		}
13550	}
13551};
13552
13553} );
13554
13555
13556/*!
13557 * jQuery UI Position 1.13.0
13558 * http://jqueryui.com
13559 *
13560 * Copyright jQuery Foundation and other contributors
13561 * Released under the MIT license.
13562 * http://jquery.org/license
13563 *
13564 * http://api.jqueryui.com/position/
13565 */
13566
13567//>>label: Position
13568//>>group: Core
13569//>>description: Positions elements relative to other elements.
13570//>>docs: http://api.jqueryui.com/position/
13571//>>demos: http://jqueryui.com/position/
13572
13573( function( factory ) {
13574	"use strict";
13575
13576	if ( typeof define === "function" && define.amd ) {
13577
13578		// AMD. Register as an anonymous module.
13579		define( [ "jquery", "./version" ], factory );
13580	} else {
13581
13582		// Browser globals
13583		factory( jQuery );
13584	}
13585} )( function( $ ) {
13586"use strict";
13587
13588( function() {
13589var cachedScrollbarWidth,
13590	max = Math.max,
13591	abs = Math.abs,
13592	rhorizontal = /left|center|right/,
13593	rvertical = /top|center|bottom/,
13594	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
13595	rposition = /^\w+/,
13596	rpercent = /%$/,
13597	_position = $.fn.position;
13598
13599function getOffsets( offsets, width, height ) {
13600	return [
13601		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
13602		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
13603	];
13604}
13605
13606function parseCss( element, property ) {
13607	return parseInt( $.css( element, property ), 10 ) || 0;
13608}
13609
13610function isWindow( obj ) {
13611	return obj != null && obj === obj.window;
13612}
13613
13614function getDimensions( elem ) {
13615	var raw = elem[ 0 ];
13616	if ( raw.nodeType === 9 ) {
13617		return {
13618			width: elem.width(),
13619			height: elem.height(),
13620			offset: { top: 0, left: 0 }
13621		};
13622	}
13623	if ( isWindow( raw ) ) {
13624		return {
13625			width: elem.width(),
13626			height: elem.height(),
13627			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
13628		};
13629	}
13630	if ( raw.preventDefault ) {
13631		return {
13632			width: 0,
13633			height: 0,
13634			offset: { top: raw.pageY, left: raw.pageX }
13635		};
13636	}
13637	return {
13638		width: elem.outerWidth(),
13639		height: elem.outerHeight(),
13640		offset: elem.offset()
13641	};
13642}
13643
13644$.position = {
13645	scrollbarWidth: function() {
13646		if ( cachedScrollbarWidth !== undefined ) {
13647			return cachedScrollbarWidth;
13648		}
13649		var w1, w2,
13650			div = $( "<div style=" +
13651				"'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
13652				"<div style='height:300px;width:auto;'></div></div>" ),
13653			innerDiv = div.children()[ 0 ];
13654
13655		$( "body" ).append( div );
13656		w1 = innerDiv.offsetWidth;
13657		div.css( "overflow", "scroll" );
13658
13659		w2 = innerDiv.offsetWidth;
13660
13661		if ( w1 === w2 ) {
13662			w2 = div[ 0 ].clientWidth;
13663		}
13664
13665		div.remove();
13666
13667		return ( cachedScrollbarWidth = w1 - w2 );
13668	},
13669	getScrollInfo: function( within ) {
13670		var overflowX = within.isWindow || within.isDocument ? "" :
13671				within.element.css( "overflow-x" ),
13672			overflowY = within.isWindow || within.isDocument ? "" :
13673				within.element.css( "overflow-y" ),
13674			hasOverflowX = overflowX === "scroll" ||
13675				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
13676			hasOverflowY = overflowY === "scroll" ||
13677				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
13678		return {
13679			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
13680			height: hasOverflowX ? $.position.scrollbarWidth() : 0
13681		};
13682	},
13683	getWithinInfo: function( element ) {
13684		var withinElement = $( element || window ),
13685			isElemWindow = isWindow( withinElement[ 0 ] ),
13686			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
13687			hasOffset = !isElemWindow && !isDocument;
13688		return {
13689			element: withinElement,
13690			isWindow: isElemWindow,
13691			isDocument: isDocument,
13692			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
13693			scrollLeft: withinElement.scrollLeft(),
13694			scrollTop: withinElement.scrollTop(),
13695			width: withinElement.outerWidth(),
13696			height: withinElement.outerHeight()
13697		};
13698	}
13699};
13700
13701$.fn.position = function( options ) {
13702	if ( !options || !options.of ) {
13703		return _position.apply( this, arguments );
13704	}
13705
13706	// Make a copy, we don't want to modify arguments
13707	options = $.extend( {}, options );
13708
13709	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
13710
13711		// Make sure string options are treated as CSS selectors
13712		target = typeof options.of === "string" ?
13713			$( document ).find( options.of ) :
13714			$( options.of ),
13715
13716		within = $.position.getWithinInfo( options.within ),
13717		scrollInfo = $.position.getScrollInfo( within ),
13718		collision = ( options.collision || "flip" ).split( " " ),
13719		offsets = {};
13720
13721	dimensions = getDimensions( target );
13722	if ( target[ 0 ].preventDefault ) {
13723
13724		// Force left top to allow flipping
13725		options.at = "left top";
13726	}
13727	targetWidth = dimensions.width;
13728	targetHeight = dimensions.height;
13729	targetOffset = dimensions.offset;
13730
13731	// Clone to reuse original targetOffset later
13732	basePosition = $.extend( {}, targetOffset );
13733
13734	// Force my and at to have valid horizontal and vertical positions
13735	// if a value is missing or invalid, it will be converted to center
13736	$.each( [ "my", "at" ], function() {
13737		var pos = ( options[ this ] || "" ).split( " " ),
13738			horizontalOffset,
13739			verticalOffset;
13740
13741		if ( pos.length === 1 ) {
13742			pos = rhorizontal.test( pos[ 0 ] ) ?
13743				pos.concat( [ "center" ] ) :
13744				rvertical.test( pos[ 0 ] ) ?
13745					[ "center" ].concat( pos ) :
13746					[ "center", "center" ];
13747		}
13748		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
13749		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
13750
13751		// Calculate offsets
13752		horizontalOffset = roffset.exec( pos[ 0 ] );
13753		verticalOffset = roffset.exec( pos[ 1 ] );
13754		offsets[ this ] = [
13755			horizontalOffset ? horizontalOffset[ 0 ] : 0,
13756			verticalOffset ? verticalOffset[ 0 ] : 0
13757		];
13758
13759		// Reduce to just the positions without the offsets
13760		options[ this ] = [
13761			rposition.exec( pos[ 0 ] )[ 0 ],
13762			rposition.exec( pos[ 1 ] )[ 0 ]
13763		];
13764	} );
13765
13766	// Normalize collision option
13767	if ( collision.length === 1 ) {
13768		collision[ 1 ] = collision[ 0 ];
13769	}
13770
13771	if ( options.at[ 0 ] === "right" ) {
13772		basePosition.left += targetWidth;
13773	} else if ( options.at[ 0 ] === "center" ) {
13774		basePosition.left += targetWidth / 2;
13775	}
13776
13777	if ( options.at[ 1 ] === "bottom" ) {
13778		basePosition.top += targetHeight;
13779	} else if ( options.at[ 1 ] === "center" ) {
13780		basePosition.top += targetHeight / 2;
13781	}
13782
13783	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
13784	basePosition.left += atOffset[ 0 ];
13785	basePosition.top += atOffset[ 1 ];
13786
13787	return this.each( function() {
13788		var collisionPosition, using,
13789			elem = $( this ),
13790			elemWidth = elem.outerWidth(),
13791			elemHeight = elem.outerHeight(),
13792			marginLeft = parseCss( this, "marginLeft" ),
13793			marginTop = parseCss( this, "marginTop" ),
13794			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
13795				scrollInfo.width,
vendor: 10,575 bytes, lines 13796-14148
13796			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
13797				scrollInfo.height,
13798			position = $.extend( {}, basePosition ),
13799			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
13800
13801		if ( options.my[ 0 ] === "right" ) {
13802			position.left -= elemWidth;
13803		} else if ( options.my[ 0 ] === "center" ) {
13804			position.left -= elemWidth / 2;
13805		}
13806
13807		if ( options.my[ 1 ] === "bottom" ) {
13808			position.top -= elemHeight;
13809		} else if ( options.my[ 1 ] === "center" ) {
13810			position.top -= elemHeight / 2;
13811		}
13812
13813		position.left += myOffset[ 0 ];
13814		position.top += myOffset[ 1 ];
13815
13816		collisionPosition = {
13817			marginLeft: marginLeft,
13818			marginTop: marginTop
13819		};
13820
13821		$.each( [ "left", "top" ], function( i, dir ) {
13822			if ( $.ui.position[ collision[ i ] ] ) {
13823				$.ui.position[ collision[ i ] ][ dir ]( position, {
13824					targetWidth: targetWidth,
13825					targetHeight: targetHeight,
13826					elemWidth: elemWidth,
13827					elemHeight: elemHeight,
13828					collisionPosition: collisionPosition,
13829					collisionWidth: collisionWidth,
13830					collisionHeight: collisionHeight,
13831					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
13832					my: options.my,
13833					at: options.at,
13834					within: within,
13835					elem: elem
13836				} );
13837			}
13838		} );
13839
13840		if ( options.using ) {
13841
13842			// Adds feedback as second argument to using callback, if present
13843			using = function( props ) {
13844				var left = targetOffset.left - position.left,
13845					right = left + targetWidth - elemWidth,
13846					top = targetOffset.top - position.top,
13847					bottom = top + targetHeight - elemHeight,
13848					feedback = {
13849						target: {
13850							element: target,
13851							left: targetOffset.left,
13852							top: targetOffset.top,
13853							width: targetWidth,
13854							height: targetHeight
13855						},
13856						element: {
13857							element: elem,
13858							left: position.left,
13859							top: position.top,
13860							width: elemWidth,
13861							height: elemHeight
13862						},
13863						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
13864						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
13865					};
13866				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
13867					feedback.horizontal = "center";
13868				}
13869				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
13870					feedback.vertical = "middle";
13871				}
13872				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
13873					feedback.important = "horizontal";
13874				} else {
13875					feedback.important = "vertical";
13876				}
13877				options.using.call( this, props, feedback );
13878			};
13879		}
13880
13881		elem.offset( $.extend( position, { using: using } ) );
13882	} );
13883};
13884
13885$.ui.position = {
13886	fit: {
13887		left: function( position, data ) {
13888			var within = data.within,
13889				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
13890				outerWidth = within.width,
13891				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
13892				overLeft = withinOffset - collisionPosLeft,
13893				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
13894				newOverRight;
13895
13896			// Element is wider than within
13897			if ( data.collisionWidth > outerWidth ) {
13898
13899				// Element is initially over the left side of within
13900				if ( overLeft > 0 && overRight <= 0 ) {
13901					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
13902						withinOffset;
13903					position.left += overLeft - newOverRight;
13904
13905				// Element is initially over right side of within
13906				} else if ( overRight > 0 && overLeft <= 0 ) {
13907					position.left = withinOffset;
13908
13909				// Element is initially over both left and right sides of within
13910				} else {
13911					if ( overLeft > overRight ) {
13912						position.left = withinOffset + outerWidth - data.collisionWidth;
13913					} else {
13914						position.left = withinOffset;
13915					}
13916				}
13917
13918			// Too far left -> align with left edge
13919			} else if ( overLeft > 0 ) {
13920				position.left += overLeft;
13921
13922			// Too far right -> align with right edge
13923			} else if ( overRight > 0 ) {
13924				position.left -= overRight;
13925
13926			// Adjust based on position and margin
13927			} else {
13928				position.left = max( position.left - collisionPosLeft, position.left );
13929			}
13930		},
13931		top: function( position, data ) {
13932			var within = data.within,
13933				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
13934				outerHeight = data.within.height,
13935				collisionPosTop = position.top - data.collisionPosition.marginTop,
13936				overTop = withinOffset - collisionPosTop,
13937				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
13938				newOverBottom;
13939
13940			// Element is taller than within
13941			if ( data.collisionHeight > outerHeight ) {
13942
13943				// Element is initially over the top of within
13944				if ( overTop > 0 && overBottom <= 0 ) {
13945					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
13946						withinOffset;
13947					position.top += overTop - newOverBottom;
13948
13949				// Element is initially over bottom of within
13950				} else if ( overBottom > 0 && overTop <= 0 ) {
13951					position.top = withinOffset;
13952
13953				// Element is initially over both top and bottom of within
13954				} else {
13955					if ( overTop > overBottom ) {
13956						position.top = withinOffset + outerHeight - data.collisionHeight;
13957					} else {
13958						position.top = withinOffset;
13959					}
13960				}
13961
13962			// Too far up -> align with top
13963			} else if ( overTop > 0 ) {
13964				position.top += overTop;
13965
13966			// Too far down -> align with bottom edge
13967			} else if ( overBottom > 0 ) {
13968				position.top -= overBottom;
13969
13970			// Adjust based on position and margin
13971			} else {
13972				position.top = max( position.top - collisionPosTop, position.top );
13973			}
13974		}
13975	},
13976	flip: {
13977		left: function( position, data ) {
13978			var within = data.within,
13979				withinOffset = within.offset.left + within.scrollLeft,
13980				outerWidth = within.width,
13981				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
13982				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
13983				overLeft = collisionPosLeft - offsetLeft,
13984				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
13985				myOffset = data.my[ 0 ] === "left" ?
13986					-data.elemWidth :
13987					data.my[ 0 ] === "right" ?
13988						data.elemWidth :
13989						0,
13990				atOffset = data.at[ 0 ] === "left" ?
13991					data.targetWidth :
13992					data.at[ 0 ] === "right" ?
13993						-data.targetWidth :
13994						0,
13995				offset = -2 * data.offset[ 0 ],
13996				newOverRight,
13997				newOverLeft;
13998
13999			if ( overLeft < 0 ) {
14000				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
14001					outerWidth - withinOffset;
14002				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
14003					position.left += myOffset + atOffset + offset;
14004				}
14005			} else if ( overRight > 0 ) {
14006				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
14007					atOffset + offset - offsetLeft;
14008				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
14009					position.left += myOffset + atOffset + offset;
14010				}
14011			}
14012		},
14013		top: function( position, data ) {
14014			var within = data.within,
14015				withinOffset = within.offset.top + within.scrollTop,
14016				outerHeight = within.height,
14017				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
14018				collisionPosTop = position.top - data.collisionPosition.marginTop,
14019				overTop = collisionPosTop - offsetTop,
14020				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
14021				top = data.my[ 1 ] === "top",
14022				myOffset = top ?
14023					-data.elemHeight :
14024					data.my[ 1 ] === "bottom" ?
14025						data.elemHeight :
14026						0,
14027				atOffset = data.at[ 1 ] === "top" ?
14028					data.targetHeight :
14029					data.at[ 1 ] === "bottom" ?
14030						-data.targetHeight :
14031						0,
14032				offset = -2 * data.offset[ 1 ],
14033				newOverTop,
14034				newOverBottom;
14035			if ( overTop < 0 ) {
14036				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
14037					outerHeight - withinOffset;
14038				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
14039					position.top += myOffset + atOffset + offset;
14040				}
14041			} else if ( overBottom > 0 ) {
14042				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
14043					offset - offsetTop;
14044				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
14045					position.top += myOffset + atOffset + offset;
14046				}
14047			}
14048		}
14049	},
14050	flipfit: {
14051		left: function() {
14052			$.ui.position.flip.left.apply( this, arguments );
14053			$.ui.position.fit.left.apply( this, arguments );
14054		},
14055		top: function() {
14056			$.ui.position.flip.top.apply( this, arguments );
14057			$.ui.position.fit.top.apply( this, arguments );
14058		}
14059	}
14060};
14061
14062} )();
14063
14064return $.ui.position;
14065
14066} );
14067
14068
14069/*!
14070 * jQuery UI Widget 1.13.0
14071 * http://jqueryui.com
14072 *
14073 * Copyright jQuery Foundation and other contributors
14074 * Released under the MIT license.
14075 * http://jquery.org/license
14076 */
14077
14078//>>label: Widget
14079//>>group: Core
14080//>>description: Provides a factory for creating stateful widgets with a common API.
14081//>>docs: http://api.jqueryui.com/jQuery.widget/
14082//>>demos: http://jqueryui.com/widget/
14083
14084( function( factory ) {
14085	"use strict";
14086
14087	if ( typeof define === "function" && define.amd ) {
14088
14089		// AMD. Register as an anonymous module.
14090		define( [ "jquery", "./version" ], factory );
14091	} else {
14092
14093		// Browser globals
14094		factory( jQuery );
14095	}
14096} )( function( $ ) {
14097"use strict";
14098
14099var widgetUuid = 0;
14100var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
14101var widgetSlice = Array.prototype.slice;
14102
14103$.cleanData = ( function( orig ) {
14104	return function( elems ) {
14105		var events, elem, i;
14106		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
14107
14108			// Only trigger remove when necessary to save time
14109			events = $._data( elem, "events" );
14110			if ( events && events.remove ) {
14111				$( elem ).triggerHandler( "remove" );
14112			}
14113		}
14114		orig( elems );
14115	};
14116} )( $.cleanData );
14117
14118$.widget = function( name, base, prototype ) {
14119	var existingConstructor, constructor, basePrototype;
14120
14121	// ProxiedPrototype allows the provided prototype to remain unmodified
14122	// so that it can be used as a mixin for multiple widgets (#8876)
14123	var proxiedPrototype = {};
14124
14125	var namespace = name.split( "." )[ 0 ];
14126	name = name.split( "." )[ 1 ];
14127	var fullName = namespace + "-" + name;
14128
14129	if ( !prototype ) {
14130		prototype = base;
14131		base = $.Widget;
14132	}
14133
14134	if ( Array.isArray( prototype ) ) {
14135		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
14136	}
14137
14138	// Create selector for plugin
14139	$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
14140		return !!$.data( elem, fullName );
14141	};
14142
14143	$[ namespace ] = $[ namespace ] || {};
14144	existingConstructor = $[ namespace ][ name ];
14145	constructor = $[ namespace ][ name ] = function( options, element ) {
14146
14147		// Allow instantiation without "new" keyword
14148		if (
vendor: 11,136 bytes, lines 14148-14570
14148 !this._createWidget ) {
14149			return new constructor( options, element );
14150		}
14151
14152		// Allow instantiation without initializing for simple inheritance
14153		// must use "new" keyword (the code above always passes args)
14154		if ( arguments.length ) {
14155			this._createWidget( options, element );
14156		}
14157	};
14158
14159	// Extend with the existing constructor to carry over any static properties
14160	$.extend( constructor, existingConstructor, {
14161		version: prototype.version,
14162
14163		// Copy the object used to create the prototype in case we need to
14164		// redefine the widget later
14165		_proto: $.extend( {}, prototype ),
14166
14167		// Track widgets that inherit from this widget in case this widget is
14168		// redefined after a widget inherits from it
14169		_childConstructors: []
14170	} );
14171
14172	basePrototype = new base();
14173
14174	// We need to make the options hash a property directly on the new instance
14175	// otherwise we'll modify the options hash on the prototype that we're
14176	// inheriting from
14177	basePrototype.options = $.widget.extend( {}, basePrototype.options );
14178	$.each( prototype, function( prop, value ) {
14179		if ( typeof value !== "function" ) {
14180			proxiedPrototype[ prop ] = value;
14181			return;
14182		}
14183		proxiedPrototype[ prop ] = ( function() {
14184			function _super() {
14185				return base.prototype[ prop ].apply( this, arguments );
14186			}
14187
14188			function _superApply( args ) {
14189				return base.prototype[ prop ].apply( this, args );
14190			}
14191
14192			return function() {
14193				var __super = this._super;
14194				var __superApply = this._superApply;
14195				var returnValue;
14196
14197				this._super = _super;
14198				this._superApply = _superApply;
14199
14200				returnValue = value.apply( this, arguments );
14201
14202				this._super = __super;
14203				this._superApply = __superApply;
14204
14205				return returnValue;
14206			};
14207		} )();
14208	} );
14209	constructor.prototype = $.widget.extend( basePrototype, {
14210
14211		// TODO: remove support for widgetEventPrefix
14212		// always use the name + a colon as the prefix, e.g., draggable:start
14213		// don't prefix for widgets that aren't DOM-based
14214		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
14215	}, proxiedPrototype, {
14216		constructor: constructor,
14217		namespace: namespace,
14218		widgetName: name,
14219		widgetFullName: fullName
14220	} );
14221
14222	// If this widget is being redefined then we need to find all widgets that
14223	// are inheriting from it and redefine all of them so that they inherit from
14224	// the new version of this widget. We're essentially trying to replace one
14225	// level in the prototype chain.
14226	if ( existingConstructor ) {
14227		$.each( existingConstructor._childConstructors, function( i, child ) {
14228			var childPrototype = child.prototype;
14229
14230			// Redefine the child widget using the same prototype that was
14231			// originally used, but inherit from the new version of the base
14232			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
14233				child._proto );
14234		} );
14235
14236		// Remove the list of existing child constructors from the old constructor
14237		// so the old child constructors can be garbage collected
14238		delete existingConstructor._childConstructors;
14239	} else {
14240		base._childConstructors.push( constructor );
14241	}
14242
14243	$.widget.bridge( name, constructor );
14244
14245	return constructor;
14246};
14247
14248$.widget.extend = function( target ) {
14249	var input = widgetSlice.call( arguments, 1 );
14250	var inputIndex = 0;
14251	var inputLength = input.length;
14252	var key;
14253	var value;
14254
14255	for ( ; inputIndex < inputLength; inputIndex++ ) {
14256		for ( key in input[ inputIndex ] ) {
14257			value = input[ inputIndex ][ key ];
14258			if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
14259
14260				// Clone objects
14261				if ( $.isPlainObject( value ) ) {
14262					target[ key ] = $.isPlainObject( target[ key ] ) ?
14263						$.widget.extend( {}, target[ key ], value ) :
14264
14265						// Don't extend strings, arrays, etc. with objects
14266						$.widget.extend( {}, value );
14267
14268				// Copy everything else by reference
14269				} else {
14270					target[ key ] = value;
14271				}
14272			}
14273		}
14274	}
14275	return target;
14276};
14277
14278$.widget.bridge = function( name, object ) {
14279	var fullName = object.prototype.widgetFullName || name;
14280	$.fn[ name ] = function( options ) {
14281		var isMethodCall = typeof options === "string";
14282		var args = widgetSlice.call( arguments, 1 );
14283		var returnValue = this;
14284
14285		if ( isMethodCall ) {
14286
14287			// If this is an empty collection, we need to have the instance method
14288			// return undefined instead of the jQuery instance
14289			if ( !this.length && options === "instance" ) {
14290				returnValue = undefined;
14291			} else {
14292				this.each( function() {
14293					var methodValue;
14294					var instance = $.data( this, fullName );
14295
14296					if ( options === "instance" ) {
14297						returnValue = instance;
14298						return false;
14299					}
14300
14301					if ( !instance ) {
14302						return $.error( "cannot call methods on " + name +
14303							" prior to initialization; " +
14304							"attempted to call method '" + options + "'" );
14305					}
14306
14307					if ( typeof instance[ options ] !== "function" ||
14308						options.charAt( 0 ) === "_" ) {
14309						return $.error( "no such method '" + options + "' for " + name +
14310							" widget instance" );
14311					}
14312
14313					methodValue = instance[ options ].apply( instance, args );
14314
14315					if ( methodValue !== instance && methodValue !== undefined ) {
14316						returnValue = methodValue && methodValue.jquery ?
14317							returnValue.pushStack( methodValue.get() ) :
14318							methodValue;
14319						return false;
14320					}
14321				} );
14322			}
14323		} else {
14324
14325			// Allow multiple hashes to be passed on init
14326			if ( args.length ) {
14327				options = $.widget.extend.apply( null, [ options ].concat( args ) );
14328			}
14329
14330			this.each( function() {
14331				var instance = $.data( this, fullName );
14332				if ( instance ) {
14333					instance.option( options || {} );
14334					if ( instance._init ) {
14335						instance._init();
14336					}
14337				} else {
14338					$.data( this, fullName, new object( options, this ) );
14339				}
14340			} );
14341		}
14342
14343		return returnValue;
14344	};
14345};
14346
14347$.Widget = function( /* options, element */ ) {};
14348$.Widget._childConstructors = [];
14349
14350$.Widget.prototype = {
14351	widgetName: "widget",
14352	widgetEventPrefix: "",
14353	defaultElement: "<div>",
14354
14355	options: {
14356		classes: {},
14357		disabled: false,
14358
14359		// Callbacks
14360		create: null
14361	},
14362
14363	_createWidget: function( options, element ) {
14364		element = $( element || this.defaultElement || this )[ 0 ];
14365		this.element = $( element );
14366		this.uuid = widgetUuid++;
14367		this.eventNamespace = "." + this.widgetName + this.uuid;
14368
14369		this.bindings = $();
14370		this.hoverable = $();
14371		this.focusable = $();
14372		this.classesElementLookup = {};
14373
14374		if ( element !== this ) {
14375			$.data( element, this.widgetFullName, this );
14376			this._on( true, this.element, {
14377				remove: function( event ) {
14378					if ( event.target === element ) {
14379						this.destroy();
14380					}
14381				}
14382			} );
14383			this.document = $( element.style ?
14384
14385				// Element within the document
14386				element.ownerDocument :
14387
14388				// Element is window or document
14389				element.document || element );
14390			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
14391		}
14392
14393		this.options = $.widget.extend( {},
14394			this.options,
14395			this._getCreateOptions(),
14396			options );
14397
14398		this._create();
14399
14400		if ( this.options.disabled ) {
14401			this._setOptionDisabled( this.options.disabled );
14402		}
14403
14404		this._trigger( "create", null, this._getCreateEventData() );
14405		this._init();
14406	},
14407
14408	_getCreateOptions: function() {
14409		return {};
14410	},
14411
14412	_getCreateEventData: $.noop,
14413
14414	_create: $.noop,
14415
14416	_init: $.noop,
14417
14418	destroy: function() {
14419		var that = this;
14420
14421		this._destroy();
14422		$.each( this.classesElementLookup, function( key, value ) {
14423			that._removeClass( value, key );
14424		} );
14425
14426		// We can probably remove the unbind calls in 2.0
14427		// all event bindings should go through this._on()
14428		this.element
14429			.off( this.eventNamespace )
14430			.removeData( this.widgetFullName );
14431		this.widget()
14432			.off( this.eventNamespace )
14433			.removeAttr( "aria-disabled" );
14434
14435		// Clean up events and states
14436		this.bindings.off( this.eventNamespace );
14437	},
14438
14439	_destroy: $.noop,
14440
14441	widget: function() {
14442		return this.element;
14443	},
14444
14445	option: function( key, value ) {
14446		var options = key;
14447		var parts;
14448		var curOption;
14449		var i;
14450
14451		if ( arguments.length === 0 ) {
14452
14453			// Don't return a reference to the internal hash
14454			return $.widget.extend( {}, this.options );
14455		}
14456
14457		if ( typeof key === "string" ) {
14458
14459			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
14460			options = {};
14461			parts = key.split( "." );
14462			key = parts.shift();
14463			if ( parts.length ) {
14464				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
14465				for ( i = 0; i < parts.length - 1; i++ ) {
14466					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
14467					curOption = curOption[ parts[ i ] ];
14468				}
14469				key = parts.pop();
14470				if ( arguments.length === 1 ) {
14471					return curOption[ key ] === undefined ? null : curOption[ key ];
14472				}
14473				curOption[ key ] = value;
14474			} else {
14475				if ( arguments.length === 1 ) {
14476					return this.options[ key ] === undefined ? null : this.options[ key ];
14477				}
14478				options[ key ] = value;
14479			}
14480		}
14481
14482		this._setOptions( options );
14483
14484		return this;
14485	},
14486
14487	_setOptions: function( options ) {
14488		var key;
14489
14490		for ( key in options ) {
14491			this._setOption( key, options[ key ] );
14492		}
14493
14494		return this;
14495	},
14496
14497	_setOption: function( key, value ) {
14498		if ( key === "classes" ) {
14499			this._setOptionClasses( value );
14500		}
14501
14502		this.options[ key ] = value;
14503
14504		if ( key === "disabled" ) {
14505			this._setOptionDisabled( value );
14506		}
14507
14508		return this;
14509	},
14510
14511	_setOptionClasses: function( value ) {
14512		var classKey, elements, currentElements;
14513
14514		for ( classKey in value ) {
14515			currentElements = this.classesElementLookup[ classKey ];
14516			if ( value[ classKey ] === this.options.classes[ classKey ] ||
14517					!currentElements ||
14518					!currentElements.length ) {
14519				continue;
14520			}
14521
14522			// We are doing this to create a new jQuery object because the _removeClass() call
14523			// on the next line is going to destroy the reference to the current elements being
14524			// tracked. We need to save a copy of this collection so that we can add the new classes
14525			// below.
14526			elements = $( currentElements.get() );
14527			this._removeClass( currentElements, classKey );
14528
14529			// We don't use _addClass() here, because that uses this.options.classes
14530			// for generating the string of classes. We want to use the value passed in from
14531			// _setOption(), this is the new value of the classes option which was passed to
14532			// _setOption(). We pass this value directly to _classes().
14533			elements.addClass( this._classes( {
14534				element: elements,
14535				keys: classKey,
14536				classes: value,
14537				add: true
14538			} ) );
14539		}
14540	},
14541
14542	_setOptionDisabled: function( value ) {
14543		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
14544
14545		// If the widget is becoming disabled, then nothing is interactive
14546		if ( value ) {
14547			this._removeClass( this.hoverable, null, "ui-state-hover" );
14548			this._removeClass( this.focusable, null, "ui-state-focus" );
14549		}
14550	},
14551
14552	enable: function() {
14553		return this._setOptions( { disabled: false } );
14554	},
14555
14556	disable: function() {
14557		return this._setOptions( { disabled: true } );
14558	},
14559
14560	_classes: function( options ) {
14561		var full = [];
14562		var that = this;
14563
14564		options = $.extend( {
14565			element: this.element,
14566			classes: this.options.classes || {}
14567		}, options );
14568
14569		function bindRemoveEvent() {
14570			
vendor: 34,981 bytes, lines 14570-16024
14570options.element.each( function( _, element ) {
14571				var isTracked = $.map( that.classesElementLookup, function( elements ) {
14572					return elements;
14573				} )
14574					.some( function( elements ) {
14575						return elements.is( element );
14576					} );
14577
14578				if ( !isTracked ) {
14579					that._on( $( element ), {
14580						remove: "_untrackClassesElement"
14581					} );
14582				}
14583			} );
14584		}
14585
14586		function processClassString( classes, checkOption ) {
14587			var current, i;
14588			for ( i = 0; i < classes.length; i++ ) {
14589				current = that.classesElementLookup[ classes[ i ] ] || $();
14590				if ( options.add ) {
14591					bindRemoveEvent();
14592					current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
14593				} else {
14594					current = $( current.not( options.element ).get() );
14595				}
14596				that.classesElementLookup[ classes[ i ] ] = current;
14597				full.push( classes[ i ] );
14598				if ( checkOption && options.classes[ classes[ i ] ] ) {
14599					full.push( options.classes[ classes[ i ] ] );
14600				}
14601			}
14602		}
14603
14604		if ( options.keys ) {
14605			processClassString( options.keys.match( /\S+/g ) || [], true );
14606		}
14607		if ( options.extra ) {
14608			processClassString( options.extra.match( /\S+/g ) || [] );
14609		}
14610
14611		return full.join( " " );
14612	},
14613
14614	_untrackClassesElement: function( event ) {
14615		var that = this;
14616		$.each( that.classesElementLookup, function( key, value ) {
14617			if ( $.inArray( event.target, value ) !== -1 ) {
14618				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
14619			}
14620		} );
14621
14622		this._off( $( event.target ) );
14623	},
14624
14625	_removeClass: function( element, keys, extra ) {
14626		return this._toggleClass( element, keys, extra, false );
14627	},
14628
14629	_addClass: function( element, keys, extra ) {
14630		return this._toggleClass( element, keys, extra, true );
14631	},
14632
14633	_toggleClass: function( element, keys, extra, add ) {
14634		add = ( typeof add === "boolean" ) ? add : extra;
14635		var shift = ( typeof element === "string" || element === null ),
14636			options = {
14637				extra: shift ? keys : extra,
14638				keys: shift ? element : keys,
14639				element: shift ? this.element : element,
14640				add: add
14641			};
14642		options.element.toggleClass( this._classes( options ), add );
14643		return this;
14644	},
14645
14646	_on: function( suppressDisabledCheck, element, handlers ) {
14647		var delegateElement;
14648		var instance = this;
14649
14650		// No suppressDisabledCheck flag, shuffle arguments
14651		if ( typeof suppressDisabledCheck !== "boolean" ) {
14652			handlers = element;
14653			element = suppressDisabledCheck;
14654			suppressDisabledCheck = false;
14655		}
14656
14657		// No element argument, shuffle and use this.element
14658		if ( !handlers ) {
14659			handlers = element;
14660			element = this.element;
14661			delegateElement = this.widget();
14662		} else {
14663			element = delegateElement = $( element );
14664			this.bindings = this.bindings.add( element );
14665		}
14666
14667		$.each( handlers, function( event, handler ) {
14668			function handlerProxy() {
14669
14670				// Allow widgets to customize the disabled handling
14671				// - disabled as an array instead of boolean
14672				// - disabled class as method for disabling individual parts
14673				if ( !suppressDisabledCheck &&
14674						( instance.options.disabled === true ||
14675						$( this ).hasClass( "ui-state-disabled" ) ) ) {
14676					return;
14677				}
14678				return ( typeof handler === "string" ? instance[ handler ] : handler )
14679					.apply( instance, arguments );
14680			}
14681
14682			// Copy the guid so direct unbinding works
14683			if ( typeof handler !== "string" ) {
14684				handlerProxy.guid = handler.guid =
14685					handler.guid || handlerProxy.guid || $.guid++;
14686			}
14687
14688			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
14689			var eventName = match[ 1 ] + instance.eventNamespace;
14690			var selector = match[ 2 ];
14691
14692			if ( selector ) {
14693				delegateElement.on( eventName, selector, handlerProxy );
14694			} else {
14695				element.on( eventName, handlerProxy );
14696			}
14697		} );
14698	},
14699
14700	_off: function( element, eventName ) {
14701		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
14702			this.eventNamespace;
14703		element.off( eventName );
14704
14705		// Clear the stack to avoid memory leaks (#10056)
14706		this.bindings = $( this.bindings.not( element ).get() );
14707		this.focusable = $( this.focusable.not( element ).get() );
14708		this.hoverable = $( this.hoverable.not( element ).get() );
14709	},
14710
14711	_delay: function( handler, delay ) {
14712		function handlerProxy() {
14713			return ( typeof handler === "string" ? instance[ handler ] : handler )
14714				.apply( instance, arguments );
14715		}
14716		var instance = this;
14717		return setTimeout( handlerProxy, delay || 0 );
14718	},
14719
14720	_hoverable: function( element ) {
14721		this.hoverable = this.hoverable.add( element );
14722		this._on( element, {
14723			mouseenter: function( event ) {
14724				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
14725			},
14726			mouseleave: function( event ) {
14727				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
14728			}
14729		} );
14730	},
14731
14732	_focusable: function( element ) {
14733		this.focusable = this.focusable.add( element );
14734		this._on( element, {
14735			focusin: function( event ) {
14736				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
14737			},
14738			focusout: function( event ) {
14739				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
14740			}
14741		} );
14742	},
14743
14744	_trigger: function( type, event, data ) {
14745		var prop, orig;
14746		var callback = this.options[ type ];
14747
14748		data = data || {};
14749		event = $.Event( event );
14750		event.type = ( type === this.widgetEventPrefix ?
14751			type :
14752			this.widgetEventPrefix + type ).toLowerCase();
14753
14754		// The original event may come from any element
14755		// so we need to reset the target on the new event
14756		event.target = this.element[ 0 ];
14757
14758		// Copy original event properties over to the new event
14759		orig = event.originalEvent;
14760		if ( orig ) {
14761			for ( prop in orig ) {
14762				if ( !( prop in event ) ) {
14763					event[ prop ] = orig[ prop ];
14764				}
14765			}
14766		}
14767
14768		this.element.trigger( event, data );
14769		return !( typeof callback === "function" &&
14770			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
14771			event.isDefaultPrevented() );
14772	}
14773};
14774
14775$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
14776	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
14777		if ( typeof options === "string" ) {
14778			options = { effect: options };
14779		}
14780
14781		var hasOptions;
14782		var effectName = !options ?
14783			method :
14784			options === true || typeof options === "number" ?
14785				defaultEffect :
14786				options.effect || defaultEffect;
14787
14788		options = options || {};
14789		if ( typeof options === "number" ) {
14790			options = { duration: options };
14791		} else if ( options === true ) {
14792			options = {};
14793		}
14794
14795		hasOptions = !$.isEmptyObject( options );
14796		options.complete = callback;
14797
14798		if ( options.delay ) {
14799			element.delay( options.delay );
14800		}
14801
14802		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
14803			element[ method ]( options );
14804		} else if ( effectName !== method && element[ effectName ] ) {
14805			element[ effectName ]( options.duration, options.easing, callback );
14806		} else {
14807			element.queue( function( next ) {
14808				$( this )[ method ]();
14809				if ( callback ) {
14810					callback.call( element[ 0 ] );
14811				}
14812				next();
14813			} );
14814		}
14815	};
14816} );
14817
14818return $.widget;
14819
14820} );
14821
14822
14823
14824/*!
14825 * jQuery UI Effects Blind 1.13.0
14826 * http://jqueryui.com
14827 *
14828 * Copyright jQuery Foundation and other contributors
14829 * Released under the MIT license.
14830 * http://jquery.org/license
14831 */
14832
14833//>>label: Blind Effect
14834//>>group: Effects
14835//>>description: Blinds the element.
14836//>>docs: http://api.jqueryui.com/blind-effect/
14837//>>demos: http://jqueryui.com/effect/
14838
14839( function( factory ) {
14840	"use strict";
14841
14842	if ( typeof define === "function" && define.amd ) {
14843
14844		// AMD. Register as an anonymous module.
14845		define( [
14846			"jquery",
14847			"../version",
14848			"../effect"
14849		], factory );
14850	} else {
14851
14852		// Browser globals
14853		factory( jQuery );
14854	}
14855} )( function( $ ) {
14856"use strict";
14857
14858return $.effects.define( "blind", "hide", function( options, done ) {
14859	var map = {
14860			up: [ "bottom", "top" ],
14861			vertical: [ "bottom", "top" ],
14862			down: [ "top", "bottom" ],
14863			left: [ "right", "left" ],
14864			horizontal: [ "right", "left" ],
14865			right: [ "left", "right" ]
14866		},
14867		element = $( this ),
14868		direction = options.direction || "up",
14869		start = element.cssClip(),
14870		animate = { clip: $.extend( {}, start ) },
14871		placeholder = $.effects.createPlaceholder( element );
14872
14873	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
14874
14875	if ( options.mode === "show" ) {
14876		element.cssClip( animate.clip );
14877		if ( placeholder ) {
14878			placeholder.css( $.effects.clipToBox( animate ) );
14879		}
14880
14881		animate.clip = start;
14882	}
14883
14884	if ( placeholder ) {
14885		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
14886	}
14887
14888	element.animate( animate, {
14889		queue: false,
14890		duration: options.duration,
14891		easing: options.easing,
14892		complete: done
14893	} );
14894} );
14895
14896} );
14897
14898
14899
14900/*!
14901 * jQuery UI Effects Bounce 1.13.0
14902 * http://jqueryui.com
14903 *
14904 * Copyright jQuery Foundation and other contributors
14905 * Released under the MIT license.
14906 * http://jquery.org/license
14907 */
14908
14909//>>label: Bounce Effect
14910//>>group: Effects
14911//>>description: Bounces an element horizontally or vertically n times.
14912//>>docs: http://api.jqueryui.com/bounce-effect/
14913//>>demos: http://jqueryui.com/effect/
14914
14915( function( factory ) {
14916	"use strict";
14917
14918	if ( typeof define === "function" && define.amd ) {
14919
14920		// AMD. Register as an anonymous module.
14921		define( [
14922			"jquery",
14923			"../version",
14924			"../effect"
14925		], factory );
14926	} else {
14927
14928		// Browser globals
14929		factory( jQuery );
14930	}
14931} )( function( $ ) {
14932"use strict";
14933
14934return $.effects.define( "bounce", function( options, done ) {
14935	var upAnim, downAnim, refValue,
14936		element = $( this ),
14937
14938		// Defaults:
14939		mode = options.mode,
14940		hide = mode === "hide",
14941		show = mode === "show",
14942		direction = options.direction || "up",
14943		distance = options.distance,
14944		times = options.times || 5,
14945
14946		// Number of internal animations
14947		anims = times * 2 + ( show || hide ? 1 : 0 ),
14948		speed = options.duration / anims,
14949		easing = options.easing,
14950
14951		// Utility:
14952		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
14953		motion = ( direction === "up" || direction === "left" ),
14954		i = 0,
14955
14956		queuelen = element.queue().length;
14957
14958	$.effects.createPlaceholder( element );
14959
14960	refValue = element.css( ref );
14961
14962	// Default distance for the BIGGEST bounce is the outer Distance / 3
14963	if ( !distance ) {
14964		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
14965	}
14966
14967	if ( show ) {
14968		downAnim = { opacity: 1 };
14969		downAnim[ ref ] = refValue;
14970
14971		// If we are showing, force opacity 0 and set the initial position
14972		// then do the "first" animation
14973		element
14974			.css( "opacity", 0 )
14975			.css( ref, motion ? -distance * 2 : distance * 2 )
14976			.animate( downAnim, speed, easing );
14977	}
14978
14979	// Start at the smallest distance if we are hiding
14980	if ( hide ) {
14981		distance = distance / Math.pow( 2, times - 1 );
14982	}
14983
14984	downAnim = {};
14985	downAnim[ ref ] = refValue;
14986
14987	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
14988	for ( ; i < times; i++ ) {
14989		upAnim = {};
14990		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
14991
14992		element
14993			.animate( upAnim, speed, easing )
14994			.animate( downAnim, speed, easing );
14995
14996		distance = hide ? distance * 2 : distance / 2;
14997	}
14998
14999	// Last Bounce when Hiding
15000	if ( hide ) {
15001		upAnim = { opacity: 0 };
15002		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
15003
15004		element.animate( upAnim, speed, easing );
15005	}
15006
15007	element.queue( done );
15008
15009	$.effects.unshift( element, queuelen, anims + 1 );
15010} );
15011
15012} );
15013
15014
15015
15016/*!
15017 * jQuery UI Effects Clip 1.13.0
15018 * http://jqueryui.com
15019 *
15020 * Copyright jQuery Foundation and other contributors
15021 * Released under the MIT license.
15022 * http://jquery.org/license
15023 */
15024
15025//>>label: Clip Effect
15026//>>group: Effects
15027//>>description: Clips the element on and off like an old TV.
15028//>>docs: http://api.jqueryui.com/clip-effect/
15029//>>demos: http://jqueryui.com/effect/
15030
15031( function( factory ) {
15032	"use strict";
15033
15034	if ( typeof define === "function" && define.amd ) {
15035
15036		// AMD. Register as an anonymous module.
15037		define( [
15038			"jquery",
15039			"../version",
15040			"../effect"
15041		], factory );
15042	} else {
15043
15044		// Browser globals
15045		factory( jQuery );
15046	}
15047} )( function( $ ) {
15048"use strict";
15049
15050return $.effects.define( "clip", "hide", function( options, done ) {
15051	var start,
15052		animate = {},
15053		element = $( this ),
15054		direction = options.direction || "vertical",
15055		both = direction === "both",
15056		horizontal = both || direction === "horizontal",
15057		vertical = both || direction === "vertical";
15058
15059	start = element.cssClip();
15060	animate.clip = {
15061		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
15062		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
15063		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
15064		left: horizontal ? ( start.right - start.left ) / 2 : start.left
15065	};
15066
15067	$.effects.createPlaceholder( element );
15068
15069	if ( options.mode === "show" ) {
15070		element.cssClip( animate.clip );
15071		animate.clip = start;
15072	}
15073
15074	element.animate( animate, {
15075		queue: false,
15076		duration: options.duration,
15077		easing: options.easing,
15078		complete: done
15079	} );
15080
15081} );
15082
15083} );
15084
15085
15086
15087/*!
15088 * jQuery UI Effects Drop 1.13.0
15089 * http://jqueryui.com
15090 *
15091 * Copyright jQuery Foundation and other contributors
15092 * Released under the MIT license.
15093 * http://jquery.org/license
15094 */
15095
15096//>>label: Drop Effect
15097//>>group: Effects
15098//>>description: Moves an element in one direction and hides it at the same time.
15099//>>docs: http://api.jqueryui.com/drop-effect/
15100//>>demos: http://jqueryui.com/effect/
15101
15102( function( factory ) {
15103	"use strict";
15104
15105	if ( typeof define === "function" && define.amd ) {
15106
15107		// AMD. Register as an anonymous module.
15108		define( [
15109			"jquery",
15110			"../version",
15111			"../effect"
15112		], factory );
15113	} else {
15114
15115		// Browser globals
15116		factory( jQuery );
15117	}
15118} )( function( $ ) {
15119"use strict";
15120
15121return $.effects.define( "drop", "hide", function( options, done ) {
15122
15123	var distance,
15124		element = $( this ),
15125		mode = options.mode,
15126		show = mode === "show",
15127		direction = options.direction || "left",
15128		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15129		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
15130		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
15131		animation = {
15132			opacity: 0
15133		};
15134
15135	$.effects.createPlaceholder( element );
15136
15137	distance = options.distance ||
15138		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
15139
15140	animation[ ref ] = motion + distance;
15141
15142	if ( show ) {
15143		element.css( animation );
15144
15145		animation[ ref ] = oppositeMotion + distance;
15146		animation.opacity = 1;
15147	}
15148
15149	// Animate
15150	element.animate( animation, {
15151		queue: false,
15152		duration: options.duration,
15153		easing: options.easing,
15154		complete: done
15155	} );
15156} );
15157
15158} );
15159
15160
15161
15162/*!
15163 * jQuery UI Effects Explode 1.13.0
15164 * http://jqueryui.com
15165 *
15166 * Copyright jQuery Foundation and other contributors
15167 * Released under the MIT license.
15168 * http://jquery.org/license
15169 */
15170
15171//>>label: Explode Effect
15172//>>group: Effects
15173/* eslint-disable max-len */
15174//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
15175/* eslint-enable max-len */
15176//>>docs: http://api.jqueryui.com/explode-effect/
15177//>>demos: http://jqueryui.com/effect/
15178
15179( function( factory ) {
15180	"use strict";
15181
15182	if ( typeof define === "function" && define.amd ) {
15183
15184		// AMD. Register as an anonymous module.
15185		define( [
15186			"jquery",
15187			"../version",
15188			"../effect"
15189		], factory );
15190	} else {
15191
15192		// Browser globals
15193		factory( jQuery );
15194	}
15195} )( function( $ ) {
15196"use strict";
15197
15198return $.effects.define( "explode", "hide", function( options, done ) {
15199
15200	var i, j, left, top, mx, my,
15201		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
15202		cells = rows,
15203		element = $( this ),
15204		mode = options.mode,
15205		show = mode === "show",
15206
15207		// Show and then visibility:hidden the element before calculating offset
15208		offset = element.show().css( "visibility", "hidden" ).offset(),
15209
15210		// Width and height of a piece
15211		width = Math.ceil( element.outerWidth() / cells ),
15212		height = Math.ceil( element.outerHeight() / rows ),
15213		pieces = [];
15214
15215	// Children animate complete:
15216	function childComplete() {
15217		pieces.push( this );
15218		if ( pieces.length === rows * cells ) {
15219			animComplete();
15220		}
15221	}
15222
15223	// Clone the element for each row and cell.
15224	for ( i = 0; i < rows; i++ ) { // ===>
15225		top = offset.top + i * height;
15226		my = i - ( rows - 1 ) / 2;
15227
15228		for ( j = 0; j < cells; j++ ) { // |||
15229			left = offset.left + j * width;
15230			mx = j - ( cells - 1 ) / 2;
15231
15232			// Create a clone of the now hidden main element that will be absolute positioned
15233			// within a wrapper div off the -left and -top equal to size of our pieces
15234			element
15235				.clone()
15236				.appendTo( "body" )
15237				.wrap( "<div></div>" )
15238				.css( {
15239					position: "absolute",
15240					visibility: "visible",
15241					left: -j * width,
15242					top: -i * height
15243				} )
15244
15245				// Select the wrapper - make it overflow: hidden and absolute positioned based on
15246				// where the original was located +left and +top equal to the size of pieces
15247				.parent()
15248					.addClass( "ui-effects-explode" )
15249					.css( {
15250						position: "absolute",
15251						overflow: "hidden",
15252						width: width,
15253						height: height,
15254						left: left + ( show ? mx * width : 0 ),
15255						top: top + ( show ? my * height : 0 ),
15256						opacity: show ? 0 : 1
15257					} )
15258					.animate( {
15259						left: left + ( show ? 0 : mx * width ),
15260						top: top + ( show ? 0 : my * height ),
15261						opacity: show ? 1 : 0
15262					}, options.duration || 500, options.easing, childComplete );
15263		}
15264	}
15265
15266	function animComplete() {
15267		element.css( {
15268			visibility: "visible"
15269		} );
15270		$( pieces ).remove();
15271		done();
15272	}
15273} );
15274
15275} );
15276
15277
15278
15279/*!
15280 * jQuery UI Effects Fade 1.13.0
15281 * http://jqueryui.com
15282 *
15283 * Copyright jQuery Foundation and other contributors
15284 * Released under the MIT license.
15285 * http://jquery.org/license
15286 */
15287
15288//>>label: Fade Effect
15289//>>group: Effects
15290//>>description: Fades the element.
15291//>>docs: http://api.jqueryui.com/fade-effect/
15292//>>demos: http://jqueryui.com/effect/
15293
15294( function( factory ) {
15295	"use strict";
15296
15297	if ( typeof define === "function" && define.amd ) {
15298
15299		// AMD. Register as an anonymous module.
15300		define( [
15301			"jquery",
15302			"../version",
15303			"../effect"
15304		], factory );
15305	} else {
15306
15307		// Browser globals
15308		factory( jQuery );
15309	}
15310} )( function( $ ) {
15311"use strict";
15312
15313return $.effects.define( "fade", "toggle", function( options, done ) {
15314	var show = options.mode === "show";
15315
15316	$( this )
15317		.css( "opacity", show ? 0 : 1 )
15318		.animate( {
15319			opacity: show ? 1 : 0
15320		}, {
15321			queue: false,
15322			duration: options.duration,
15323			easing: options.easing,
15324			complete: done
15325		} );
15326} );
15327
15328} );
15329
15330
15331
15332/*!
15333 * jQuery UI Effects Fold 1.13.0
15334 * http://jqueryui.com
15335 *
15336 * Copyright jQuery Foundation and other contributors
15337 * Released under the MIT license.
15338 * http://jquery.org/license
15339 */
15340
15341//>>label: Fold Effect
15342//>>group: Effects
15343//>>description: Folds an element first horizontally and then vertically.
15344//>>docs: http://api.jqueryui.com/fold-effect/
15345//>>demos: http://jqueryui.com/effect/
15346
15347( function( factory ) {
15348	"use strict";
15349
15350	if ( typeof define === "function" && define.amd ) {
15351
15352		// AMD. Register as an anonymous module.
15353		define( [
15354			"jquery",
15355			"../version",
15356			"../effect"
15357		], factory );
15358	} else {
15359
15360		// Browser globals
15361		factory( jQuery );
15362	}
15363} )( function( $ ) {
15364"use strict";
15365
15366return $.effects.define( "fold", "hide", function( options, done ) {
15367
15368	// Create element
15369	var element = $( this ),
15370		mode = options.mode,
15371		show = mode === "show",
15372		hide = mode === "hide",
15373		size = options.size || 15,
15374		percent = /([0-9]+)%/.exec( size ),
15375		horizFirst = !!options.horizFirst,
15376		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
15377		duration = options.duration / 2,
15378
15379		placeholder = $.effects.createPlaceholder( element ),
15380
15381		start = element.cssClip(),
15382		animation1 = { clip: $.extend( {}, start ) },
15383		animation2 = { clip: $.extend( {}, start ) },
15384
15385		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
15386
15387		queuelen = element.queue().length;
15388
15389	if ( percent ) {
15390		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
15391	}
15392	animation1.clip[ ref[ 0 ] ] = size;
15393	animation2.clip[ ref[ 0 ] ] = size;
15394	animation2.clip[ ref[ 1 ] ] = 0;
15395
15396	if ( show ) {
15397		element.cssClip( animation2.clip );
15398		if ( placeholder ) {
15399			placeholder.css( $.effects.clipToBox( animation2 ) );
15400		}
15401
15402		animation2.clip = start;
15403	}
15404
15405	// Animate
15406	element
15407		.queue( function( next ) {
15408			if ( placeholder ) {
15409				placeholder
15410					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
15411					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
15412			}
15413
15414			next();
15415		} )
15416		.animate( animation1, duration, options.easing )
15417		.animate( animation2, duration, options.easing )
15418		.queue( done );
15419
15420	$.effects.unshift( element, queuelen, 4 );
15421} );
15422
15423} );
15424
15425
15426
15427/*!
15428 * jQuery UI Effects Highlight 1.13.0
15429 * http://jqueryui.com
15430 *
15431 * Copyright jQuery Foundation and other contributors
15432 * Released under the MIT license.
15433 * http://jquery.org/license
15434 */
15435
15436//>>label: Highlight Effect
15437//>>group: Effects
15438//>>description: Highlights the background of an element in a defined color for a custom duration.
15439//>>docs: http://api.jqueryui.com/highlight-effect/
15440//>>demos: http://jqueryui.com/effect/
15441
15442( function( factory ) {
15443	"use strict";
15444
15445	if ( typeof define === "function" && define.amd ) {
15446
15447		// AMD. Register as an anonymous module.
15448		define( [
15449			"jquery",
15450			"../version",
15451			"../effect"
15452		], factory );
15453	} else {
15454
15455		// Browser globals
15456		factory( jQuery );
15457	}
15458} )( function( $ ) {
15459"use strict";
15460
15461return $.effects.define( "highlight", "show", function( options, done ) {
15462	var element = $( this ),
15463		animation = {
15464			backgroundColor: element.css( "backgroundColor" )
15465		};
15466
15467	if ( options.mode === "hide" ) {
15468		animation.opacity = 0;
15469	}
15470
15471	$.effects.saveStyle( element );
15472
15473	element
15474		.css( {
15475			backgroundImage: "none",
15476			backgroundColor: options.color || "#ffff99"
15477		} )
15478		.animate( animation, {
15479			queue: false,
15480			duration: options.duration,
15481			easing: options.easing,
15482			complete: done
15483		} );
15484} );
15485
15486} );
15487
15488
15489
15490/*!
15491 * jQuery UI Effects Size 1.13.0
15492 * http://jqueryui.com
15493 *
15494 * Copyright jQuery Foundation and other contributors
15495 * Released under the MIT license.
15496 * http://jquery.org/license
15497 */
15498
15499//>>label: Size Effect
15500//>>group: Effects
15501//>>description: Resize an element to a specified width and height.
15502//>>docs: http://api.jqueryui.com/size-effect/
15503//>>demos: http://jqueryui.com/effect/
15504
15505( function( factory ) {
15506	"use strict";
15507
15508	if ( typeof define === "function" && define.amd ) {
15509
15510		// AMD. Register as an anonymous module.
15511		define( [
15512			"jquery",
15513			"../version",
15514			"../effect"
15515		], factory );
15516	} else {
15517
15518		// Browser globals
15519		factory( jQuery );
15520	}
15521} )( function( $ ) {
15522"use strict";
15523
15524return $.effects.define( "size", function( options, done ) {
15525
15526	// Create element
15527	var baseline, factor, temp,
15528		element = $( this ),
15529
15530		// Copy for children
15531		cProps = [ "fontSize" ],
15532		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
15533		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
15534
15535		// Set options
15536		mode = options.mode,
15537		restore = mode !== "effect",
15538		scale = options.scale || "both",
15539		origin = options.origin || [ "middle", "center" ],
15540		position = element.css( "position" ),
15541		pos = element.position(),
15542		original = $.effects.scaledDimensions( element ),
15543		from = options.from || original,
15544		to = options.to || $.effects.scaledDimensions( element, 0 );
15545
15546	$.effects.createPlaceholder( element );
15547
15548	if ( mode === "show" ) {
15549		temp = from;
15550		from = to;
15551		to = temp;
15552	}
15553
15554	// Set scaling factor
15555	factor = {
15556		from: {
15557			y: from.height / original.height,
15558			x: from.width / original.width
15559		},
15560		to: {
15561			y: to.height / original.height,
15562			x: to.width / original.width
15563		}
15564	};
15565
15566	// Scale the css box
15567	if ( scale === "box" || scale === "both" ) {
15568
15569		// Vertical props scaling
15570		if ( factor.from.y !== factor.to.y ) {
15571			from = $.effects.setTransition( element, vProps, factor.from.y, from );
15572			to = $.effects.setTransition( element, vProps, factor.to.y, to );
15573		}
15574
15575		// Horizontal props scaling
15576		if ( factor.from.x !== factor.to.x ) {
15577			from = $.effects.setTransition( element, hProps, factor.from.x, from );
15578			to = $.effects.setTransition( element, hProps, factor.to.x, to );
15579		}
15580	}
15581
15582	// Scale the content
15583	if ( scale === "content" || scale === "both" ) {
15584
15585		// Vertical props scaling
15586		if ( factor.from.y !== factor.to.y ) {
15587			from = $.effects.setTransition( element, cProps, factor.from.y, from );
15588			to = $.effects.setTransition( element, cProps, factor.to.y, to );
15589		}
15590	}
15591
15592	// Adjust the position properties based on the provided origin points
15593	if ( origin ) {
15594		baseline = $.effects.getBaseline( origin, original );
15595		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
15596		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
15597		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
15598		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
15599	}
15600	delete from.outerHeight;
15601	delete from.outerWidth;
15602	element.css( from );
15603
15604	// Animate the children if desired
15605	if ( scale === "content" || scale === "both" ) {
15606
15607		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
15608		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
15609
15610		// Only animate children with width attributes specified
15611		// TODO: is this right? should we include anything with css width specified as well
15612		element.find( "*[width]" ).each( function() {
15613			var child = $( this ),
15614				childOriginal = $.effects.scaledDimensions( child ),
15615				childFrom = {
15616					height: childOriginal.height * factor.from.y,
15617					width: childOriginal.width * factor.from.x,
15618					outerHeight: childOriginal.outerHeight * factor.from.y,
15619					outerWidth: childOriginal.outerWidth * factor.from.x
15620				},
15621				childTo = {
15622					height: childOriginal.height * factor.to.y,
15623					width: childOriginal.width * factor.to.x,
15624					outerHeight: childOriginal.height * factor.to.y,
15625					outerWidth: childOriginal.width * factor.to.x
15626				};
15627
15628			// Vertical props scaling
15629			if ( factor.from.y !== factor.to.y ) {
15630				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
15631				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
15632			}
15633
15634			// Horizontal props scaling
15635			if ( factor.from.x !== factor.to.x ) {
15636				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
15637				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
15638			}
15639
15640			if ( restore ) {
15641				$.effects.saveStyle( child );
15642			}
15643
15644			// Animate children
15645			child.css( childFrom );
15646			child.animate( childTo, options.duration, options.easing, function() {
15647
15648				// Restore children
15649				if ( restore ) {
15650					$.effects.restoreStyle( child );
15651				}
15652			} );
15653		} );
15654	}
15655
15656	// Animate
15657	element.animate( to, {
15658		queue: false,
15659		duration: options.duration,
15660		easing: options.easing,
15661		complete: function() {
15662
15663			var offset = element.offset();
15664
15665			if ( to.opacity === 0 ) {
15666				element.css( "opacity", from.opacity );
15667			}
15668
15669			if ( !restore ) {
15670				element
15671					.css( "position", position === "static" ? "relative" : position )
15672					.offset( offset );
15673
15674				// Need to save style here so that automatic style restoration
15675				// doesn't restore to the original styles from before the animation.
15676				$.effects.saveStyle( element );
15677			}
15678
15679			done();
15680		}
15681	} );
15682
15683} );
15684
15685} );
15686
15687
15688
15689
15690/*!
15691 * jQuery UI Effects Scale 1.13.0
15692 * http://jqueryui.com
15693 *
15694 * Copyright jQuery Foundation and other contributors
15695 * Released under the MIT license.
15696 * http://jquery.org/license
15697 */
15698
15699//>>label: Scale Effect
15700//>>group: Effects
15701//>>description: Grows or shrinks an element and its content.
15702//>>docs: http://api.jqueryui.com/scale-effect/
15703//>>demos: http://jqueryui.com/effect/
15704
15705( function( factory ) {
15706	"use strict";
15707
15708	if ( typeof define === "function" && define.amd ) {
15709
15710		// AMD. Register as an anonymous module.
15711		define( [
15712			"jquery",
15713			"../version",
15714			"../effect",
15715			"./effect-size"
15716		], factory );
15717	} else {
15718
15719		// Browser globals
15720		factory( jQuery );
15721	}
15722} )( function( $ ) {
15723"use strict";
15724
15725return $.effects.define( "scale", function( options, done ) {
15726
15727	// Create element
15728	var el = $( this ),
15729		mode = options.mode,
15730		percent = parseInt( options.percent, 10 ) ||
15731			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
15732
15733		newOptions = $.extend( true, {
15734			from: $.effects.scaledDimensions( el ),
15735			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
15736			origin: options.origin || [ "middle", "center" ]
15737		}, options );
15738
15739	// Fade option to support puff
15740	if ( options.fade ) {
15741		newOptions.from.opacity = 1;
15742		newOptions.to.opacity = 0;
15743	}
15744
15745	$.effects.effect.size.call( this, newOptions, done );
15746} );
15747
15748} );
15749
15750
15751
15752
15753/*!
15754 * jQuery UI Effects Puff 1.13.0
15755 * http://jqueryui.com
15756 *
15757 * Copyright jQuery Foundation and other contributors
15758 * Released under the MIT license.
15759 * http://jquery.org/license
15760 */
15761
15762//>>label: Puff Effect
15763//>>group: Effects
15764//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
15765//>>docs: http://api.jqueryui.com/puff-effect/
15766//>>demos: http://jqueryui.com/effect/
15767
15768( function( factory ) {
15769	"use strict";
15770
15771	if ( typeof define === "function" && define.amd ) {
15772
15773		// AMD. Register as an anonymous module.
15774		define( [
15775			"jquery",
15776			"../version",
15777			"../effect",
15778			"./effect-scale"
15779		], factory );
15780	} else {
15781
15782		// Browser globals
15783		factory( jQuery );
15784	}
15785} )( function( $ ) {
15786"use strict";
15787
15788return $.effects.define( "puff", "hide", function( options, done ) {
15789	var newOptions = $.extend( true, {}, options, {
15790		fade: true,
15791		percent: parseInt( options.percent, 10 ) || 150
15792	} );
15793
15794	$.effects.effect.scale.call( this, newOptions, done );
15795} );
15796
15797} );
15798
15799
15800
15801/*!
15802 * jQuery UI Effects Pulsate 1.13.0
15803 * http://jqueryui.com
15804 *
15805 * Copyright jQuery Foundation and other contributors
15806 * Released under the MIT license.
15807 * http://jquery.org/license
15808 */
15809
15810//>>label: Pulsate Effect
15811//>>group: Effects
15812//>>description: Pulsates an element n times by changing the opacity to zero and back.
15813//>>docs: http://api.jqueryui.com/pulsate-effect/
15814//>>demos: http://jqueryui.com/effect/
15815
15816( function( factory ) {
15817	"use strict";
15818
15819	if ( typeof define === "function" && define.amd ) {
15820
15821		// AMD. Register as an anonymous module.
15822		define( [
15823			"jquery",
15824			"../version",
15825			"../effect"
15826		], factory );
15827	} else {
15828
15829		// Browser globals
15830		factory( jQuery );
15831	}
15832} )( function( $ ) {
15833"use strict";
15834
15835return $.effects.define( "pulsate", "show", function( options, done ) {
15836	var element = $( this ),
15837		mode = options.mode,
15838		show = mode === "show",
15839		hide = mode === "hide",
15840		showhide = show || hide,
15841
15842		// Showing or hiding leaves off the "last" animation
15843		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
15844		duration = options.duration / anims,
15845		animateTo = 0,
15846		i = 1,
15847		queuelen = element.queue().length;
15848
15849	if ( show || !element.is( ":visible" ) ) {
15850		element.css( "opacity", 0 ).show();
15851		animateTo = 1;
15852	}
15853
15854	// Anims - 1 opacity "toggles"
15855	for ( ; i < anims; i++ ) {
15856		element.animate( { opacity: animateTo }, duration, options.easing );
15857		animateTo = 1 - animateTo;
15858	}
15859
15860	element.animate( { opacity: animateTo }, duration, options.easing );
15861
15862	element.queue( done );
15863
15864	$.effects.unshift( element, queuelen, anims + 1 );
15865} );
15866
15867} );
15868
15869
15870
15871/*!
15872 * jQuery UI Effects Shake 1.13.0
15873 * http://jqueryui.com
15874 *
15875 * Copyright jQuery Foundation and other contributors
15876 * Released under the MIT license.
15877 * http://jquery.org/license
15878 */
15879
15880//>>label: Shake Effect
15881//>>group: Effects
15882//>>description: Shakes an element horizontally or vertically n times.
15883//>>docs: http://api.jqueryui.com/shake-effect/
15884//>>demos: http://jqueryui.com/effect/
15885
15886( function( factory ) {
15887	"use strict";
15888
15889	if ( typeof define === "function" && define.amd ) {
15890
15891		// AMD. Register as an anonymous module.
15892		define( [
15893			"jquery",
15894			"../version",
15895			"../effect"
15896		], factory );
15897	} else {
15898
15899		// Browser globals
15900		factory( jQuery );
15901	}
15902} )( function( $ ) {
15903"use strict";
15904
15905return $.effects.define( "shake", function( options, done ) {
15906
15907	var i = 1,
15908		element = $( this ),
15909		direction = options.direction || "left",
15910		distance = options.distance || 20,
15911		times = options.times || 3,
15912		anims = times * 2 + 1,
15913		speed = Math.round( options.duration / anims ),
15914		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15915		positiveMotion = ( direction === "up" || direction === "left" ),
15916		animation = {},
15917		animation1 = {},
15918		animation2 = {},
15919
15920		queuelen = element.queue().length;
15921
15922	$.effects.createPlaceholder( element );
15923
15924	// Animation
15925	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
15926	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
15927	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
15928
15929	// Animate
15930	element.animate( animation, speed, options.easing );
15931
15932	// Shakes
15933	for ( ; i < times; i++ ) {
15934		element
15935			.animate( animation1, speed, options.easing )
15936			.animate( animation2, speed, options.easing );
15937	}
15938
15939	element
15940		.animate( animation1, speed, options.easing )
15941		.animate( animation, speed / 2, options.easing )
15942		.queue( done );
15943
15944	$.effects.unshift( element, queuelen, anims + 1 );
15945} );
15946
15947} );
15948
15949
15950
15951/*!
15952 * jQuery UI Effects Slide 1.13.0
15953 * http://jqueryui.com
15954 *
15955 * Copyright jQuery Foundation and other contributors
15956 * Released under the MIT license.
15957 * http://jquery.org/license
15958 */
15959
15960//>>label: Slide Effect
15961//>>group: Effects
15962//>>description: Slides an element in and out of the viewport.
15963//>>docs: http://api.jqueryui.com/slide-effect/
15964//>>demos: http://jqueryui.com/effect/
15965
15966( function( factory ) {
15967	"use strict";
15968
15969	if ( typeof define === "function" && define.amd ) {
15970
15971		// AMD. Register as an anonymous module.
15972		define( [
15973			"jquery",
15974			"../version",
15975			"../effect"
15976		], factory );
15977	} else {
15978
15979		// Browser globals
15980		factory( jQuery );
15981	}
15982} )( function( $ ) {
15983"use strict";
15984
15985return $.effects.define( "slide", "show", function( options, done ) {
15986	var startClip, startRef,
15987		element = $( this ),
15988		map = {
15989			up: [ "bottom", "top" ],
15990			down: [ "top", "bottom" ],
15991			left: [ "right", "left" ],
15992			right: [ "left", "right" ]
15993		},
15994		mode = options.mode,
15995		direction = options.direction || "left",
15996		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
15997		positiveMotion = ( direction === "up" || direction === "left" ),
15998		distance = options.distance ||
15999			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
16000		animation = {};
16001
16002	$.effects.createPlaceholder( element );
16003
16004	startClip = element.cssClip();
16005	startRef = element.position()[ ref ];
16006
16007	// Define hide animation
16008	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
16009	animation.clip = element.cssClip();
16010	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
16011
16012	// Reverse the animation if we're showing
16013	if ( mode === "show" ) {
16014		element.cssClip( animation.clip );
16015		element.css( ref, animation[ ref ] );
16016		animation.clip = startClip;
16017		animation[ ref ] = startRef;
16018	}
16019
16020	// Actually animate
16021	element.animate( animation, {
16022		queue: false,
16023		duration: options.duration,
16024		easing: options.easing,
16025		complete: done
16026	} );
16027} );
16028
16029} );
16030
16031
16032
16033/*!
16034 * jQuery UI Effects Transfer 1.13.0
16035 * http://jqueryui.com
16036 *
16037 * Copyright jQuery Foundation and other contributors
16038 * Released under the MIT license.
16039 * http://jquery.org/license
16040 */
16041
16042//>>label: Transfer Effect
16043//>>group: Effects
16044//>>description: Displays a transfer effect from one element to another.
16045//>>docs: http://api.jqueryui.com/transfer-effect/
16046//>>demos: http://jqueryui.com/effect/
16047
16048( function( factory ) {
16049	"use strict";
16050
16051	if ( typeof define === "function" && define.amd ) {
16052
16053		// AMD. Register as an anonymous module.
16054		define( [
16055			"jquery",
16056			"../version",
16057			"../effect"
16058		], factory );
16059	} else {
16060
16061		// Browser globals
16062		factory( jQuery );
16063	}
16064} )( function( $ ) {
16065"use strict";
16066
16067var effect;
16068if ( $.uiBackCompat !== false ) {
16069	effect = $.effects.define( "transfer", function( options, done ) {
16070		$( this ).transfer( options, done );
16071	} );
16072}
16073return effect;
16074
16075} );
16076
16077
16078
16079
16080
16081/*!
16082 * jQuery UI Accordion 1.13.0
16083 * http://jqueryui.com
16084 *
16085 * Copyright jQuery Foundation and other contributors
16086 * Released under the MIT license.
16087 * http://jquery.org/license
16088 */
16089
16090//>>label: Accordion
16091//>>group: Widgets
16092/* eslint-disable max-len */
16093//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
16094/* eslint-enable max-len */
16095//>>docs: http://api.jqueryui.com/accordion/
16096//>>demos: http://jqueryui.com/accordion/
16097//>>css.structure: ../../themes/base/core.css
16098//>>css.structure: ../../themes/base/accordion.css
16099//>>css.theme: ../../themes/base/theme.css
16100
16101( function( factory ) {
16102	"use strict";
16103
16104	if ( typeof define === "function" && define.amd ) {
16105
16106		// AMD. Register as an anonymous module.
16107		define( [
16108			"jquery",
16109			"../version",
16110			"../keycode",
16111			"../unique-id",
16112			"../widget"
16113		], factory );
16114	} else {
16115
16116		// Browser globals
16117		factory( jQuery );
16118	}
16119} )( function( $ ) {
16120"use strict";
16121
16122return $.widget( "ui.accordion", {
16123	version: "1.13.0
vendor: 15,121 bytes, lines 16123-16701
16123",
16124	options: {
16125		active: 0,
16126		animate: {},
16127		classes: {
16128			"ui-accordion-header": "ui-corner-top",
16129			"ui-accordion-header-collapsed": "ui-corner-all",
16130			"ui-accordion-content": "ui-corner-bottom"
16131		},
16132		collapsible: false,
16133		event: "click",
16134		header: function( elem ) {
16135			return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() );
16136		},
16137		heightStyle: "auto",
16138		icons: {
16139			activeHeader: "ui-icon-triangle-1-s",
16140			header: "ui-icon-triangle-1-e"
16141		},
16142
16143		// Callbacks
16144		activate: null,
16145		beforeActivate: null
16146	},
16147
16148	hideProps: {
16149		borderTopWidth: "hide",
16150		borderBottomWidth: "hide",
16151		paddingTop: "hide",
16152		paddingBottom: "hide",
16153		height: "hide"
16154	},
16155
16156	showProps: {
16157		borderTopWidth: "show",
16158		borderBottomWidth: "show",
16159		paddingTop: "show",
16160		paddingBottom: "show",
16161		height: "show"
16162	},
16163
16164	_create: function() {
16165		var options = this.options;
16166
16167		this.prevShow = this.prevHide = $();
16168		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
16169		this.element.attr( "role", "tablist" );
16170
16171		// Don't allow collapsible: false and active: false / null
16172		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
16173			options.active = 0;
16174		}
16175
16176		this._processPanels();
16177
16178		// handle negative values
16179		if ( options.active < 0 ) {
16180			options.active += this.headers.length;
16181		}
16182		this._refresh();
16183	},
16184
16185	_getCreateEventData: function() {
16186		return {
16187			header: this.active,
16188			panel: !this.active.length ? $() : this.active.next()
16189		};
16190	},
16191
16192	_createIcons: function() {
16193		var icon, children,
16194			icons = this.options.icons;
16195
16196		if ( icons ) {
16197			icon = $( "<span>" );
16198			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
16199			icon.prependTo( this.headers );
16200			children = this.active.children( ".ui-accordion-header-icon" );
16201			this._removeClass( children, icons.header )
16202				._addClass( children, null, icons.activeHeader )
16203				._addClass( this.headers, "ui-accordion-icons" );
16204		}
16205	},
16206
16207	_destroyIcons: function() {
16208		this._removeClass( this.headers, "ui-accordion-icons" );
16209		this.headers.children( ".ui-accordion-header-icon" ).remove();
16210	},
16211
16212	_destroy: function() {
16213		var contents;
16214
16215		// Clean up main element
16216		this.element.removeAttr( "role" );
16217
16218		// Clean up headers
16219		this.headers
16220			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
16221			.removeUniqueId();
16222
16223		this._destroyIcons();
16224
16225		// Clean up content panels
16226		contents = this.headers.next()
16227			.css( "display", "" )
16228			.removeAttr( "role aria-hidden aria-labelledby" )
16229			.removeUniqueId();
16230
16231		if ( this.options.heightStyle !== "content" ) {
16232			contents.css( "height", "" );
16233		}
16234	},
16235
16236	_setOption: function( key, value ) {
16237		if ( key === "active" ) {
16238
16239			// _activate() will handle invalid values and update this.options
16240			this._activate( value );
16241			return;
16242		}
16243
16244		if ( key === "event" ) {
16245			if ( this.options.event ) {
16246				this._off( this.headers, this.options.event );
16247			}
16248			this._setupEvents( value );
16249		}
16250
16251		this._super( key, value );
16252
16253		// Setting collapsible: false while collapsed; open first panel
16254		if ( key === "collapsible" && !value && this.options.active === false ) {
16255			this._activate( 0 );
16256		}
16257
16258		if ( key === "icons" ) {
16259			this._destroyIcons();
16260			if ( value ) {
16261				this._createIcons();
16262			}
16263		}
16264	},
16265
16266	_setOptionDisabled: function( value ) {
16267		this._super( value );
16268
16269		this.element.attr( "aria-disabled", value );
16270
16271		// Support: IE8 Only
16272		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
16273		// so we need to add the disabled class to the headers and panels
16274		this._toggleClass( null, "ui-state-disabled", !!value );
16275		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
16276			!!value );
16277	},
16278
16279	_keydown: function( event ) {
16280		if ( event.altKey || event.ctrlKey ) {
16281			return;
16282		}
16283
16284		var keyCode = $.ui.keyCode,
16285			length = this.headers.length,
16286			currentIndex = this.headers.index( event.target ),
16287			toFocus = false;
16288
16289		switch ( event.keyCode ) {
16290		case keyCode.RIGHT:
16291		case keyCode.DOWN:
16292			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
16293			break;
16294		case keyCode.LEFT:
16295		case keyCode.UP:
16296			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
16297			break;
16298		case keyCode.SPACE:
16299		case keyCode.ENTER:
16300			this._eventHandler( event );
16301			break;
16302		case keyCode.HOME:
16303			toFocus = this.headers[ 0 ];
16304			break;
16305		case keyCode.END:
16306			toFocus = this.headers[ length - 1 ];
16307			break;
16308		}
16309
16310		if ( toFocus ) {
16311			$( event.target ).attr( "tabIndex", -1 );
16312			$( toFocus ).attr( "tabIndex", 0 );
16313			$( toFocus ).trigger( "focus" );
16314			event.preventDefault();
16315		}
16316	},
16317
16318	_panelKeyDown: function( event ) {
16319		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
16320			$( event.currentTarget ).prev().trigger( "focus" );
16321		}
16322	},
16323
16324	refresh: function() {
16325		var options = this.options;
16326		this._processPanels();
16327
16328		// Was collapsed or no panel
16329		if ( ( options.active === false && options.collapsible === true ) ||
16330				!this.headers.length ) {
16331			options.active = false;
16332			this.active = $();
16333
16334		// active false only when collapsible is true
16335		} else if ( options.active === false ) {
16336			this._activate( 0 );
16337
16338		// was active, but active panel is gone
16339		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
16340
16341			// all remaining panel are disabled
16342			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
16343				options.active = false;
16344				this.active = $();
16345
16346			// activate previous panel
16347			} else {
16348				this._activate( Math.max( 0, options.active - 1 ) );
16349			}
16350
16351		// was active, active panel still exists
16352		} else {
16353
16354			// make sure active index is correct
16355			options.active = this.headers.index( this.active );
16356		}
16357
16358		this._destroyIcons();
16359
16360		this._refresh();
16361	},
16362
16363	_processPanels: function() {
16364		var prevHeaders = this.headers,
16365			prevPanels = this.panels;
16366
16367		if ( typeof this.options.header === "function" ) {
16368			this.headers = this.options.header( this.element );
16369		} else {
16370			this.headers = this.element.find( this.options.header );
16371		}
16372		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
16373			"ui-state-default" );
16374
16375		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
16376		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
16377
16378		// Avoid memory leaks (#10056)
16379		if ( prevPanels ) {
16380			this._off( prevHeaders.not( this.headers ) );
16381			this._off( prevPanels.not( this.panels ) );
16382		}
16383	},
16384
16385	_refresh: function() {
16386		var maxHeight,
16387			options = this.options,
16388			heightStyle = options.heightStyle,
16389			parent = this.element.parent();
16390
16391		this.active = this._findActive( options.active );
16392		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
16393			._removeClass( this.active, "ui-accordion-header-collapsed" );
16394		this._addClass( this.active.next(), "ui-accordion-content-active" );
16395		this.active.next().show();
16396
16397		this.headers
16398			.attr( "role", "tab" )
16399			.each( function() {
16400				var header = $( this ),
16401					headerId = header.uniqueId().attr( "id" ),
16402					panel = header.next(),
16403					panelId = panel.uniqueId().attr( "id" );
16404				header.attr( "aria-controls", panelId );
16405				panel.attr( "aria-labelledby", headerId );
16406			} )
16407			.next()
16408				.attr( "role", "tabpanel" );
16409
16410		this.headers
16411			.not( this.active )
16412				.attr( {
16413					"aria-selected": "false",
16414					"aria-expanded": "false",
16415					tabIndex: -1
16416				} )
16417				.next()
16418					.attr( {
16419						"aria-hidden": "true"
16420					} )
16421					.hide();
16422
16423		// Make sure at least one header is in the tab order
16424		if ( !this.active.length ) {
16425			this.headers.eq( 0 ).attr( "tabIndex", 0 );
16426		} else {
16427			this.active.attr( {
16428				"aria-selected": "true",
16429				"aria-expanded": "true",
16430				tabIndex: 0
16431			} )
16432				.next()
16433					.attr( {
16434						"aria-hidden": "false"
16435					} );
16436		}
16437
16438		this._createIcons();
16439
16440		this._setupEvents( options.event );
16441
16442		if ( heightStyle === "fill" ) {
16443			maxHeight = parent.height();
16444			this.element.siblings( ":visible" ).each( function() {
16445				var elem = $( this ),
16446					position = elem.css( "position" );
16447
16448				if ( position === "absolute" || position === "fixed" ) {
16449					return;
16450				}
16451				maxHeight -= elem.outerHeight( true );
16452			} );
16453
16454			this.headers.each( function() {
16455				maxHeight -= $( this ).outerHeight( true );
16456			} );
16457
16458			this.headers.next()
16459				.each( function() {
16460					$( this ).height( Math.max( 0, maxHeight -
16461						$( this ).innerHeight() + $( this ).height() ) );
16462				} )
16463				.css( "overflow", "auto" );
16464		} else if ( heightStyle === "auto" ) {
16465			maxHeight = 0;
16466			this.headers.next()
16467				.each( function() {
16468					var isVisible = $( this ).is( ":visible" );
16469					if ( !isVisible ) {
16470						$( this ).show();
16471					}
16472					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
16473					if ( !isVisible ) {
16474						$( this ).hide();
16475					}
16476				} )
16477				.height( maxHeight );
16478		}
16479	},
16480
16481	_activate: function( index ) {
16482		var active = this._findActive( index )[ 0 ];
16483
16484		// Trying to activate the already active panel
16485		if ( active === this.active[ 0 ] ) {
16486			return;
16487		}
16488
16489		// Trying to collapse, simulate a click on the currently active header
16490		active = active || this.active[ 0 ];
16491
16492		this._eventHandler( {
16493			target: active,
16494			currentTarget: active,
16495			preventDefault: $.noop
16496		} );
16497	},
16498
16499	_findActive: function( selector ) {
16500		return typeof selector === "number" ? this.headers.eq( selector ) : $();
16501	},
16502
16503	_setupEvents: function( event ) {
16504		var events = {
16505			keydown: "_keydown"
16506		};
16507		if ( event ) {
16508			$.each( event.split( " " ), function( index, eventName ) {
16509				events[ eventName ] = "_eventHandler";
16510			} );
16511		}
16512
16513		this._off( this.headers.add( this.headers.next() ) );
16514		this._on( this.headers, events );
16515		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
16516		this._hoverable( this.headers );
16517		this._focusable( this.headers );
16518	},
16519
16520	_eventHandler: function( event ) {
16521		var activeChildren, clickedChildren,
16522			options = this.options,
16523			active = this.active,
16524			clicked = $( event.currentTarget ),
16525			clickedIsActive = clicked[ 0 ] === active[ 0 ],
16526			collapsing = clickedIsActive && options.collapsible,
16527			toShow = collapsing ? $() : clicked.next(),
16528			toHide = active.next(),
16529			eventData = {
16530				oldHeader: active,
16531				oldPanel: toHide,
16532				newHeader: collapsing ? $() : clicked,
16533				newPanel: toShow
16534			};
16535
16536		event.preventDefault();
16537
16538		if (
16539
16540				// click on active header, but not collapsible
16541				( clickedIsActive && !options.collapsible ) ||
16542
16543				// allow canceling activation
16544				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
16545			return;
16546		}
16547
16548		options.active = collapsing ? false : this.headers.index( clicked );
16549
16550		// When the call to ._toggle() comes after the class changes
16551		// it causes a very odd bug in IE 8 (see #6720)
16552		this.active = clickedIsActive ? $() : clicked;
16553		this._toggle( eventData );
16554
16555		// Switch classes
16556		// corner classes on the previously active header stay after the animation
16557		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
16558		if ( options.icons ) {
16559			activeChildren = active.children( ".ui-accordion-header-icon" );
16560			this._removeClass( activeChildren, null, options.icons.activeHeader )
16561				._addClass( activeChildren, null, options.icons.header );
16562		}
16563
16564		if ( !clickedIsActive ) {
16565			this._removeClass( clicked, "ui-accordion-header-collapsed" )
16566				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
16567			if ( options.icons ) {
16568				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
16569				this._removeClass( clickedChildren, null, options.icons.header )
16570					._addClass( clickedChildren, null, options.icons.activeHeader );
16571			}
16572
16573			this._addClass( clicked.next(), "ui-accordion-content-active" );
16574		}
16575	},
16576
16577	_toggle: function( data ) {
16578		var toShow = data.newPanel,
16579			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
16580
16581		// Handle activating a panel during the animation for another activation
16582		this.prevShow.add( this.prevHide ).stop( true, true );
16583		this.prevShow = toShow;
16584		this.prevHide = toHide;
16585
16586		if ( this.options.animate ) {
16587			this._animate( toShow, toHide, data );
16588		} else {
16589			toHide.hide();
16590			toShow.show();
16591			this._toggleComplete( data );
16592		}
16593
16594		toHide.attr( {
16595			"aria-hidden": "true"
16596		} );
16597		toHide.prev().attr( {
16598			"aria-selected": "false",
16599			"aria-expanded": "false"
16600		} );
16601
16602		// if we're switching panels, remove the old header from the tab order
16603		// if we're opening from collapsed state, remove the previous header from the tab order
16604		// if we're collapsing, then keep the collapsing header in the tab order
16605		if ( toShow.length && toHide.length ) {
16606			toHide.prev().attr( {
16607				"tabIndex": -1,
16608				"aria-expanded": "false"
16609			} );
16610		} else if ( toShow.length ) {
16611			this.headers.filter( function() {
16612				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
16613			} )
16614				.attr( "tabIndex", -1 );
16615		}
16616
16617		toShow
16618			.attr( "aria-hidden", "false" )
16619			.prev()
16620				.attr( {
16621					"aria-selected": "true",
16622					"aria-expanded": "true",
16623					tabIndex: 0
16624				} );
16625	},
16626
16627	_animate: function( toShow, toHide, data ) {
16628		var total, easing, duration,
16629			that = this,
16630			adjust = 0,
16631			boxSizing = toShow.css( "box-sizing" ),
16632			down = toShow.length &&
16633				( !toHide.length || ( toShow.index() < toHide.index() ) ),
16634			animate = this.options.animate || {},
16635			options = down && animate.down || animate,
16636			complete = function() {
16637				that._toggleComplete( data );
16638			};
16639
16640		if ( typeof options === "number" ) {
16641			duration = options;
16642		}
16643		if ( typeof options === "string" ) {
16644			easing = options;
16645		}
16646
16647		// fall back from options to animation in case of partial down settings
16648		easing = easing || options.easing || animate.easing;
16649		duration = duration || options.duration || animate.duration;
16650
16651		if ( !toHide.length ) {
16652			return toShow.animate( this.showProps, duration, easing, complete );
16653		}
16654		if ( !toShow.length ) {
16655			return toHide.animate( this.hideProps, duration, easing, complete );
16656		}
16657
16658		total = toShow.show().outerHeight();
16659		toHide.animate( this.hideProps, {
16660			duration: duration,
16661			easing: easing,
16662			step: function( now, fx ) {
16663				fx.now = Math.round( now );
16664			}
16665		} );
16666		toShow
16667			.hide()
16668			.animate( this.showProps, {
16669				duration: duration,
16670				easing: easing,
16671				complete: complete,
16672				step: function( now, fx ) {
16673					fx.now = Math.round( now );
16674					if ( fx.prop !== "height" ) {
16675						if ( boxSizing === "content-box" ) {
16676							adjust += fx.now;
16677						}
16678					} else if ( that.options.heightStyle !== "content" ) {
16679						fx.now = Math.round( total - toHide.outerHeight() - adjust );
16680						adjust = 0;
16681					}
16682				}
16683			} );
16684	},
16685
16686	_toggleComplete: function( data ) {
16687		var toHide = data.oldPanel,
16688			prev = toHide.prev();
16689
16690		this._removeClass( toHide, "ui-accordion-content-active" );
16691		this._removeClass( prev, "ui-accordion-header-active" )
16692			._addClass( prev, "ui-accordion-header-collapsed" );
16693
16694		// Work around for rendering bug in IE (#5421)
16695		if ( toHide.length ) {
16696			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
16697		}
16698		this._trigger( "activate", null, data );
16699	}
16700} );
16701
16702} );
16703
16704
16705
16706
16707
16708
16709
16710/*!
16711 * jQuery UI Menu 1.13.0
16712 * http://jqueryui.com
16713 *
16714 * Copyright jQuery Foundation and other contributors
16715 * Released under the MIT license.
16716 * http://jquery.org/license
16717 */
16718
16719//>>label: Menu
16720//>>group: Widgets
16721//>>description: Creates nestable menus.
16722//>>docs: http://api.jqueryui.com/menu/
16723//>>demos: http://jqueryui.com/menu/
16724//>>css.structure: ../../themes/base/core.css
16725//>>css.structure: ../../themes/base/menu.css
16726//>>css.theme: ../../themes/base/theme.css
16727
16728( function( factory ) {
16729	"use strict";
16730
16731	if ( typeof define === "function" && define.amd ) {
16732
16733		// AMD. Register as an anonymous module.
16734		define( [
16735			"jquery",
16736			"../keycode",
16737			"../position",
16738			"../safe-active-element",
16739			"../unique-id",
16740			"../version",
16741			"../widget"
16742		], factory );
16743	} else {
16744
16745		// Browser globals
16746		factory( jQuery );
16747	}
16748} )( function( $ ) {
16749"use strict";
16750
16751return $.widget( "ui.menu", {
16752	version: "1.13.0
vendor: 2,668 bytes, lines 16752-16854
16752",
16753	defaultElement: "<ul>",
16754	delay: 300,
16755	options: {
16756		icons: {
16757			submenu: "ui-icon-caret-1-e"
16758		},
16759		items: "> *",
16760		menus: "ul",
16761		position: {
16762			my: "left top",
16763			at: "right top"
16764		},
16765		role: "menu",
16766
16767		// Callbacks
16768		blur: null,
16769		focus: null,
16770		select: null
16771	},
16772
16773	_create: function() {
16774		this.activeMenu = this.element;
16775
16776		// Flag used to prevent firing of the click handler
16777		// as the event bubbles up through nested menus
16778		this.mouseHandled = false;
16779		this.lastMousePosition = { x: null, y: null };
16780		this.element
16781			.uniqueId()
16782			.attr( {
16783				role: this.options.role,
16784				tabIndex: 0
16785			} );
16786
16787		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
16788		this._on( {
16789
16790			// Prevent focus from sticking to links inside menu after clicking
16791			// them (focus should always stay on UL during navigation).
16792			"mousedown .ui-menu-item": function( event ) {
16793				event.preventDefault();
16794
16795				this._activateItem( event );
16796			},
16797			"click .ui-menu-item": function( event ) {
16798				var target = $( event.target );
16799				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
16800				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
16801					this.select( event );
16802
16803					// Only set the mouseHandled flag if the event will bubble, see #9469.
16804					if ( !event.isPropagationStopped() ) {
16805						this.mouseHandled = true;
16806					}
16807
16808					// Open submenu on click
16809					if ( target.has( ".ui-menu" ).length ) {
16810						this.expand( event );
16811					} else if ( !this.element.is( ":focus" ) &&
16812							active.closest( ".ui-menu" ).length ) {
16813
16814						// Redirect focus to the menu
16815						this.element.trigger( "focus", [ true ] );
16816
16817						// If the active item is on the top level, let it stay active.
16818						// Otherwise, blur the active item since it is no longer visible.
16819						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
16820							clearTimeout( this.timer );
16821						}
16822					}
16823				}
16824			},
16825			"mouseenter .ui-menu-item": "_activateItem",
16826			"mousemove .ui-menu-item": "_activateItem",
16827			mouseleave: "collapseAll",
16828			"mouseleave .ui-menu": "collapseAll",
16829			focus: function( event, keepActiveItem ) {
16830
16831				// If there's already an active item, keep it active
16832				// If not, activate the first item
16833				var item = this.active || this._menuItems().first();
16834
16835				if ( !keepActiveItem ) {
16836					this.focus( event, item );
16837				}
16838			},
16839			blur: function( event ) {
16840				this._delay( function() {
16841					var notContained = !$.contains(
16842						this.element[ 0 ],
16843						$.ui.safeActiveElement( this.document[ 0 ] )
16844					);
16845					if ( notContained ) {
16846						this.collapseAll( event );
16847					}
16848				} );
16849			},
16850			keydown: "_keydown"
16851		} );
16852
16853		this.refresh();
16854
vendor: 3,056 bytes, lines 16855-16971
16855		// Clicks outside of a menu collapse any open menus
16856		this._on( this.document, {
16857			click: function( event ) {
16858				if ( this._closeOnDocumentClick( event ) ) {
16859					this.collapseAll( event, true );
16860				}
16861
16862				// Reset the mouseHandled flag
16863				this.mouseHandled = false;
16864			}
16865		} );
16866	},
16867
16868	_activateItem: function( event ) {
16869
16870		// Ignore mouse events while typeahead is active, see #10458.
16871		// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
16872		// is over an item in the menu
16873		if ( this.previousFilter ) {
16874			return;
16875		}
16876
16877		// If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
16878		if ( event.clientX === this.lastMousePosition.x &&
16879				event.clientY === this.lastMousePosition.y ) {
16880			return;
16881		}
16882
16883		this.lastMousePosition = {
16884			x: event.clientX,
16885			y: event.clientY
16886		};
16887
16888		var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
16889			target = $( event.currentTarget );
16890
16891		// Ignore bubbled events on parent items, see #11641
16892		if ( actualTarget[ 0 ] !== target[ 0 ] ) {
16893			return;
16894		}
16895
16896		// If the item is already active, there's nothing to do
16897		if ( target.is( ".ui-state-active" ) ) {
16898			return;
16899		}
16900
16901		// Remove ui-state-active class from siblings of the newly focused menu item
16902		// to avoid a jump caused by adjacent elements both having a class with a border
16903		this._removeClass( target.siblings().children( ".ui-state-active" ),
16904			null, "ui-state-active" );
16905		this.focus( event, target );
16906	},
16907
16908	_destroy: function() {
16909		var items = this.element.find( ".ui-menu-item" )
16910				.removeAttr( "role aria-disabled" ),
16911			submenus = items.children( ".ui-menu-item-wrapper" )
16912				.removeUniqueId()
16913				.removeAttr( "tabIndex role aria-haspopup" );
16914
16915		// Destroy (sub)menus
16916		this.element
16917			.removeAttr( "aria-activedescendant" )
16918			.find( ".ui-menu" ).addBack()
16919				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
16920					"tabIndex" )
16921				.removeUniqueId()
16922				.show();
16923
16924		submenus.children().each( function() {
16925			var elem = $( this );
16926			if ( elem.data( "ui-menu-submenu-caret" ) ) {
16927				elem.remove();
16928			}
16929		} );
16930	},
16931
16932	_keydown: function( event ) {
16933		var match, prev, character, skip,
16934			preventDefault = true;
16935
16936		switch ( event.keyCode ) {
16937		case $.ui.keyCode.PAGE_UP:
16938			this.previousPage( event );
16939			break;
16940		case $.ui.keyCode.PAGE_DOWN:
16941			this.nextPage( event );
16942			break;
16943		case $.ui.keyCode.HOME:
16944			this._move( "first", "first", event );
16945			break;
16946		case $.ui.keyCode.END:
16947			this._move( "last", "last", event );
16948			break;
16949		case $.ui.keyCode.UP:
16950			this.previous( event );
16951			break;
16952		case $.ui.keyCode.DOWN:
16953			this.next( event );
16954			break;
16955		case $.ui.keyCode.LEFT:
16956			this.collapse( event );
16957			break;
16958		case $.ui.keyCode.RIGHT:
16959			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
16960				this.expand( event );
16961			}
16962			break;
16963		case $.ui.keyCode.ENTER:
16964		case $.ui.keyCode.SPACE:
16965			this._activate( event );
16966			break;
16967		case $.ui.keyCode.ESCAPE:
16968			this.collapse( event );
16969			break;
16970		default:
16971			preventDefault = false;
vendor: 2,378 bytes, lines 16972-17057
16972			prev = this.previousFilter || "";
16973			skip = false;
16974
16975			// Support number pad values
16976			character = event.keyCode >= 96 && event.keyCode <= 105 ?
16977				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
16978
16979			clearTimeout( this.filterTimer );
16980
16981			if ( character === prev ) {
16982				skip = true;
16983			} else {
16984				character = prev + character;
16985			}
16986
16987			match = this._filterMenuItems( character );
16988			match = skip && match.index( this.active.next() ) !== -1 ?
16989				this.active.nextAll( ".ui-menu-item" ) :
16990				match;
16991
16992			// If no matches on the current filter, reset to the last character pressed
16993			// to move down the menu to the first item that starts with that character
16994			if ( !match.length ) {
16995				character = String.fromCharCode( event.keyCode );
16996				match = this._filterMenuItems( character );
16997			}
16998
16999			if ( match.length ) {
17000				this.focus( event, match );
17001				this.previousFilter = character;
17002				this.filterTimer = this._delay( function() {
17003					delete this.previousFilter;
17004				}, 1000 );
17005			} else {
17006				delete this.previousFilter;
17007			}
17008		}
17009
17010		if ( preventDefault ) {
17011			event.preventDefault();
17012		}
17013	},
17014
17015	_activate: function( event ) {
17016		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
17017			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
17018				this.expand( event );
17019			} else {
17020				this.select( event );
17021			}
17022		}
17023	},
17024
17025	refresh: function() {
17026		var menus, items, newSubmenus, newItems, newWrappers,
17027			that = this,
17028			icon = this.options.icons.submenu,
17029			submenus = this.element.find( this.options.menus );
17030
17031		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
17032
17033		// Initialize nested menus
17034		newSubmenus = submenus.filter( ":not(.ui-menu)" )
17035			.hide()
17036			.attr( {
17037				role: this.options.role,
17038				"aria-hidden": "true",
17039				"aria-expanded": "false"
17040			} )
17041			.each( function() {
17042				var menu = $( this ),
17043					item = menu.prev(),
17044					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
17045
17046				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
17047				item
17048					.attr( "aria-haspopup", "true" )
17049					.prepend( submenuCaret );
17050				menu.attr( "aria-labelledby", item.attr( "id" ) );
17051			} );
17052
17053		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
17054
17055		menus = submenus.add( this.element );
17056		items = menus.find( this.options.items );
17057
vendor: 4,552 bytes, lines 17058-17220
17058		// Initialize menu-items containing spaces and/or dashes only as dividers
17059		items.not( ".ui-menu-item" ).each( function() {
17060			var item = $( this );
17061			if ( that._isDivider( item ) ) {
17062				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
17063			}
17064		} );
17065
17066		// Don't refresh list items that are already adapted
17067		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
17068		newWrappers = newItems.children()
17069			.not( ".ui-menu" )
17070				.uniqueId()
17071				.attr( {
17072					tabIndex: -1,
17073					role: this._itemRole()
17074				} );
17075		this._addClass( newItems, "ui-menu-item" )
17076			._addClass( newWrappers, "ui-menu-item-wrapper" );
17077
17078		// Add aria-disabled attribute to any disabled menu item
17079		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
17080
17081		// If the active item has been removed, blur the menu
17082		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
17083			this.blur();
17084		}
17085	},
17086
17087	_itemRole: function() {
17088		return {
17089			menu: "menuitem",
17090			listbox: "option"
17091		}[ this.options.role ];
17092	},
17093
17094	_setOption: function( key, value ) {
17095		if ( key === "icons" ) {
17096			var icons = this.element.find( ".ui-menu-icon" );
17097			this._removeClass( icons, null, this.options.icons.submenu )
17098				._addClass( icons, null, value.submenu );
17099		}
17100		this._super( key, value );
17101	},
17102
17103	_setOptionDisabled: function( value ) {
17104		this._super( value );
17105
17106		this.element.attr( "aria-disabled", String( value ) );
17107		this._toggleClass( null, "ui-state-disabled", !!value );
17108	},
17109
17110	focus: function( event, item ) {
17111		var nested, focused, activeParent;
17112		this.blur( event, event && event.type === "focus" );
17113
17114		this._scrollIntoView( item );
17115
17116		this.active = item.first();
17117
17118		focused = this.active.children( ".ui-menu-item-wrapper" );
17119		this._addClass( focused, null, "ui-state-active" );
17120
17121		// Only update aria-activedescendant if there's a role
17122		// otherwise we assume focus is managed elsewhere
17123		if ( this.options.role ) {
17124			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
17125		}
17126
17127		// Highlight active parent menu item, if any
17128		activeParent = this.active
17129			.parent()
17130				.closest( ".ui-menu-item" )
17131					.children( ".ui-menu-item-wrapper" );
17132		this._addClass( activeParent, null, "ui-state-active" );
17133
17134		if ( event && event.type === "keydown" ) {
17135			this._close();
17136		} else {
17137			this.timer = this._delay( function() {
17138				this._close();
17139			}, this.delay );
17140		}
17141
17142		nested = item.children( ".ui-menu" );
17143		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
17144			this._startOpening( nested );
17145		}
17146		this.activeMenu = item.parent();
17147
17148		this._trigger( "focus", event, { item: item } );
17149	},
17150
17151	_scrollIntoView: function( item ) {
17152		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
17153		if ( this._hasScroll() ) {
17154			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
17155			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
17156			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
17157			scroll = this.activeMenu.scrollTop();
17158			elementHeight = this.activeMenu.height();
17159			itemHeight = item.outerHeight();
17160
17161			if ( offset < 0 ) {
17162				this.activeMenu.scrollTop( scroll + offset );
17163			} else if ( offset + itemHeight > elementHeight ) {
17164				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
17165			}
17166		}
17167	},
17168
17169	blur: function( event, fromFocus ) {
17170		if ( !fromFocus ) {
17171			clearTimeout( this.timer );
17172		}
17173
17174		if ( !this.active ) {
17175			return;
17176		}
17177
17178		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
17179			null, "ui-state-active" );
17180
17181		this._trigger( "blur", event, { item: this.active } );
17182		this.active = null;
17183	},
17184
17185	_startOpening: function( submenu ) {
17186		clearTimeout( this.timer );
17187
17188		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
17189		// shift in the submenu position when mousing over the caret icon
17190		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
17191			return;
17192		}
17193
17194		this.timer = this._delay( function() {
17195			this._close();
17196			this._open( submenu );
17197		}, this.delay );
17198	},
17199
17200	_open: function( submenu ) {
17201		var position = $.extend( {
17202			of: this.active
17203		}, this.options.position );
17204
17205		clearTimeout( this.timer );
17206		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
17207			.hide()
17208			.attr( "aria-hidden", "true" );
17209
17210		submenu
17211			.show()
17212			.removeAttr( "aria-hidden" )
17213			.attr( "aria-expanded", "true" )
17214			.position( position );
17215	},
17216
17217	collapseAll: function( event, all ) {
17218		clearTimeout( this.timer );
17219		this.timer = this._delay( function() {
17220
vendor: 5,398 bytes, lines 17221-17421
17221			// If we were passed an event, look for the submenu that contains the event
17222			var currentMenu = all ? this.element :
17223				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
17224
17225			// If we found no valid submenu ancestor, use the main menu to close all
17226			// sub menus anyway
17227			if ( !currentMenu.length ) {
17228				currentMenu = this.element;
17229			}
17230
17231			this._close( currentMenu );
17232
17233			this.blur( event );
17234
17235			// Work around active item staying active after menu is blurred
17236			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
17237
17238			this.activeMenu = currentMenu;
17239		}, all ? 0 : this.delay );
17240	},
17241
17242	// With no arguments, closes the currently active menu - if nothing is active
17243	// it closes all menus.  If passed an argument, it will search for menus BELOW
17244	_close: function( startMenu ) {
17245		if ( !startMenu ) {
17246			startMenu = this.active ? this.active.parent() : this.element;
17247		}
17248
17249		startMenu.find( ".ui-menu" )
17250			.hide()
17251			.attr( "aria-hidden", "true" )
17252			.attr( "aria-expanded", "false" );
17253	},
17254
17255	_closeOnDocumentClick: function( event ) {
17256		return !$( event.target ).closest( ".ui-menu" ).length;
17257	},
17258
17259	_isDivider: function( item ) {
17260
17261		// Match hyphen, em dash, en dash
17262		return !/[^\-\u2014\u2013\s]/.test( item.text() );
17263	},
17264
17265	collapse: function( event ) {
17266		var newItem = this.active &&
17267			this.active.parent().closest( ".ui-menu-item", this.element );
17268		if ( newItem && newItem.length ) {
17269			this._close();
17270			this.focus( event, newItem );
17271		}
17272	},
17273
17274	expand: function( event ) {
17275		var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
17276
17277		if ( newItem && newItem.length ) {
17278			this._open( newItem.parent() );
17279
17280			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
17281			this._delay( function() {
17282				this.focus( event, newItem );
17283			} );
17284		}
17285	},
17286
17287	next: function( event ) {
17288		this._move( "next", "first", event );
17289	},
17290
17291	previous: function( event ) {
17292		this._move( "prev", "last", event );
17293	},
17294
17295	isFirstItem: function() {
17296		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
17297	},
17298
17299	isLastItem: function() {
17300		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
17301	},
17302
17303	_menuItems: function( menu ) {
17304		return ( menu || this.element )
17305			.find( this.options.items )
17306			.filter( ".ui-menu-item" );
17307	},
17308
17309	_move: function( direction, filter, event ) {
17310		var next;
17311		if ( this.active ) {
17312			if ( direction === "first" || direction === "last" ) {
17313				next = this.active
17314					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
17315					.last();
17316			} else {
17317				next = this.active
17318					[ direction + "All" ]( ".ui-menu-item" )
17319					.first();
17320			}
17321		}
17322		if ( !next || !next.length || !this.active ) {
17323			next = this._menuItems( this.activeMenu )[ filter ]();
17324		}
17325
17326		this.focus( event, next );
17327	},
17328
17329	nextPage: function( event ) {
17330		var item, base, height;
17331
17332		if ( !this.active ) {
17333			this.next( event );
17334			return;
17335		}
17336		if ( this.isLastItem() ) {
17337			return;
17338		}
17339		if ( this._hasScroll() ) {
17340			base = this.active.offset().top;
17341			height = this.element.innerHeight();
17342
17343			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
17344			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
17345				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
17346			}
17347
17348			this.active.nextAll( ".ui-menu-item" ).each( function() {
17349				item = $( this );
17350				return item.offset().top - base - height < 0;
17351			} );
17352
17353			this.focus( event, item );
17354		} else {
17355			this.focus( event, this._menuItems( this.activeMenu )
17356				[ !this.active ? "first" : "last" ]() );
17357		}
17358	},
17359
17360	previousPage: function( event ) {
17361		var item, base, height;
17362		if ( !this.active ) {
17363			this.next( event );
17364			return;
17365		}
17366		if ( this.isFirstItem() ) {
17367			return;
17368		}
17369		if ( this._hasScroll() ) {
17370			base = this.active.offset().top;
17371			height = this.element.innerHeight();
17372
17373			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
17374			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
17375				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
17376			}
17377
17378			this.active.prevAll( ".ui-menu-item" ).each( function() {
17379				item = $( this );
17380				return item.offset().top - base + height > 0;
17381			} );
17382
17383			this.focus( event, item );
17384		} else {
17385			this.focus( event, this._menuItems( this.activeMenu ).first() );
17386		}
17387	},
17388
17389	_hasScroll: function() {
17390		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
17391	},
17392
17393	select: function( event ) {
17394
17395		// TODO: It should never be possible to not have an active item at this
17396		// point, but the tests don't trigger mouseenter before click.
17397		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
17398		var ui = { item: this.active };
17399		if ( !this.active.has( ".ui-menu" ).length ) {
17400			this.collapseAll( event, true );
17401		}
17402		this._trigger( "select", event, ui );
17403	},
17404
17405	_filterMenuItems: function( character ) {
17406		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
17407			regex = new RegExp( "^" + escapedCharacter, "i" );
17408
17409		return this.activeMenu
17410			.find( this.options.items )
17411
17412				// Only match on items, not dividers or other content (#10571)
17413				.filter( ".ui-menu-item" )
17414					.filter( function() {
17415						return regex.test(
17416							String.prototype.trim.call(
17417								$( this ).children( ".ui-menu-item-wrapper" ).text() ) );
17418					} );
17419	}
17420} );
17421
17422} );
17423
17424
17425
17426
17427
17428
17429
17430/*!
17431 * jQuery UI Autocomplete 1.13.0
17432 * http://jqueryui.com
17433 *
17434 * Copyright jQuery Foundation and other contributors
17435 * Released under the MIT license.
17436 * http://jquery.org/license
17437 */
17438
17439//>>label: Autocomplete
17440//>>group: Widgets
17441//>>description: Lists suggested words as the user is typing.
17442//>>docs: http://api.jqueryui.com/autocomplete/
17443//>>demos: http://jqueryui.com/autocomplete/
17444//>>css.structure: ../../themes/base/core.css
17445//>>css.structure: ../../themes/base/autocomplete.css
17446//>>css.theme: ../../themes/base/theme.css
17447
17448( function( factory ) {
17449	"use strict";
17450
17451	if ( typeof define === "function" && define.amd ) {
17452
17453		// AMD. Register as an anonymous module.
17454		define( [
17455			"jquery",
17456			"./menu",
17457			"../keycode",
17458			"../position",
17459			"../safe-active-element",
17460			"../version",
17461			"../widget"
17462		], factory );
17463	} else {
17464
17465		// Browser globals
17466		factory( jQuery );
17467	}
17468} )( function( $ ) {
17469"use strict";
17470
17471$.widget( "ui.autocomplete", {
17472	version: "1.13.0",
17473	defaultElement: "<input>",
17474	options: {
17475		appendTo: null,
17476		autoFocus: false,
17477		delay: 300,
17478		minLength: 1,
17479		position: {
17480			my: "left top",
17481			at: "left bottom",
17482			collision: "none"
17483		},
17484		source: null,
17485
17486		// Callbacks
17487		change: null,
17488		close: null,
17489		focus: null,
17490		open: null,
17491		response: null,
17492		search: null,
17493		select: null
17494	},
17495
17496	requestIndex: 0,
17497	pending: 0
vendor: 5,947 bytes, lines 17497-17699
17497,
17498
17499	_create: function() {
17500
17501		// Some browsers only repeat keydown events, not keypress events,
17502		// so we use the suppressKeyPress flag to determine if we've already
17503		// handled the keydown event. #7269
17504		// Unfortunately the code for & in keypress is the same as the up arrow,
17505		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
17506		// events when we know the keydown event was used to modify the
17507		// search term. #7799
17508		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
17509			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
17510			isTextarea = nodeName === "textarea",
17511			isInput = nodeName === "input";
17512
17513		// Textareas are always multi-line
17514		// Inputs are always single-line, even if inside a contentEditable element
17515		// IE also treats inputs as contentEditable
17516		// All other element types are determined by whether or not they're contentEditable
17517		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
17518
17519		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
17520		this.isNewMenu = true;
17521
17522		this._addClass( "ui-autocomplete-input" );
17523		this.element.attr( "autocomplete", "off" );
17524
17525		this._on( this.element, {
17526			keydown: function( event ) {
17527				if ( this.element.prop( "readOnly" ) ) {
17528					suppressKeyPress = true;
17529					suppressInput = true;
17530					suppressKeyPressRepeat = true;
17531					return;
17532				}
17533
17534				suppressKeyPress = false;
17535				suppressInput = false;
17536				suppressKeyPressRepeat = false;
17537				var keyCode = $.ui.keyCode;
17538				switch ( event.keyCode ) {
17539				case keyCode.PAGE_UP:
17540					suppressKeyPress = true;
17541					this._move( "previousPage", event );
17542					break;
17543				case keyCode.PAGE_DOWN:
17544					suppressKeyPress = true;
17545					this._move( "nextPage", event );
17546					break;
17547				case keyCode.UP:
17548					suppressKeyPress = true;
17549					this._keyEvent( "previous", event );
17550					break;
17551				case keyCode.DOWN:
17552					suppressKeyPress = true;
17553					this._keyEvent( "next", event );
17554					break;
17555				case keyCode.ENTER:
17556
17557					// when menu is open and has focus
17558					if ( this.menu.active ) {
17559
17560						// #6055 - Opera still allows the keypress to occur
17561						// which causes forms to submit
17562						suppressKeyPress = true;
17563						event.preventDefault();
17564						this.menu.select( event );
17565					}
17566					break;
17567				case keyCode.TAB:
17568					if ( this.menu.active ) {
17569						this.menu.select( event );
17570					}
17571					break;
17572				case keyCode.ESCAPE:
17573					if ( this.menu.element.is( ":visible" ) ) {
17574						if ( !this.isMultiLine ) {
17575							this._value( this.term );
17576						}
17577						this.close( event );
17578
17579						// Different browsers have different default behavior for escape
17580						// Single press can mean undo or clear
17581						// Double press in IE means clear the whole form
17582						event.preventDefault();
17583					}
17584					break;
17585				default:
17586					suppressKeyPressRepeat = true;
17587
17588					// search timeout should be triggered before the input value is changed
17589					this._searchTimeout( event );
17590					break;
17591				}
17592			},
17593			keypress: function( event ) {
17594				if ( suppressKeyPress ) {
17595					suppressKeyPress = false;
17596					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
17597						event.preventDefault();
17598					}
17599					return;
17600				}
17601				if ( suppressKeyPressRepeat ) {
17602					return;
17603				}
17604
17605				// Replicate some key handlers to allow them to repeat in Firefox and Opera
17606				var keyCode = $.ui.keyCode;
17607				switch ( event.keyCode ) {
17608				case keyCode.PAGE_UP:
17609					this._move( "previousPage", event );
17610					break;
17611				case keyCode.PAGE_DOWN:
17612					this._move( "nextPage", event );
17613					break;
17614				case keyCode.UP:
17615					this._keyEvent( "previous", event );
17616					break;
17617				case keyCode.DOWN:
17618					this._keyEvent( "next", event );
17619					break;
17620				}
17621			},
17622			input: function( event ) {
17623				if ( suppressInput ) {
17624					suppressInput = false;
17625					event.preventDefault();
17626					return;
17627				}
17628				this._searchTimeout( event );
17629			},
17630			focus: function() {
17631				this.selectedItem = null;
17632				this.previous = this._value();
17633			},
17634			blur: function( event ) {
17635				clearTimeout( this.searching );
17636				this.close( event );
17637				this._change( event );
17638			}
17639		} );
17640
17641		this._initSource();
17642		this.menu = $( "<ul>" )
17643			.appendTo( this._appendTo() )
17644			.menu( {
17645
17646				// disable ARIA support, the live region takes care of that
17647				role: null
17648			} )
17649			.hide()
17650
17651			// Support: IE 11 only, Edge <= 14
17652			// For other browsers, we preventDefault() on the mousedown event
17653			// to keep the dropdown from taking focus from the input. This doesn't
17654			// work for IE/Edge, causing problems with selection and scrolling (#9638)
17655			// Happily, IE and Edge support an "unselectable" attribute that
17656			// prevents an element from receiving focus, exactly what we want here.
17657			.attr( {
17658				"unselectable": "on"
17659			} )
17660			.menu( "instance" );
17661
17662		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
17663		this._on( this.menu.element, {
17664			mousedown: function( event ) {
17665
17666				// Prevent moving focus out of the text field
17667				event.preventDefault();
17668			},
17669			menufocus: function( event, ui ) {
17670				var label, item;
17671
17672				// support: Firefox
17673				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
17674				if ( this.isNewMenu ) {
17675					this.isNewMenu = false;
17676					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
17677						this.menu.blur();
17678
17679						this.document.one( "mousemove", function() {
17680							$( event.target ).trigger( event.originalEvent );
17681						} );
17682
17683						return;
17684					}
17685				}
17686
17687				item = ui.item.data( "ui-autocomplete-item" );
17688				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
17689
17690					// use value to match what will end up in the input, if it was a key event
17691					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
17692						this._value( item.value );
17693					}
17694				}
17695
17696				// Announce the value in the liveRegion
17697				label = ui.item.attr( "aria-label" ) || item.value;
17698				if ( label && String.prototype.trim.call( label ).length ) {
17699					
17699this.liveRegion.children().hide();
17700					$( "<div>" ).text( label ).appendTo( this.liveRegion
vendor: 9,873 bytes, lines 17700-18095
17700 );
17701				}
17702			},
17703			menuselect: function( event, ui ) {
17704				var item = ui.item.data( "ui-autocomplete-item" ),
17705					previous = this.previous;
17706
17707				// Only trigger when focus was lost (click on menu)
17708				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
17709					this.element.trigger( "focus" );
17710					this.previous = previous;
17711
17712					// #6109 - IE triggers two focus events and the second
17713					// is asynchronous, so we need to reset the previous
17714					// term synchronously and asynchronously :-(
17715					this._delay( function() {
17716						this.previous = previous;
17717						this.selectedItem = item;
17718					} );
17719				}
17720
17721				if ( false !== this._trigger( "select", event, { item: item } ) ) {
17722					this._value( item.value );
17723				}
17724
17725				// reset the term after the select event
17726				// this allows custom select handling to work properly
17727				this.term = this._value();
17728
17729				this.close( event );
17730				this.selectedItem = item;
17731			}
17732		} );
17733
17734		this.liveRegion = $( "<div>", {
17735			role: "status",
17736			"aria-live": "assertive",
17737			"aria-relevant": "additions"
17738		} )
17739			.appendTo( this.document[ 0 ].body );
17740
17741		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
17742
17743		// Turning off autocomplete prevents the browser from remembering the
17744		// value when navigating through history, so we re-enable autocomplete
17745		// if the page is unloaded before the widget is destroyed. #7790
17746		this._on( this.window, {
17747			beforeunload: function() {
17748				this.element.removeAttr( "autocomplete" );
17749			}
17750		} );
17751	},
17752
17753	_destroy: function() {
17754		clearTimeout( this.searching );
17755		this.element.removeAttr( "autocomplete" );
17756		this.menu.element.remove();
17757		this.liveRegion.remove();
17758	},
17759
17760	_setOption: function( key, value ) {
17761		this._super( key, value );
17762		if ( key === "source" ) {
17763			this._initSource();
17764		}
17765		if ( key === "appendTo" ) {
17766			this.menu.element.appendTo( this._appendTo() );
17767		}
17768		if ( key === "disabled" && value && this.xhr ) {
17769			this.xhr.abort();
17770		}
17771	},
17772
17773	_isEventTargetInWidget: function( event ) {
17774		var menuElement = this.menu.element[ 0 ];
17775
17776		return event.target === this.element[ 0 ] ||
17777			event.target === menuElement ||
17778			$.contains( menuElement, event.target );
17779	},
17780
17781	_closeOnClickOutside: function( event ) {
17782		if ( !this._isEventTargetInWidget( event ) ) {
17783			this.close();
17784		}
17785	},
17786
17787	_appendTo: function() {
17788		var element = this.options.appendTo;
17789
17790		if ( element ) {
17791			element = element.jquery || element.nodeType ?
17792				$( element ) :
17793				this.document.find( element ).eq( 0 );
17794		}
17795
17796		if ( !element || !element[ 0 ] ) {
17797			element = this.element.closest( ".ui-front, dialog" );
17798		}
17799
17800		if ( !element.length ) {
17801			element = this.document[ 0 ].body;
17802		}
17803
17804		return element;
17805	},
17806
17807	_initSource: function() {
17808		var array, url,
17809			that = this;
17810		if ( Array.isArray( this.options.source ) ) {
17811			array = this.options.source;
17812			this.source = function( request, response ) {
17813				response( $.ui.autocomplete.filter( array, request.term ) );
17814			};
17815		} else if ( typeof this.options.source === "string" ) {
17816			url = this.options.source;
17817			this.source = function( request, response ) {
17818				if ( that.xhr ) {
17819					that.xhr.abort();
17820				}
17821				that.xhr = $.ajax( {
17822					url: url,
17823					data: request,
17824					dataType: "json",
17825					success: function( data ) {
17826						response( data );
17827					},
17828					error: function() {
17829						response( [] );
17830					}
17831				} );
17832			};
17833		} else {
17834			this.source = this.options.source;
17835		}
17836	},
17837
17838	_searchTimeout: function( event ) {
17839		clearTimeout( this.searching );
17840		this.searching = this._delay( function() {
17841
17842			// Search if the value has changed, or if the user retypes the same value (see #7434)
17843			var equalValues = this.term === this._value(),
17844				menuVisible = this.menu.element.is( ":visible" ),
17845				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
17846
17847			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
17848				this.selectedItem = null;
17849				this.search( null, event );
17850			}
17851		}, this.options.delay );
17852	},
17853
17854	search: function( value, event ) {
17855		value = value != null ? value : this._value();
17856
17857		// Always save the actual value, not the one passed as an argument
17858		this.term = this._value();
17859
17860		if ( value.length < this.options.minLength ) {
17861			return this.close( event );
17862		}
17863
17864		if ( this._trigger( "search", event ) === false ) {
17865			return;
17866		}
17867
17868		return this._search( value );
17869	},
17870
17871	_search: function( value ) {
17872		this.pending++;
17873		this._addClass( "ui-autocomplete-loading" );
17874		this.cancelSearch = false;
17875
17876		this.source( { term: value }, this._response() );
17877	},
17878
17879	_response: function() {
17880		var index = ++this.requestIndex;
17881
17882		return function( content ) {
17883			if ( index === this.requestIndex ) {
17884				this.__response( content );
17885			}
17886
17887			this.pending--;
17888			if ( !this.pending ) {
17889				this._removeClass( "ui-autocomplete-loading" );
17890			}
17891		}.bind( this );
17892	},
17893
17894	__response: function( content ) {
17895		if ( content ) {
17896			content = this._normalize( content );
17897		}
17898		this._trigger( "response", null, { content: content } );
17899		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
17900			this._suggest( content );
17901			this._trigger( "open" );
17902		} else {
17903
17904			// use ._close() instead of .close() so we don't cancel future searches
17905			this._close();
17906		}
17907	},
17908
17909	close: function( event ) {
17910		this.cancelSearch = true;
17911		this._close( event );
17912	},
17913
17914	_close: function( event ) {
17915
17916		// Remove the handler that closes the menu on outside clicks
17917		this._off( this.document, "mousedown" );
17918
17919		if ( this.menu.element.is( ":visible" ) ) {
17920			this.menu.element.hide();
17921			this.menu.blur();
17922			this.isNewMenu = true;
17923			this._trigger( "close", event );
17924		}
17925	},
17926
17927	_change: function( event ) {
17928		if ( this.previous !== this._value() ) {
17929			this._trigger( "change", event, { item: this.selectedItem } );
17930		}
17931	},
17932
17933	_normalize: function( items ) {
17934
17935		// assume all items have the right format when the first item is complete
17936		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
17937			return items;
17938		}
17939		return $.map( items, function( item ) {
17940			if ( typeof item === "string" ) {
17941				return {
17942					label: item,
17943					value: item
17944				};
17945			}
17946			return $.extend( {}, item, {
17947				label: item.label || item.value,
17948				value: item.value || item.label
17949			} );
17950		} );
17951	},
17952
17953	_suggest: function( items ) {
17954		var ul = this.menu.element.empty();
17955		this._renderMenu( ul, items );
17956		this.isNewMenu = true;
17957		this.menu.refresh();
17958
17959		// Size and position menu
17960		ul.show();
17961		this._resizeMenu();
17962		ul.position( $.extend( {
17963			of: this.element
17964		}, this.options.position ) );
17965
17966		if ( this.options.autoFocus ) {
17967			this.menu.next();
17968		}
17969
17970		// Listen for interactions outside of the widget (#6642)
17971		this._on( this.document, {
17972			mousedown: "_closeOnClickOutside"
17973		} );
17974	},
17975
17976	_resizeMenu: function() {
17977		var ul = this.menu.element;
17978		ul.outerWidth( Math.max(
17979
17980			// Firefox wraps long text (possibly a rounding bug)
17981			// so we add 1px to avoid the wrapping (#7513)
17982			ul.width( "" ).outerWidth() + 1,
17983			this.element.outerWidth()
17984		) );
17985	},
17986
17987	_renderMenu: function( ul, items ) {
17988		var that = this;
17989		$.each( items, function( index, item ) {
17990			that._renderItemData( ul, item );
17991		} );
17992	},
17993
17994	_renderItemData: function( ul, item ) {
17995		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
17996	},
17997
17998	_renderItem: function( ul, item ) {
17999		return $( "<li>" )
18000			.append( $( "<div>" ).text( item.label ) )
18001			.appendTo( ul );
18002	},
18003
18004	_move: function( direction, event ) {
18005		if ( !this.menu.element.is( ":visible" ) ) {
18006			this.search( null, event );
18007			return;
18008		}
18009		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
18010				this.menu.isLastItem() && /^next/.test( direction ) ) {
18011
18012			if ( !this.isMultiLine ) {
18013				this._value( this.term );
18014			}
18015
18016			this.menu.blur();
18017			return;
18018		}
18019		this.menu[ direction ]( event );
18020	},
18021
18022	widget: function() {
18023		return this.menu.element;
18024	},
18025
18026	_value: function() {
18027		return this.valueMethod.apply( this.element, arguments );
18028	},
18029
18030	_keyEvent: function( keyEvent, event ) {
18031		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
18032			this._move( keyEvent, event );
18033
18034			// Prevents moving cursor to beginning/end of the text field in some browsers
18035			event.preventDefault();
18036		}
18037	},
18038
18039	// Support: Chrome <=50
18040	// We should be able to just use this.element.prop( "isContentEditable" )
18041	// but hidden elements always report false in Chrome.
18042	// https://code.google.com/p/chromium/issues/detail?id=313082
18043	_isContentEditable: function( element ) {
18044		if ( !element.length ) {
18045			return false;
18046		}
18047
18048		var editable = element.prop( "contentEditable" );
18049
18050		if ( editable === "inherit" ) {
18051			return this._isContentEditable( element.parent() );
18052		}
18053
18054		return editable === "true";
18055	}
18056} );
18057
18058$.extend( $.ui.autocomplete, {
18059	escapeRegex: function( value ) {
18060		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
18061	},
18062	filter: function( array, term ) {
18063		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
18064		return $.grep( array, function( value ) {
18065			return matcher.test( value.label || value.value || value );
18066		} );
18067	}
18068} );
18069
18070// Live region extension, adding a `messages` option
18071// NOTE: This is an experimental API. We are still investigating
18072// a full solution for string manipulation and internationalization.
18073$.widget( "ui.autocomplete", $.ui.autocomplete, {
18074	options: {
18075		messages: {
18076			noResults: "No search results.",
18077			results: function( amount ) {
18078				return amount + ( amount > 1 ? " results are" : " result is" ) +
18079					" available, use up and down arrow keys to navigate.";
18080			}
18081		}
18082	},
18083
18084	__response: function( content ) {
18085		var message;
18086		this._superApply( arguments );
18087		if ( this.options.disabled || this.cancelSearch ) {
18088			return;
18089		}
18090		if ( content && content.length ) {
18091			message = this.options.messages.results( content.length );
18092		} else {
18093			message = this.options.messages.noResults;
18094		}
18095		
18095this.liveRegion.children().hide();
18096		$( "<div>" ).text( message ).appendTo( this.liveRegion );
18097	}
18098} );
18099
18100return $.ui.autocomplete;
18101
18102} );
18103
18104
18105/*!
18106 * jQuery UI Controlgroup 1.13.0
18107 * http://jqueryui.com
18108 *
18109 * Copyright jQuery Foundation and other contributors
18110 * Released under the MIT license.
18111 * http://jquery.org/license
18112 */
18113
18114//>>label: Controlgroup
18115//>>group: Widgets
18116//>>description: Visually groups form control widgets
18117//>>docs: http://api.jqueryui.com/controlgroup/
18118//>>demos: http://jqueryui.com/controlgroup/
18119//>>css.structure: ../../themes/base/core.css
18120//>>css.structure: ../../themes/base/controlgroup.css
18121//>>css.theme: ../../themes/base/theme.css
18122
18123( function( factory ) {
18124	"use strict";
18125
18126	if ( typeof define === "function" && define.amd ) {
18127
18128		// AMD. Register as an anonymous module.
18129		define( [
18130			"jquery",
18131			"../widget"
18132		], factory );
18133	} else {
18134
18135		// Browser globals
18136		factory( jQuery );
18137	}
18138} )( function( $ ) {
18139"use strict";
18140
18141var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
18142
18143return $.widget( "ui.controlgroup", {
18144	version: "1.13.0
vendor: 7,699 bytes, lines 18144-18405
18144",
18145	defaultElement: "<div>",
18146	options: {
18147		direction: "horizontal",
18148		disabled: null,
18149		onlyVisible: true,
18150		items: {
18151			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
18152			"controlgroupLabel": ".ui-controlgroup-label",
18153			"checkboxradio": "input[type='checkbox'], input[type='radio']",
18154			"selectmenu": "select",
18155			"spinner": ".ui-spinner-input"
18156		}
18157	},
18158
18159	_create: function() {
18160		this._enhance();
18161	},
18162
18163	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
18164	_enhance: function() {
18165		this.element.attr( "role", "toolbar" );
18166		this.refresh();
18167	},
18168
18169	_destroy: function() {
18170		this._callChildMethod( "destroy" );
18171		this.childWidgets.removeData( "ui-controlgroup-data" );
18172		this.element.removeAttr( "role" );
18173		if ( this.options.items.controlgroupLabel ) {
18174			this.element
18175				.find( this.options.items.controlgroupLabel )
18176				.find( ".ui-controlgroup-label-contents" )
18177				.contents().unwrap();
18178		}
18179	},
18180
18181	_initWidgets: function() {
18182		var that = this,
18183			childWidgets = [];
18184
18185		// First we iterate over each of the items options
18186		$.each( this.options.items, function( widget, selector ) {
18187			var labels;
18188			var options = {};
18189
18190			// Make sure the widget has a selector set
18191			if ( !selector ) {
18192				return;
18193			}
18194
18195			if ( widget === "controlgroupLabel" ) {
18196				labels = that.element.find( selector );
18197				labels.each( function() {
18198					var element = $( this );
18199
18200					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
18201						return;
18202					}
18203					element.contents()
18204						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
18205				} );
18206				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
18207				childWidgets = childWidgets.concat( labels.get() );
18208				return;
18209			}
18210
18211			// Make sure the widget actually exists
18212			if ( !$.fn[ widget ] ) {
18213				return;
18214			}
18215
18216			// We assume everything is in the middle to start because we can't determine
18217			// first / last elements until all enhancments are done.
18218			if ( that[ "_" + widget + "Options" ] ) {
18219				options = that[ "_" + widget + "Options" ]( "middle" );
18220			} else {
18221				options = { classes: {} };
18222			}
18223
18224			// Find instances of this widget inside controlgroup and init them
18225			that.element
18226				.find( selector )
18227				.each( function() {
18228					var element = $( this );
18229					var instance = element[ widget ]( "instance" );
18230
18231					// We need to clone the default options for this type of widget to avoid
18232					// polluting the variable options which has a wider scope than a single widget.
18233					var instanceOptions = $.widget.extend( {}, options );
18234
18235					// If the button is the child of a spinner ignore it
18236					// TODO: Find a more generic solution
18237					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
18238						return;
18239					}
18240
18241					// Create the widget if it doesn't exist
18242					if ( !instance ) {
18243						instance = element[ widget ]()[ widget ]( "instance" );
18244					}
18245					if ( instance ) {
18246						instanceOptions.classes =
18247							that._resolveClassesValues( instanceOptions.classes, instance );
18248					}
18249					element[ widget ]( instanceOptions );
18250
18251					// Store an instance of the controlgroup to be able to reference
18252					// from the outermost element for changing options and refresh
18253					var widgetElement = element[ widget ]( "widget" );
18254					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
18255						instance ? instance : element[ widget ]( "instance" ) );
18256
18257					childWidgets.push( widgetElement[ 0 ] );
18258				} );
18259		} );
18260
18261		this.childWidgets = $( $.uniqueSort( childWidgets ) );
18262		this._addClass( this.childWidgets, "ui-controlgroup-item" );
18263	},
18264
18265	_callChildMethod: function( method ) {
18266		this.childWidgets.each( function() {
18267			var element = $( this ),
18268				data = element.data( "ui-controlgroup-data" );
18269			if ( data && data[ method ] ) {
18270				data[ method ]();
18271			}
18272		} );
18273	},
18274
18275	_updateCornerClass: function( element, position ) {
18276		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
18277		var add = this._buildSimpleOptions( position, "label" ).classes.label;
18278
18279		this._removeClass( element, null, remove );
18280		this._addClass( element, null, add );
18281	},
18282
18283	_buildSimpleOptions: function( position, key ) {
18284		var direction = this.options.direction === "vertical";
18285		var result = {
18286			classes: {}
18287		};
18288		result.classes[ key ] = {
18289			"middle": "",
18290			"first": "ui-corner-" + ( direction ? "top" : "left" ),
18291			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
18292			"only": "ui-corner-all"
18293		}[ position ];
18294
18295		return result;
18296	},
18297
18298	_spinnerOptions: function( position ) {
18299		var options = this._buildSimpleOptions( position, "ui-spinner" );
18300
18301		options.classes[ "ui-spinner-up" ] = "";
18302		options.classes[ "ui-spinner-down" ] = "";
18303
18304		return options;
18305	},
18306
18307	_buttonOptions: function( position ) {
18308		return this._buildSimpleOptions( position, "ui-button" );
18309	},
18310
18311	_checkboxradioOptions: function( position ) {
18312		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
18313	},
18314
18315	_selectmenuOptions: function( position ) {
18316		var direction = this.options.direction === "vertical";
18317		return {
18318			width: direction ? "auto" : false,
18319			classes: {
18320				middle: {
18321					"ui-selectmenu-button-open": "",
18322					"ui-selectmenu-button-closed": ""
18323				},
18324				first: {
18325					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
18326					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
18327				},
18328				last: {
18329					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
18330					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
18331				},
18332				only: {
18333					"ui-selectmenu-button-open": "ui-corner-top",
18334					"ui-selectmenu-button-closed": "ui-corner-all"
18335				}
18336
18337			}[ position ]
18338		};
18339	},
18340
18341	_resolveClassesValues: function( classes, instance ) {
18342		var result = {};
18343		$.each( classes, function( key ) {
18344			var current = instance.options.classes[ key ] || "";
18345			current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
18346			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
18347		} );
18348		return result;
18349	},
18350
18351	_setOption: function( key, value ) {
18352		if ( key === "direction" ) {
18353			this._removeClass( "ui-controlgroup-" + this.options.direction );
18354		}
18355
18356		this._super( key, value );
18357		if ( key === "disabled" ) {
18358			this._callChildMethod( value ? "disable" : "enable" );
18359			return;
18360		}
18361
18362		this.refresh();
18363	},
18364
18365	refresh: function() {
18366		var children,
18367			that = this;
18368
18369		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
18370
18371		if ( this.options.direction === "horizontal" ) {
18372			this._addClass( null, "ui-helper-clearfix" );
18373		}
18374		this._initWidgets();
18375
18376		children = this.childWidgets;
18377
18378		// We filter here because we need to track all childWidgets not just the visible ones
18379		if ( this.options.onlyVisible ) {
18380			children = children.filter( ":visible" );
18381		}
18382
18383		if ( children.length ) {
18384
18385			// We do this last because we need to make sure all enhancment is done
18386			// before determining first and last
18387			$.each( [ "first", "last" ], function( index, value ) {
18388				var instance = children[ value ]().data( "ui-controlgroup-data" );
18389
18390				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
18391					var options = that[ "_" + instance.widgetName + "Options" ](
18392						children.length === 1 ? "only" : value
18393					);
18394					options.classes = that._resolveClassesValues( options.classes, instance );
18395					instance.element[ instance.widgetName ]( options );
18396				} else {
18397					that._updateCornerClass( children[ value ](), value );
18398				}
18399			} );
18400
18401			// Finally call the refresh method on each of the child widgets.
18402			this._callChildMethod( "refresh" );
18403		}
18404	}
18405} );
vendor: 5,352 bytes, lines 18406-18609
18406} );
18407
18408
18409
18410
18411/*!
18412 * jQuery UI Checkboxradio 1.13.0
18413 * http://jqueryui.com
18414 *
18415 * Copyright jQuery Foundation and other contributors
18416 * Released under the MIT license.
18417 * http://jquery.org/license
18418 */
18419
18420//>>label: Checkboxradio
18421//>>group: Widgets
18422//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
18423//>>docs: http://api.jqueryui.com/checkboxradio/
18424//>>demos: http://jqueryui.com/checkboxradio/
18425//>>css.structure: ../../themes/base/core.css
18426//>>css.structure: ../../themes/base/button.css
18427//>>css.structure: ../../themes/base/checkboxradio.css
18428//>>css.theme: ../../themes/base/theme.css
18429
18430( function( factory ) {
18431	"use strict";
18432
18433	if ( typeof define === "function" && define.amd ) {
18434
18435		// AMD. Register as an anonymous module.
18436		define( [
18437			"jquery",
18438			"../form-reset-mixin",
18439			"../labels",
18440			"../widget"
18441		], factory );
18442	} else {
18443
18444		// Browser globals
18445		factory( jQuery );
18446	}
18447} )( function( $ ) {
18448"use strict";
18449
18450$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
18451	version: "1.13.0",
18452	options: {
18453		disabled: null,
18454		label: null,
18455		icon: true,
18456		classes: {
18457			"ui-checkboxradio-label": "ui-corner-all",
18458			"ui-checkboxradio-icon": "ui-corner-all"
18459		}
18460	},
18461
18462	_getCreateOptions: function() {
18463		var disabled, labels;
18464		var that = this;
18465		var options = this._super() || {};
18466
18467		// We read the type here, because it makes more sense to throw a element type error first,
18468		// rather then the error for lack of a label. Often if its the wrong type, it
18469		// won't have a label (e.g. calling on a div, btn, etc)
18470		this._readType();
18471
18472		labels = this.element.labels();
18473
18474		// If there are multiple labels, use the last one
18475		this.label = $( labels[ labels.length - 1 ] );
18476		if ( !this.label.length ) {
18477			$.error( "No label found for checkboxradio widget" );
18478		}
18479
18480		this.originalLabel = "";
18481
18482		// We need to get the label text but this may also need to make sure it does not contain the
18483		// input itself.
18484		this.label.contents().not( this.element[ 0 ] ).each( function() {
18485
18486			// The label contents could be text, html, or a mix. We concat each element to get a
18487			// string representation of the label, without the input as part of it.
18488			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
18489		} );
18490
18491		// Set the label option if we found label text
18492		if ( this.originalLabel ) {
18493			options.label = this.originalLabel;
18494		}
18495
18496		disabled = this.element[ 0 ].disabled;
18497		if ( disabled != null ) {
18498			options.disabled = disabled;
18499		}
18500		return options;
18501	},
18502
18503	_create: function() {
18504		var checked = this.element[ 0 ].checked;
18505
18506		this._bindFormResetHandler();
18507
18508		if ( this.options.disabled == null ) {
18509			this.options.disabled = this.element[ 0 ].disabled;
18510		}
18511
18512		this._setOption( "disabled", this.options.disabled );
18513		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
18514		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
18515
18516		if ( this.type === "radio" ) {
18517			this._addClass( this.label, "ui-checkboxradio-radio-label" );
18518		}
18519
18520		if ( this.options.label && this.options.label !== this.originalLabel ) {
18521			this._updateLabel();
18522		} else if ( this.originalLabel ) {
18523			this.options.label = this.originalLabel;
18524		}
18525
18526		this._enhance();
18527
18528		if ( checked ) {
18529			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
18530		}
18531
18532		this._on( {
18533			change: "_toggleClasses",
18534			focus: function() {
18535				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
18536			},
18537			blur: function() {
18538				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
18539			}
18540		} );
18541	},
18542
18543	_readType: function() {
18544		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
18545		this.type = this.element[ 0 ].type;
18546		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
18547			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
18548				" and element.type=" + this.type );
18549		}
18550	},
18551
18552	// Support jQuery Mobile enhanced option
18553	_enhance: function() {
18554		this._updateIcon( this.element[ 0 ].checked );
18555	},
18556
18557	widget: function() {
18558		return this.label;
18559	},
18560
18561	_getRadioGroup: function() {
18562		var group;
18563		var name = this.element[ 0 ].name;
18564		var nameSelector = "input[name='" + $.escapeSelector( name ) + "']";
18565
18566		if ( !name ) {
18567			return $( [] );
18568		}
18569
18570		if ( this.form.length ) {
18571			group = $( this.form[ 0 ].elements ).filter( nameSelector );
18572		} else {
18573
18574			// Not inside a form, check all inputs that also are not inside a form
18575			group = $( nameSelector ).filter( function() {
18576				return $( this )._form().length === 0;
18577			} );
18578		}
18579
18580		return group.not( this.element );
18581	},
18582
18583	_toggleClasses: function() {
18584		var checked = this.element[ 0 ].checked;
18585		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
18586
18587		if ( this.options.icon && this.type === "checkbox" ) {
18588			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
18589				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
18590		}
18591
18592		if ( this.type === "radio" ) {
18593			this._getRadioGroup()
18594				.each( function() {
18595					var instance = $( this ).checkboxradio( "instance" );
18596
18597					if ( instance ) {
18598						instance._removeClass( instance.label,
18599							"ui-checkboxradio-checked", "ui-state-active" );
18600					}
18601				} );
18602		}
18603	},
18604
18605	_destroy: function() {
18606		this._unbindFormResetHandler();
18607
18608		if ( this.icon ) {
18609			this.icon.remove();
vendor: 3,109 bytes, lines 18610-18745
18610			this.iconSpace.remove();
18611		}
18612	},
18613
18614	_setOption: function( key, value ) {
18615
18616		// We don't allow the value to be set to nothing
18617		if ( key === "label" && !value ) {
18618			return;
18619		}
18620
18621		this._super( key, value );
18622
18623		if ( key === "disabled" ) {
18624			this._toggleClass( this.label, null, "ui-state-disabled", value );
18625			this.element[ 0 ].disabled = value;
18626
18627			// Don't refresh when setting disabled
18628			return;
18629		}
18630		this.refresh();
18631	},
18632
18633	_updateIcon: function( checked ) {
18634		var toAdd = "ui-icon ui-icon-background ";
18635
18636		if ( this.options.icon ) {
18637			if ( !this.icon ) {
18638				this.icon = $( "<span>" );
18639				this.iconSpace = $( "<span> </span>" );
18640				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
18641			}
18642
18643			if ( this.type === "checkbox" ) {
18644				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
18645				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
18646			} else {
18647				toAdd += "ui-icon-blank";
18648			}
18649			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
18650			if ( !checked ) {
18651				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
18652			}
18653			this.icon.prependTo( this.label ).after( this.iconSpace );
18654		} else if ( this.icon !== undefined ) {
18655			this.icon.remove();
18656			this.iconSpace.remove();
18657			delete this.icon;
18658		}
18659	},
18660
18661	_updateLabel: function() {
18662
18663		// Remove the contents of the label ( minus the icon, icon space, and input )
18664		var contents = this.label.contents().not( this.element[ 0 ] );
18665		if ( this.icon ) {
18666			contents = contents.not( this.icon[ 0 ] );
18667		}
18668		if ( this.iconSpace ) {
18669			contents = contents.not( this.iconSpace[ 0 ] );
18670		}
18671		contents.remove();
18672
18673		this.label.append( this.options.label );
18674	},
18675
18676	refresh: function() {
18677		var checked = this.element[ 0 ].checked,
18678			isDisabled = this.element[ 0 ].disabled;
18679
18680		this._updateIcon( checked );
18681		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
18682		if ( this.options.label !== null ) {
18683			this._updateLabel();
18684		}
18685
18686		if ( isDisabled !== this.options.disabled ) {
18687			this._setOptions( { "disabled": isDisabled } );
18688		}
18689	}
18690
18691} ] );
18692
18693return $.ui.checkboxradio;
18694
18695} );
18696
18697
18698
18699
18700
18701/*!
18702 * jQuery UI Button 1.13.0
18703 * http://jqueryui.com
18704 *
18705 * Copyright jQuery Foundation and other contributors
18706 * Released under the MIT license.
18707 * http://jquery.org/license
18708 */
18709
18710//>>label: Button
18711//>>group: Widgets
18712//>>description: Enhances a form with themeable buttons.
18713//>>docs: http://api.jqueryui.com/button/
18714//>>demos: http://jqueryui.com/button/
18715//>>css.structure: ../../themes/base/core.css
18716//>>css.structure: ../../themes/base/button.css
18717//>>css.theme: ../../themes/base/theme.css
18718
18719( function( factory ) {
18720	"use strict";
18721
18722	if ( typeof define === "function" && define.amd ) {
18723
18724		// AMD. Register as an anonymous module.
18725		define( [
18726			"jquery",
18727
18728			// These are only for backcompat
18729			// TODO: Remove after 1.12
18730			"./controlgroup",
18731			"./checkboxradio",
18732
18733			"../keycode",
18734			"../widget"
18735		], factory );
18736	} else {
18737
18738		// Browser globals
18739		factory( jQuery );
18740	}
18741} )( function( $ ) {
18742"use strict";
18743
18744$.widget( "ui.button", {
18745	version: "1.13.0
vendor: 10,728 bytes, lines 18745-19146
18745",
18746	defaultElement: "<button>",
18747	options: {
18748		classes: {
18749			"ui-button": "ui-corner-all"
18750		},
18751		disabled: null,
18752		icon: null,
18753		iconPosition: "beginning",
18754		label: null,
18755		showLabel: true
18756	},
18757
18758	_getCreateOptions: function() {
18759		var disabled,
18760
18761			// This is to support cases like in jQuery Mobile where the base widget does have
18762			// an implementation of _getCreateOptions
18763			options = this._super() || {};
18764
18765		this.isInput = this.element.is( "input" );
18766
18767		disabled = this.element[ 0 ].disabled;
18768		if ( disabled != null ) {
18769			options.disabled = disabled;
18770		}
18771
18772		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
18773		if ( this.originalLabel ) {
18774			options.label = this.originalLabel;
18775		}
18776
18777		return options;
18778	},
18779
18780	_create: function() {
18781		if ( !this.option.showLabel & !this.options.icon ) {
18782			this.options.showLabel = true;
18783		}
18784
18785		// We have to check the option again here even though we did in _getCreateOptions,
18786		// because null may have been passed on init which would override what was set in
18787		// _getCreateOptions
18788		if ( this.options.disabled == null ) {
18789			this.options.disabled = this.element[ 0 ].disabled || false;
18790		}
18791
18792		this.hasTitle = !!this.element.attr( "title" );
18793
18794		// Check to see if the label needs to be set or if its already correct
18795		if ( this.options.label && this.options.label !== this.originalLabel ) {
18796			if ( this.isInput ) {
18797				this.element.val( this.options.label );
18798			} else {
18799				this.element.html( this.options.label );
18800			}
18801		}
18802		this._addClass( "ui-button", "ui-widget" );
18803		this._setOption( "disabled", this.options.disabled );
18804		this._enhance();
18805
18806		if ( this.element.is( "a" ) ) {
18807			this._on( {
18808				"keyup": function( event ) {
18809					if ( event.keyCode === $.ui.keyCode.SPACE ) {
18810						event.preventDefault();
18811
18812						// Support: PhantomJS <= 1.9, IE 8 Only
18813						// If a native click is available use it so we actually cause navigation
18814						// otherwise just trigger a click event
18815						if ( this.element[ 0 ].click ) {
18816							this.element[ 0 ].click();
18817						} else {
18818							this.element.trigger( "click" );
18819						}
18820					}
18821				}
18822			} );
18823		}
18824	},
18825
18826	_enhance: function() {
18827		if ( !this.element.is( "button" ) ) {
18828			this.element.attr( "role", "button" );
18829		}
18830
18831		if ( this.options.icon ) {
18832			this._updateIcon( "icon", this.options.icon );
18833			this._updateTooltip();
18834		}
18835	},
18836
18837	_updateTooltip: function() {
18838		this.title = this.element.attr( "title" );
18839
18840		if ( !this.options.showLabel && !this.title ) {
18841			this.element.attr( "title", this.options.label );
18842		}
18843	},
18844
18845	_updateIcon: function( option, value ) {
18846		var icon = option !== "iconPosition",
18847			position = icon ? this.options.iconPosition : value,
18848			displayBlock = position === "top" || position === "bottom";
18849
18850		// Create icon
18851		if ( !this.icon ) {
18852			this.icon = $( "<span>" );
18853
18854			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
18855
18856			if ( !this.options.showLabel ) {
18857				this._addClass( "ui-button-icon-only" );
18858			}
18859		} else if ( icon ) {
18860
18861			// If we are updating the icon remove the old icon class
18862			this._removeClass( this.icon, null, this.options.icon );
18863		}
18864
18865		// If we are updating the icon add the new icon class
18866		if ( icon ) {
18867			this._addClass( this.icon, null, value );
18868		}
18869
18870		this._attachIcon( position );
18871
18872		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
18873		// the iconSpace if there is one.
18874		if ( displayBlock ) {
18875			this._addClass( this.icon, null, "ui-widget-icon-block" );
18876			if ( this.iconSpace ) {
18877				this.iconSpace.remove();
18878			}
18879		} else {
18880
18881			// Position is beginning or end so remove the ui-widget-icon-block class and add the
18882			// space if it does not exist
18883			if ( !this.iconSpace ) {
18884				this.iconSpace = $( "<span> </span>" );
18885				this._addClass( this.iconSpace, "ui-button-icon-space" );
18886			}
18887			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
18888			this._attachIconSpace( position );
18889		}
18890	},
18891
18892	_destroy: function() {
18893		this.element.removeAttr( "role" );
18894
18895		if ( this.icon ) {
18896			this.icon.remove();
18897		}
18898		if ( this.iconSpace ) {
18899			this.iconSpace.remove();
18900		}
18901		if ( !this.hasTitle ) {
18902			this.element.removeAttr( "title" );
18903		}
18904	},
18905
18906	_attachIconSpace: function( iconPosition ) {
18907		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
18908	},
18909
18910	_attachIcon: function( iconPosition ) {
18911		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
18912	},
18913
18914	_setOptions: function( options ) {
18915		var newShowLabel = options.showLabel === undefined ?
18916				this.options.showLabel :
18917				options.showLabel,
18918			newIcon = options.icon === undefined ? this.options.icon : options.icon;
18919
18920		if ( !newShowLabel && !newIcon ) {
18921			options.showLabel = true;
18922		}
18923		this._super( options );
18924	},
18925
18926	_setOption: function( key, value ) {
18927		if ( key === "icon" ) {
18928			if ( value ) {
18929				this._updateIcon( key, value );
18930			} else if ( this.icon ) {
18931				this.icon.remove();
18932				if ( this.iconSpace ) {
18933					this.iconSpace.remove();
18934				}
18935			}
18936		}
18937
18938		if ( key === "iconPosition" ) {
18939			this._updateIcon( key, value );
18940		}
18941
18942		// Make sure we can't end up with a button that has neither text nor icon
18943		if ( key === "showLabel" ) {
18944				this._toggleClass( "ui-button-icon-only", null, !value );
18945				this._updateTooltip();
18946		}
18947
18948		if ( key === "label" ) {
18949			if ( this.isInput ) {
18950				this.element.val( value );
18951			} else {
18952
18953				// If there is an icon, append it, else nothing then append the value
18954				// this avoids removal of the icon when setting label text
18955				this.element.html( value );
18956				if ( this.icon ) {
18957					this._attachIcon( this.options.iconPosition );
18958					this._attachIconSpace( this.options.iconPosition );
18959				}
18960			}
18961		}
18962
18963		this._super( key, value );
18964
18965		if ( key === "disabled" ) {
18966			this._toggleClass( null, "ui-state-disabled", value );
18967			this.element[ 0 ].disabled = value;
18968			if ( value ) {
18969				this.element.trigger( "blur" );
18970			}
18971		}
18972	},
18973
18974	refresh: function() {
18975
18976		// Make sure to only check disabled if its an element that supports this otherwise
18977		// check for the disabled class to determine state
18978		var isDisabled = this.element.is( "input, button" ) ?
18979			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
18980
18981		if ( isDisabled !== this.options.disabled ) {
18982			this._setOptions( { disabled: isDisabled } );
18983		}
18984
18985		this._updateTooltip();
18986	}
18987} );
18988
18989// DEPRECATED
18990if ( $.uiBackCompat !== false ) {
18991
18992	// Text and Icons options
18993	$.widget( "ui.button", $.ui.button, {
18994		options: {
18995			text: true,
18996			icons: {
18997				primary: null,
18998				secondary: null
18999			}
19000		},
19001
19002		_create: function() {
19003			if ( this.options.showLabel && !this.options.text ) {
19004				this.options.showLabel = this.options.text;
19005			}
19006			if ( !this.options.showLabel && this.options.text ) {
19007				this.options.text = this.options.showLabel;
19008			}
19009			if ( !this.options.icon && ( this.options.icons.primary ||
19010					this.options.icons.secondary ) ) {
19011				if ( this.options.icons.primary ) {
19012					this.options.icon = this.options.icons.primary;
19013				} else {
19014					this.options.icon = this.options.icons.secondary;
19015					this.options.iconPosition = "end";
19016				}
19017			} else if ( this.options.icon ) {
19018				this.options.icons.primary = this.options.icon;
19019			}
19020			this._super();
19021		},
19022
19023		_setOption: function( key, value ) {
19024			if ( key === "text" ) {
19025				this._super( "showLabel", value );
19026				return;
19027			}
19028			if ( key === "showLabel" ) {
19029				this.options.text = value;
19030			}
19031			if ( key === "icon" ) {
19032				this.options.icons.primary = value;
19033			}
19034			if ( key === "icons" ) {
19035				if ( value.primary ) {
19036					this._super( "icon", value.primary );
19037					this._super( "iconPosition", "beginning" );
19038				} else if ( value.secondary ) {
19039					this._super( "icon", value.secondary );
19040					this._super( "iconPosition", "end" );
19041				}
19042			}
19043			this._superApply( arguments );
19044		}
19045	} );
19046
19047	$.fn.button = ( function( orig ) {
19048		return function( options ) {
19049			var isMethodCall = typeof options === "string";
19050			var args = Array.prototype.slice.call( arguments, 1 );
19051			var returnValue = this;
19052
19053			if ( isMethodCall ) {
19054
19055				// If this is an empty collection, we need to have the instance method
19056				// return undefined instead of the jQuery instance
19057				if ( !this.length && options === "instance" ) {
19058					returnValue = undefined;
19059				} else {
19060					this.each( function() {
19061						var methodValue;
19062						var type = $( this ).attr( "type" );
19063						var name = type !== "checkbox" && type !== "radio" ?
19064							"button" :
19065							"checkboxradio";
19066						var instance = $.data( this, "ui-" + name );
19067
19068						if ( options === "instance" ) {
19069							returnValue = instance;
19070							return false;
19071						}
19072
19073						if ( !instance ) {
19074							return $.error( "cannot call methods on button" +
19075								" prior to initialization; " +
19076								"attempted to call method '" + options + "'" );
19077						}
19078
19079						if ( typeof instance[ options ] !== "function" ||
19080							options.charAt( 0 ) === "_" ) {
19081							return $.error( "no such method '" + options + "' for button" +
19082								" widget instance" );
19083						}
19084
19085						methodValue = instance[ options ].apply( instance, args );
19086
19087						if ( methodValue !== instance && methodValue !== undefined ) {
19088							returnValue = methodValue && methodValue.jquery ?
19089								returnValue.pushStack( methodValue.get() ) :
19090								methodValue;
19091							return false;
19092						}
19093					} );
19094				}
19095			} else {
19096
19097				// Allow multiple hashes to be passed on init
19098				if ( args.length ) {
19099					options = $.widget.extend.apply( null, [ options ].concat( args ) );
19100				}
19101
19102				this.each( function() {
19103					var type = $( this ).attr( "type" );
19104					var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
19105					var instance = $.data( this, "ui-" + name );
19106
19107					if ( instance ) {
19108						instance.option( options || {} );
19109						if ( instance._init ) {
19110							instance._init();
19111						}
19112					} else {
19113						if ( name === "button" ) {
19114							orig.call( $( this ), options );
19115							return;
19116						}
19117
19118						$( this ).checkboxradio( $.extend( { icon: false }, options ) );
19119					}
19120				} );
19121			}
19122
19123			return returnValue;
19124		};
19125	} )( $.fn.button );
19126
19127	$.fn.buttonset = function() {
19128		if ( !$.ui.controlgroup ) {
19129			$.error( "Controlgroup widget missing" );
19130		}
19131		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
19132			return this.controlgroup.apply( this,
19133				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
19134		}
19135		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
19136			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
19137		}
19138		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
19139			arguments[ 0 ].items = {
19140				button: arguments[ 0 ].items
19141			};
19142		}
19143		return this.controlgroup.apply( this, arguments );
19144	};
19145}
19146
19147return $.ui.button;
19148
19149} );
19150
19151
19152
19153/* eslint-disable max-len, camelcase */
19154/*!
19155 * jQuery UI Datepicker 1.13.0
19156 * http://jqueryui.com
19157 *
19158 * Copyright jQuery Foundation and other contributors
19159 * Released under the MIT license.
19160 * http://jquery.org/license
19161 */
19162
19163//>>label: Datepicker
19164//>>group: Widgets
19165//>>description: Displays a calendar from an input or inline for selecting dates.
19166//>>docs: http://api.jqueryui.com/datepicker/
19167//>>demos: http://jqueryui.com/datepicker/
19168//>>css.structure: ../../themes/base/core.css
19169//>>css.structure: ../../themes/base/datepicker.css
19170//>>css.theme: ../../themes/base/theme.css
19171
19172( function( factory ) {
19173	"use strict";
19174
19175	if ( typeof define === "function" && define.amd ) {
19176
19177		// AMD. Register as an anonymous module.
19178		define( [
19179			"jquery",
19180			"../version",
19181			"../keycode"
19182		], factory );
19183	} else {
19184
19185		// Browser globals
19186		factory( jQuery );
19187	}
19188} )( function( $ ) {
19189"use strict";
19190
19191$.extend( $.ui, { datepicker: { version: "1.13.0
vendor: 14,162 bytes, lines 19191-19508
19191" } } );
19192
19193var datepicker_instActive;
19194
19195function datepicker_getZindex( elem ) {
19196	var position, value;
19197	while ( elem.length && elem[ 0 ] !== document ) {
19198
19199		// Ignore z-index if position is set to a value where z-index is ignored by the browser
19200		// This makes behavior of this function consistent across browsers
19201		// WebKit always returns auto if the element is positioned
19202		position = elem.css( "position" );
19203		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
19204
19205			// IE returns 0 when zIndex is not specified
19206			// other browsers return a string
19207			// we ignore the case of nested elements with an explicit value of 0
19208			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
19209			value = parseInt( elem.css( "zIndex" ), 10 );
19210			if ( !isNaN( value ) && value !== 0 ) {
19211				return value;
19212			}
19213		}
19214		elem = elem.parent();
19215	}
19216
19217	return 0;
19218}
19219
19220/* Date picker manager.
19221   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
19222   Settings for (groups of) date pickers are maintained in an instance object,
19223   allowing multiple different settings on the same page. */
19224
19225function Datepicker() {
19226	this._curInst = null; // The current instance in use
19227	this._keyEvent = false; // If the last event was a key event
19228	this._disabledInputs = []; // List of date picker inputs that have been disabled
19229	this._datepickerShowing = false; // True if the popup picker is showing , false if not
19230	this._inDialog = false; // True if showing within a "dialog", false if not
19231	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
19232	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
19233	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
19234	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
19235	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
19236	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
19237	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
19238	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
19239	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
19240	this.regional = []; // Available regional settings, indexed by language code
19241	this.regional[ "" ] = { // Default regional settings
19242		closeText: "Done", // Display text for close link
19243		prevText: "Prev", // Display text for previous month link
19244		nextText: "Next", // Display text for next month link
19245		currentText: "Today", // Display text for current month link
19246		monthNames: [ "January", "February", "March", "April", "May", "June",
19247			"July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
19248		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
19249		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
19250		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
19251		dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
19252		weekHeader: "Wk", // Column header for week of the year
19253		dateFormat: "mm/dd/yy", // See format options on parseDate
19254		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
19255		isRTL: false, // True if right-to-left language, false if left-to-right
19256		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
19257		yearSuffix: "", // Additional text to append to the year in the month headers,
19258		selectMonthLabel: "Select month", // Invisible label for month selector
19259		selectYearLabel: "Select year" // Invisible label for year selector
19260	};
19261	this._defaults = { // Global defaults for all the date picker instances
19262		showOn: "focus", // "focus" for popup on focus,
19263			// "button" for trigger button, or "both" for either
19264		showAnim: "fadeIn", // Name of jQuery animation for popup
19265		showOptions: {}, // Options for enhanced animations
19266		defaultDate: null, // Used when field is blank: actual date,
19267			// +/-number for offset from today, null for today
19268		appendText: "", // Display text following the input box, e.g. showing the format
19269		buttonText: "...", // Text for trigger button
19270		buttonImage: "", // URL for trigger button image
19271		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
19272		hideIfNoPrevNext: false, // True to hide next/previous month links
19273			// if not applicable, false to just disable them
19274		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
19275		gotoCurrent: false, // True if today link goes back to current selection instead
19276		changeMonth: false, // True if month can be selected directly, false if only prev/next
19277		changeYear: false, // True if year can be selected directly, false if only prev/next
19278		yearRange: "c-10:c+10", // Range of years to display in drop-down,
19279			// either relative to today's year (-nn:+nn), relative to currently displayed year
19280			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
19281		showOtherMonths: false, // True to show dates in other months, false to leave blank
19282		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
19283		showWeek: false, // True to show week of the year, false to not show it
19284		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
19285			// takes a Date and returns the number of the week for it
19286		shortYearCutoff: "+10", // Short year values < this are in the current century,
19287			// > this are in the previous century,
19288			// string value starting with "+" for current year + value
19289		minDate: null, // The earliest selectable date, or null for no limit
19290		maxDate: null, // The latest selectable date, or null for no limit
19291		duration: "fast", // Duration of display/closure
19292		beforeShowDay: null, // Function that takes a date and returns an array with
19293			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
19294			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
19295		beforeShow: null, // Function that takes an input field and
19296			// returns a set of custom settings for the date picker
19297		onSelect: null, // Define a callback function when a date is selected
19298		onChangeMonthYear: null, // Define a callback function when the month or year is changed
19299		onClose: null, // Define a callback function when the datepicker is closed
19300		onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
19301		numberOfMonths: 1, // Number of months to show at a time
19302		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
19303		stepMonths: 1, // Number of months to step back/forward
19304		stepBigMonths: 12, // Number of months to step back/forward for the big links
19305		altField: "", // Selector for an alternate field to store selected dates into
19306		altFormat: "", // The date format to use for the alternate field
19307		constrainInput: true, // The input is constrained by the current date format
19308		showButtonPanel: false, // True to show button panel, false to not show it
19309		autoSize: false, // True to size the input for the date format, false to leave as is
19310		disabled: false // The initial disabled state
19311	};
19312	$.extend( this._defaults, this.regional[ "" ] );
19313	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
19314	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
19315	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
19316}
19317
19318$.extend( Datepicker.prototype, {
19319
19320	/* Class name added to elements to indicate already configured with a date picker. */
19321	markerClassName: "hasDatepicker",
19322
19323	//Keep track of the maximum number of rows displayed (see #7043)
19324	maxRows: 4,
19325
19326	// TODO rename to "widget" when switching to widget factory
19327	_widgetDatepicker: function() {
19328		return this.dpDiv;
19329	},
19330
19331	/* Override the default settings for all instances of the date picker.
19332	 * @param  settings  object - the new settings to use as defaults (anonymous object)
19333	 * @return the manager object
19334	 */
19335	setDefaults: function( settings ) {
19336		datepicker_extendRemove( this._defaults, settings || {} );
19337		return this;
19338	},
19339
19340	/* Attach the date picker to a jQuery selection.
19341	 * @param  target	element - the target input field or division or span
19342	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
19343	 */
19344	_attachDatepicker: function( target, settings ) {
19345		var nodeName, inline, inst;
19346		nodeName = target.nodeName.toLowerCase();
19347		inline = ( nodeName === "div" || nodeName === "span" );
19348		if ( !target.id ) {
19349			this.uuid += 1;
19350			target.id = "dp" + this.uuid;
19351		}
19352		inst = this._newInst( $( target ), inline );
19353		inst.settings = $.extend( {}, settings || {} );
19354		if ( nodeName === "input" ) {
19355			this._connectDatepicker( target, inst );
19356		} else if ( inline ) {
19357			this._inlineDatepicker( target, inst );
19358		}
19359	},
19360
19361	/* Create a new instance object. */
19362	_newInst: function( target, inline ) {
19363		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
19364		return { id: id, input: target, // associated target
19365			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
19366			drawMonth: 0, drawYear: 0, // month being drawn
19367			inline: inline, // is datepicker inline or not
19368			dpDiv: ( !inline ? this.dpDiv : // presentation div
19369			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
19370	},
19371
19372	/* Attach the date picker to an input field. */
19373	_connectDatepicker: function( target, inst ) {
19374		var input = $( target );
19375		inst.append = $( [] );
19376		inst.trigger = $( [] );
19377		if ( input.hasClass( this.markerClassName ) ) {
19378			return;
19379		}
19380		this._attachments( input, inst );
19381		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
19382			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
19383		this._autoSize( inst );
19384		$.data( target, "datepicker", inst );
19385
19386		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
19387		if ( inst.settings.disabled ) {
19388			this._disableDatepicker( target );
19389		}
19390	},
19391
19392	/* Make attachments based on settings. */
19393	_attachments: function( input, inst ) {
19394		var showOn, buttonText, buttonImage,
19395			appendText = this._get( inst, "appendText" ),
19396			isRTL = this._get( inst, "isRTL" );
19397
19398		if ( inst.append ) {
19399			inst.append.remove();
19400		}
19401		if ( appendText ) {
19402			inst.append = $( "<span>" )
19403				.addClass( this._appendClass )
19404				.text( appendText );
19405			input[ isRTL ? "before" : "after" ]( inst.append );
19406		}
19407
19408		input.off( "focus", this._showDatepicker );
19409
19410		if ( inst.trigger ) {
19411			inst.trigger.remove();
19412		}
19413
19414		showOn = this._get( inst, "showOn" );
19415		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
19416			input.on( "focus", this._showDatepicker );
19417		}
19418		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
19419			buttonText = this._get( inst, "buttonText" );
19420			buttonImage = this._get( inst, "buttonImage" );
19421
19422			if ( this._get( inst, "buttonImageOnly" ) ) {
19423				inst.trigger = $( "<img>" )
19424					.addClass( this._triggerClass )
19425					.attr( {
19426						src: buttonImage,
19427						alt: buttonText,
19428						title: buttonText
19429					} );
19430			} else {
19431				inst.trigger = $( "<button type='button'>" )
19432					.addClass( this._triggerClass );
19433				if ( buttonImage ) {
19434					inst.trigger.html(
19435						$( "<img>" )
19436							.attr( {
19437								src: buttonImage,
19438								alt: buttonText,
19439								title: buttonText
19440							} )
19441					);
19442				} else {
19443					inst.trigger.text( buttonText );
19444				}
19445			}
19446
19447			input[ isRTL ? "before" : "after" ]( inst.trigger );
19448			inst.trigger.on( "click", function() {
19449				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
19450					$.datepicker._hideDatepicker();
19451				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
19452					$.datepicker._hideDatepicker();
19453					$.datepicker._showDatepicker( input[ 0 ] );
19454				} else {
19455					$.datepicker._showDatepicker( input[ 0 ] );
19456				}
19457				return false;
19458			} );
19459		}
19460	},
19461
19462	/* Apply the maximum length for the date format. */
19463	_autoSize: function( inst ) {
19464		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
19465			var findMax, max, maxI, i,
19466				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
19467				dateFormat = this._get( inst, "dateFormat" );
19468
19469			if ( dateFormat.match( /[DM]/ ) ) {
19470				findMax = function( names ) {
19471					max = 0;
19472					maxI = 0;
19473					for ( i = 0; i < names.length; i++ ) {
19474						if ( names[ i ].length > max ) {
19475							max = names[ i ].length;
19476							maxI = i;
19477						}
19478					}
19479					return maxI;
19480				};
19481				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
19482					"monthNames" : "monthNamesShort" ) ) ) );
19483				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
19484					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
19485			}
19486			inst.input.attr( "size", this._formatDate( inst, date ).length );
19487		}
19488	},
19489
19490	/* Attach an inline date picker to a div. */
19491	_inlineDatepicker: function( target, inst ) {
19492		var divSpan = $( target );
19493		if ( divSpan.hasClass( this.markerClassName ) ) {
19494			return;
19495		}
19496		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
19497		$.data( target, "datepicker", inst );
19498		this._setDate( inst, this._getDefaultDate( inst ), true );
19499		this._updateDatepicker( inst );
19500		this._updateAlternate( inst );
19501
19502		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
19503		if ( inst.settings.disabled ) {
19504			this._disableDatepicker( target );
19505		}
19506
19507		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
19508		// http
vendor: 14,693 bytes, lines 19508-19930
19508://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
19509		inst.dpDiv.css( "display", "block" );
19510	},
19511
19512	/* Pop-up the date picker in a "dialog" box.
19513	 * @param  input element - ignored
19514	 * @param  date	string or Date - the initial date to display
19515	 * @param  onSelect  function - the function to call when a date is selected
19516	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
19517	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
19518	 *					event - with x/y coordinates or
19519	 *					leave empty for default (screen centre)
19520	 * @return the manager object
19521	 */
19522	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
19523		var id, browserWidth, browserHeight, scrollX, scrollY,
19524			inst = this._dialogInst; // internal instance
19525
19526		if ( !inst ) {
19527			this.uuid += 1;
19528			id = "dp" + this.uuid;
19529			this._dialogInput = $( "<input type='text' id='" + id +
19530				"' style='position: absolute; top: -100px; width: 0px;'/>" );
19531			this._dialogInput.on( "keydown", this._doKeyDown );
19532			$( "body" ).append( this._dialogInput );
19533			inst = this._dialogInst = this._newInst( this._dialogInput, false );
19534			inst.settings = {};
19535			$.data( this._dialogInput[ 0 ], "datepicker", inst );
19536		}
19537		datepicker_extendRemove( inst.settings, settings || {} );
19538		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
19539		this._dialogInput.val( date );
19540
19541		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
19542		if ( !this._pos ) {
19543			browserWidth = document.documentElement.clientWidth;
19544			browserHeight = document.documentElement.clientHeight;
19545			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
19546			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
19547			this._pos = // should use actual width/height below
19548				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
19549		}
19550
19551		// Move input on screen for focus, but hidden behind dialog
19552		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
19553		inst.settings.onSelect = onSelect;
19554		this._inDialog = true;
19555		this.dpDiv.addClass( this._dialogClass );
19556		this._showDatepicker( this._dialogInput[ 0 ] );
19557		if ( $.blockUI ) {
19558			$.blockUI( this.dpDiv );
19559		}
19560		$.data( this._dialogInput[ 0 ], "datepicker", inst );
19561		return this;
19562	},
19563
19564	/* Detach a datepicker from its control.
19565	 * @param  target	element - the target input field or division or span
19566	 */
19567	_destroyDatepicker: function( target ) {
19568		var nodeName,
19569			$target = $( target ),
19570			inst = $.data( target, "datepicker" );
19571
19572		if ( !$target.hasClass( this.markerClassName ) ) {
19573			return;
19574		}
19575
19576		nodeName = target.nodeName.toLowerCase();
19577		$.removeData( target, "datepicker" );
19578		if ( nodeName === "input" ) {
19579			inst.append.remove();
19580			inst.trigger.remove();
19581			$target.removeClass( this.markerClassName ).
19582				off( "focus", this._showDatepicker ).
19583				off( "keydown", this._doKeyDown ).
19584				off( "keypress", this._doKeyPress ).
19585				off( "keyup", this._doKeyUp );
19586		} else if ( nodeName === "div" || nodeName === "span" ) {
19587			$target.removeClass( this.markerClassName ).empty();
19588		}
19589
19590		if ( datepicker_instActive === inst ) {
19591			datepicker_instActive = null;
19592			this._curInst = null;
19593		}
19594	},
19595
19596	/* Enable the date picker to a jQuery selection.
19597	 * @param  target	element - the target input field or division or span
19598	 */
19599	_enableDatepicker: function( target ) {
19600		var nodeName, inline,
19601			$target = $( target ),
19602			inst = $.data( target, "datepicker" );
19603
19604		if ( !$target.hasClass( this.markerClassName ) ) {
19605			return;
19606		}
19607
19608		nodeName = target.nodeName.toLowerCase();
19609		if ( nodeName === "input" ) {
19610			target.disabled = false;
19611			inst.trigger.filter( "button" ).
19612				each( function() {
19613					this.disabled = false;
19614				} ).end().
19615				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
19616		} else if ( nodeName === "div" || nodeName === "span" ) {
19617			inline = $target.children( "." + this._inlineClass );
19618			inline.children().removeClass( "ui-state-disabled" );
19619			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
19620				prop( "disabled", false );
19621		}
19622		this._disabledInputs = $.map( this._disabledInputs,
19623
19624			// Delete entry
19625			function( value ) {
19626				return ( value === target ? null : value );
19627			} );
19628	},
19629
19630	/* Disable the date picker to a jQuery selection.
19631	 * @param  target	element - the target input field or division or span
19632	 */
19633	_disableDatepicker: function( target ) {
19634		var nodeName, inline,
19635			$target = $( target ),
19636			inst = $.data( target, "datepicker" );
19637
19638		if ( !$target.hasClass( this.markerClassName ) ) {
19639			return;
19640		}
19641
19642		nodeName = target.nodeName.toLowerCase();
19643		if ( nodeName === "input" ) {
19644			target.disabled = true;
19645			inst.trigger.filter( "button" ).
19646				each( function() {
19647					this.disabled = true;
19648				} ).end().
19649				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
19650		} else if ( nodeName === "div" || nodeName === "span" ) {
19651			inline = $target.children( "." + this._inlineClass );
19652			inline.children().addClass( "ui-state-disabled" );
19653			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
19654				prop( "disabled", true );
19655		}
19656		this._disabledInputs = $.map( this._disabledInputs,
19657
19658			// Delete entry
19659			function( value ) {
19660				return ( value === target ? null : value );
19661			} );
19662		this._disabledInputs[ this._disabledInputs.length ] = target;
19663	},
19664
19665	/* Is the first field in a jQuery collection disabled as a datepicker?
19666	 * @param  target	element - the target input field or division or span
19667	 * @return boolean - true if disabled, false if enabled
19668	 */
19669	_isDisabledDatepicker: function( target ) {
19670		if ( !target ) {
19671			return false;
19672		}
19673		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
19674			if ( this._disabledInputs[ i ] === target ) {
19675				return true;
19676			}
19677		}
19678		return false;
19679	},
19680
19681	/* Retrieve the instance data for the target control.
19682	 * @param  target  element - the target input field or division or span
19683	 * @return  object - the associated instance data
19684	 * @throws  error if a jQuery problem getting data
19685	 */
19686	_getInst: function( target ) {
19687		try {
19688			return $.data( target, "datepicker" );
19689		} catch ( err ) {
19690			throw "Missing instance data for this datepicker";
19691		}
19692	},
19693
19694	/* Update or retrieve the settings for a date picker attached to an input field or division.
19695	 * @param  target  element - the target input field or division or span
19696	 * @param  name	object - the new settings to update or
19697	 *				string - the name of the setting to change or retrieve,
19698	 *				when retrieving also "all" for all instance settings or
19699	 *				"defaults" for all global defaults
19700	 * @param  value   any - the new value for the setting
19701	 *				(omit if above is an object or to retrieve a value)
19702	 */
19703	_optionDatepicker: function( target, name, value ) {
19704		var settings, date, minDate, maxDate,
19705			inst = this._getInst( target );
19706
19707		if ( arguments.length === 2 && typeof name === "string" ) {
19708			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
19709				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
19710				this._get( inst, name ) ) : null ) );
19711		}
19712
19713		settings = name || {};
19714		if ( typeof name === "string" ) {
19715			settings = {};
19716			settings[ name ] = value;
19717		}
19718
19719		if ( inst ) {
19720			if ( this._curInst === inst ) {
19721				this._hideDatepicker();
19722			}
19723
19724			date = this._getDateDatepicker( target, true );
19725			minDate = this._getMinMaxDate( inst, "min" );
19726			maxDate = this._getMinMaxDate( inst, "max" );
19727			datepicker_extendRemove( inst.settings, settings );
19728
19729			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
19730			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
19731				inst.settings.minDate = this._formatDate( inst, minDate );
19732			}
19733			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
19734				inst.settings.maxDate = this._formatDate( inst, maxDate );
19735			}
19736			if ( "disabled" in settings ) {
19737				if ( settings.disabled ) {
19738					this._disableDatepicker( target );
19739				} else {
19740					this._enableDatepicker( target );
19741				}
19742			}
19743			this._attachments( $( target ), inst );
19744			this._autoSize( inst );
19745			this._setDate( inst, date );
19746			this._updateAlternate( inst );
19747			this._updateDatepicker( inst );
19748		}
19749	},
19750
19751	// Change method deprecated
19752	_changeDatepicker: function( target, name, value ) {
19753		this._optionDatepicker( target, name, value );
19754	},
19755
19756	/* Redraw the date picker attached to an input field or division.
19757	 * @param  target  element - the target input field or division or span
19758	 */
19759	_refreshDatepicker: function( target ) {
19760		var inst = this._getInst( target );
19761		if ( inst ) {
19762			this._updateDatepicker( inst );
19763		}
19764	},
19765
19766	/* Set the dates for a jQuery selection.
19767	 * @param  target element - the target input field or division or span
19768	 * @param  date	Date - the new date
19769	 */
19770	_setDateDatepicker: function( target, date ) {
19771		var inst = this._getInst( target );
19772		if ( inst ) {
19773			this._setDate( inst, date );
19774			this._updateDatepicker( inst );
19775			this._updateAlternate( inst );
19776		}
19777	},
19778
19779	/* Get the date(s) for the first entry in a jQuery selection.
19780	 * @param  target element - the target input field or division or span
19781	 * @param  noDefault boolean - true if no default date is to be used
19782	 * @return Date - the current date
19783	 */
19784	_getDateDatepicker: function( target, noDefault ) {
19785		var inst = this._getInst( target );
19786		if ( inst && !inst.inline ) {
19787			this._setDateFromField( inst, noDefault );
19788		}
19789		return ( inst ? this._getDate( inst ) : null );
19790	},
19791
19792	/* Handle keystrokes. */
19793	_doKeyDown: function( event ) {
19794		var onSelect, dateStr, sel,
19795			inst = $.datepicker._getInst( event.target ),
19796			handled = true,
19797			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
19798
19799		inst._keyEvent = true;
19800		if ( $.datepicker._datepickerShowing ) {
19801			switch ( event.keyCode ) {
19802				case 9: $.datepicker._hideDatepicker();
19803						handled = false;
19804						break; // hide on tab out
19805				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
19806									$.datepicker._currentClass + ")", inst.dpDiv );
19807						if ( sel[ 0 ] ) {
19808							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
19809						}
19810
19811						onSelect = $.datepicker._get( inst, "onSelect" );
19812						if ( onSelect ) {
19813							dateStr = $.datepicker._formatDate( inst );
19814
19815							// Trigger custom callback
19816							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
19817						} else {
19818							$.datepicker._hideDatepicker();
19819						}
19820
19821						return false; // don't submit the form
19822				case 27: $.datepicker._hideDatepicker();
19823						break; // hide on escape
19824				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
19825							-$.datepicker._get( inst, "stepBigMonths" ) :
19826							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
19827						break; // previous month/year on page up/+ ctrl
19828				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
19829							+$.datepicker._get( inst, "stepBigMonths" ) :
19830							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
19831						break; // next month/year on page down/+ ctrl
19832				case 35: if ( event.ctrlKey || event.metaKey ) {
19833							$.datepicker._clearDate( event.target );
19834						}
19835						handled = event.ctrlKey || event.metaKey;
19836						break; // clear on ctrl or command +end
19837				case 36: if ( event.ctrlKey || event.metaKey ) {
19838							$.datepicker._gotoToday( event.target );
19839						}
19840						handled = event.ctrlKey || event.metaKey;
19841						break; // current on ctrl or command +home
19842				case 37: if ( event.ctrlKey || event.metaKey ) {
19843							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
19844						}
19845						handled = event.ctrlKey || event.metaKey;
19846
19847						// -1 day on ctrl or command +left
19848						if ( event.originalEvent.altKey ) {
19849							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
19850								-$.datepicker._get( inst, "stepBigMonths" ) :
19851								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
19852						}
19853
19854						// next month/year on alt +left on Mac
19855						break;
19856				case 38: if ( event.ctrlKey || event.metaKey ) {
19857							$.datepicker._adjustDate( event.target, -7, "D" );
19858						}
19859						handled = event.ctrlKey || event.metaKey;
19860						break; // -1 week on ctrl or command +up
19861				case 39: if ( event.ctrlKey || event.metaKey ) {
19862							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
19863						}
19864						handled = event.ctrlKey || event.metaKey;
19865
19866						// +1 day on ctrl or command +right
19867						if ( event.originalEvent.altKey ) {
19868							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
19869								+$.datepicker._get( inst, "stepBigMonths" ) :
19870								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
19871						}
19872
19873						// next month/year on alt +right
19874						break;
19875				case 40: if ( event.ctrlKey || event.metaKey ) {
19876							$.datepicker._adjustDate( event.target, +7, "D" );
19877						}
19878						handled = event.ctrlKey || event.metaKey;
19879						break; // +1 week on ctrl or command +down
19880				default: handled = false;
19881			}
19882		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
19883			$.datepicker._showDatepicker( this );
19884		} else {
19885			handled = false;
19886		}
19887
19888		if ( handled ) {
19889			event.preventDefault();
19890			event.stopPropagation();
19891		}
19892	},
19893
19894	/* Filter entered characters - based on date format. */
19895	_doKeyPress: function( event ) {
19896		var chars, chr,
19897			inst = $.datepicker._getInst( event.target );
19898
19899		if ( $.datepicker._get( inst, "constrainInput" ) ) {
19900			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
19901			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
19902			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
19903		}
19904	},
19905
19906	/* Synchronise manual entry and field/alternate field. */
19907	_doKeyUp: function( event ) {
19908		var date,
19909			inst = $.datepicker._getInst( event.target );
19910
19911		if ( inst.input.val() !== inst.lastVal ) {
19912			try {
19913				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
19914					( inst.input ? inst.input.val() : null ),
19915					$.datepicker._getFormatConfig( inst ) );
19916
19917				if ( date ) { // only if valid
19918					$.datepicker._setDateFromField( inst );
19919					$.datepicker._updateAlternate( inst );
19920					$.datepicker._updateDatepicker( inst );
19921				}
19922			} catch ( err ) {
19923			}
19924		}
19925		return true;
19926	},
19927
19928	/* Pop-up the date picker for a given input field.
19929	 * If false returned from beforeShow event handler do not show.
19930	 * @param  input  element - the input field attached to the date picker or
vendor: 4,332 bytes, lines 19931-20053
19931	 *					event - if triggered by focus
19932	 */
19933	_showDatepicker: function( input ) {
19934		input = input.target || input;
19935		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
19936			input = $( "input", input.parentNode )[ 0 ];
19937		}
19938
19939		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
19940			return;
19941		}
19942
19943		var inst, beforeShow, beforeShowSettings, isFixed,
19944			offset, showAnim, duration;
19945
19946		inst = $.datepicker._getInst( input );
19947		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
19948			$.datepicker._curInst.dpDiv.stop( true, true );
19949			if ( inst && $.datepicker._datepickerShowing ) {
19950				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
19951			}
19952		}
19953
19954		beforeShow = $.datepicker._get( inst, "beforeShow" );
19955		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
19956		if ( beforeShowSettings === false ) {
19957			return;
19958		}
19959		datepicker_extendRemove( inst.settings, beforeShowSettings );
19960
19961		inst.lastVal = null;
19962		$.datepicker._lastInput = input;
19963		$.datepicker._setDateFromField( inst );
19964
19965		if ( $.datepicker._inDialog ) { // hide cursor
19966			input.value = "";
19967		}
19968		if ( !$.datepicker._pos ) { // position below input
19969			$.datepicker._pos = $.datepicker._findPos( input );
19970			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
19971		}
19972
19973		isFixed = false;
19974		$( input ).parents().each( function() {
19975			isFixed |= $( this ).css( "position" ) === "fixed";
19976			return !isFixed;
19977		} );
19978
19979		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
19980		$.datepicker._pos = null;
19981
19982		//to avoid flashes on Firefox
19983		inst.dpDiv.empty();
19984
19985		// determine sizing offscreen
19986		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
19987		$.datepicker._updateDatepicker( inst );
19988
19989		// fix width for dynamic number of date pickers
19990		// and adjust position before showing
19991		offset = $.datepicker._checkOffset( inst, offset, isFixed );
19992		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
19993			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
19994			left: offset.left + "px", top: offset.top + "px" } );
19995
19996		if ( !inst.inline ) {
19997			showAnim = $.datepicker._get( inst, "showAnim" );
19998			duration = $.datepicker._get( inst, "duration" );
19999			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
20000			$.datepicker._datepickerShowing = true;
20001
20002			if ( $.effects && $.effects.effect[ showAnim ] ) {
20003				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
20004			} else {
20005				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
20006			}
20007
20008			if ( $.datepicker._shouldFocusInput( inst ) ) {
20009				inst.input.trigger( "focus" );
20010			}
20011
20012			$.datepicker._curInst = inst;
20013		}
20014	},
20015
20016	/* Generate the date picker content. */
20017	_updateDatepicker: function( inst ) {
20018		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
20019		datepicker_instActive = inst; // for delegate hover events
20020		inst.dpDiv.empty().append( this._generateHTML( inst ) );
20021		this._attachHandlers( inst );
20022
20023		var origyearshtml,
20024			numMonths = this._getNumberOfMonths( inst ),
20025			cols = numMonths[ 1 ],
20026			width = 17,
20027			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
20028			onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
20029
20030		if ( activeCell.length > 0 ) {
20031			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
20032		}
20033
20034		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
20035		if ( cols > 1 ) {
20036			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
20037		}
20038		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
20039			"Class" ]( "ui-datepicker-multi" );
20040		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
20041			"Class" ]( "ui-datepicker-rtl" );
20042
20043		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
20044			inst.input.trigger( "focus" );
20045		}
20046
20047		// Deffered render of the years select (to avoid flashes on Firefox)
20048		if ( inst.yearshtml ) {
20049			origyearshtml = inst.yearshtml;
20050			setTimeout( function() {
20051
20052				//assure that inst.yearshtml didn't change.
20053				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
vendor: 5,508 bytes, lines 20054-20212
20054					inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
20055				}
20056				origyearshtml = inst.yearshtml = null;
20057			}, 0 );
20058		}
20059
20060		if ( onUpdateDatepicker ) {
20061			onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
20062		}
20063	},
20064
20065	// #6694 - don't focus the input if it's already focused
20066	// this breaks the change event in IE
20067	// Support: IE and jQuery <1.9
20068	_shouldFocusInput: function( inst ) {
20069		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
20070	},
20071
20072	/* Check positioning to remain on screen. */
20073	_checkOffset: function( inst, offset, isFixed ) {
20074		var dpWidth = inst.dpDiv.outerWidth(),
20075			dpHeight = inst.dpDiv.outerHeight(),
20076			inputWidth = inst.input ? inst.input.outerWidth() : 0,
20077			inputHeight = inst.input ? inst.input.outerHeight() : 0,
20078			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
20079			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
20080
20081		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
20082		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
20083		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
20084
20085		// Now check if datepicker is showing outside window viewport - move to a better place if so.
20086		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
20087			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
20088		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
20089			Math.abs( dpHeight + inputHeight ) : 0 );
20090
20091		return offset;
20092	},
20093
20094	/* Find an object's position on the screen. */
20095	_findPos: function( obj ) {
20096		var position,
20097			inst = this._getInst( obj ),
20098			isRTL = this._get( inst, "isRTL" );
20099
20100		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
20101			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
20102		}
20103
20104		position = $( obj ).offset();
20105		return [ position.left, position.top ];
20106	},
20107
20108	/* Hide the date picker from view.
20109	 * @param  input  element - the input field attached to the date picker
20110	 */
20111	_hideDatepicker: function( input ) {
20112		var showAnim, duration, postProcess, onClose,
20113			inst = this._curInst;
20114
20115		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
20116			return;
20117		}
20118
20119		if ( this._datepickerShowing ) {
20120			showAnim = this._get( inst, "showAnim" );
20121			duration = this._get( inst, "duration" );
20122			postProcess = function() {
20123				$.datepicker._tidyDialog( inst );
20124			};
20125
20126			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
20127			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
20128				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
20129			} else {
20130				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
20131					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
20132			}
20133
20134			if ( !showAnim ) {
20135				postProcess();
20136			}
20137			this._datepickerShowing = false;
20138
20139			onClose = this._get( inst, "onClose" );
20140			if ( onClose ) {
20141				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
20142			}
20143
20144			this._lastInput = null;
20145			if ( this._inDialog ) {
20146				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
20147				if ( $.blockUI ) {
20148					$.unblockUI();
20149					$( "body" ).append( this.dpDiv );
20150				}
20151			}
20152			this._inDialog = false;
20153		}
20154	},
20155
20156	/* Tidy up after a dialog display. */
20157	_tidyDialog: function( inst ) {
20158		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
20159	},
20160
20161	/* Close date picker if clicked elsewhere. */
20162	_checkExternalClick: function( event ) {
20163		if ( !$.datepicker._curInst ) {
20164			return;
20165		}
20166
20167		var $target = $( event.target ),
20168			inst = $.datepicker._getInst( $target[ 0 ] );
20169
20170		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
20171				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
20172				!$target.hasClass( $.datepicker.markerClassName ) &&
20173				!$target.closest( "." + $.datepicker._triggerClass ).length &&
20174				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
20175			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
20176				$.datepicker._hideDatepicker();
20177		}
20178	},
20179
20180	/* Adjust one of the date sub-fields. */
20181	_adjustDate: function( id, offset, period ) {
20182		var target = $( id ),
20183			inst = this._getInst( target[ 0 ] );
20184
20185		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
20186			return;
20187		}
20188		this._adjustInstDate( inst, offset, period );
20189		this._updateDatepicker( inst );
20190	},
20191
20192	/* Action for current link. */
20193	_gotoToday: function( id ) {
20194		var date,
20195			target = $( id ),
20196			inst = this._getInst( target[ 0 ] );
20197
20198		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
20199			inst.selectedDay = inst.currentDay;
20200			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
20201			inst.drawYear = inst.selectedYear = inst.currentYear;
20202		} else {
20203			date = new Date();
20204			inst.selectedDay = date.getDate();
20205			inst.drawMonth = inst.selectedMonth = date.getMonth();
20206			inst.drawYear = inst.selectedYear = date.getFullYear();
20207		}
20208		this._notifyChange( inst );
20209		this._adjustDate( target );
20210	},
20211
20212	/* Action for selecting a new month/year. */
vendor: 4,615 bytes, lines 20213-20344
20213	_selectMonthYear: function( id, select, period ) {
20214		var target = $( id ),
20215			inst = this._getInst( target[ 0 ] );
20216
20217		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
20218		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
20219			parseInt( select.options[ select.selectedIndex ].value, 10 );
20220
20221		this._notifyChange( inst );
20222		this._adjustDate( target );
20223	},
20224
20225	/* Action for selecting a day. */
20226	_selectDay: function( id, month, year, td ) {
20227		var inst,
20228			target = $( id );
20229
20230		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
20231			return;
20232		}
20233
20234		inst = this._getInst( target[ 0 ] );
20235		inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
20236		inst.selectedMonth = inst.currentMonth = month;
20237		inst.selectedYear = inst.currentYear = year;
20238		this._selectDate( id, this._formatDate( inst,
20239			inst.currentDay, inst.currentMonth, inst.currentYear ) );
20240	},
20241
20242	/* Erase the input field and hide the date picker. */
20243	_clearDate: function( id ) {
20244		var target = $( id );
20245		this._selectDate( target, "" );
20246	},
20247
20248	/* Update the input field with the selected date. */
20249	_selectDate: function( id, dateStr ) {
20250		var onSelect,
20251			target = $( id ),
20252			inst = this._getInst( target[ 0 ] );
20253
20254		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
20255		if ( inst.input ) {
20256			inst.input.val( dateStr );
20257		}
20258		this._updateAlternate( inst );
20259
20260		onSelect = this._get( inst, "onSelect" );
20261		if ( onSelect ) {
20262			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
20263		} else if ( inst.input ) {
20264			inst.input.trigger( "change" ); // fire the change event
20265		}
20266
20267		if ( inst.inline ) {
20268			this._updateDatepicker( inst );
20269		} else {
20270			this._hideDatepicker();
20271			this._lastInput = inst.input[ 0 ];
20272			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
20273				inst.input.trigger( "focus" ); // restore focus
20274			}
20275			this._lastInput = null;
20276		}
20277	},
20278
20279	/* Update any alternate field to synchronise with the main field. */
20280	_updateAlternate: function( inst ) {
20281		var altFormat, date, dateStr,
20282			altField = this._get( inst, "altField" );
20283
20284		if ( altField ) { // update alternate field too
20285			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
20286			date = this._getDate( inst );
20287			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
20288			$( document ).find( altField ).val( dateStr );
20289		}
20290	},
20291
20292	/* Set as beforeShowDay function to prevent selection of weekends.
20293	 * @param  date  Date - the date to customise
20294	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
20295	 */
20296	noWeekends: function( date ) {
20297		var day = date.getDay();
20298		return [ ( day > 0 && day < 6 ), "" ];
20299	},
20300
20301	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
20302	 * @param  date  Date - the date to get the week for
20303	 * @return  number - the number of the week within the year that contains this date
20304	 */
20305	iso8601Week: function( date ) {
20306		var time,
20307			checkDate = new Date( date.getTime() );
20308
20309		// Find Thursday of this week starting on Monday
20310		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
20311
20312		time = checkDate.getTime();
20313		checkDate.setMonth( 0 ); // Compare with Jan 1
20314		checkDate.setDate( 1 );
20315		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
20316	},
20317
20318	/* Parse a string value into a date object.
20319	 * See formatDate below for the possible formats.
20320	 *
20321	 * @param  format string - the expected format of the date
20322	 * @param  value string - the date in the above format
20323	 * @param  settings Object - attributes include:
20324	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
20325	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
20326	 *					dayNames		string[7] - names of the days from Sunday (optional)
20327	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
20328	 *					monthNames		string[12] - names of the months (optional)
20329	 * @return  Date - the extracted date value or null if value is blank
20330	 */
20331	parseDate: function( format, value, settings ) {
20332		if ( format == null || value == null ) {
20333			throw "Invalid arguments";
20334		}
20335
20336		value = ( typeof value === "object" ? value.toString() : value + "" );
20337		if ( value === "" ) {
20338			return null;
20339		}
20340
20341		var iFormat, dim, extra,
20342			iValue = 0,
20343			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
20344			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 16,988 bytes, lines 20344-20873
20344:
20345				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
20346			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
20347			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
20348			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
20349			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
20350			year = -1,
20351			month = -1,
20352			day = -1,
20353			doy = -1,
20354			literal = false,
20355			date,
20356
20357			// Check whether a format character is doubled
20358			lookAhead = function( match ) {
20359				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20360				if ( matches ) {
20361					iFormat++;
20362				}
20363				return matches;
20364			},
20365
20366			// Extract a number from the string value
20367			getNumber = function( match ) {
20368				var isDoubled = lookAhead( match ),
20369					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
20370					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
20371					minSize = ( match === "y" ? size : 1 ),
20372					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
20373					num = value.substring( iValue ).match( digits );
20374				if ( !num ) {
20375					throw "Missing number at position " + iValue;
20376				}
20377				iValue += num[ 0 ].length;
20378				return parseInt( num[ 0 ], 10 );
20379			},
20380
20381			// Extract a name from the string value and convert to an index
20382			getName = function( match, shortNames, longNames ) {
20383				var index = -1,
20384					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
20385						return [ [ k, v ] ];
20386					} ).sort( function( a, b ) {
20387						return -( a[ 1 ].length - b[ 1 ].length );
20388					} );
20389
20390				$.each( names, function( i, pair ) {
20391					var name = pair[ 1 ];
20392					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
20393						index = pair[ 0 ];
20394						iValue += name.length;
20395						return false;
20396					}
20397				} );
20398				if ( index !== -1 ) {
20399					return index + 1;
20400				} else {
20401					throw "Unknown name at position " + iValue;
20402				}
20403			},
20404
20405			// Confirm that a literal character matches the string value
20406			checkLiteral = function() {
20407				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
20408					throw "Unexpected literal at position " + iValue;
20409				}
20410				iValue++;
20411			};
20412
20413		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20414			if ( literal ) {
20415				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20416					literal = false;
20417				} else {
20418					checkLiteral();
20419				}
20420			} else {
20421				switch ( format.charAt( iFormat ) ) {
20422					case "d":
20423						day = getNumber( "d" );
20424						break;
20425					case "D":
20426						getName( "D", dayNamesShort, dayNames );
20427						break;
20428					case "o":
20429						doy = getNumber( "o" );
20430						break;
20431					case "m":
20432						month = getNumber( "m" );
20433						break;
20434					case "M":
20435						month = getName( "M", monthNamesShort, monthNames );
20436						break;
20437					case "y":
20438						year = getNumber( "y" );
20439						break;
20440					case "@":
20441						date = new Date( getNumber( "@" ) );
20442						year = date.getFullYear();
20443						month = date.getMonth() + 1;
20444						day = date.getDate();
20445						break;
20446					case "!":
20447						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
20448						year = date.getFullYear();
20449						month = date.getMonth() + 1;
20450						day = date.getDate();
20451						break;
20452					case "'":
20453						if ( lookAhead( "'" ) ) {
20454							checkLiteral();
20455						} else {
20456							literal = true;
20457						}
20458						break;
20459					default:
20460						checkLiteral();
20461				}
20462			}
20463		}
20464
20465		if ( iValue < value.length ) {
20466			extra = value.substr( iValue );
20467			if ( !/^\s+/.test( extra ) ) {
20468				throw "Extra/unparsed characters found in date: " + extra;
20469			}
20470		}
20471
20472		if ( year === -1 ) {
20473			year = new Date().getFullYear();
20474		} else if ( year < 100 ) {
20475			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
20476				( year <= shortYearCutoff ? 0 : -100 );
20477		}
20478
20479		if ( doy > -1 ) {
20480			month = 1;
20481			day = doy;
20482			do {
20483				dim = this._getDaysInMonth( year, month - 1 );
20484				if ( day <= dim ) {
20485					break;
20486				}
20487				month++;
20488				day -= dim;
20489			} while ( true );
20490		}
20491
20492		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
20493		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
20494			throw "Invalid date"; // E.g. 31/02/00
20495		}
20496		return date;
20497	},
20498
20499	/* Standard date formats. */
20500	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
20501	COOKIE: "D, dd M yy",
20502	ISO_8601: "yy-mm-dd",
20503	RFC_822: "D, d M y",
20504	RFC_850: "DD, dd-M-y",
20505	RFC_1036: "D, d M y",
20506	RFC_1123: "D, d M yy",
20507	RFC_2822: "D, d M yy",
20508	RSS: "D, d M y", // RFC 822
20509	TICKS: "!",
20510	TIMESTAMP: "@",
20511	W3C: "yy-mm-dd", // ISO 8601
20512
20513	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
20514		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
20515
20516	/* Format a date object into a string value.
20517	 * The format can be combinations of the following:
20518	 * d  - day of month (no leading zero)
20519	 * dd - day of month (two digit)
20520	 * o  - day of year (no leading zeros)
20521	 * oo - day of year (three digit)
20522	 * D  - day name short
20523	 * DD - day name long
20524	 * m  - month of year (no leading zero)
20525	 * mm - month of year (two digit)
20526	 * M  - month name short
20527	 * MM - month name long
20528	 * y  - year (two digit)
20529	 * yy - year (four digit)
20530	 * @ - Unix timestamp (ms since 01/01/1970)
20531	 * ! - Windows ticks (100ns since 01/01/0001)
20532	 * "..." - literal text
20533	 * '' - single quote
20534	 *
20535	 * @param  format string - the desired format of the date
20536	 * @param  date Date - the date value to format
20537	 * @param  settings Object - attributes include:
20538	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
20539	 *					dayNames		string[7] - names of the days from Sunday (optional)
20540	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
20541	 *					monthNames		string[12] - names of the months (optional)
20542	 * @return  string - the date in the above format
20543	 */
20544	formatDate: function( format, date, settings ) {
20545		if ( !date ) {
20546			return "";
20547		}
20548
20549		var iFormat,
20550			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
20551			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
20552			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
20553			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
20554
20555			// Check whether a format character is doubled
20556			lookAhead = function( match ) {
20557				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20558				if ( matches ) {
20559					iFormat++;
20560				}
20561				return matches;
20562			},
20563
20564			// Format a number, with leading zero if necessary
20565			formatNumber = function( match, value, len ) {
20566				var num = "" + value;
20567				if ( lookAhead( match ) ) {
20568					while ( num.length < len ) {
20569						num = "0" + num;
20570					}
20571				}
20572				return num;
20573			},
20574
20575			// Format a name, short or long as requested
20576			formatName = function( match, value, shortNames, longNames ) {
20577				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
20578			},
20579			output = "",
20580			literal = false;
20581
20582		if ( date ) {
20583			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20584				if ( literal ) {
20585					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20586						literal = false;
20587					} else {
20588						output += format.charAt( iFormat );
20589					}
20590				} else {
20591					switch ( format.charAt( iFormat ) ) {
20592						case "d":
20593							output += formatNumber( "d", date.getDate(), 2 );
20594							break;
20595						case "D":
20596							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
20597							break;
20598						case "o":
20599							output += formatNumber( "o",
20600								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
20601							break;
20602						case "m":
20603							output += formatNumber( "m", date.getMonth() + 1, 2 );
20604							break;
20605						case "M":
20606							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
20607							break;
20608						case "y":
20609							output += ( lookAhead( "y" ) ? date.getFullYear() :
20610								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
20611							break;
20612						case "@":
20613							output += date.getTime();
20614							break;
20615						case "!":
20616							output += date.getTime() * 10000 + this._ticksTo1970;
20617							break;
20618						case "'":
20619							if ( lookAhead( "'" ) ) {
20620								output += "'";
20621							} else {
20622								literal = true;
20623							}
20624							break;
20625						default:
20626							output += format.charAt( iFormat );
20627					}
20628				}
20629			}
20630		}
20631		return output;
20632	},
20633
20634	/* Extract all possible characters from the date format. */
20635	_possibleChars: function( format ) {
20636		var iFormat,
20637			chars = "",
20638			literal = false,
20639
20640			// Check whether a format character is doubled
20641			lookAhead = function( match ) {
20642				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
20643				if ( matches ) {
20644					iFormat++;
20645				}
20646				return matches;
20647			};
20648
20649		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
20650			if ( literal ) {
20651				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
20652					literal = false;
20653				} else {
20654					chars += format.charAt( iFormat );
20655				}
20656			} else {
20657				switch ( format.charAt( iFormat ) ) {
20658					case "d": case "m": case "y": case "@":
20659						chars += "0123456789";
20660						break;
20661					case "D": case "M":
20662						return null; // Accept anything
20663					case "'":
20664						if ( lookAhead( "'" ) ) {
20665							chars += "'";
20666						} else {
20667							literal = true;
20668						}
20669						break;
20670					default:
20671						chars += format.charAt( iFormat );
20672				}
20673			}
20674		}
20675		return chars;
20676	},
20677
20678	/* Get a setting value, defaulting if necessary. */
20679	_get: function( inst, name ) {
20680		return inst.settings[ name ] !== undefined ?
20681			inst.settings[ name ] : this._defaults[ name ];
20682	},
20683
20684	/* Parse existing date and initialise date picker. */
20685	_setDateFromField: function( inst, noDefault ) {
20686		if ( inst.input.val() === inst.lastVal ) {
20687			return;
20688		}
20689
20690		var dateFormat = this._get( inst, "dateFormat" ),
20691			dates = inst.lastVal = inst.input ? inst.input.val() : null,
20692			defaultDate = this._getDefaultDate( inst ),
20693			date = defaultDate,
20694			settings = this._getFormatConfig( inst );
20695
20696		try {
20697			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
20698		} catch ( event ) {
20699			dates = ( noDefault ? "" : dates );
20700		}
20701		inst.selectedDay = date.getDate();
20702		inst.drawMonth = inst.selectedMonth = date.getMonth();
20703		inst.drawYear = inst.selectedYear = date.getFullYear();
20704		inst.currentDay = ( dates ? date.getDate() : 0 );
20705		inst.currentMonth = ( dates ? date.getMonth() : 0 );
20706		inst.currentYear = ( dates ? date.getFullYear() : 0 );
20707		this._adjustInstDate( inst );
20708	},
20709
20710	/* Retrieve the default date shown on opening. */
20711	_getDefaultDate: function( inst ) {
20712		return this._restrictMinMax( inst,
20713			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
20714	},
20715
20716	/* A date may be specified as an exact value or a relative one. */
20717	_determineDate: function( inst, date, defaultDate ) {
20718		var offsetNumeric = function( offset ) {
20719				var date = new Date();
20720				date.setDate( date.getDate() + offset );
20721				return date;
20722			},
20723			offsetString = function( offset ) {
20724				try {
20725					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
20726						offset, $.datepicker._getFormatConfig( inst ) );
20727				} catch ( e ) {
20728
20729					// Ignore
20730				}
20731
20732				var date = ( offset.toLowerCase().match( /^c/ ) ?
20733					$.datepicker._getDate( inst ) : null ) || new Date(),
20734					year = date.getFullYear(),
20735					month = date.getMonth(),
20736					day = date.getDate(),
20737					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
20738					matches = pattern.exec( offset );
20739
20740				while ( matches ) {
20741					switch ( matches[ 2 ] || "d" ) {
20742						case "d" : case "D" :
20743							day += parseInt( matches[ 1 ], 10 ); break;
20744						case "w" : case "W" :
20745							day += parseInt( matches[ 1 ], 10 ) * 7; break;
20746						case "m" : case "M" :
20747							month += parseInt( matches[ 1 ], 10 );
20748							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
20749							break;
20750						case "y": case "Y" :
20751							year += parseInt( matches[ 1 ], 10 );
20752							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
20753							break;
20754					}
20755					matches = pattern.exec( offset );
20756				}
20757				return new Date( year, month, day );
20758			},
20759			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
20760				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
20761
20762		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
20763		if ( newDate ) {
20764			newDate.setHours( 0 );
20765			newDate.setMinutes( 0 );
20766			newDate.setSeconds( 0 );
20767			newDate.setMilliseconds( 0 );
20768		}
20769		return this._daylightSavingAdjust( newDate );
20770	},
20771
20772	/* Handle switch to/from daylight saving.
20773	 * Hours may be non-zero on daylight saving cut-over:
20774	 * > 12 when midnight changeover, but then cannot generate
20775	 * midnight datetime, so jump to 1AM, otherwise reset.
20776	 * @param  date  (Date) the date to check
20777	 * @return  (Date) the corrected date
20778	 */
20779	_daylightSavingAdjust: function( date ) {
20780		if ( !date ) {
20781			return null;
20782		}
20783		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
20784		return date;
20785	},
20786
20787	/* Set the date(s) directly. */
20788	_setDate: function( inst, date, noChange ) {
20789		var clear = !date,
20790			origMonth = inst.selectedMonth,
20791			origYear = inst.selectedYear,
20792			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
20793
20794		inst.selectedDay = inst.currentDay = newDate.getDate();
20795		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
20796		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
20797		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
20798			this._notifyChange( inst );
20799		}
20800		this._adjustInstDate( inst );
20801		if ( inst.input ) {
20802			inst.input.val( clear ? "" : this._formatDate( inst ) );
20803		}
20804	},
20805
20806	/* Retrieve the date(s) directly. */
20807	_getDate: function( inst ) {
20808		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
20809			this._daylightSavingAdjust( new Date(
20810			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
20811			return startDate;
20812	},
20813
20814	/* Attach the onxxx handlers.  These are declared statically so
20815	 * they work with static code transformers like Caja.
20816	 */
20817	_attachHandlers: function( inst ) {
20818		var stepMonths = this._get( inst, "stepMonths" ),
20819			id = "#" + inst.id.replace( /\\\\/g, "\\" );
20820		inst.dpDiv.find( "[data-handler]" ).map( function() {
20821			var handler = {
20822				prev: function() {
20823					$.datepicker._adjustDate( id, -stepMonths, "M" );
20824				},
20825				next: function() {
20826					$.datepicker._adjustDate( id, +stepMonths, "M" );
20827				},
20828				hide: function() {
20829					$.datepicker._hideDatepicker();
20830				},
20831				today: function() {
20832					$.datepicker._gotoToday( id );
20833				},
20834				selectDay: function() {
20835					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
20836					return false;
20837				},
20838				selectMonth: function() {
20839					$.datepicker._selectMonthYear( id, this, "M" );
20840					return false;
20841				},
20842				selectYear: function() {
20843					$.datepicker._selectMonthYear( id, this, "Y" );
20844					return false;
20845				}
20846			};
20847			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
20848		} );
20849	},
20850
20851	/* Generate the HTML for the current state of the date picker. */
20852	_generateHTML: function( inst ) {
20853		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
20854			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
20855			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
20856			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
20857			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
20858			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
20859			tempDate = new Date(),
20860			today = this._daylightSavingAdjust(
20861				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
20862			isRTL = this._get( inst, "isRTL" ),
20863			showButtonPanel = this._get( inst, "showButtonPanel" ),
20864			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
20865			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
20866			numMonths = this._getNumberOfMonths( inst ),
20867			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
20868			stepMonths = this._get( inst, "stepMonths" ),
20869			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
20870			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
20871				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
20872			minDate = this._getMinMaxDate( inst, "min" ),
20873			maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,257 bytes, lines 20874-21388
20874			drawMonth = inst.drawMonth - showCurrentAtPos,
20875			drawYear = inst.drawYear;
20876
20877		if ( drawMonth < 0 ) {
20878			drawMonth += 12;
20879			drawYear--;
20880		}
20881		if ( maxDate ) {
20882			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
20883				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
20884			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
20885			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
20886				drawMonth--;
20887				if ( drawMonth < 0 ) {
20888					drawMonth = 11;
20889					drawYear--;
20890				}
20891			}
20892		}
20893		inst.drawMonth = drawMonth;
20894		inst.drawYear = drawYear;
20895
20896		prevText = this._get( inst, "prevText" );
20897		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
20898			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
20899			this._getFormatConfig( inst ) ) );
20900
20901		if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
20902			prev = $( "<a>" )
20903				.attr( {
20904					"class": "ui-datepicker-prev ui-corner-all",
20905					"data-handler": "prev",
20906					"data-event": "click",
20907					title: prevText
20908				} )
20909				.append(
20910					$( "<span>" )
20911						.addClass( "ui-icon ui-icon-circle-triangle-" +
20912							( isRTL ? "e" : "w" ) )
20913						.text( prevText )
20914				)[ 0 ].outerHTML;
20915		} else if ( hideIfNoPrevNext ) {
20916			prev = "";
20917		} else {
20918			prev = $( "<a>" )
20919				.attr( {
20920					"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
20921					title: prevText
20922				} )
20923				.append(
20924					$( "<span>" )
20925						.addClass( "ui-icon ui-icon-circle-triangle-" +
20926							( isRTL ? "e" : "w" ) )
20927						.text( prevText )
20928				)[ 0 ].outerHTML;
20929		}
20930
20931		nextText = this._get( inst, "nextText" );
20932		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
20933			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
20934			this._getFormatConfig( inst ) ) );
20935
20936		if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
20937			next = $( "<a>" )
20938				.attr( {
20939					"class": "ui-datepicker-next ui-corner-all",
20940					"data-handler": "next",
20941					"data-event": "click",
20942					title: nextText
20943				} )
20944				.append(
20945					$( "<span>" )
20946						.addClass( "ui-icon ui-icon-circle-triangle-" +
20947							( isRTL ? "w" : "e" ) )
20948						.text( nextText )
20949				)[ 0 ].outerHTML;
20950		} else if ( hideIfNoPrevNext ) {
20951			next = "";
20952		} else {
20953			next = $( "<a>" )
20954				.attr( {
20955					"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
20956					title: nextText
20957				} )
20958				.append(
20959					$( "<span>" )
20960						.attr( "class", "ui-icon ui-icon-circle-triangle-" +
20961							( isRTL ? "w" : "e" ) )
20962						.text( nextText )
20963				)[ 0 ].outerHTML;
20964		}
20965
20966		currentText = this._get( inst, "currentText" );
20967		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
20968		currentText = ( !navigationAsDateFormat ? currentText :
20969			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
20970
20971		controls = "";
20972		if ( !inst.inline ) {
20973			controls = $( "<button>" )
20974				.attr( {
20975					type: "button",
20976					"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
20977					"data-handler": "hide",
20978					"data-event": "click"
20979				} )
20980				.text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
20981		}
20982
20983		buttonPanel = "";
20984		if ( showButtonPanel ) {
20985			buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
20986				.append( isRTL ? controls : "" )
20987				.append( this._isInRange( inst, gotoDate ) ?
20988					$( "<button>" )
20989						.attr( {
20990							type: "button",
20991							"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
20992							"data-handler": "today",
20993							"data-event": "click"
20994						} )
20995						.text( currentText ) :
20996					"" )
20997				.append( isRTL ? "" : controls )[ 0 ].outerHTML;
20998		}
20999
21000		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
21001		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
21002
21003		showWeek = this._get( inst, "showWeek" );
21004		dayNames = this._get( inst, "dayNames" );
21005		dayNamesMin = this._get( inst, "dayNamesMin" );
21006		monthNames = this._get( inst, "monthNames" );
21007		monthNamesShort = this._get( inst, "monthNamesShort" );
21008		beforeShowDay = this._get( inst, "beforeShowDay" );
21009		showOtherMonths = this._get( inst, "showOtherMonths" );
21010		selectOtherMonths = this._get( inst, "selectOtherMonths" );
21011		defaultDate = this._getDefaultDate( inst );
21012		html = "";
21013
21014		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
21015			group = "";
21016			this.maxRows = 4;
21017			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
21018				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
21019				cornerClass = " ui-corner-all";
21020				calender = "";
21021				if ( isMultiMonth ) {
21022					calender += "<div class='ui-datepicker-group";
21023					if ( numMonths[ 1 ] > 1 ) {
21024						switch ( col ) {
21025							case 0: calender += " ui-datepicker-group-first";
21026								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
21027							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
21028								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
21029							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
21030						}
21031					}
21032					calender += "'>";
21033				}
21034				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
21035					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
21036					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
21037					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
21038					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
21039					"</div><table class='ui-datepicker-calendar'><thead>" +
21040					"<tr>";
21041				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
21042				for ( dow = 0; dow < 7; dow++ ) { // days of the week
21043					day = ( dow + firstDay ) % 7;
21044					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
21045						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
21046				}
21047				calender += thead + "</tr></thead><tbody>";
21048				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
21049				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
21050					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
21051				}
21052				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
21053				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
21054				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
21055				this.maxRows = numRows;
21056				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
21057				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
21058					calender += "<tr>";
21059					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
21060						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
21061					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
21062						daySettings = ( beforeShowDay ?
21063							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
21064						otherMonth = ( printDate.getMonth() !== drawMonth );
21065						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
21066							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
21067						tbody += "<td class='" +
21068							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
21069							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
21070							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
21071							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
21072
21073							// or defaultDate is current printedDate and defaultDate is selectedDate
21074							" " + this._dayOverClass : "" ) + // highlight selected day
21075							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
21076							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
21077							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
21078							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
21079							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
21080							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
21081							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
21082							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
21083							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
21084							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
21085							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
21086							"' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
21087							"' data-date='" + printDate.getDate() + // store date as data
21088							"'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
21089						printDate.setDate( printDate.getDate() + 1 );
21090						printDate = this._daylightSavingAdjust( printDate );
21091					}
21092					calender += tbody + "</tr>";
21093				}
21094				drawMonth++;
21095				if ( drawMonth > 11 ) {
21096					drawMonth = 0;
21097					drawYear++;
21098				}
21099				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
21100							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
21101				group += calender;
21102			}
21103			html += group;
21104		}
21105		html += buttonPanel;
21106		inst._keyEvent = false;
21107		return html;
21108	},
21109
21110	/* Generate the month and year header. */
21111	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
21112			secondary, monthNames, monthNamesShort ) {
21113
21114		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
21115			changeMonth = this._get( inst, "changeMonth" ),
21116			changeYear = this._get( inst, "changeYear" ),
21117			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
21118			selectMonthLabel = this._get( inst, "selectMonthLabel" ),
21119			selectYearLabel = this._get( inst, "selectYearLabel" ),
21120			html = "<div class='ui-datepicker-title'>",
21121			monthHtml = "";
21122
21123		// Month selection
21124		if ( secondary || !changeMonth ) {
21125			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
21126		} else {
21127			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
21128			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
21129			monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
21130			for ( month = 0; month < 12; month++ ) {
21131				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
21132					monthHtml += "<option value='" + month + "'" +
21133						( month === drawMonth ? " selected='selected'" : "" ) +
21134						">" + monthNamesShort[ month ] + "</option>";
21135				}
21136			}
21137			monthHtml += "</select>";
21138		}
21139
21140		if ( !showMonthAfterYear ) {
21141			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
21142		}
21143
21144		// Year selection
21145		if ( !inst.yearshtml ) {
21146			inst.yearshtml = "";
21147			if ( secondary || !changeYear ) {
21148				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
21149			} else {
21150
21151				// determine range of years to display
21152				years = this._get( inst, "yearRange" ).split( ":" );
21153				thisYear = new Date().getFullYear();
21154				determineYear = function( value ) {
21155					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
21156						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
21157						parseInt( value, 10 ) ) );
21158					return ( isNaN( year ) ? thisYear : year );
21159				};
21160				year = determineYear( years[ 0 ] );
21161				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
21162				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
21163				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
21164				inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
21165				for ( ; year <= endYear; year++ ) {
21166					inst.yearshtml += "<option value='" + year + "'" +
21167						( year === drawYear ? " selected='selected'" : "" ) +
21168						">" + year + "</option>";
21169				}
21170				inst.yearshtml += "</select>";
21171
21172				html += inst.yearshtml;
21173				inst.yearshtml = null;
21174			}
21175		}
21176
21177		html += this._get( inst, "yearSuffix" );
21178		if ( showMonthAfterYear ) {
21179			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
21180		}
21181		html += "</div>"; // Close datepicker_header
21182		return html;
21183	},
21184
21185	/* Adjust one of the date sub-fields. */
21186	_adjustInstDate: function( inst, offset, period ) {
21187		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
21188			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
21189			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
21190			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
21191
21192		inst.selectedDay = date.getDate();
21193		inst.drawMonth = inst.selectedMonth = date.getMonth();
21194		inst.drawYear = inst.selectedYear = date.getFullYear();
21195		if ( period === "M" || period === "Y" ) {
21196			this._notifyChange( inst );
21197		}
21198	},
21199
21200	/* Ensure a date is within any min/max bounds. */
21201	_restrictMinMax: function( inst, date ) {
21202		var minDate = this._getMinMaxDate( inst, "min" ),
21203			maxDate = this._getMinMaxDate( inst, "max" ),
21204			newDate = ( minDate && date < minDate ? minDate : date );
21205		return ( maxDate && newDate > maxDate ? maxDate : newDate );
21206	},
21207
21208	/* Notify change of month/year. */
21209	_notifyChange: function( inst ) {
21210		var onChange = this._get( inst, "onChangeMonthYear" );
21211		if ( onChange ) {
21212			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
21213				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
21214		}
21215	},
21216
21217	/* Determine the number of months to show. */
21218	_getNumberOfMonths: function( inst ) {
21219		var numMonths = this._get( inst, "numberOfMonths" );
21220		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
21221	},
21222
21223	/* Determine the current maximum date - ensure no time components are set. */
21224	_getMinMaxDate: function( inst, minMax ) {
21225		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
21226	},
21227
21228	/* Find the number of days in a given month. */
21229	_getDaysInMonth: function( year, month ) {
21230		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
21231	},
21232
21233	/* Find the day of the week of the first of a month. */
21234	_getFirstDayOfMonth: function( year, month ) {
21235		return new Date( year, month, 1 ).getDay();
21236	},
21237
21238	/* Determines if we should allow a "next/prev" month display change. */
21239	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
21240		var numMonths = this._getNumberOfMonths( inst ),
21241			date = this._daylightSavingAdjust( new Date( curYear,
21242			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
21243
21244		if ( offset < 0 ) {
21245			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
21246		}
21247		return this._isInRange( inst, date );
21248	},
21249
21250	/* Is the given date in the accepted range? */
21251	_isInRange: function( inst, date ) {
21252		var yearSplit, currentYear,
21253			minDate = this._getMinMaxDate( inst, "min" ),
21254			maxDate = this._getMinMaxDate( inst, "max" ),
21255			minYear = null,
21256			maxYear = null,
21257			years = this._get( inst, "yearRange" );
21258			if ( years ) {
21259				yearSplit = years.split( ":" );
21260				currentYear = new Date().getFullYear();
21261				minYear = parseInt( yearSplit[ 0 ], 10 );
21262				maxYear = parseInt( yearSplit[ 1 ], 10 );
21263				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
21264					minYear += currentYear;
21265				}
21266				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
21267					maxYear += currentYear;
21268				}
21269			}
21270
21271		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
21272			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
21273			( !minYear || date.getFullYear() >= minYear ) &&
21274			( !maxYear || date.getFullYear() <= maxYear ) );
21275	},
21276
21277	/* Provide the configuration settings for formatting/parsing. */
21278	_getFormatConfig: function( inst ) {
21279		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
21280		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
21281			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
21282		return { shortYearCutoff: shortYearCutoff,
21283			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
21284			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
21285	},
21286
21287	/* Format the given date for display. */
21288	_formatDate: function( inst, day, month, year ) {
21289		if ( !day ) {
21290			inst.currentDay = inst.selectedDay;
21291			inst.currentMonth = inst.selectedMonth;
21292			inst.currentYear = inst.selectedYear;
21293		}
21294		var date = ( day ? ( typeof day === "object" ? day :
21295			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
21296			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
21297		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
21298	}
21299} );
21300
21301/*
21302 * Bind hover events for datepicker elements.
21303 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
21304 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
21305 */
21306function datepicker_bindHover( dpDiv ) {
21307	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
21308	return dpDiv.on( "mouseout", selector, function() {
21309			$( this ).removeClass( "ui-state-hover" );
21310			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
21311				$( this ).removeClass( "ui-datepicker-prev-hover" );
21312			}
21313			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
21314				$( this ).removeClass( "ui-datepicker-next-hover" );
21315			}
21316		} )
21317		.on( "mouseover", selector, datepicker_handleMouseover );
21318}
21319
21320function datepicker_handleMouseover() {
21321	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
21322		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
21323		$( this ).addClass( "ui-state-hover" );
21324		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
21325			$( this ).addClass( "ui-datepicker-prev-hover" );
21326		}
21327		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
21328			$( this ).addClass( "ui-datepicker-next-hover" );
21329		}
21330	}
21331}
21332
21333/* jQuery extend now ignores nulls! */
21334function datepicker_extendRemove( target, props ) {
21335	$.extend( target, props );
21336	for ( var name in props ) {
21337		if ( props[ name ] == null ) {
21338			target[ name ] = props[ name ];
21339		}
21340	}
21341	return target;
21342}
21343
21344/* Invoke the datepicker functionality.
21345   @param  options  string - a command, optionally followed by additional parameters or
21346					Object - settings for attaching new datepicker functionality
21347   @return  jQuery object */
21348$.fn.datepicker = function( options ) {
21349
21350	/* Verify an empty collection wasn't passed - Fixes #6976 */
21351	if ( !this.length ) {
21352		return this;
21353	}
21354
21355	/* Initialise the date picker. */
21356	if ( !$.datepicker.initialized ) {
21357		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
21358		$.datepicker.initialized = true;
21359	}
21360
21361	/* Append datepicker main container to body if not exist. */
21362	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
21363		$( "body" ).append( $.datepicker.dpDiv );
21364	}
21365
21366	var otherArgs = Array.prototype.slice.call( arguments, 1 );
21367	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
21368		return $.datepicker[ "_" + options + "Datepicker" ].
21369			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
21370	}
21371	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
21372		return $.datepicker[ "_" + options + "Datepicker" ].
21373			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
21374	}
21375	return this.each( function() {
21376		if ( typeof options === "string" ) {
21377			$.datepicker[ "_" + options + "Datepicker" ]
21378				.apply( $.datepicker, [ this ].concat( otherArgs ) );
21379		} else {
21380			$.datepicker._attachDatepicker( this, options );
21381		}
21382	} );
21383};
21384
21385$.datepicker = new Datepicker(); // singleton instance
21386$.datepicker.initialized = false;
21387$.datepicker.uuid = new Date().getTime();
21388$.datepicker.version = "1.1
vendor: 7,177 bytes, lines 21388-21685
213883.0";
21389
21390return $.datepicker;
21391
21392} );
21393
21394
21395
21396
21397/*!
21398 * jQuery UI Mouse 1.13.0
21399 * http://jqueryui.com
21400 *
21401 * Copyright jQuery Foundation and other contributors
21402 * Released under the MIT license.
21403 * http://jquery.org/license
21404 */
21405
21406//>>label: Mouse
21407//>>group: Widgets
21408//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
21409//>>docs: http://api.jqueryui.com/mouse/
21410
21411( function( factory ) {
21412	"use strict";
21413
21414	if ( typeof define === "function" && define.amd ) {
21415
21416		// AMD. Register as an anonymous module.
21417		define( [
21418			"jquery",
21419			"../ie",
21420			"../version",
21421			"../widget"
21422		], factory );
21423	} else {
21424
21425		// Browser globals
21426		factory( jQuery );
21427	}
21428} )( function( $ ) {
21429"use strict";
21430
21431var mouseHandled = false;
21432$( document ).on( "mouseup", function() {
21433	mouseHandled = false;
21434} );
21435
21436return $.widget( "ui.mouse", {
21437	version: "1.13.0",
21438	options: {
21439		cancel: "input, textarea, button, select, option",
21440		distance: 1,
21441		delay: 0
21442	},
21443	_mouseInit: function() {
21444		var that = this;
21445
21446		this.element
21447			.on( "mousedown." + this.widgetName, function( event ) {
21448				return that._mouseDown( event );
21449			} )
21450			.on( "click." + this.widgetName, function( event ) {
21451				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
21452					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
21453					event.stopImmediatePropagation();
21454					return false;
21455				}
21456			} );
21457
21458		this.started = false;
21459	},
21460
21461	// TODO: make sure destroying one instance of mouse doesn't mess with
21462	// other instances of mouse
21463	_mouseDestroy: function() {
21464		this.element.off( "." + this.widgetName );
21465		if ( this._mouseMoveDelegate ) {
21466			this.document
21467				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21468				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
21469		}
21470	},
21471
21472	_mouseDown: function( event ) {
21473
21474		// don't let more than one widget handle mouseStart
21475		if ( mouseHandled ) {
21476			return;
21477		}
21478
21479		this._mouseMoved = false;
21480
21481		// We may have missed mouseup (out of window)
21482		if ( this._mouseStarted ) {
21483			this._mouseUp( event );
21484		}
21485
21486		this._mouseDownEvent = event;
21487
21488		var that = this,
21489			btnIsLeft = ( event.which === 1 ),
21490
21491			// event.target.nodeName works around a bug in IE 8 with
21492			// disabled inputs (#7620)
21493			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
21494				$( event.target ).closest( this.options.cancel ).length : false );
21495		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
21496			return true;
21497		}
21498
21499		this.mouseDelayMet = !this.options.delay;
21500		if ( !this.mouseDelayMet ) {
21501			this._mouseDelayTimer = setTimeout( function() {
21502				that.mouseDelayMet = true;
21503			}, this.options.delay );
21504		}
21505
21506		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
21507			this._mouseStarted = ( this._mouseStart( event ) !== false );
21508			if ( !this._mouseStarted ) {
21509				event.preventDefault();
21510				return true;
21511			}
21512		}
21513
21514		// Click event may never have fired (Gecko & Opera)
21515		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
21516			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
21517		}
21518
21519		// These delegates are required to keep context
21520		this._mouseMoveDelegate = function( event ) {
21521			return that._mouseMove( event );
21522		};
21523		this._mouseUpDelegate = function( event ) {
21524			return that._mouseUp( event );
21525		};
21526
21527		this.document
21528			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21529			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
21530
21531		event.preventDefault();
21532
21533		mouseHandled = true;
21534		return true;
21535	},
21536
21537	_mouseMove: function( event ) {
21538
21539		// Only check for mouseups outside the document if you've moved inside the document
21540		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
21541		// fire a mousemove event if content is placed under the cursor. See #7778
21542		// Support: IE <9
21543		if ( this._mouseMoved ) {
21544
21545			// IE mouseup check - mouseup happened when mouse was out of window
21546			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
21547					!event.button ) {
21548				return this._mouseUp( event );
21549
21550			// Iframe mouseup check - mouseup occurred in another document
21551			} else if ( !event.which ) {
21552
21553				// Support: Safari <=8 - 9
21554				// Safari sets which to 0 if you press any of the following keys
21555				// during a drag (#14461)
21556				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
21557						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
21558					this.ignoreMissingWhich = true;
21559				} else if ( !this.ignoreMissingWhich ) {
21560					return this._mouseUp( event );
21561				}
21562			}
21563		}
21564
21565		if ( event.which || event.button ) {
21566			this._mouseMoved = true;
21567		}
21568
21569		if ( this._mouseStarted ) {
21570			this._mouseDrag( event );
21571			return event.preventDefault();
21572		}
21573
21574		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
21575			this._mouseStarted =
21576				( this._mouseStart( this._mouseDownEvent, event ) !== false );
21577			if ( this._mouseStarted ) {
21578				this._mouseDrag( event );
21579			} else {
21580				this._mouseUp( event );
21581			}
21582		}
21583
21584		return !this._mouseStarted;
21585	},
21586
21587	_mouseUp: function( event ) {
21588		this.document
21589			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
21590			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
21591
21592		if ( this._mouseStarted ) {
21593			this._mouseStarted = false;
21594
21595			if ( event.target === this._mouseDownEvent.target ) {
21596				$.data( event.target, this.widgetName + ".preventClickEvent", true );
21597			}
21598
21599			this._mouseStop( event );
21600		}
21601
21602		if ( this._mouseDelayTimer ) {
21603			clearTimeout( this._mouseDelayTimer );
21604			delete this._mouseDelayTimer;
21605		}
21606
21607		this.ignoreMissingWhich = false;
21608		mouseHandled = false;
21609		event.preventDefault();
21610	},
21611
21612	_mouseDistanceMet: function( event ) {
21613		return ( Math.max(
21614				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
21615				Math.abs( this._mouseDownEvent.pageY - event.pageY )
21616			) >= this.options.distance
21617		);
21618	},
21619
21620	_mouseDelayMet: function( /* event */ ) {
21621		return this.mouseDelayMet;
21622	},
21623
21624	// These are placeholder methods, to be overriden by extending plugin
21625	_mouseStart: function( /* event */ ) {},
21626	_mouseDrag: function( /* event */ ) {},
21627	_mouseStop: function( /* event */ ) {},
21628	_mouseCapture: function( /* event */ ) {
21629		return true;
21630	}
21631} );
21632
21633} );
21634
21635
21636
21637
21638
21639
21640
21641
21642
21643/*!
21644 * jQuery UI Draggable 1.13.0
21645 * http://jqueryui.com
21646 *
21647 * Copyright jQuery Foundation and other contributors
21648 * Released under the MIT license.
21649 * http://jquery.org/license
21650 */
21651
21652//>>label: Draggable
21653//>>group: Interactions
21654//>>description: Enables dragging functionality for any element.
21655//>>docs: http://api.jqueryui.com/draggable/
21656//>>demos: http://jqueryui.com/draggable/
21657//>>css.structure: ../../themes/base/draggable.css
21658
21659( function( factory ) {
21660	"use strict";
21661
21662	if ( typeof define === "function" && define.amd ) {
21663
21664		// AMD. Register as an anonymous module.
21665		define( [
21666			"jquery",
21667			"./mouse",
21668			"../data",
21669			"../plugin",
21670			"../safe-active-element",
21671			"../safe-blur",
21672			"../scroll-parent",
21673			"../version",
21674			"../widget"
21675		], factory );
21676	} else {
21677
21678		// Browser globals
21679		factory( jQuery );
21680	}
21681} )( function( $ ) {
21682"use strict";
21683
21684$.widget( "ui.draggable", $.ui.mouse, {
21685	version: "1.13.0
vendor: 8,684 bytes, lines 21685-22031
21685",
21686	widgetEventPrefix: "drag",
21687	options: {
21688		addClasses: true,
21689		appendTo: "parent",
21690		axis: false,
21691		connectToSortable: false,
21692		containment: false,
21693		cursor: "auto",
21694		cursorAt: false,
21695		grid: false,
21696		handle: false,
21697		helper: "original",
21698		iframeFix: false,
21699		opacity: false,
21700		refreshPositions: false,
21701		revert: false,
21702		revertDuration: 500,
21703		scope: "default",
21704		scroll: true,
21705		scrollSensitivity: 20,
21706		scrollSpeed: 20,
21707		snap: false,
21708		snapMode: "both",
21709		snapTolerance: 20,
21710		stack: false,
21711		zIndex: false,
21712
21713		// Callbacks
21714		drag: null,
21715		start: null,
21716		stop: null
21717	},
21718	_create: function() {
21719
21720		if ( this.options.helper === "original" ) {
21721			this._setPositionRelative();
21722		}
21723		if ( this.options.addClasses ) {
21724			this._addClass( "ui-draggable" );
21725		}
21726		this._setHandleClassName();
21727
21728		this._mouseInit();
21729	},
21730
21731	_setOption: function( key, value ) {
21732		this._super( key, value );
21733		if ( key === "handle" ) {
21734			this._removeHandleClassName();
21735			this._setHandleClassName();
21736		}
21737	},
21738
21739	_destroy: function() {
21740		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
21741			this.destroyOnClear = true;
21742			return;
21743		}
21744		this._removeHandleClassName();
21745		this._mouseDestroy();
21746	},
21747
21748	_mouseCapture: function( event ) {
21749		var o = this.options;
21750
21751		// Among others, prevent a drag on a resizable-handle
21752		if ( this.helper || o.disabled ||
21753				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
21754			return false;
21755		}
21756
21757		//Quit if we're not on a valid handle
21758		this.handle = this._getHandle( event );
21759		if ( !this.handle ) {
21760			return false;
21761		}
21762
21763		this._blurActiveElement( event );
21764
21765		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
21766
21767		return true;
21768
21769	},
21770
21771	_blockFrames: function( selector ) {
21772		this.iframeBlocks = this.document.find( selector ).map( function() {
21773			var iframe = $( this );
21774
21775			return $( "<div>" )
21776				.css( "position", "absolute" )
21777				.appendTo( iframe.parent() )
21778				.outerWidth( iframe.outerWidth() )
21779				.outerHeight( iframe.outerHeight() )
21780				.offset( iframe.offset() )[ 0 ];
21781		} );
21782	},
21783
21784	_unblockFrames: function() {
21785		if ( this.iframeBlocks ) {
21786			this.iframeBlocks.remove();
21787			delete this.iframeBlocks;
21788		}
21789	},
21790
21791	_blurActiveElement: function( event ) {
21792		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
21793			target = $( event.target );
21794
21795		// Don't blur if the event occurred on an element that is within
21796		// the currently focused element
21797		// See #10527, #12472
21798		if ( target.closest( activeElement ).length ) {
21799			return;
21800		}
21801
21802		// Blur any element that currently has focus, see #4261
21803		$.ui.safeBlur( activeElement );
21804	},
21805
21806	_mouseStart: function( event ) {
21807
21808		var o = this.options;
21809
21810		//Create and append the visible helper
21811		this.helper = this._createHelper( event );
21812
21813		this._addClass( this.helper, "ui-draggable-dragging" );
21814
21815		//Cache the helper size
21816		this._cacheHelperProportions();
21817
21818		//If ddmanager is used for droppables, set the global draggable
21819		if ( $.ui.ddmanager ) {
21820			$.ui.ddmanager.current = this;
21821		}
21822
21823		/*
21824		 * - Position generation -
21825		 * This block generates everything position related - it's the core of draggables.
21826		 */
21827
21828		//Cache the margins of the original element
21829		this._cacheMargins();
21830
21831		//Store the helper's css position
21832		this.cssPosition = this.helper.css( "position" );
21833		this.scrollParent = this.helper.scrollParent( true );
21834		this.offsetParent = this.helper.offsetParent();
21835		this.hasFixedAncestor = this.helper.parents().filter( function() {
21836				return $( this ).css( "position" ) === "fixed";
21837			} ).length > 0;
21838
21839		//The element's absolute position on the page minus margins
21840		this.positionAbs = this.element.offset();
21841		this._refreshOffsets( event );
21842
21843		//Generate the original position
21844		this.originalPosition = this.position = this._generatePosition( event, false );
21845		this.originalPageX = event.pageX;
21846		this.originalPageY = event.pageY;
21847
21848		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
21849		if ( o.cursorAt ) {
21850			this._adjustOffsetFromHelper( o.cursorAt );
21851		}
21852
21853		//Set a containment if given in the options
21854		this._setContainment();
21855
21856		//Trigger event + callbacks
21857		if ( this._trigger( "start", event ) === false ) {
21858			this._clear();
21859			return false;
21860		}
21861
21862		//Recache the helper size
21863		this._cacheHelperProportions();
21864
21865		//Prepare the droppable offsets
21866		if ( $.ui.ddmanager && !o.dropBehaviour ) {
21867			$.ui.ddmanager.prepareOffsets( this, event );
21868		}
21869
21870		// Execute the drag once - this causes the helper not to be visible before getting its
21871		// correct position
21872		this._mouseDrag( event, true );
21873
21874		// If the ddmanager is used for droppables, inform the manager that dragging has started
21875		// (see #5003)
21876		if ( $.ui.ddmanager ) {
21877			$.ui.ddmanager.dragStart( this, event );
21878		}
21879
21880		return true;
21881	},
21882
21883	_refreshOffsets: function( event ) {
21884		this.offset = {
21885			top: this.positionAbs.top - this.margins.top,
21886			left: this.positionAbs.left - this.margins.left,
21887			scroll: false,
21888			parent: this._getParentOffset(),
21889			relative: this._getRelativeOffset()
21890		};
21891
21892		this.offset.click = {
21893			left: event.pageX - this.offset.left,
21894			top: event.pageY - this.offset.top
21895		};
21896	},
21897
21898	_mouseDrag: function( event, noPropagation ) {
21899
21900		// reset any necessary cached properties (see #5009)
21901		if ( this.hasFixedAncestor ) {
21902			this.offset.parent = this._getParentOffset();
21903		}
21904
21905		//Compute the helpers position
21906		this.position = this._generatePosition( event, true );
21907		this.positionAbs = this._convertPositionTo( "absolute" );
21908
21909		//Call plugins and callbacks and use the resulting position if something is returned
21910		if ( !noPropagation ) {
21911			var ui = this._uiHash();
21912			if ( this._trigger( "drag", event, ui ) === false ) {
21913				this._mouseUp( new $.Event( "mouseup", event ) );
21914				return false;
21915			}
21916			this.position = ui.position;
21917		}
21918
21919		this.helper[ 0 ].style.left = this.position.left + "px";
21920		this.helper[ 0 ].style.top = this.position.top + "px";
21921
21922		if ( $.ui.ddmanager ) {
21923			$.ui.ddmanager.drag( this, event );
21924		}
21925
21926		return false;
21927	},
21928
21929	_mouseStop: function( event ) {
21930
21931		//If we are using droppables, inform the manager about the drop
21932		var that = this,
21933			dropped = false;
21934		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
21935			dropped = $.ui.ddmanager.drop( this, event );
21936		}
21937
21938		//if a drop comes from outside (a sortable)
21939		if ( this.dropped ) {
21940			dropped = this.dropped;
21941			this.dropped = false;
21942		}
21943
21944		if ( ( this.options.revert === "invalid" && !dropped ) ||
21945				( this.options.revert === "valid" && dropped ) ||
21946				this.options.revert === true || ( typeof this.options.revert === "function" &&
21947				this.options.revert.call( this.element, dropped ) )
21948		) {
21949			$( this.helper ).animate(
21950				this.originalPosition,
21951				parseInt( this.options.revertDuration, 10 ),
21952				function() {
21953					if ( that._trigger( "stop", event ) !== false ) {
21954						that._clear();
21955					}
21956				}
21957			);
21958		} else {
21959			if ( this._trigger( "stop", event ) !== false ) {
21960				this._clear();
21961			}
21962		}
21963
21964		return false;
21965	},
21966
21967	_mouseUp: function( event ) {
21968		this._unblockFrames();
21969
21970		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
21971		// (see #5003)
21972		if ( $.ui.ddmanager ) {
21973			$.ui.ddmanager.dragStop( this, event );
21974		}
21975
21976		// Only need to focus if the event occurred on the draggable itself, see #10527
21977		if ( this.handleElement.is( event.target ) ) {
21978
21979			// The interaction is over; whether or not the click resulted in a drag,
21980			// focus the element
21981			this.element.trigger( "focus" );
21982		}
21983
21984		return $.ui.mouse.prototype._mouseUp.call( this, event );
21985	},
21986
21987	cancel: function() {
21988
21989		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
21990			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
21991		} else {
21992			this._clear();
21993		}
21994
21995		return this;
21996
21997	},
21998
21999	_getHandle: function( event ) {
22000		return this.options.handle ?
22001			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
22002			true;
22003	},
22004
22005	_setHandleClassName: function() {
22006		this.handleElement = this.options.handle ?
22007			this.element.find( this.options.handle ) : this.element;
22008		this._addClass( this.handleElement, "ui-draggable-handle" );
22009	},
22010
22011	_removeHandleClassName: function() {
22012		this._removeClass( this.handleElement, "ui-draggable-handle" );
22013	},
22014
22015	_createHelper: function( event ) {
22016
22017		var o = this.options,
22018			helperIsFunction = typeof o.helper === "function",
22019			helper = helperIsFunction ?
22020				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
22021				( o.helper === "clone" ?
22022					this.element.clone().removeAttr( "id" ) :
22023					this.element );
22024
22025		if ( !helper.parents( "body" ).length ) {
22026			helper.appendTo( ( o.appendTo === "parent" ?
22027				this.element[ 0 ].parentNode :
22028				o.appendTo ) );
22029		}
22030
22031		// 
22031Http
vendor: 25,918 bytes, lines 22031-22898
22031://bugs.jqueryui.com/ticket/9446
22032		// a helper function can return the original element
22033		// which wouldn't have been set to relative in _create
22034		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
22035			this._setPositionRelative();
22036		}
22037
22038		if ( helper[ 0 ] !== this.element[ 0 ] &&
22039				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
22040			helper.css( "position", "absolute" );
22041		}
22042
22043		return helper;
22044
22045	},
22046
22047	_setPositionRelative: function() {
22048		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
22049			this.element[ 0 ].style.position = "relative";
22050		}
22051	},
22052
22053	_adjustOffsetFromHelper: function( obj ) {
22054		if ( typeof obj === "string" ) {
22055			obj = obj.split( " " );
22056		}
22057		if ( Array.isArray( obj ) ) {
22058			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
22059		}
22060		if ( "left" in obj ) {
22061			this.offset.click.left = obj.left + this.margins.left;
22062		}
22063		if ( "right" in obj ) {
22064			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
22065		}
22066		if ( "top" in obj ) {
22067			this.offset.click.top = obj.top + this.margins.top;
22068		}
22069		if ( "bottom" in obj ) {
22070			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
22071		}
22072	},
22073
22074	_isRootNode: function( element ) {
22075		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
22076	},
22077
22078	_getParentOffset: function() {
22079
22080		//Get the offsetParent and cache its position
22081		var po = this.offsetParent.offset(),
22082			document = this.document[ 0 ];
22083
22084		// This is a special case where we need to modify a offset calculated on start, since the
22085		// following happened:
22086		// 1. The position of the helper is absolute, so it's position is calculated based on the
22087		// next positioned parent
22088		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
22089		// the document, which means that the scroll is included in the initial calculation of the
22090		// offset of the parent, and never recalculated upon drag
22091		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
22092				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
22093			po.left += this.scrollParent.scrollLeft();
22094			po.top += this.scrollParent.scrollTop();
22095		}
22096
22097		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
22098			po = { top: 0, left: 0 };
22099		}
22100
22101		return {
22102			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
22103			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
22104		};
22105
22106	},
22107
22108	_getRelativeOffset: function() {
22109		if ( this.cssPosition !== "relative" ) {
22110			return { top: 0, left: 0 };
22111		}
22112
22113		var p = this.element.position(),
22114			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
22115
22116		return {
22117			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
22118				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
22119			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
22120				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
22121		};
22122
22123	},
22124
22125	_cacheMargins: function() {
22126		this.margins = {
22127			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
22128			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
22129			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
22130			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
22131		};
22132	},
22133
22134	_cacheHelperProportions: function() {
22135		this.helperProportions = {
22136			width: this.helper.outerWidth(),
22137			height: this.helper.outerHeight()
22138		};
22139	},
22140
22141	_setContainment: function() {
22142
22143		var isUserScrollable, c, ce,
22144			o = this.options,
22145			document = this.document[ 0 ];
22146
22147		this.relativeContainer = null;
22148
22149		if ( !o.containment ) {
22150			this.containment = null;
22151			return;
22152		}
22153
22154		if ( o.containment === "window" ) {
22155			this.containment = [
22156				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
22157				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
22158				$( window ).scrollLeft() + $( window ).width() -
22159					this.helperProportions.width - this.margins.left,
22160				$( window ).scrollTop() +
22161					( $( window ).height() || document.body.parentNode.scrollHeight ) -
22162					this.helperProportions.height - this.margins.top
22163			];
22164			return;
22165		}
22166
22167		if ( o.containment === "document" ) {
22168			this.containment = [
22169				0,
22170				0,
22171				$( document ).width() - this.helperProportions.width - this.margins.left,
22172				( $( document ).height() || document.body.parentNode.scrollHeight ) -
22173					this.helperProportions.height - this.margins.top
22174			];
22175			return;
22176		}
22177
22178		if ( o.containment.constructor === Array ) {
22179			this.containment = o.containment;
22180			return;
22181		}
22182
22183		if ( o.containment === "parent" ) {
22184			o.containment = this.helper[ 0 ].parentNode;
22185		}
22186
22187		c = $( o.containment );
22188		ce = c[ 0 ];
22189
22190		if ( !ce ) {
22191			return;
22192		}
22193
22194		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
22195
22196		this.containment = [
22197			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
22198				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
22199			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
22200				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
22201			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
22202				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
22203				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
22204				this.helperProportions.width -
22205				this.margins.left -
22206				this.margins.right,
22207			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
22208				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
22209				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
22210				this.helperProportions.height -
22211				this.margins.top -
22212				this.margins.bottom
22213		];
22214		this.relativeContainer = c;
22215	},
22216
22217	_convertPositionTo: function( d, pos ) {
22218
22219		if ( !pos ) {
22220			pos = this.position;
22221		}
22222
22223		var mod = d === "absolute" ? 1 : -1,
22224			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
22225
22226		return {
22227			top: (
22228
22229				// The absolute mouse position
22230				pos.top	+
22231
22232				// Only for relative positioned nodes: Relative offset from element to offset parent
22233				this.offset.relative.top * mod +
22234
22235				// The offsetParent's offset without borders (offset + border)
22236				this.offset.parent.top * mod -
22237				( ( this.cssPosition === "fixed" ?
22238					-this.offset.scroll.top :
22239					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
22240			),
22241			left: (
22242
22243				// The absolute mouse position
22244				pos.left +
22245
22246				// Only for relative positioned nodes: Relative offset from element to offset parent
22247				this.offset.relative.left * mod +
22248
22249				// The offsetParent's offset without borders (offset + border)
22250				this.offset.parent.left * mod	-
22251				( ( this.cssPosition === "fixed" ?
22252					-this.offset.scroll.left :
22253					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
22254			)
22255		};
22256
22257	},
22258
22259	_generatePosition: function( event, constrainPosition ) {
22260
22261		var containment, co, top, left,
22262			o = this.options,
22263			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
22264			pageX = event.pageX,
22265			pageY = event.pageY;
22266
22267		// Cache the scroll
22268		if ( !scrollIsRootNode || !this.offset.scroll ) {
22269			this.offset.scroll = {
22270				top: this.scrollParent.scrollTop(),
22271				left: this.scrollParent.scrollLeft()
22272			};
22273		}
22274
22275		/*
22276		 * - Position constraining -
22277		 * Constrain the position to a mix of grid, containment.
22278		 */
22279
22280		// If we are not dragging yet, we won't check for options
22281		if ( constrainPosition ) {
22282			if ( this.containment ) {
22283				if ( this.relativeContainer ) {
22284					co = this.relativeContainer.offset();
22285					containment = [
22286						this.containment[ 0 ] + co.left,
22287						this.containment[ 1 ] + co.top,
22288						this.containment[ 2 ] + co.left,
22289						this.containment[ 3 ] + co.top
22290					];
22291				} else {
22292					containment = this.containment;
22293				}
22294
22295				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
22296					pageX = containment[ 0 ] + this.offset.click.left;
22297				}
22298				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
22299					pageY = containment[ 1 ] + this.offset.click.top;
22300				}
22301				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
22302					pageX = containment[ 2 ] + this.offset.click.left;
22303				}
22304				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
22305					pageY = containment[ 3 ] + this.offset.click.top;
22306				}
22307			}
22308
22309			if ( o.grid ) {
22310
22311				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
22312				// argument errors in IE (see ticket #6950)
22313				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
22314					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
22315				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
22316					top - this.offset.click.top > containment[ 3 ] ) ?
22317						top :
22318						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
22319							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
22320
22321				left = o.grid[ 0 ] ? this.originalPageX +
22322					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
22323					this.originalPageX;
22324				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
22325					left - this.offset.click.left > containment[ 2 ] ) ?
22326						left :
22327						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
22328							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
22329			}
22330
22331			if ( o.axis === "y" ) {
22332				pageX = this.originalPageX;
22333			}
22334
22335			if ( o.axis === "x" ) {
22336				pageY = this.originalPageY;
22337			}
22338		}
22339
22340		return {
22341			top: (
22342
22343				// The absolute mouse position
22344				pageY -
22345
22346				// Click offset (relative to the element)
22347				this.offset.click.top -
22348
22349				// Only for relative positioned nodes: Relative offset from element to offset parent
22350				this.offset.relative.top -
22351
22352				// The offsetParent's offset without borders (offset + border)
22353				this.offset.parent.top +
22354				( this.cssPosition === "fixed" ?
22355					-this.offset.scroll.top :
22356					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
22357			),
22358			left: (
22359
22360				// The absolute mouse position
22361				pageX -
22362
22363				// Click offset (relative to the element)
22364				this.offset.click.left -
22365
22366				// Only for relative positioned nodes: Relative offset from element to offset parent
22367				this.offset.relative.left -
22368
22369				// The offsetParent's offset without borders (offset + border)
22370				this.offset.parent.left +
22371				( this.cssPosition === "fixed" ?
22372					-this.offset.scroll.left :
22373					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
22374			)
22375		};
22376
22377	},
22378
22379	_clear: function() {
22380		this._removeClass( this.helper, "ui-draggable-dragging" );
22381		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
22382			this.helper.remove();
22383		}
22384		this.helper = null;
22385		this.cancelHelperRemoval = false;
22386		if ( this.destroyOnClear ) {
22387			this.destroy();
22388		}
22389	},
22390
22391	// From now on bulk stuff - mainly helpers
22392
22393	_trigger: function( type, event, ui ) {
22394		ui = ui || this._uiHash();
22395		$.ui.plugin.call( this, type, [ event, ui, this ], true );
22396
22397		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
22398		if ( /^(drag|start|stop)/.test( type ) ) {
22399			this.positionAbs = this._convertPositionTo( "absolute" );
22400			ui.offset = this.positionAbs;
22401		}
22402		return $.Widget.prototype._trigger.call( this, type, event, ui );
22403	},
22404
22405	plugins: {},
22406
22407	_uiHash: function() {
22408		return {
22409			helper: this.helper,
22410			position: this.position,
22411			originalPosition: this.originalPosition,
22412			offset: this.positionAbs
22413		};
22414	}
22415
22416} );
22417
22418$.ui.plugin.add( "draggable", "connectToSortable", {
22419	start: function( event, ui, draggable ) {
22420		var uiSortable = $.extend( {}, ui, {
22421			item: draggable.element
22422		} );
22423
22424		draggable.sortables = [];
22425		$( draggable.options.connectToSortable ).each( function() {
22426			var sortable = $( this ).sortable( "instance" );
22427
22428			if ( sortable && !sortable.options.disabled ) {
22429				draggable.sortables.push( sortable );
22430
22431				// RefreshPositions is called at drag start to refresh the containerCache
22432				// which is used in drag. This ensures it's initialized and synchronized
22433				// with any changes that might have happened on the page since initialization.
22434				sortable.refreshPositions();
22435				sortable._trigger( "activate", event, uiSortable );
22436			}
22437		} );
22438	},
22439	stop: function( event, ui, draggable ) {
22440		var uiSortable = $.extend( {}, ui, {
22441			item: draggable.element
22442		} );
22443
22444		draggable.cancelHelperRemoval = false;
22445
22446		$.each( draggable.sortables, function() {
22447			var sortable = this;
22448
22449			if ( sortable.isOver ) {
22450				sortable.isOver = 0;
22451
22452				// Allow this sortable to handle removing the helper
22453				draggable.cancelHelperRemoval = true;
22454				sortable.cancelHelperRemoval = false;
22455
22456				// Use _storedCSS To restore properties in the sortable,
22457				// as this also handles revert (#9675) since the draggable
22458				// may have modified them in unexpected ways (#8809)
22459				sortable._storedCSS = {
22460					position: sortable.placeholder.css( "position" ),
22461					top: sortable.placeholder.css( "top" ),
22462					left: sortable.placeholder.css( "left" )
22463				};
22464
22465				sortable._mouseStop( event );
22466
22467				// Once drag has ended, the sortable should return to using
22468				// its original helper, not the shared helper from draggable
22469				sortable.options.helper = sortable.options._helper;
22470			} else {
22471
22472				// Prevent this Sortable from removing the helper.
22473				// However, don't set the draggable to remove the helper
22474				// either as another connected Sortable may yet handle the removal.
22475				sortable.cancelHelperRemoval = true;
22476
22477				sortable._trigger( "deactivate", event, uiSortable );
22478			}
22479		} );
22480	},
22481	drag: function( event, ui, draggable ) {
22482		$.each( draggable.sortables, function() {
22483			var innermostIntersecting = false,
22484				sortable = this;
22485
22486			// Copy over variables that sortable's _intersectsWith uses
22487			sortable.positionAbs = draggable.positionAbs;
22488			sortable.helperProportions = draggable.helperProportions;
22489			sortable.offset.click = draggable.offset.click;
22490
22491			if ( sortable._intersectsWith( sortable.containerCache ) ) {
22492				innermostIntersecting = true;
22493
22494				$.each( draggable.sortables, function() {
22495
22496					// Copy over variables that sortable's _intersectsWith uses
22497					this.positionAbs = draggable.positionAbs;
22498					this.helperProportions = draggable.helperProportions;
22499					this.offset.click = draggable.offset.click;
22500
22501					if ( this !== sortable &&
22502							this._intersectsWith( this.containerCache ) &&
22503							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
22504						innermostIntersecting = false;
22505					}
22506
22507					return innermostIntersecting;
22508				} );
22509			}
22510
22511			if ( innermostIntersecting ) {
22512
22513				// If it intersects, we use a little isOver variable and set it once,
22514				// so that the move-in stuff gets fired only once.
22515				if ( !sortable.isOver ) {
22516					sortable.isOver = 1;
22517
22518					// Store draggable's parent in case we need to reappend to it later.
22519					draggable._parent = ui.helper.parent();
22520
22521					sortable.currentItem = ui.helper
22522						.appendTo( sortable.element )
22523						.data( "ui-sortable-item", true );
22524
22525					// Store helper option to later restore it
22526					sortable.options._helper = sortable.options.helper;
22527
22528					sortable.options.helper = function() {
22529						return ui.helper[ 0 ];
22530					};
22531
22532					// Fire the start events of the sortable with our passed browser event,
22533					// and our own helper (so it doesn't create a new one)
22534					event.target = sortable.currentItem[ 0 ];
22535					sortable._mouseCapture( event, true );
22536					sortable._mouseStart( event, true, true );
22537
22538					// Because the browser event is way off the new appended portlet,
22539					// modify necessary variables to reflect the changes
22540					sortable.offset.click.top = draggable.offset.click.top;
22541					sortable.offset.click.left = draggable.offset.click.left;
22542					sortable.offset.parent.left -= draggable.offset.parent.left -
22543						sortable.offset.parent.left;
22544					sortable.offset.parent.top -= draggable.offset.parent.top -
22545						sortable.offset.parent.top;
22546
22547					draggable._trigger( "toSortable", event );
22548
22549					// Inform draggable that the helper is in a valid drop zone,
22550					// used solely in the revert option to handle "valid/invalid".
22551					draggable.dropped = sortable.element;
22552
22553					// Need to refreshPositions of all sortables in the case that
22554					// adding to one sortable changes the location of the other sortables (#9675)
22555					$.each( draggable.sortables, function() {
22556						this.refreshPositions();
22557					} );
22558
22559					// Hack so receive/update callbacks work (mostly)
22560					draggable.currentItem = draggable.element;
22561					sortable.fromOutside = draggable;
22562				}
22563
22564				if ( sortable.currentItem ) {
22565					sortable._mouseDrag( event );
22566
22567					// Copy the sortable's position because the draggable's can potentially reflect
22568					// a relative position, while sortable is always absolute, which the dragged
22569					// element has now become. (#8809)
22570					ui.position = sortable.position;
22571				}
22572			} else {
22573
22574				// If it doesn't intersect with the sortable, and it intersected before,
22575				// we fake the drag stop of the sortable, but make sure it doesn't remove
22576				// the helper by using cancelHelperRemoval.
22577				if ( sortable.isOver ) {
22578
22579					sortable.isOver = 0;
22580					sortable.cancelHelperRemoval = true;
22581
22582					// Calling sortable's mouseStop would trigger a revert,
22583					// so revert must be temporarily false until after mouseStop is called.
22584					sortable.options._revert = sortable.options.revert;
22585					sortable.options.revert = false;
22586
22587					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
22588					sortable._mouseStop( event, true );
22589
22590					// Restore sortable behaviors that were modfied
22591					// when the draggable entered the sortable area (#9481)
22592					sortable.options.revert = sortable.options._revert;
22593					sortable.options.helper = sortable.options._helper;
22594
22595					if ( sortable.placeholder ) {
22596						sortable.placeholder.remove();
22597					}
22598
22599					// Restore and recalculate the draggable's offset considering the sortable
22600					// may have modified them in unexpected ways. (#8809, #10669)
22601					ui.helper.appendTo( draggable._parent );
22602					draggable._refreshOffsets( event );
22603					ui.position = draggable._generatePosition( event, true );
22604
22605					draggable._trigger( "fromSortable", event );
22606
22607					// Inform draggable that the helper is no longer in a valid drop zone
22608					draggable.dropped = false;
22609
22610					// Need to refreshPositions of all sortables just in case removing
22611					// from one sortable changes the location of other sortables (#9675)
22612					$.each( draggable.sortables, function() {
22613						this.refreshPositions();
22614					} );
22615				}
22616			}
22617		} );
22618	}
22619} );
22620
22621$.ui.plugin.add( "draggable", "cursor", {
22622	start: function( event, ui, instance ) {
22623		var t = $( "body" ),
22624			o = instance.options;
22625
22626		if ( t.css( "cursor" ) ) {
22627			o._cursor = t.css( "cursor" );
22628		}
22629		t.css( "cursor", o.cursor );
22630	},
22631	stop: function( event, ui, instance ) {
22632		var o = instance.options;
22633		if ( o._cursor ) {
22634			$( "body" ).css( "cursor", o._cursor );
22635		}
22636	}
22637} );
22638
22639$.ui.plugin.add( "draggable", "opacity", {
22640	start: function( event, ui, instance ) {
22641		var t = $( ui.helper ),
22642			o = instance.options;
22643		if ( t.css( "opacity" ) ) {
22644			o._opacity = t.css( "opacity" );
22645		}
22646		t.css( "opacity", o.opacity );
22647	},
22648	stop: function( event, ui, instance ) {
22649		var o = instance.options;
22650		if ( o._opacity ) {
22651			$( ui.helper ).css( "opacity", o._opacity );
22652		}
22653	}
22654} );
22655
22656$.ui.plugin.add( "draggable", "scroll", {
22657	start: function( event, ui, i ) {
22658		if ( !i.scrollParentNotHidden ) {
22659			i.scrollParentNotHidden = i.helper.scrollParent( false );
22660		}
22661
22662		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
22663				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
22664			i.overflowOffset = i.scrollParentNotHidden.offset();
22665		}
22666	},
22667	drag: function( event, ui, i  ) {
22668
22669		var o = i.options,
22670			scrolled = false,
22671			scrollParent = i.scrollParentNotHidden[ 0 ],
22672			document = i.document[ 0 ];
22673
22674		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
22675			if ( !o.axis || o.axis !== "x" ) {
22676				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
22677						o.scrollSensitivity ) {
22678					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
22679				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
22680					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
22681				}
22682			}
22683
22684			if ( !o.axis || o.axis !== "y" ) {
22685				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
22686						o.scrollSensitivity ) {
22687					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
22688				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
22689					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
22690				}
22691			}
22692
22693		} else {
22694
22695			if ( !o.axis || o.axis !== "x" ) {
22696				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
22697					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
22698				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
22699						o.scrollSensitivity ) {
22700					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
22701				}
22702			}
22703
22704			if ( !o.axis || o.axis !== "y" ) {
22705				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
22706					scrolled = $( document ).scrollLeft(
22707						$( document ).scrollLeft() - o.scrollSpeed
22708					);
22709				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
22710						o.scrollSensitivity ) {
22711					scrolled = $( document ).scrollLeft(
22712						$( document ).scrollLeft() + o.scrollSpeed
22713					);
22714				}
22715			}
22716
22717		}
22718
22719		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
22720			$.ui.ddmanager.prepareOffsets( i, event );
22721		}
22722
22723	}
22724} );
22725
22726$.ui.plugin.add( "draggable", "snap", {
22727	start: function( event, ui, i ) {
22728
22729		var o = i.options;
22730
22731		i.snapElements = [];
22732
22733		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
22734			.each( function() {
22735				var $t = $( this ),
22736					$o = $t.offset();
22737				if ( this !== i.element[ 0 ] ) {
22738					i.snapElements.push( {
22739						item: this,
22740						width: $t.outerWidth(), height: $t.outerHeight(),
22741						top: $o.top, left: $o.left
22742					} );
22743				}
22744			} );
22745
22746	},
22747	drag: function( event, ui, inst ) {
22748
22749		var ts, bs, ls, rs, l, r, t, b, i, first,
22750			o = inst.options,
22751			d = o.snapTolerance,
22752			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
22753			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
22754
22755		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
22756
22757			l = inst.snapElements[ i ].left - inst.margins.left;
22758			r = l + inst.snapElements[ i ].width;
22759			t = inst.snapElements[ i ].top - inst.margins.top;
22760			b = t + inst.snapElements[ i ].height;
22761
22762			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
22763					!$.contains( inst.snapElements[ i ].item.ownerDocument,
22764					inst.snapElements[ i ].item ) ) {
22765				if ( inst.snapElements[ i ].snapping ) {
22766					if ( inst.options.snap.release ) {
22767						inst.options.snap.release.call(
22768							inst.element,
22769							event,
22770							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
22771						);
22772					}
22773				}
22774				inst.snapElements[ i ].snapping = false;
22775				continue;
22776			}
22777
22778			if ( o.snapMode !== "inner" ) {
22779				ts = Math.abs( t - y2 ) <= d;
22780				bs = Math.abs( b - y1 ) <= d;
22781				ls = Math.abs( l - x2 ) <= d;
22782				rs = Math.abs( r - x1 ) <= d;
22783				if ( ts ) {
22784					ui.position.top = inst._convertPositionTo( "relative", {
22785						top: t - inst.helperProportions.height,
22786						left: 0
22787					} ).top;
22788				}
22789				if ( bs ) {
22790					ui.position.top = inst._convertPositionTo( "relative", {
22791						top: b,
22792						left: 0
22793					} ).top;
22794				}
22795				if ( ls ) {
22796					ui.position.left = inst._convertPositionTo( "relative", {
22797						top: 0,
22798						left: l - inst.helperProportions.width
22799					} ).left;
22800				}
22801				if ( rs ) {
22802					ui.position.left = inst._convertPositionTo( "relative", {
22803						top: 0,
22804						left: r
22805					} ).left;
22806				}
22807			}
22808
22809			first = ( ts || bs || ls || rs );
22810
22811			if ( o.snapMode !== "outer" ) {
22812				ts = Math.abs( t - y1 ) <= d;
22813				bs = Math.abs( b - y2 ) <= d;
22814				ls = Math.abs( l - x1 ) <= d;
22815				rs = Math.abs( r - x2 ) <= d;
22816				if ( ts ) {
22817					ui.position.top = inst._convertPositionTo( "relative", {
22818						top: t,
22819						left: 0
22820					} ).top;
22821				}
22822				if ( bs ) {
22823					ui.position.top = inst._convertPositionTo( "relative", {
22824						top: b - inst.helperProportions.height,
22825						left: 0
22826					} ).top;
22827				}
22828				if ( ls ) {
22829					ui.position.left = inst._convertPositionTo( "relative", {
22830						top: 0,
22831						left: l
22832					} ).left;
22833				}
22834				if ( rs ) {
22835					ui.position.left = inst._convertPositionTo( "relative", {
22836						top: 0,
22837						left: r - inst.helperProportions.width
22838					} ).left;
22839				}
22840			}
22841
22842			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
22843				if ( inst.options.snap.snap ) {
22844					inst.options.snap.snap.call(
22845						inst.element,
22846						event,
22847						$.extend( inst._uiHash(), {
22848							snapItem: inst.snapElements[ i ].item
22849						} ) );
22850				}
22851			}
22852			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
22853
22854		}
22855
22856	}
22857} );
22858
22859$.ui.plugin.add( "draggable", "stack", {
22860	start: function( event, ui, instance ) {
22861		var min,
22862			o = instance.options,
22863			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
22864				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
22865					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
22866			} );
22867
22868		if ( !group.length ) {
22869			return;
22870		}
22871
22872		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
22873		$( group ).each( function( i ) {
22874			$( this ).css( "zIndex", min + i );
22875		} );
22876		this.css( "zIndex", ( min + group.length ) );
22877	}
22878} );
22879
22880$.ui.plugin.add( "draggable", "zIndex", {
22881	start: function( event, ui, instance ) {
22882		var t = $( ui.helper ),
22883			o = instance.options;
22884
22885		if ( t.css( "zIndex" ) ) {
22886			o._zIndex = t.css( "zIndex" );
22887		}
22888		t.css( "zIndex", o.zIndex );
22889	},
22890	stop: function( event, ui, instance ) {
22891		var o = instance.options;
22892
22893		if ( o._zIndex ) {
22894			$( ui.helper ).css( "zIndex", o._zIndex );
22895		}
22896	}
22897} );
22898
22899return $.ui.draggable;
22900
22901} );
22902
22903
22904
22905
22906
22907
22908/*!
22909 * jQuery UI Resizable 1.13.0
22910 * http://jqueryui.com
22911 *
22912 * Copyright jQuery Foundation and other contributors
22913 * Released under the MIT license.
22914 * http://jquery.org/license
22915 */
22916
22917//>>label: Resizable
22918//>>group: Interactions
22919//>>description: Enables resize functionality for any element.
22920//>>docs: http://api.jqueryui.com/resizable/
22921//>>demos: http://jqueryui.com/resizable/
22922//>>css.structure: ../../themes/base/core.css
22923//>>css.structure: ../../themes/base/resizable.css
22924//>>css.theme: ../../themes/base/theme.css
22925
22926( function( factory ) {
22927	"use strict";
22928
22929	if ( typeof define === "function" && define.amd ) {
22930
22931		// AMD. Register as an anonymous module.
22932		define( [
22933			"jquery",
22934			"./mouse",
22935			"../disable-selection",
22936			"../plugin",
22937			"../version",
22938			"../widget"
22939		], factory );
22940	} else {
22941
22942		// Browser globals
22943		factory( jQuery );
22944	}
22945} )( function( $ ) {
22946"use strict";
22947
22948$.widget( "ui.resizable", $.ui.mouse, {
22949	version: "1.13.0
vendor: 11,739 bytes, lines 22949-23442
22949",
22950	widgetEventPrefix: "resize",
22951	options: {
22952		alsoResize: false,
22953		animate: false,
22954		animateDuration: "slow",
22955		animateEasing: "swing",
22956		aspectRatio: false,
22957		autoHide: false,
22958		classes: {
22959			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
22960		},
22961		containment: false,
22962		ghost: false,
22963		grid: false,
22964		handles: "e,s,se",
22965		helper: false,
22966		maxHeight: null,
22967		maxWidth: null,
22968		minHeight: 10,
22969		minWidth: 10,
22970
22971		// See #7960
22972		zIndex: 90,
22973
22974		// Callbacks
22975		resize: null,
22976		start: null,
22977		stop: null
22978	},
22979
22980	_num: function( value ) {
22981		return parseFloat( value ) || 0;
22982	},
22983
22984	_isNumber: function( value ) {
22985		return !isNaN( parseFloat( value ) );
22986	},
22987
22988	_hasScroll: function( el, a ) {
22989
22990		if ( $( el ).css( "overflow" ) === "hidden" ) {
22991			return false;
22992		}
22993
22994		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
22995			has = false;
22996
22997		if ( el[ scroll ] > 0 ) {
22998			return true;
22999		}
23000
23001		// TODO: determine which cases actually cause this to happen
23002		// if the element doesn't have the scroll set, see if it's possible to
23003		// set the scroll
23004		try {
23005			el[ scroll ] = 1;
23006			has = ( el[ scroll ] > 0 );
23007			el[ scroll ] = 0;
23008		} catch ( e ) {
23009
23010			// `el` might be a string, then setting `scroll` will throw
23011			// an error in strict mode; ignore it.
23012		}
23013		return has;
23014	},
23015
23016	_create: function() {
23017
23018		var margins,
23019			o = this.options,
23020			that = this;
23021		this._addClass( "ui-resizable" );
23022
23023		$.extend( this, {
23024			_aspectRatio: !!( o.aspectRatio ),
23025			aspectRatio: o.aspectRatio,
23026			originalElement: this.element,
23027			_proportionallyResizeElements: [],
23028			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
23029		} );
23030
23031		// Wrap the element if it cannot hold child nodes
23032		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
23033
23034			this.element.wrap(
23035				$( "<div class='ui-wrapper'></div>" ).css( {
23036					overflow: "hidden",
23037					position: this.element.css( "position" ),
23038					width: this.element.outerWidth(),
23039					height: this.element.outerHeight(),
23040					top: this.element.css( "top" ),
23041					left: this.element.css( "left" )
23042				} )
23043			);
23044
23045			this.element = this.element.parent().data(
23046				"ui-resizable", this.element.resizable( "instance" )
23047			);
23048
23049			this.elementIsWrapper = true;
23050
23051			margins = {
23052				marginTop: this.originalElement.css( "marginTop" ),
23053				marginRight: this.originalElement.css( "marginRight" ),
23054				marginBottom: this.originalElement.css( "marginBottom" ),
23055				marginLeft: this.originalElement.css( "marginLeft" )
23056			};
23057
23058			this.element.css( margins );
23059			this.originalElement.css( "margin", 0 );
23060
23061			// support: Safari
23062			// Prevent Safari textarea resize
23063			this.originalResizeStyle = this.originalElement.css( "resize" );
23064			this.originalElement.css( "resize", "none" );
23065
23066			this._proportionallyResizeElements.push( this.originalElement.css( {
23067				position: "static",
23068				zoom: 1,
23069				display: "block"
23070			} ) );
23071
23072			// Support: IE9
23073			// avoid IE jump (hard set the margin)
23074			this.originalElement.css( margins );
23075
23076			this._proportionallyResize();
23077		}
23078
23079		this._setupHandles();
23080
23081		if ( o.autoHide ) {
23082			$( this.element )
23083				.on( "mouseenter", function() {
23084					if ( o.disabled ) {
23085						return;
23086					}
23087					that._removeClass( "ui-resizable-autohide" );
23088					that._handles.show();
23089				} )
23090				.on( "mouseleave", function() {
23091					if ( o.disabled ) {
23092						return;
23093					}
23094					if ( !that.resizing ) {
23095						that._addClass( "ui-resizable-autohide" );
23096						that._handles.hide();
23097					}
23098				} );
23099		}
23100
23101		this._mouseInit();
23102	},
23103
23104	_destroy: function() {
23105
23106		this._mouseDestroy();
23107		this._addedHandles.remove();
23108
23109		var wrapper,
23110			_destroy = function( exp ) {
23111				$( exp )
23112					.removeData( "resizable" )
23113					.removeData( "ui-resizable" )
23114					.off( ".resizable" );
23115			};
23116
23117		// TODO: Unwrap at same DOM position
23118		if ( this.elementIsWrapper ) {
23119			_destroy( this.element );
23120			wrapper = this.element;
23121			this.originalElement.css( {
23122				position: wrapper.css( "position" ),
23123				width: wrapper.outerWidth(),
23124				height: wrapper.outerHeight(),
23125				top: wrapper.css( "top" ),
23126				left: wrapper.css( "left" )
23127			} ).insertAfter( wrapper );
23128			wrapper.remove();
23129		}
23130
23131		this.originalElement.css( "resize", this.originalResizeStyle );
23132		_destroy( this.originalElement );
23133
23134		return this;
23135	},
23136
23137	_setOption: function( key, value ) {
23138		this._super( key, value );
23139
23140		switch ( key ) {
23141		case "handles":
23142			this._removeHandles();
23143			this._setupHandles();
23144			break;
23145		case "aspectRatio":
23146			this._aspectRatio = !!value;
23147			break;
23148		default:
23149			break;
23150		}
23151	},
23152
23153	_setupHandles: function() {
23154		var o = this.options, handle, i, n, hname, axis, that = this;
23155		this.handles = o.handles ||
23156			( !$( ".ui-resizable-handle", this.element ).length ?
23157				"e,s,se" : {
23158					n: ".ui-resizable-n",
23159					e: ".ui-resizable-e",
23160					s: ".ui-resizable-s",
23161					w: ".ui-resizable-w",
23162					se: ".ui-resizable-se",
23163					sw: ".ui-resizable-sw",
23164					ne: ".ui-resizable-ne",
23165					nw: ".ui-resizable-nw"
23166				} );
23167
23168		this._handles = $();
23169		this._addedHandles = $();
23170		if ( this.handles.constructor === String ) {
23171
23172			if ( this.handles === "all" ) {
23173				this.handles = "n,e,s,w,se,sw,ne,nw";
23174			}
23175
23176			n = this.handles.split( "," );
23177			this.handles = {};
23178
23179			for ( i = 0; i < n.length; i++ ) {
23180
23181				handle = String.prototype.trim.call( n[ i ] );
23182				hname = "ui-resizable-" + handle;
23183				axis = $( "<div>" );
23184				this._addClass( axis, "ui-resizable-handle " + hname );
23185
23186				axis.css( { zIndex: o.zIndex } );
23187
23188				this.handles[ handle ] = ".ui-resizable-" + handle;
23189				if ( !this.element.children( this.handles[ handle ] ).length ) {
23190					this.element.append( axis );
23191					this._addedHandles = this._addedHandles.add( axis );
23192				}
23193			}
23194
23195		}
23196
23197		this._renderAxis = function( target ) {
23198
23199			var i, axis, padPos, padWrapper;
23200
23201			target = target || this.element;
23202
23203			for ( i in this.handles ) {
23204
23205				if ( this.handles[ i ].constructor === String ) {
23206					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
23207				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
23208					this.handles[ i ] = $( this.handles[ i ] );
23209					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
23210				}
23211
23212				if ( this.elementIsWrapper &&
23213						this.originalElement[ 0 ]
23214							.nodeName
23215							.match( /^(textarea|input|select|button)$/i ) ) {
23216					axis = $( this.handles[ i ], this.element );
23217
23218					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
23219						axis.outerHeight() :
23220						axis.outerWidth();
23221
23222					padPos = [ "padding",
23223						/ne|nw|n/.test( i ) ? "Top" :
23224						/se|sw|s/.test( i ) ? "Bottom" :
23225						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
23226
23227					target.css( padPos, padWrapper );
23228
23229					this._proportionallyResize();
23230				}
23231
23232				this._handles = this._handles.add( this.handles[ i ] );
23233			}
23234		};
23235
23236		// TODO: make renderAxis a prototype function
23237		this._renderAxis( this.element );
23238
23239		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
23240		this._handles.disableSelection();
23241
23242		this._handles.on( "mouseover", function() {
23243			if ( !that.resizing ) {
23244				if ( this.className ) {
23245					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
23246				}
23247				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
23248			}
23249		} );
23250
23251		if ( o.autoHide ) {
23252			this._handles.hide();
23253			this._addClass( "ui-resizable-autohide" );
23254		}
23255	},
23256
23257	_removeHandles: function() {
23258		this._addedHandles.remove();
23259	},
23260
23261	_mouseCapture: function( event ) {
23262		var i, handle,
23263			capture = false;
23264
23265		for ( i in this.handles ) {
23266			handle = $( this.handles[ i ] )[ 0 ];
23267			if ( handle === event.target || $.contains( handle, event.target ) ) {
23268				capture = true;
23269			}
23270		}
23271
23272		return !this.options.disabled && capture;
23273	},
23274
23275	_mouseStart: function( event ) {
23276
23277		var curleft, curtop, cursor,
23278			o = this.options,
23279			el = this.element;
23280
23281		this.resizing = true;
23282
23283		this._renderProxy();
23284
23285		curleft = this._num( this.helper.css( "left" ) );
23286		curtop = this._num( this.helper.css( "top" ) );
23287
23288		if ( o.containment ) {
23289			curleft += $( o.containment ).scrollLeft() || 0;
23290			curtop += $( o.containment ).scrollTop() || 0;
23291		}
23292
23293		this.offset = this.helper.offset();
23294		this.position = { left: curleft, top: curtop };
23295
23296		this.size = this._helper ? {
23297				width: this.helper.width(),
23298				height: this.helper.height()
23299			} : {
23300				width: el.width(),
23301				height: el.height()
23302			};
23303
23304		this.originalSize = this._helper ? {
23305				width: el.outerWidth(),
23306				height: el.outerHeight()
23307			} : {
23308				width: el.width(),
23309				height: el.height()
23310			};
23311
23312		this.sizeDiff = {
23313			width: el.outerWidth() - el.width(),
23314			height: el.outerHeight() - el.height()
23315		};
23316
23317		this.originalPosition = { left: curleft, top: curtop };
23318		this.originalMousePosition = { left: event.pageX, top: event.pageY };
23319
23320		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
23321			o.aspectRatio :
23322			( ( this.originalSize.width / this.originalSize.height ) || 1 );
23323
23324		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
23325		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
23326
23327		this._addClass( "ui-resizable-resizing" );
23328		this._propagate( "start", event );
23329		return true;
23330	},
23331
23332	_mouseDrag: function( event ) {
23333
23334		var data, props,
23335			smp = this.originalMousePosition,
23336			a = this.axis,
23337			dx = ( event.pageX - smp.left ) || 0,
23338			dy = ( event.pageY - smp.top ) || 0,
23339			trigger = this._change[ a ];
23340
23341		this._updatePrevProperties();
23342
23343		if ( !trigger ) {
23344			return false;
23345		}
23346
23347		data = trigger.apply( this, [ event, dx, dy ] );
23348
23349		this._updateVirtualBoundaries( event.shiftKey );
23350		if ( this._aspectRatio || event.shiftKey ) {
23351			data = this._updateRatio( data, event );
23352		}
23353
23354		data = this._respectSize( data, event );
23355
23356		this._updateCache( data );
23357
23358		this._propagate( "resize", event );
23359
23360		props = this._applyChanges();
23361
23362		if ( !this._helper && this._proportionallyResizeElements.length ) {
23363			this._proportionallyResize();
23364		}
23365
23366		if ( !$.isEmptyObject( props ) ) {
23367			this._updatePrevProperties();
23368			this._trigger( "resize", event, this.ui() );
23369			this._applyChanges();
23370		}
23371
23372		return false;
23373	},
23374
23375	_mouseStop: function( event ) {
23376
23377		this.resizing = false;
23378		var pr, ista, soffseth, soffsetw, s, left, top,
23379			o = this.options, that = this;
23380
23381		if ( this._helper ) {
23382
23383			pr = this._proportionallyResizeElements;
23384			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
23385			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
23386			soffsetw = ista ? 0 : that.sizeDiff.width;
23387
23388			s = {
23389				width: ( that.helper.width()  - soffsetw ),
23390				height: ( that.helper.height() - soffseth )
23391			};
23392			left = ( parseFloat( that.element.css( "left" ) ) +
23393				( that.position.left - that.originalPosition.left ) ) || null;
23394			top = ( parseFloat( that.element.css( "top" ) ) +
23395				( that.position.top - that.originalPosition.top ) ) || null;
23396
23397			if ( !o.animate ) {
23398				this.element.css( $.extend( s, { top: top, left: left } ) );
23399			}
23400
23401			that.helper.height( that.size.height );
23402			that.helper.width( that.size.width );
23403
23404			if ( this._helper && !o.animate ) {
23405				this._proportionallyResize();
23406			}
23407		}
23408
23409		$( "body" ).css( "cursor", "auto" );
23410
23411		this._removeClass( "ui-resizable-resizing" );
23412
23413		this._propagate( "stop", event );
23414
23415		if ( this._helper ) {
23416			this.helper.remove();
23417		}
23418
23419		return false;
23420
23421	},
23422
23423	_updatePrevProperties: function() {
23424		this.prevPosition = {
23425			top: this.position.top,
23426			left: this.position.left
23427		};
23428		this.prevSize = {
23429			width: this.size.width,
23430			height: this.size.height
23431		};
23432	},
23433
23434	_applyChanges: function() {
23435		var props = {};
23436
23437		if ( this.position.top !== this.prevPosition.top ) {
23438			props.top = this.position.top + "px";
23439		}
23440		if ( this.position.left !== this.prevPosition.left ) {
23441			props.left = this.position.left + "px";
23442		}
vendor: 9,533 bytes, lines 23443-23810
23443		if ( this.size.width !== this.prevSize.width ) {
23444			props.width = this.size.width + "px";
23445		}
23446		if ( this.size.height !== this.prevSize.height ) {
23447			props.height = this.size.height + "px";
23448		}
23449
23450		this.helper.css( props );
23451
23452		return props;
23453	},
23454
23455	_updateVirtualBoundaries: function( forceAspectRatio ) {
23456		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
23457			o = this.options;
23458
23459		b = {
23460			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
23461			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
23462			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
23463			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
23464		};
23465
23466		if ( this._aspectRatio || forceAspectRatio ) {
23467			pMinWidth = b.minHeight * this.aspectRatio;
23468			pMinHeight = b.minWidth / this.aspectRatio;
23469			pMaxWidth = b.maxHeight * this.aspectRatio;
23470			pMaxHeight = b.maxWidth / this.aspectRatio;
23471
23472			if ( pMinWidth > b.minWidth ) {
23473				b.minWidth = pMinWidth;
23474			}
23475			if ( pMinHeight > b.minHeight ) {
23476				b.minHeight = pMinHeight;
23477			}
23478			if ( pMaxWidth < b.maxWidth ) {
23479				b.maxWidth = pMaxWidth;
23480			}
23481			if ( pMaxHeight < b.maxHeight ) {
23482				b.maxHeight = pMaxHeight;
23483			}
23484		}
23485		this._vBoundaries = b;
23486	},
23487
23488	_updateCache: function( data ) {
23489		this.offset = this.helper.offset();
23490		if ( this._isNumber( data.left ) ) {
23491			this.position.left = data.left;
23492		}
23493		if ( this._isNumber( data.top ) ) {
23494			this.position.top = data.top;
23495		}
23496		if ( this._isNumber( data.height ) ) {
23497			this.size.height = data.height;
23498		}
23499		if ( this._isNumber( data.width ) ) {
23500			this.size.width = data.width;
23501		}
23502	},
23503
23504	_updateRatio: function( data ) {
23505
23506		var cpos = this.position,
23507			csize = this.size,
23508			a = this.axis;
23509
23510		if ( this._isNumber( data.height ) ) {
23511			data.width = ( data.height * this.aspectRatio );
23512		} else if ( this._isNumber( data.width ) ) {
23513			data.height = ( data.width / this.aspectRatio );
23514		}
23515
23516		if ( a === "sw" ) {
23517			data.left = cpos.left + ( csize.width - data.width );
23518			data.top = null;
23519		}
23520		if ( a === "nw" ) {
23521			data.top = cpos.top + ( csize.height - data.height );
23522			data.left = cpos.left + ( csize.width - data.width );
23523		}
23524
23525		return data;
23526	},
23527
23528	_respectSize: function( data ) {
23529
23530		var o = this._vBoundaries,
23531			a = this.axis,
23532			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
23533			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
23534			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
23535			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
23536			dw = this.originalPosition.left + this.originalSize.width,
23537			dh = this.originalPosition.top + this.originalSize.height,
23538			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
23539		if ( isminw ) {
23540			data.width = o.minWidth;
23541		}
23542		if ( isminh ) {
23543			data.height = o.minHeight;
23544		}
23545		if ( ismaxw ) {
23546			data.width = o.maxWidth;
23547		}
23548		if ( ismaxh ) {
23549			data.height = o.maxHeight;
23550		}
23551
23552		if ( isminw && cw ) {
23553			data.left = dw - o.minWidth;
23554		}
23555		if ( ismaxw && cw ) {
23556			data.left = dw - o.maxWidth;
23557		}
23558		if ( isminh && ch ) {
23559			data.top = dh - o.minHeight;
23560		}
23561		if ( ismaxh && ch ) {
23562			data.top = dh - o.maxHeight;
23563		}
23564
23565		// Fixing jump error on top/left - bug #2330
23566		if ( !data.width && !data.height && !data.left && data.top ) {
23567			data.top = null;
23568		} else if ( !data.width && !data.height && !data.top && data.left ) {
23569			data.left = null;
23570		}
23571
23572		return data;
23573	},
23574
23575	_getPaddingPlusBorderDimensions: function( element ) {
23576		var i = 0,
23577			widths = [],
23578			borders = [
23579				element.css( "borderTopWidth" ),
23580				element.css( "borderRightWidth" ),
23581				element.css( "borderBottomWidth" ),
23582				element.css( "borderLeftWidth" )
23583			],
23584			paddings = [
23585				element.css( "paddingTop" ),
23586				element.css( "paddingRight" ),
23587				element.css( "paddingBottom" ),
23588				element.css( "paddingLeft" )
23589			];
23590
23591		for ( ; i < 4; i++ ) {
23592			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
23593			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
23594		}
23595
23596		return {
23597			height: widths[ 0 ] + widths[ 2 ],
23598			width: widths[ 1 ] + widths[ 3 ]
23599		};
23600	},
23601
23602	_proportionallyResize: function() {
23603
23604		if ( !this._proportionallyResizeElements.length ) {
23605			return;
23606		}
23607
23608		var prel,
23609			i = 0,
23610			element = this.helper || this.element;
23611
23612		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
23613
23614			prel = this._proportionallyResizeElements[ i ];
23615
23616			// TODO: Seems like a bug to cache this.outerDimensions
23617			// considering that we are in a loop.
23618			if ( !this.outerDimensions ) {
23619				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
23620			}
23621
23622			prel.css( {
23623				height: ( element.height() - this.outerDimensions.height ) || 0,
23624				width: ( element.width() - this.outerDimensions.width ) || 0
23625			} );
23626
23627		}
23628
23629	},
23630
23631	_renderProxy: function() {
23632
23633		var el = this.element, o = this.options;
23634		this.elementOffset = el.offset();
23635
23636		if ( this._helper ) {
23637
23638			this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
23639
23640			this._addClass( this.helper, this._helper );
23641			this.helper.css( {
23642				width: this.element.outerWidth(),
23643				height: this.element.outerHeight(),
23644				position: "absolute",
23645				left: this.elementOffset.left + "px",
23646				top: this.elementOffset.top + "px",
23647				zIndex: ++o.zIndex //TODO: Don't modify option
23648			} );
23649
23650			this.helper
23651				.appendTo( "body" )
23652				.disableSelection();
23653
23654		} else {
23655			this.helper = this.element;
23656		}
23657
23658	},
23659
23660	_change: {
23661		e: function( event, dx ) {
23662			return { width: this.originalSize.width + dx };
23663		},
23664		w: function( event, dx ) {
23665			var cs = this.originalSize, sp = this.originalPosition;
23666			return { left: sp.left + dx, width: cs.width - dx };
23667		},
23668		n: function( event, dx, dy ) {
23669			var cs = this.originalSize, sp = this.originalPosition;
23670			return { top: sp.top + dy, height: cs.height - dy };
23671		},
23672		s: function( event, dx, dy ) {
23673			return { height: this.originalSize.height + dy };
23674		},
23675		se: function( event, dx, dy ) {
23676			return $.extend( this._change.s.apply( this, arguments ),
23677				this._change.e.apply( this, [ event, dx, dy ] ) );
23678		},
23679		sw: function( event, dx, dy ) {
23680			return $.extend( this._change.s.apply( this, arguments ),
23681				this._change.w.apply( this, [ event, dx, dy ] ) );
23682		},
23683		ne: function( event, dx, dy ) {
23684			return $.extend( this._change.n.apply( this, arguments ),
23685				this._change.e.apply( this, [ event, dx, dy ] ) );
23686		},
23687		nw: function( event, dx, dy ) {
23688			return $.extend( this._change.n.apply( this, arguments ),
23689				this._change.w.apply( this, [ event, dx, dy ] ) );
23690		}
23691	},
23692
23693	_propagate: function( n, event ) {
23694		$.ui.plugin.call( this, n, [ event, this.ui() ] );
23695		if ( n !== "resize" ) {
23696			this._trigger( n, event, this.ui() );
23697		}
23698	},
23699
23700	plugins: {},
23701
23702	ui: function() {
23703		return {
23704			originalElement: this.originalElement,
23705			element: this.element,
23706			helper: this.helper,
23707			position: this.position,
23708			size: this.size,
23709			originalSize: this.originalSize,
23710			originalPosition: this.originalPosition
23711		};
23712	}
23713
23714} );
23715
23716/*
23717 * Resizable Extensions
23718 */
23719
23720$.ui.plugin.add( "resizable", "animate", {
23721
23722	stop: function( event ) {
23723		var that = $( this ).resizable( "instance" ),
23724			o = that.options,
23725			pr = that._proportionallyResizeElements,
23726			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
23727			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
23728			soffsetw = ista ? 0 : that.sizeDiff.width,
23729			style = {
23730				width: ( that.size.width - soffsetw ),
23731				height: ( that.size.height - soffseth )
23732			},
23733			left = ( parseFloat( that.element.css( "left" ) ) +
23734				( that.position.left - that.originalPosition.left ) ) || null,
23735			top = ( parseFloat( that.element.css( "top" ) ) +
23736				( that.position.top - that.originalPosition.top ) ) || null;
23737
23738		that.element.animate(
23739			$.extend( style, top && left ? { top: top, left: left } : {} ), {
23740				duration: o.animateDuration,
23741				easing: o.animateEasing,
23742				step: function() {
23743
23744					var data = {
23745						width: parseFloat( that.element.css( "width" ) ),
23746						height: parseFloat( that.element.css( "height" ) ),
23747						top: parseFloat( that.element.css( "top" ) ),
23748						left: parseFloat( that.element.css( "left" ) )
23749					};
23750
23751					if ( pr && pr.length ) {
23752						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
23753					}
23754
23755					// Propagating resize, and updating values for each animation step
23756					that._updateCache( data );
23757					that._propagate( "resize", event );
23758
23759				}
23760			}
23761		);
23762	}
23763
23764} );
23765
23766$.ui.plugin.add( "resizable", "containment", {
23767
23768	start: function() {
23769		var element, p, co, ch, cw, width, height,
23770			that = $( this ).resizable( "instance" ),
23771			o = that.options,
23772			el = that.element,
23773			oc = o.containment,
23774			ce = ( oc instanceof $ ) ?
23775				oc.get( 0 ) :
23776				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
23777
23778		if ( !ce ) {
23779			return;
23780		}
23781
23782		that.containerElement = $( ce );
23783
23784		if ( /document/.test( oc ) || oc === document ) {
23785			that.containerOffset = {
23786				left: 0,
23787				top: 0
23788			};
23789			that.containerPosition = {
23790				left: 0,
23791				top: 0
23792			};
23793
23794			that.parentData = {
23795				element: $( document ),
23796				left: 0,
23797				top: 0,
23798				width: $( document ).width(),
23799				height: $( document ).height() || document.body.parentNode.scrollHeight
23800			};
23801		} else {
23802			element = $( ce );
23803			p = [];
23804			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
23805				p[ i ] = that._num( element.css( "padding" + name ) );
23806			} );
23807
23808			that.containerOffset = element.offset();
23809			that.containerPosition = element.position();
23810			that.containerSize = {
vendor: 5,871 bytes, lines 23811-24035
23811				height: ( element.innerHeight() - p[ 3 ] ),
23812				width: ( element.innerWidth() - p[ 1 ] )
23813			};
23814
23815			co = that.containerOffset;
23816			ch = that.containerSize.height;
23817			cw = that.containerSize.width;
23818			width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
23819			height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
23820
23821			that.parentData = {
23822				element: ce,
23823				left: co.left,
23824				top: co.top,
23825				width: width,
23826				height: height
23827			};
23828		}
23829	},
23830
23831	resize: function( event ) {
23832		var woset, hoset, isParent, isOffsetRelative,
23833			that = $( this ).resizable( "instance" ),
23834			o = that.options,
23835			co = that.containerOffset,
23836			cp = that.position,
23837			pRatio = that._aspectRatio || event.shiftKey,
23838			cop = {
23839				top: 0,
23840				left: 0
23841			},
23842			ce = that.containerElement,
23843			continueResize = true;
23844
23845		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
23846			cop = co;
23847		}
23848
23849		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
23850			that.size.width = that.size.width +
23851				( that._helper ?
23852					( that.position.left - co.left ) :
23853					( that.position.left - cop.left ) );
23854
23855			if ( pRatio ) {
23856				that.size.height = that.size.width / that.aspectRatio;
23857				continueResize = false;
23858			}
23859			that.position.left = o.helper ? co.left : 0;
23860		}
23861
23862		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
23863			that.size.height = that.size.height +
23864				( that._helper ?
23865					( that.position.top - co.top ) :
23866					that.position.top );
23867
23868			if ( pRatio ) {
23869				that.size.width = that.size.height * that.aspectRatio;
23870				continueResize = false;
23871			}
23872			that.position.top = that._helper ? co.top : 0;
23873		}
23874
23875		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
23876		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
23877
23878		if ( isParent && isOffsetRelative ) {
23879			that.offset.left = that.parentData.left + that.position.left;
23880			that.offset.top = that.parentData.top + that.position.top;
23881		} else {
23882			that.offset.left = that.element.offset().left;
23883			that.offset.top = that.element.offset().top;
23884		}
23885
23886		woset = Math.abs( that.sizeDiff.width +
23887			( that._helper ?
23888				that.offset.left - cop.left :
23889				( that.offset.left - co.left ) ) );
23890
23891		hoset = Math.abs( that.sizeDiff.height +
23892			( that._helper ?
23893				that.offset.top - cop.top :
23894				( that.offset.top - co.top ) ) );
23895
23896		if ( woset + that.size.width >= that.parentData.width ) {
23897			that.size.width = that.parentData.width - woset;
23898			if ( pRatio ) {
23899				that.size.height = that.size.width / that.aspectRatio;
23900				continueResize = false;
23901			}
23902		}
23903
23904		if ( hoset + that.size.height >= that.parentData.height ) {
23905			that.size.height = that.parentData.height - hoset;
23906			if ( pRatio ) {
23907				that.size.width = that.size.height * that.aspectRatio;
23908				continueResize = false;
23909			}
23910		}
23911
23912		if ( !continueResize ) {
23913			that.position.left = that.prevPosition.left;
23914			that.position.top = that.prevPosition.top;
23915			that.size.width = that.prevSize.width;
23916			that.size.height = that.prevSize.height;
23917		}
23918	},
23919
23920	stop: function() {
23921		var that = $( this ).resizable( "instance" ),
23922			o = that.options,
23923			co = that.containerOffset,
23924			cop = that.containerPosition,
23925			ce = that.containerElement,
23926			helper = $( that.helper ),
23927			ho = helper.offset(),
23928			w = helper.outerWidth() - that.sizeDiff.width,
23929			h = helper.outerHeight() - that.sizeDiff.height;
23930
23931		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
23932			$( this ).css( {
23933				left: ho.left - cop.left - co.left,
23934				width: w,
23935				height: h
23936			} );
23937		}
23938
23939		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
23940			$( this ).css( {
23941				left: ho.left - cop.left - co.left,
23942				width: w,
23943				height: h
23944			} );
23945		}
23946	}
23947} );
23948
23949$.ui.plugin.add( "resizable", "alsoResize", {
23950
23951	start: function() {
23952		var that = $( this ).resizable( "instance" ),
23953			o = that.options;
23954
23955		$( o.alsoResize ).each( function() {
23956			var el = $( this );
23957			el.data( "ui-resizable-alsoresize", {
23958				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
23959				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
23960			} );
23961		} );
23962	},
23963
23964	resize: function( event, ui ) {
23965		var that = $( this ).resizable( "instance" ),
23966			o = that.options,
23967			os = that.originalSize,
23968			op = that.originalPosition,
23969			delta = {
23970				height: ( that.size.height - os.height ) || 0,
23971				width: ( that.size.width - os.width ) || 0,
23972				top: ( that.position.top - op.top ) || 0,
23973				left: ( that.position.left - op.left ) || 0
23974			};
23975
23976			$( o.alsoResize ).each( function() {
23977				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
23978					css = el.parents( ui.originalElement[ 0 ] ).length ?
23979							[ "width", "height" ] :
23980							[ "width", "height", "top", "left" ];
23981
23982				$.each( css, function( i, prop ) {
23983					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
23984					if ( sum && sum >= 0 ) {
23985						style[ prop ] = sum || null;
23986					}
23987				} );
23988
23989				el.css( style );
23990			} );
23991	},
23992
23993	stop: function() {
23994		$( this ).removeData( "ui-resizable-alsoresize" );
23995	}
23996} );
23997
23998$.ui.plugin.add( "resizable", "ghost", {
23999
24000	start: function() {
24001
24002		var that = $( this ).resizable( "instance" ), cs = that.size;
24003
24004		that.ghost = that.originalElement.clone();
24005		that.ghost.css( {
24006			opacity: 0.25,
24007			display: "block",
24008			position: "relative",
24009			height: cs.height,
24010			width: cs.width,
24011			margin: 0,
24012			left: 0,
24013			top: 0
24014		} );
24015
24016		that._addClass( that.ghost, "ui-resizable-ghost" );
24017
24018		// DEPRECATED
24019		// TODO: remove after 1.12
24020		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
24021
24022			// Ghost option
24023			that.ghost.addClass( this.options.ghost );
24024		}
24025
24026		that.ghost.appendTo( that.helper );
24027
24028	},
24029
24030	resize: function() {
24031		var that = $( this ).resizable( "instance" );
24032		if ( that.ghost ) {
24033			that.ghost.css( {
24034				position: "relative",
24035				height: that.size.height,
vendor: 3,370 bytes, lines 24036-24190
24036				width: that.size.width
24037			} );
24038		}
24039	},
24040
24041	stop: function() {
24042		var that = $( this ).resizable( "instance" );
24043		if ( that.ghost && that.helper ) {
24044			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
24045		}
24046	}
24047
24048} );
24049
24050$.ui.plugin.add( "resizable", "grid", {
24051
24052	resize: function() {
24053		var outerDimensions,
24054			that = $( this ).resizable( "instance" ),
24055			o = that.options,
24056			cs = that.size,
24057			os = that.originalSize,
24058			op = that.originalPosition,
24059			a = that.axis,
24060			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
24061			gridX = ( grid[ 0 ] || 1 ),
24062			gridY = ( grid[ 1 ] || 1 ),
24063			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
24064			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
24065			newWidth = os.width + ox,
24066			newHeight = os.height + oy,
24067			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
24068			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
24069			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
24070			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
24071
24072		o.grid = grid;
24073
24074		if ( isMinWidth ) {
24075			newWidth += gridX;
24076		}
24077		if ( isMinHeight ) {
24078			newHeight += gridY;
24079		}
24080		if ( isMaxWidth ) {
24081			newWidth -= gridX;
24082		}
24083		if ( isMaxHeight ) {
24084			newHeight -= gridY;
24085		}
24086
24087		if ( /^(se|s|e)$/.test( a ) ) {
24088			that.size.width = newWidth;
24089			that.size.height = newHeight;
24090		} else if ( /^(ne)$/.test( a ) ) {
24091			that.size.width = newWidth;
24092			that.size.height = newHeight;
24093			that.position.top = op.top - oy;
24094		} else if ( /^(sw)$/.test( a ) ) {
24095			that.size.width = newWidth;
24096			that.size.height = newHeight;
24097			that.position.left = op.left - ox;
24098		} else {
24099			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
24100				outerDimensions = that._getPaddingPlusBorderDimensions( this );
24101			}
24102
24103			if ( newHeight - gridY > 0 ) {
24104				that.size.height = newHeight;
24105				that.position.top = op.top - oy;
24106			} else {
24107				newHeight = gridY - outerDimensions.height;
24108				that.size.height = newHeight;
24109				that.position.top = op.top + os.height - newHeight;
24110			}
24111			if ( newWidth - gridX > 0 ) {
24112				that.size.width = newWidth;
24113				that.position.left = op.left - ox;
24114			} else {
24115				newWidth = gridX - outerDimensions.width;
24116				that.size.width = newWidth;
24117				that.position.left = op.left + os.width - newWidth;
24118			}
24119		}
24120	}
24121
24122} );
24123
24124return $.ui.resizable;
24125
24126} );
24127
24128
24129
24130
24131
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141/*!
24142 * jQuery UI Dialog 1.13.0
24143 * http://jqueryui.com
24144 *
24145 * Copyright jQuery Foundation and other contributors
24146 * Released under the MIT license.
24147 * http://jquery.org/license
24148 */
24149
24150//>>label: Dialog
24151//>>group: Widgets
24152//>>description: Displays customizable dialog windows.
24153//>>docs: http://api.jqueryui.com/dialog/
24154//>>demos: http://jqueryui.com/dialog/
24155//>>css.structure: ../../themes/base/core.css
24156//>>css.structure: ../../themes/base/dialog.css
24157//>>css.theme: ../../themes/base/theme.css
24158
24159( function( factory ) {
24160	"use strict";
24161
24162	if ( typeof define === "function" && define.amd ) {
24163
24164		// AMD. Register as an anonymous module.
24165		define( [
24166			"jquery",
24167			"./button",
24168			"./draggable",
24169			"./mouse",
24170			"./resizable",
24171			"../focusable",
24172			"../keycode",
24173			"../position",
24174			"../safe-active-element",
24175			"../safe-blur",
24176			"../tabbable",
24177			"../unique-id",
24178			"../version",
24179			"../widget"
24180		], factory );
24181	} else {
24182
24183		// Browser globals
24184		factory( jQuery );
24185	}
24186} )( function( $ ) {
24187"use strict";
24188
24189$.widget( "ui.dialog", {
24190	version: "1.13.0
vendor: 20,928 bytes, lines 24190-25024
24190",
24191	options: {
24192		appendTo: "body",
24193		autoOpen: true,
24194		buttons: [],
24195		classes: {
24196			"ui-dialog": "ui-corner-all",
24197			"ui-dialog-titlebar": "ui-corner-all"
24198		},
24199		closeOnEscape: true,
24200		closeText: "Close",
24201		draggable: true,
24202		hide: null,
24203		height: "auto",
24204		maxHeight: null,
24205		maxWidth: null,
24206		minHeight: 150,
24207		minWidth: 150,
24208		modal: false,
24209		position: {
24210			my: "center",
24211			at: "center",
24212			of: window,
24213			collision: "fit",
24214
24215			// Ensure the titlebar is always visible
24216			using: function( pos ) {
24217				var topOffset = $( this ).css( pos ).offset().top;
24218				if ( topOffset < 0 ) {
24219					$( this ).css( "top", pos.top - topOffset );
24220				}
24221			}
24222		},
24223		resizable: true,
24224		show: null,
24225		title: null,
24226		width: 300,
24227
24228		// Callbacks
24229		beforeClose: null,
24230		close: null,
24231		drag: null,
24232		dragStart: null,
24233		dragStop: null,
24234		focus: null,
24235		open: null,
24236		resize: null,
24237		resizeStart: null,
24238		resizeStop: null
24239	},
24240
24241	sizeRelatedOptions: {
24242		buttons: true,
24243		height: true,
24244		maxHeight: true,
24245		maxWidth: true,
24246		minHeight: true,
24247		minWidth: true,
24248		width: true
24249	},
24250
24251	resizableRelatedOptions: {
24252		maxHeight: true,
24253		maxWidth: true,
24254		minHeight: true,
24255		minWidth: true
24256	},
24257
24258	_create: function() {
24259		this.originalCss = {
24260			display: this.element[ 0 ].style.display,
24261			width: this.element[ 0 ].style.width,
24262			minHeight: this.element[ 0 ].style.minHeight,
24263			maxHeight: this.element[ 0 ].style.maxHeight,
24264			height: this.element[ 0 ].style.height
24265		};
24266		this.originalPosition = {
24267			parent: this.element.parent(),
24268			index: this.element.parent().children().index( this.element )
24269		};
24270		this.originalTitle = this.element.attr( "title" );
24271		if ( this.options.title == null && this.originalTitle != null ) {
24272			this.options.title = this.originalTitle;
24273		}
24274
24275		// Dialogs can't be disabled
24276		if ( this.options.disabled ) {
24277			this.options.disabled = false;
24278		}
24279
24280		this._createWrapper();
24281
24282		this.element
24283			.show()
24284			.removeAttr( "title" )
24285			.appendTo( this.uiDialog );
24286
24287		this._addClass( "ui-dialog-content", "ui-widget-content" );
24288
24289		this._createTitlebar();
24290		this._createButtonPane();
24291
24292		if ( this.options.draggable && $.fn.draggable ) {
24293			this._makeDraggable();
24294		}
24295		if ( this.options.resizable && $.fn.resizable ) {
24296			this._makeResizable();
24297		}
24298
24299		this._isOpen = false;
24300
24301		this._trackFocus();
24302	},
24303
24304	_init: function() {
24305		if ( this.options.autoOpen ) {
24306			this.open();
24307		}
24308	},
24309
24310	_appendTo: function() {
24311		var element = this.options.appendTo;
24312		if ( element && ( element.jquery || element.nodeType ) ) {
24313			return $( element );
24314		}
24315		return this.document.find( element || "body" ).eq( 0 );
24316	},
24317
24318	_destroy: function() {
24319		var next,
24320			originalPosition = this.originalPosition;
24321
24322		this._untrackInstance();
24323		this._destroyOverlay();
24324
24325		this.element
24326			.removeUniqueId()
24327			.css( this.originalCss )
24328
24329			// Without detaching first, the following becomes really slow
24330			.detach();
24331
24332		this.uiDialog.remove();
24333
24334		if ( this.originalTitle ) {
24335			this.element.attr( "title", this.originalTitle );
24336		}
24337
24338		next = originalPosition.parent.children().eq( originalPosition.index );
24339
24340		// Don't try to place the dialog next to itself (#8613)
24341		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
24342			next.before( this.element );
24343		} else {
24344			originalPosition.parent.append( this.element );
24345		}
24346	},
24347
24348	widget: function() {
24349		return this.uiDialog;
24350	},
24351
24352	disable: $.noop,
24353	enable: $.noop,
24354
24355	close: function( event ) {
24356		var that = this;
24357
24358		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
24359			return;
24360		}
24361
24362		this._isOpen = false;
24363		this._focusedElement = null;
24364		this._destroyOverlay();
24365		this._untrackInstance();
24366
24367		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
24368
24369			// Hiding a focused element doesn't trigger blur in WebKit
24370			// so in case we have nothing to focus on, explicitly blur the active element
24371			// https://bugs.webkit.org/show_bug.cgi?id=47182
24372			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
24373		}
24374
24375		this._hide( this.uiDialog, this.options.hide, function() {
24376			that._trigger( "close", event );
24377		} );
24378	},
24379
24380	isOpen: function() {
24381		return this._isOpen;
24382	},
24383
24384	moveToTop: function() {
24385		this._moveToTop();
24386	},
24387
24388	_moveToTop: function( event, silent ) {
24389		var moved = false,
24390			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
24391				return +$( this ).css( "z-index" );
24392			} ).get(),
24393			zIndexMax = Math.max.apply( null, zIndices );
24394
24395		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
24396			this.uiDialog.css( "z-index", zIndexMax + 1 );
24397			moved = true;
24398		}
24399
24400		if ( moved && !silent ) {
24401			this._trigger( "focus", event );
24402		}
24403		return moved;
24404	},
24405
24406	open: function() {
24407		var that = this;
24408		if ( this._isOpen ) {
24409			if ( this._moveToTop() ) {
24410				this._focusTabbable();
24411			}
24412			return;
24413		}
24414
24415		this._isOpen = true;
24416		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
24417
24418		this._size();
24419		this._position();
24420		this._createOverlay();
24421		this._moveToTop( null, true );
24422
24423		// Ensure the overlay is moved to the top with the dialog, but only when
24424		// opening. The overlay shouldn't move after the dialog is open so that
24425		// modeless dialogs opened after the modal dialog stack properly.
24426		if ( this.overlay ) {
24427			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
24428		}
24429
24430		this._show( this.uiDialog, this.options.show, function() {
24431			that._focusTabbable();
24432			that._trigger( "focus" );
24433		} );
24434
24435		// Track the dialog immediately upon opening in case a focus event
24436		// somehow occurs outside of the dialog before an element inside the
24437		// dialog is focused (#10152)
24438		this._makeFocusTarget();
24439
24440		this._trigger( "open" );
24441	},
24442
24443	_focusTabbable: function() {
24444
24445		// Set focus to the first match:
24446		// 1. An element that was focused previously
24447		// 2. First element inside the dialog matching [autofocus]
24448		// 3. Tabbable element inside the content element
24449		// 4. Tabbable element inside the buttonpane
24450		// 5. The close button
24451		// 6. The dialog itself
24452		var hasFocus = this._focusedElement;
24453		if ( !hasFocus ) {
24454			hasFocus = this.element.find( "[autofocus]" );
24455		}
24456		if ( !hasFocus.length ) {
24457			hasFocus = this.element.find( ":tabbable" );
24458		}
24459		if ( !hasFocus.length ) {
24460			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
24461		}
24462		if ( !hasFocus.length ) {
24463			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
24464		}
24465		if ( !hasFocus.length ) {
24466			hasFocus = this.uiDialog;
24467		}
24468		hasFocus.eq( 0 ).trigger( "focus" );
24469	},
24470
24471	_restoreTabbableFocus: function() {
24472		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
24473			isActive = this.uiDialog[ 0 ] === activeElement ||
24474				$.contains( this.uiDialog[ 0 ], activeElement );
24475		if ( !isActive ) {
24476			this._focusTabbable();
24477		}
24478	},
24479
24480	_keepFocus: function( event ) {
24481		event.preventDefault();
24482		this._restoreTabbableFocus();
24483
24484		// support: IE
24485		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
24486		// so we check again later
24487		this._delay( this._restoreTabbableFocus );
24488	},
24489
24490	_createWrapper: function() {
24491		this.uiDialog = $( "<div>" )
24492			.hide()
24493			.attr( {
24494
24495				// Setting tabIndex makes the div focusable
24496				tabIndex: -1,
24497				role: "dialog"
24498			} )
24499			.appendTo( this._appendTo() );
24500
24501		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
24502		this._on( this.uiDialog, {
24503			keydown: function( event ) {
24504				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
24505						event.keyCode === $.ui.keyCode.ESCAPE ) {
24506					event.preventDefault();
24507					this.close( event );
24508					return;
24509				}
24510
24511				// Prevent tabbing out of dialogs
24512				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
24513					return;
24514				}
24515				var tabbables = this.uiDialog.find( ":tabbable" ),
24516					first = tabbables.first(),
24517					last = tabbables.last();
24518
24519				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
24520						!event.shiftKey ) {
24521					this._delay( function() {
24522						first.trigger( "focus" );
24523					} );
24524					event.preventDefault();
24525				} else if ( ( event.target === first[ 0 ] ||
24526						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
24527					this._delay( function() {
24528						last.trigger( "focus" );
24529					} );
24530					event.preventDefault();
24531				}
24532			},
24533			mousedown: function( event ) {
24534				if ( this._moveToTop( event ) ) {
24535					this._focusTabbable();
24536				}
24537			}
24538		} );
24539
24540		// We assume that any existing aria-describedby attribute means
24541		// that the dialog content is marked up properly
24542		// otherwise we brute force the content as the description
24543		if ( !this.element.find( "[aria-describedby]" ).length ) {
24544			this.uiDialog.attr( {
24545				"aria-describedby": this.element.uniqueId().attr( "id" )
24546			} );
24547		}
24548	},
24549
24550	_createTitlebar: function() {
24551		var uiDialogTitle;
24552
24553		this.uiDialogTitlebar = $( "<div>" );
24554		this._addClass( this.uiDialogTitlebar,
24555			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
24556		this._on( this.uiDialogTitlebar, {
24557			mousedown: function( event ) {
24558
24559				// Don't prevent click on close button (#8838)
24560				// Focusing a dialog that is partially scrolled out of view
24561				// causes the browser to scroll it into view, preventing the click event
24562				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
24563
24564					// Dialog isn't getting focus when dragging (#8063)
24565					this.uiDialog.trigger( "focus" );
24566				}
24567			}
24568		} );
24569
24570		// Support: IE
24571		// Use type="button" to prevent enter keypresses in textboxes from closing the
24572		// dialog in IE (#9312)
24573		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
24574			.button( {
24575				label: $( "<a>" ).text( this.options.closeText ).html(),
24576				icon: "ui-icon-closethick",
24577				showLabel: false
24578			} )
24579			.appendTo( this.uiDialogTitlebar );
24580
24581		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
24582		this._on( this.uiDialogTitlebarClose, {
24583			click: function( event ) {
24584				event.preventDefault();
24585				this.close( event );
24586			}
24587		} );
24588
24589		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
24590		this._addClass( uiDialogTitle, "ui-dialog-title" );
24591		this._title( uiDialogTitle );
24592
24593		this.uiDialogTitlebar.prependTo( this.uiDialog );
24594
24595		this.uiDialog.attr( {
24596			"aria-labelledby": uiDialogTitle.attr( "id" )
24597		} );
24598	},
24599
24600	_title: function( title ) {
24601		if ( this.options.title ) {
24602			title.text( this.options.title );
24603		} else {
24604			title.html( "&#160;" );
24605		}
24606	},
24607
24608	_createButtonPane: function() {
24609		this.uiDialogButtonPane = $( "<div>" );
24610		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
24611			"ui-widget-content ui-helper-clearfix" );
24612
24613		this.uiButtonSet = $( "<div>" )
24614			.appendTo( this.uiDialogButtonPane );
24615		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
24616
24617		this._createButtons();
24618	},
24619
24620	_createButtons: function() {
24621		var that = this,
24622			buttons = this.options.buttons;
24623
24624		// If we already have a button pane, remove it
24625		this.uiDialogButtonPane.remove();
24626		this.uiButtonSet.empty();
24627
24628		if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
24629			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
24630			return;
24631		}
24632
24633		$.each( buttons, function( name, props ) {
24634			var click, buttonOptions;
24635			props = typeof props === "function" ?
24636				{ click: props, text: name } :
24637				props;
24638
24639			// Default to a non-submitting button
24640			props = $.extend( { type: "button" }, props );
24641
24642			// Change the context for the click callback to be the main element
24643			click = props.click;
24644			buttonOptions = {
24645				icon: props.icon,
24646				iconPosition: props.iconPosition,
24647				showLabel: props.showLabel,
24648
24649				// Deprecated options
24650				icons: props.icons,
24651				text: props.text
24652			};
24653
24654			delete props.click;
24655			delete props.icon;
24656			delete props.iconPosition;
24657			delete props.showLabel;
24658
24659			// Deprecated options
24660			delete props.icons;
24661			if ( typeof props.text === "boolean" ) {
24662				delete props.text;
24663			}
24664
24665			$( "<button></button>", props )
24666				.button( buttonOptions )
24667				.appendTo( that.uiButtonSet )
24668				.on( "click", function() {
24669					click.apply( that.element[ 0 ], arguments );
24670				} );
24671		} );
24672		this._addClass( this.uiDialog, "ui-dialog-buttons" );
24673		this.uiDialogButtonPane.appendTo( this.uiDialog );
24674	},
24675
24676	_makeDraggable: function() {
24677		var that = this,
24678			options = this.options;
24679
24680		function filteredUi( ui ) {
24681			return {
24682				position: ui.position,
24683				offset: ui.offset
24684			};
24685		}
24686
24687		this.uiDialog.draggable( {
24688			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
24689			handle: ".ui-dialog-titlebar",
24690			containment: "document",
24691			start: function( event, ui ) {
24692				that._addClass( $( this ), "ui-dialog-dragging" );
24693				that._blockFrames();
24694				that._trigger( "dragStart", event, filteredUi( ui ) );
24695			},
24696			drag: function( event, ui ) {
24697				that._trigger( "drag", event, filteredUi( ui ) );
24698			},
24699			stop: function( event, ui ) {
24700				var left = ui.offset.left - that.document.scrollLeft(),
24701					top = ui.offset.top - that.document.scrollTop();
24702
24703				options.position = {
24704					my: "left top",
24705					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
24706						"top" + ( top >= 0 ? "+" : "" ) + top,
24707					of: that.window
24708				};
24709				that._removeClass( $( this ), "ui-dialog-dragging" );
24710				that._unblockFrames();
24711				that._trigger( "dragStop", event, filteredUi( ui ) );
24712			}
24713		} );
24714	},
24715
24716	_makeResizable: function() {
24717		var that = this,
24718			options = this.options,
24719			handles = options.resizable,
24720
24721			// .ui-resizable has position: relative defined in the stylesheet
24722			// but dialogs have to use absolute or fixed positioning
24723			position = this.uiDialog.css( "position" ),
24724			resizeHandles = typeof handles === "string" ?
24725				handles :
24726				"n,e,s,w,se,sw,ne,nw";
24727
24728		function filteredUi( ui ) {
24729			return {
24730				originalPosition: ui.originalPosition,
24731				originalSize: ui.originalSize,
24732				position: ui.position,
24733				size: ui.size
24734			};
24735		}
24736
24737		this.uiDialog.resizable( {
24738			cancel: ".ui-dialog-content",
24739			containment: "document",
24740			alsoResize: this.element,
24741			maxWidth: options.maxWidth,
24742			maxHeight: options.maxHeight,
24743			minWidth: options.minWidth,
24744			minHeight: this._minHeight(),
24745			handles: resizeHandles,
24746			start: function( event, ui ) {
24747				that._addClass( $( this ), "ui-dialog-resizing" );
24748				that._blockFrames();
24749				that._trigger( "resizeStart", event, filteredUi( ui ) );
24750			},
24751			resize: function( event, ui ) {
24752				that._trigger( "resize", event, filteredUi( ui ) );
24753			},
24754			stop: function( event, ui ) {
24755				var offset = that.uiDialog.offset(),
24756					left = offset.left - that.document.scrollLeft(),
24757					top = offset.top - that.document.scrollTop();
24758
24759				options.height = that.uiDialog.height();
24760				options.width = that.uiDialog.width();
24761				options.position = {
24762					my: "left top",
24763					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
24764						"top" + ( top >= 0 ? "+" : "" ) + top,
24765					of: that.window
24766				};
24767				that._removeClass( $( this ), "ui-dialog-resizing" );
24768				that._unblockFrames();
24769				that._trigger( "resizeStop", event, filteredUi( ui ) );
24770			}
24771		} )
24772			.css( "position", position );
24773	},
24774
24775	_trackFocus: function() {
24776		this._on( this.widget(), {
24777			focusin: function( event ) {
24778				this._makeFocusTarget();
24779				this._focusedElement = $( event.target );
24780			}
24781		} );
24782	},
24783
24784	_makeFocusTarget: function() {
24785		this._untrackInstance();
24786		this._trackingInstances().unshift( this );
24787	},
24788
24789	_untrackInstance: function() {
24790		var instances = this._trackingInstances(),
24791			exists = $.inArray( this, instances );
24792		if ( exists !== -1 ) {
24793			instances.splice( exists, 1 );
24794		}
24795	},
24796
24797	_trackingInstances: function() {
24798		var instances = this.document.data( "ui-dialog-instances" );
24799		if ( !instances ) {
24800			instances = [];
24801			this.document.data( "ui-dialog-instances", instances );
24802		}
24803		return instances;
24804	},
24805
24806	_minHeight: function() {
24807		var options = this.options;
24808
24809		return options.height === "auto" ?
24810			options.minHeight :
24811			Math.min( options.minHeight, options.height );
24812	},
24813
24814	_position: function() {
24815
24816		// Need to show the dialog to get the actual offset in the position plugin
24817		var isVisible = this.uiDialog.is( ":visible" );
24818		if ( !isVisible ) {
24819			this.uiDialog.show();
24820		}
24821		this.uiDialog.position( this.options.position );
24822		if ( !isVisible ) {
24823			this.uiDialog.hide();
24824		}
24825	},
24826
24827	_setOptions: function( options ) {
24828		var that = this,
24829			resize = false,
24830			resizableOptions = {};
24831
24832		$.each( options, function( key, value ) {
24833			that._setOption( key, value );
24834
24835			if ( key in that.sizeRelatedOptions ) {
24836				resize = true;
24837			}
24838			if ( key in that.resizableRelatedOptions ) {
24839				resizableOptions[ key ] = value;
24840			}
24841		} );
24842
24843		if ( resize ) {
24844			this._size();
24845			this._position();
24846		}
24847		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
24848			this.uiDialog.resizable( "option", resizableOptions );
24849		}
24850	},
24851
24852	_setOption: function( key, value ) {
24853		var isDraggable, isResizable,
24854			uiDialog = this.uiDialog;
24855
24856		if ( key === "disabled" ) {
24857			return;
24858		}
24859
24860		this._super( key, value );
24861
24862		if ( key === "appendTo" ) {
24863			this.uiDialog.appendTo( this._appendTo() );
24864		}
24865
24866		if ( key === "buttons" ) {
24867			this._createButtons();
24868		}
24869
24870		if ( key === "closeText" ) {
24871			this.uiDialogTitlebarClose.button( {
24872
24873				// Ensure that we always pass a string
24874				label: $( "<a>" ).text( "" + this.options.closeText ).html()
24875			} );
24876		}
24877
24878		if ( key === "draggable" ) {
24879			isDraggable = uiDialog.is( ":data(ui-draggable)" );
24880			if ( isDraggable && !value ) {
24881				uiDialog.draggable( "destroy" );
24882			}
24883
24884			if ( !isDraggable && value ) {
24885				this._makeDraggable();
24886			}
24887		}
24888
24889		if ( key === "position" ) {
24890			this._position();
24891		}
24892
24893		if ( key === "resizable" ) {
24894
24895			// currently resizable, becoming non-resizable
24896			isResizable = uiDialog.is( ":data(ui-resizable)" );
24897			if ( isResizable && !value ) {
24898				uiDialog.resizable( "destroy" );
24899			}
24900
24901			// Currently resizable, changing handles
24902			if ( isResizable && typeof value === "string" ) {
24903				uiDialog.resizable( "option", "handles", value );
24904			}
24905
24906			// Currently non-resizable, becoming resizable
24907			if ( !isResizable && value !== false ) {
24908				this._makeResizable();
24909			}
24910		}
24911
24912		if ( key === "title" ) {
24913			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
24914		}
24915	},
24916
24917	_size: function() {
24918
24919		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
24920		// divs will both have width and height set, so we need to reset them
24921		var nonContentHeight, minContentHeight, maxContentHeight,
24922			options = this.options;
24923
24924		// Reset content sizing
24925		this.element.show().css( {
24926			width: "auto",
24927			minHeight: 0,
24928			maxHeight: "none",
24929			height: 0
24930		} );
24931
24932		if ( options.minWidth > options.width ) {
24933			options.width = options.minWidth;
24934		}
24935
24936		// Reset wrapper sizing
24937		// determine the height of all the non-content elements
24938		nonContentHeight = this.uiDialog.css( {
24939			height: "auto",
24940			width: options.width
24941		} )
24942			.outerHeight();
24943		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
24944		maxContentHeight = typeof options.maxHeight === "number" ?
24945			Math.max( 0, options.maxHeight - nonContentHeight ) :
24946			"none";
24947
24948		if ( options.height === "auto" ) {
24949			this.element.css( {
24950				minHeight: minContentHeight,
24951				maxHeight: maxContentHeight,
24952				height: "auto"
24953			} );
24954		} else {
24955			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
24956		}
24957
24958		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
24959			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
24960		}
24961	},
24962
24963	_blockFrames: function() {
24964		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
24965			var iframe = $( this );
24966
24967			return $( "<div>" )
24968				.css( {
24969					position: "absolute",
24970					width: iframe.outerWidth(),
24971					height: iframe.outerHeight()
24972				} )
24973				.appendTo( iframe.parent() )
24974				.offset( iframe.offset() )[ 0 ];
24975		} );
24976	},
24977
24978	_unblockFrames: function() {
24979		if ( this.iframeBlocks ) {
24980			this.iframeBlocks.remove();
24981			delete this.iframeBlocks;
24982		}
24983	},
24984
24985	_allowInteraction: function( event ) {
24986		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
24987			return true;
24988		}
24989
24990		// TODO: Remove hack when datepicker implements
24991		// the .ui-front logic (#8989)
24992		return !!$( event.target ).closest( ".ui-datepicker" ).length;
24993	},
24994
24995	_createOverlay: function() {
24996		if ( !this.options.modal ) {
24997			return;
24998		}
24999
25000		var jqMinor = $.fn.jquery.substring( 0, 4 );
25001
25002		// We use a delay in case the overlay is created from an
25003		// event that we're going to be cancelling (#2804)
25004		var isOpening = true;
25005		this._delay( function() {
25006			isOpening = false;
25007		} );
25008
25009		if ( !this.document.data( "ui-dialog-overlays" ) ) {
25010
25011			// Prevent use of anchors and inputs
25012			// This doesn't use `_on()` because it is a shared event handler
25013			// across all open modal dialogs.
25014			this.document.on( "focusin.ui-dialog", function( event ) {
25015				if ( isOpening ) {
25016					return;
25017				}
25018
25019				var instance = this._trackingInstances()[ 0 ];
25020				if ( !instance._allowInteraction( event ) ) {
25021					event.preventDefault();
25022					instance._focusTabbable();
25023
25024					// Support: jQuery >=3.4 <3.
250246 only
25025					// Focus re-triggering in jQuery 3.4/3.5 makes the original element
25026					// have its focus event propagated last, breaking the re-targeting.
25027					// Trigger focus in a delay in addition if needed to avoid the issue
25028					// See https://github.com/jquery/jquery/issues/4382
25029					if ( jqMinor === "3.4." || jqMinor === "3.5." ) {
25030						instance._delay( instance._restoreTabbableFocus );
25031					}
25032				}
25033			}.bind( this ) );
25034		}
25035
25036		this.overlay = $( "<div>" )
25037			.appendTo( this._appendTo() );
25038
25039		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
25040		this._on( this.overlay, {
25041			mousedown: "_keepFocus"
25042		} );
25043		this.document.data( "ui-dialog-overlays",
25044			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
25045	},
25046
25047	_destroyOverlay: function() {
25048		if ( !this.options.modal ) {
25049			return;
25050		}
25051
25052		if ( this.overlay ) {
25053			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
25054
25055			if ( !overlays ) {
25056				this.document.off( "focusin.ui-dialog" );
25057				this.document.removeData( "ui-dialog-overlays" );
25058			} else {
25059				this.document.data( "ui-dialog-overlays", overlays );
25060			}
25061
25062			this.overlay.remove();
25063			this.overlay = null;
25064		}
25065	}
25066} );
25067
25068// DEPRECATED
25069// TODO: switch return back to widget declaration at top of file when this is removed
25070if ( $.uiBackCompat !== false ) {
25071
25072	// Backcompat for dialogClass option
25073	$.widget( "ui.dialog", $.ui.dialog, {
25074		options: {
25075			dialogClass: ""
25076		},
25077		_createWrapper: function() {
25078			this._super();
25079			this.uiDialog.addClass( this.options.dialogClass );
25080		},
25081		_setOption: function( key, value ) {
25082			if ( key === "dialogClass" ) {
25083				this.uiDialog
25084					.removeClass( this.options.dialogClass )
25085					.addClass( value );
25086			}
25087			this._superApply( arguments );
25088		}
25089	} );
25090}
25091
25092return $.ui.dialog;
25093
25094} );
25095
25096
25097
25098
25099
25100/*!
25101 * jQuery UI Droppable 1.13.0
25102 * http://jqueryui.com
25103 *
25104 * Copyright jQuery Foundation and other contributors
25105 * Released under the MIT license.
25106 * http://jquery.org/license
25107 */
25108
25109//>>label: Droppable
25110//>>group: Interactions
25111//>>description: Enables drop targets for draggable elements.
25112//>>docs: http://api.jqueryui.com/droppable/
25113//>>demos: http://jqueryui.com/droppable/
25114
25115( function( factory ) {
25116	"use strict";
25117
25118	if ( typeof define === "function" && define.amd ) {
25119
25120		// AMD. Register as an anonymous module.
25121		define( [
25122			"jquery",
25123			"./draggable",
25124			"./mouse",
25125			"../version",
25126			"../widget"
25127		], factory );
25128	} else {
25129
25130		// Browser globals
25131		factory( jQuery );
25132	}
25133} )( function( $ ) {
25134"use strict";
25135
25136$.widget( "ui.droppable", {
25137	version: "1.13.0
vendor: 11,311 bytes, lines 25137-25565
25137",
25138	widgetEventPrefix: "drop",
25139	options: {
25140		accept: "*",
25141		addClasses: true,
25142		greedy: false,
25143		scope: "default",
25144		tolerance: "intersect",
25145
25146		// Callbacks
25147		activate: null,
25148		deactivate: null,
25149		drop: null,
25150		out: null,
25151		over: null
25152	},
25153	_create: function() {
25154
25155		var proportions,
25156			o = this.options,
25157			accept = o.accept;
25158
25159		this.isover = false;
25160		this.isout = true;
25161
25162		this.accept = typeof accept === "function" ? accept : function( d ) {
25163			return d.is( accept );
25164		};
25165
25166		this.proportions = function( /* valueToWrite */ ) {
25167			if ( arguments.length ) {
25168
25169				// Store the droppable's proportions
25170				proportions = arguments[ 0 ];
25171			} else {
25172
25173				// Retrieve or derive the droppable's proportions
25174				return proportions ?
25175					proportions :
25176					proportions = {
25177						width: this.element[ 0 ].offsetWidth,
25178						height: this.element[ 0 ].offsetHeight
25179					};
25180			}
25181		};
25182
25183		this._addToManager( o.scope );
25184
25185		if ( o.addClasses ) {
25186			this._addClass( "ui-droppable" );
25187		}
25188
25189	},
25190
25191	_addToManager: function( scope ) {
25192
25193		// Add the reference and positions to the manager
25194		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
25195		$.ui.ddmanager.droppables[ scope ].push( this );
25196	},
25197
25198	_splice: function( drop ) {
25199		var i = 0;
25200		for ( ; i < drop.length; i++ ) {
25201			if ( drop[ i ] === this ) {
25202				drop.splice( i, 1 );
25203			}
25204		}
25205	},
25206
25207	_destroy: function() {
25208		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25209
25210		this._splice( drop );
25211	},
25212
25213	_setOption: function( key, value ) {
25214
25215		if ( key === "accept" ) {
25216			this.accept = typeof value === "function" ? value : function( d ) {
25217				return d.is( value );
25218			};
25219		} else if ( key === "scope" ) {
25220			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
25221
25222			this._splice( drop );
25223			this._addToManager( value );
25224		}
25225
25226		this._super( key, value );
25227	},
25228
25229	_activate: function( event ) {
25230		var draggable = $.ui.ddmanager.current;
25231
25232		this._addActiveClass();
25233		if ( draggable ) {
25234			this._trigger( "activate", event, this.ui( draggable ) );
25235		}
25236	},
25237
25238	_deactivate: function( event ) {
25239		var draggable = $.ui.ddmanager.current;
25240
25241		this._removeActiveClass();
25242		if ( draggable ) {
25243			this._trigger( "deactivate", event, this.ui( draggable ) );
25244		}
25245	},
25246
25247	_over: function( event ) {
25248
25249		var draggable = $.ui.ddmanager.current;
25250
25251		// Bail if draggable and droppable are same element
25252		if ( !draggable || ( draggable.currentItem ||
25253				draggable.element )[ 0 ] === this.element[ 0 ] ) {
25254			return;
25255		}
25256
25257		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
25258				draggable.element ) ) ) {
25259			this._addHoverClass();
25260			this._trigger( "over", event, this.ui( draggable ) );
25261		}
25262
25263	},
25264
25265	_out: function( event ) {
25266
25267		var draggable = $.ui.ddmanager.current;
25268
25269		// Bail if draggable and droppable are same element
25270		if ( !draggable || ( draggable.currentItem ||
25271				draggable.element )[ 0 ] === this.element[ 0 ] ) {
25272			return;
25273		}
25274
25275		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
25276				draggable.element ) ) ) {
25277			this._removeHoverClass();
25278			this._trigger( "out", event, this.ui( draggable ) );
25279		}
25280
25281	},
25282
25283	_drop: function( event, custom ) {
25284
25285		var draggable = custom || $.ui.ddmanager.current,
25286			childrenIntersection = false;
25287
25288		// Bail if draggable and droppable are same element
25289		if ( !draggable || ( draggable.currentItem ||
25290				draggable.element )[ 0 ] === this.element[ 0 ] ) {
25291			return false;
25292		}
25293
25294		this.element
25295			.find( ":data(ui-droppable)" )
25296			.not( ".ui-draggable-dragging" )
25297			.each( function() {
25298				var inst = $( this ).droppable( "instance" );
25299				if (
25300					inst.options.greedy &&
25301					!inst.options.disabled &&
25302					inst.options.scope === draggable.options.scope &&
25303					inst.accept.call(
25304						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
25305					) &&
25306					$.ui.intersect(
25307						draggable,
25308						$.extend( inst, { offset: inst.element.offset() } ),
25309						inst.options.tolerance, event
25310					)
25311				) {
25312					childrenIntersection = true;
25313					return false;
25314				}
25315			} );
25316		if ( childrenIntersection ) {
25317			return false;
25318		}
25319
25320		if ( this.accept.call( this.element[ 0 ],
25321				( draggable.currentItem || draggable.element ) ) ) {
25322			this._removeActiveClass();
25323			this._removeHoverClass();
25324
25325			this._trigger( "drop", event, this.ui( draggable ) );
25326			return this.element;
25327		}
25328
25329		return false;
25330
25331	},
25332
25333	ui: function( c ) {
25334		return {
25335			draggable: ( c.currentItem || c.element ),
25336			helper: c.helper,
25337			position: c.position,
25338			offset: c.positionAbs
25339		};
25340	},
25341
25342	// Extension points just to make backcompat sane and avoid duplicating logic
25343	// TODO: Remove in 1.14 along with call to it below
25344	_addHoverClass: function() {
25345		this._addClass( "ui-droppable-hover" );
25346	},
25347
25348	_removeHoverClass: function() {
25349		this._removeClass( "ui-droppable-hover" );
25350	},
25351
25352	_addActiveClass: function() {
25353		this._addClass( "ui-droppable-active" );
25354	},
25355
25356	_removeActiveClass: function() {
25357		this._removeClass( "ui-droppable-active" );
25358	}
25359} );
25360
25361$.ui.intersect = ( function() {
25362	function isOverAxis( x, reference, size ) {
25363		return ( x >= reference ) && ( x < ( reference + size ) );
25364	}
25365
25366	return function( draggable, droppable, toleranceMode, event ) {
25367
25368		if ( !droppable.offset ) {
25369			return false;
25370		}
25371
25372		var x1 = ( draggable.positionAbs ||
25373				draggable.position.absolute ).left + draggable.margins.left,
25374			y1 = ( draggable.positionAbs ||
25375				draggable.position.absolute ).top + draggable.margins.top,
25376			x2 = x1 + draggable.helperProportions.width,
25377			y2 = y1 + draggable.helperProportions.height,
25378			l = droppable.offset.left,
25379			t = droppable.offset.top,
25380			r = l + droppable.proportions().width,
25381			b = t + droppable.proportions().height;
25382
25383		switch ( toleranceMode ) {
25384		case "fit":
25385			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
25386		case "intersect":
25387			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
25388				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
25389				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
25390				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
25391		case "pointer":
25392			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
25393				isOverAxis( event.pageX, l, droppable.proportions().width );
25394		case "touch":
25395			return (
25396				( y1 >= t && y1 <= b ) || // Top edge touching
25397				( y2 >= t && y2 <= b ) || // Bottom edge touching
25398				( y1 < t && y2 > b ) // Surrounded vertically
25399			) && (
25400				( x1 >= l && x1 <= r ) || // Left edge touching
25401				( x2 >= l && x2 <= r ) || // Right edge touching
25402				( x1 < l && x2 > r ) // Surrounded horizontally
25403			);
25404		default:
25405			return false;
25406		}
25407	};
25408} )();
25409
25410/*
25411	This manager tracks offsets of draggables and droppables
25412*/
25413$.ui.ddmanager = {
25414	current: null,
25415	droppables: { "default": [] },
25416	prepareOffsets: function( t, event ) {
25417
25418		var i, j,
25419			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
25420			type = event ? event.type : null, // workaround for #2317
25421			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
25422
25423		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
25424
25425			// No disabled and non-accepted
25426			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
25427					( t.currentItem || t.element ) ) ) ) {
25428				continue;
25429			}
25430
25431			// Filter out elements in the current dragged item
25432			for ( j = 0; j < list.length; j++ ) {
25433				if ( list[ j ] === m[ i ].element[ 0 ] ) {
25434					m[ i ].proportions().height = 0;
25435					continue droppablesLoop;
25436				}
25437			}
25438
25439			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
25440			if ( !m[ i ].visible ) {
25441				continue;
25442			}
25443
25444			// Activate the droppable if used directly from draggables
25445			if ( type === "mousedown" ) {
25446				m[ i ]._activate.call( m[ i ], event );
25447			}
25448
25449			m[ i ].offset = m[ i ].element.offset();
25450			m[ i ].proportions( {
25451				width: m[ i ].element[ 0 ].offsetWidth,
25452				height: m[ i ].element[ 0 ].offsetHeight
25453			} );
25454
25455		}
25456
25457	},
25458	drop: function( draggable, event ) {
25459
25460		var dropped = false;
25461
25462		// Create a copy of the droppables in case the list changes during the drop (#9116)
25463		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
25464
25465			if ( !this.options ) {
25466				return;
25467			}
25468			if ( !this.options.disabled && this.visible &&
25469					$.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
25470				dropped = this._drop.call( this, event ) || dropped;
25471			}
25472
25473			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
25474					( draggable.currentItem || draggable.element ) ) ) {
25475				this.isout = true;
25476				this.isover = false;
25477				this._deactivate.call( this, event );
25478			}
25479
25480		} );
25481		return dropped;
25482
25483	},
25484	dragStart: function( draggable, event ) {
25485
25486		// Listen for scrolling so that if the dragging causes scrolling the position of the
25487		// droppables can be recalculated (see #5003)
25488		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
25489			if ( !draggable.options.refreshPositions ) {
25490				$.ui.ddmanager.prepareOffsets( draggable, event );
25491			}
25492		} );
25493	},
25494	drag: function( draggable, event ) {
25495
25496		// If you have a highly dynamic page, you might try this option. It renders positions
25497		// every time you move the mouse.
25498		if ( draggable.options.refreshPositions ) {
25499			$.ui.ddmanager.prepareOffsets( draggable, event );
25500		}
25501
25502		// Run through all droppables and check their positions based on specific tolerance options
25503		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
25504
25505			if ( this.options.disabled || this.greedyChild || !this.visible ) {
25506				return;
25507			}
25508
25509			var parentInstance, scope, parent,
25510				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
25511				c = !intersects && this.isover ?
25512					"isout" :
25513					( intersects && !this.isover ? "isover" : null );
25514			if ( !c ) {
25515				return;
25516			}
25517
25518			if ( this.options.greedy ) {
25519
25520				// find droppable parents with same scope
25521				scope = this.options.scope;
25522				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
25523					return $( this ).droppable( "instance" ).options.scope === scope;
25524				} );
25525
25526				if ( parent.length ) {
25527					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
25528					parentInstance.greedyChild = ( c === "isover" );
25529				}
25530			}
25531
25532			// We just moved into a greedy child
25533			if ( parentInstance && c === "isover" ) {
25534				parentInstance.isover = false;
25535				parentInstance.isout = true;
25536				parentInstance._out.call( parentInstance, event );
25537			}
25538
25539			this[ c ] = true;
25540			this[ c === "isout" ? "isover" : "isout" ] = false;
25541			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
25542
25543			// We just moved out of a greedy child
25544			if ( parentInstance && c === "isout" ) {
25545				parentInstance.isout = false;
25546				parentInstance.isover = true;
25547				parentInstance._over.call( parentInstance, event );
25548			}
25549		} );
25550
25551	},
25552	dragStop: function( draggable, event ) {
25553		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
25554
25555		// Call prepareOffsets one final time since IE does not fire return scroll events when
25556		// overflow was caused by drag (see #5003)
25557		if ( !draggable.options.refreshPositions ) {
25558			$.ui.ddmanager.prepareOffsets( draggable, event );
25559		}
25560	}
25561};
25562
25563// DEPRECATED
25564// TODO: switch return back to widget declaration at top of file when this is removed
25565if ( $.uiBackCompat 
25565!== false ) {
25566
25567	// Backcompat for activeClass and hoverClass options
25568	$.widget( "ui.droppable", $.ui.droppable, {
25569		options: {
25570			hoverClass: false,
25571			activeClass: false
25572		},
25573		_addActiveClass: function() {
25574			this._super();
25575			if ( this.options.activeClass ) {
25576				this.element.addClass( this.options.activeClass );
25577			}
25578		},
25579		_removeActiveClass: function() {
25580			this._super();
25581			if ( this.options.activeClass ) {
25582				this.element.removeClass( this.options.activeClass );
25583			}
25584		},
25585		_addHoverClass: function() {
25586			this._super();
25587			if ( this.options.hoverClass ) {
25588				this.element.addClass( this.options.hoverClass );
25589			}
25590		},
25591		_removeHoverClass: function() {
25592			this._super();
25593			if ( this.options.hoverClass ) {
25594				this.element.removeClass( this.options.hoverClass );
25595			}
25596		}
25597	} );
25598}
25599
25600return $.ui.droppable;
25601
25602} );
25603
25604
25605
25606/*!
25607 * jQuery UI Progressbar 1.13.0
25608 * http://jqueryui.com
25609 *
25610 * Copyright jQuery Foundation and other contributors
25611 * Released under the MIT license.
25612 * http://jquery.org/license
25613 */
25614
25615//>>label: Progressbar
25616//>>group: Widgets
25617/* eslint-disable max-len */
25618//>>
vendor: 4,806 bytes, lines 25618-25828
25618description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
25619/* eslint-enable max-len */
25620//>>docs: http://api.jqueryui.com/progressbar/
25621//>>demos: http://jqueryui.com/progressbar/
25622//>>css.structure: ../../themes/base/core.css
25623//>>css.structure: ../../themes/base/progressbar.css
25624//>>css.theme: ../../themes/base/theme.css
25625
25626( function( factory ) {
25627	"use strict";
25628
25629	if ( typeof define === "function" && define.amd ) {
25630
25631		// AMD. Register as an anonymous module.
25632		define( [
25633			"jquery",
25634			"../version",
25635			"../widget"
25636		], factory );
25637	} else {
25638
25639		// Browser globals
25640		factory( jQuery );
25641	}
25642} )( function( $ ) {
25643"use strict";
25644
25645return $.widget( "ui.progressbar", {
25646	version: "1.13.0",
25647	options: {
25648		classes: {
25649			"ui-progressbar": "ui-corner-all",
25650			"ui-progressbar-value": "ui-corner-left",
25651			"ui-progressbar-complete": "ui-corner-right"
25652		},
25653		max: 100,
25654		value: 0,
25655
25656		change: null,
25657		complete: null
25658	},
25659
25660	min: 0,
25661
25662	_create: function() {
25663
25664		// Constrain initial value
25665		this.oldValue = this.options.value = this._constrainedValue();
25666
25667		this.element.attr( {
25668
25669			// Only set static values; aria-valuenow and aria-valuemax are
25670			// set inside _refreshValue()
25671			role: "progressbar",
25672			"aria-valuemin": this.min
25673		} );
25674		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
25675
25676		this.valueDiv = $( "<div>" ).appendTo( this.element );
25677		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
25678		this._refreshValue();
25679	},
25680
25681	_destroy: function() {
25682		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
25683
25684		this.valueDiv.remove();
25685	},
25686
25687	value: function( newValue ) {
25688		if ( newValue === undefined ) {
25689			return this.options.value;
25690		}
25691
25692		this.options.value = this._constrainedValue( newValue );
25693		this._refreshValue();
25694	},
25695
25696	_constrainedValue: function( newValue ) {
25697		if ( newValue === undefined ) {
25698			newValue = this.options.value;
25699		}
25700
25701		this.indeterminate = newValue === false;
25702
25703		// Sanitize value
25704		if ( typeof newValue !== "number" ) {
25705			newValue = 0;
25706		}
25707
25708		return this.indeterminate ? false :
25709			Math.min( this.options.max, Math.max( this.min, newValue ) );
25710	},
25711
25712	_setOptions: function( options ) {
25713
25714		// Ensure "value" option is set after other values (like max)
25715		var value = options.value;
25716		delete options.value;
25717
25718		this._super( options );
25719
25720		this.options.value = this._constrainedValue( value );
25721		this._refreshValue();
25722	},
25723
25724	_setOption: function( key, value ) {
25725		if ( key === "max" ) {
25726
25727			// Don't allow a max less than min
25728			value = Math.max( this.min, value );
25729		}
25730		this._super( key, value );
25731	},
25732
25733	_setOptionDisabled: function( value ) {
25734		this._super( value );
25735
25736		this.element.attr( "aria-disabled", value );
25737		this._toggleClass( null, "ui-state-disabled", !!value );
25738	},
25739
25740	_percentage: function() {
25741		return this.indeterminate ?
25742			100 :
25743			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
25744	},
25745
25746	_refreshValue: function() {
25747		var value = this.options.value,
25748			percentage = this._percentage();
25749
25750		this.valueDiv
25751			.toggle( this.indeterminate || value > this.min )
25752			.width( percentage.toFixed( 0 ) + "%" );
25753
25754		this
25755			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
25756				value === this.options.max )
25757			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
25758
25759		if ( this.indeterminate ) {
25760			this.element.removeAttr( "aria-valuenow" );
25761			if ( !this.overlayDiv ) {
25762				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
25763				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
25764			}
25765		} else {
25766			this.element.attr( {
25767				"aria-valuemax": this.options.max,
25768				"aria-valuenow": value
25769			} );
25770			if ( this.overlayDiv ) {
25771				this.overlayDiv.remove();
25772				this.overlayDiv = null;
25773			}
25774		}
25775
25776		if ( this.oldValue !== value ) {
25777			this.oldValue = value;
25778			this._trigger( "change" );
25779		}
25780		if ( value === this.options.max ) {
25781			this._trigger( "complete" );
25782		}
25783	}
25784} );
25785
25786} );
25787
25788
25789
25790
25791/*!
25792 * jQuery UI Selectable 1.13.0
25793 * http://jqueryui.com
25794 *
25795 * Copyright jQuery Foundation and other contributors
25796 * Released under the MIT license.
25797 * http://jquery.org/license
25798 */
25799
25800//>>label: Selectable
25801//>>group: Interactions
25802//>>description: Allows groups of elements to be selected with the mouse.
25803//>>docs: http://api.jqueryui.com/selectable/
25804//>>demos: http://jqueryui.com/selectable/
25805//>>css.structure: ../../themes/base/selectable.css
25806
25807( function( factory ) {
25808	"use strict";
25809
25810	if ( typeof define === "function" && define.amd ) {
25811
25812		// AMD. Register as an anonymous module.
25813		define( [
25814			"jquery",
25815			"./mouse",
25816			"../version",
25817			"../widget"
25818		], factory );
25819	} else {
25820
25821		// Browser globals
25822		factory( jQuery );
25823	}
25824} )( function( $ ) {
25825"use strict";
25826
25827return $.widget( "ui.selectable", $.ui.mouse, {
25828	version: "1.13.0
vendor: 7,293 bytes, lines 25828-26106
25828",
25829	options: {
25830		appendTo: "body",
25831		autoRefresh: true,
25832		distance: 0,
25833		filter: "*",
25834		tolerance: "touch",
25835
25836		// Callbacks
25837		selected: null,
25838		selecting: null,
25839		start: null,
25840		stop: null,
25841		unselected: null,
25842		unselecting: null
25843	},
25844	_create: function() {
25845		var that = this;
25846
25847		this._addClass( "ui-selectable" );
25848
25849		this.dragged = false;
25850
25851		// Cache selectee children based on filter
25852		this.refresh = function() {
25853			that.elementPos = $( that.element[ 0 ] ).offset();
25854			that.selectees = $( that.options.filter, that.element[ 0 ] );
25855			that._addClass( that.selectees, "ui-selectee" );
25856			that.selectees.each( function() {
25857				var $this = $( this ),
25858					selecteeOffset = $this.offset(),
25859					pos = {
25860						left: selecteeOffset.left - that.elementPos.left,
25861						top: selecteeOffset.top - that.elementPos.top
25862					};
25863				$.data( this, "selectable-item", {
25864					element: this,
25865					$element: $this,
25866					left: pos.left,
25867					top: pos.top,
25868					right: pos.left + $this.outerWidth(),
25869					bottom: pos.top + $this.outerHeight(),
25870					startselected: false,
25871					selected: $this.hasClass( "ui-selected" ),
25872					selecting: $this.hasClass( "ui-selecting" ),
25873					unselecting: $this.hasClass( "ui-unselecting" )
25874				} );
25875			} );
25876		};
25877		this.refresh();
25878
25879		this._mouseInit();
25880
25881		this.helper = $( "<div>" );
25882		this._addClass( this.helper, "ui-selectable-helper" );
25883	},
25884
25885	_destroy: function() {
25886		this.selectees.removeData( "selectable-item" );
25887		this._mouseDestroy();
25888	},
25889
25890	_mouseStart: function( event ) {
25891		var that = this,
25892			options = this.options;
25893
25894		this.opos = [ event.pageX, event.pageY ];
25895		this.elementPos = $( this.element[ 0 ] ).offset();
25896
25897		if ( this.options.disabled ) {
25898			return;
25899		}
25900
25901		this.selectees = $( options.filter, this.element[ 0 ] );
25902
25903		this._trigger( "start", event );
25904
25905		$( options.appendTo ).append( this.helper );
25906
25907		// position helper (lasso)
25908		this.helper.css( {
25909			"left": event.pageX,
25910			"top": event.pageY,
25911			"width": 0,
25912			"height": 0
25913		} );
25914
25915		if ( options.autoRefresh ) {
25916			this.refresh();
25917		}
25918
25919		this.selectees.filter( ".ui-selected" ).each( function() {
25920			var selectee = $.data( this, "selectable-item" );
25921			selectee.startselected = true;
25922			if ( !event.metaKey && !event.ctrlKey ) {
25923				that._removeClass( selectee.$element, "ui-selected" );
25924				selectee.selected = false;
25925				that._addClass( selectee.$element, "ui-unselecting" );
25926				selectee.unselecting = true;
25927
25928				// selectable UNSELECTING callback
25929				that._trigger( "unselecting", event, {
25930					unselecting: selectee.element
25931				} );
25932			}
25933		} );
25934
25935		$( event.target ).parents().addBack().each( function() {
25936			var doSelect,
25937				selectee = $.data( this, "selectable-item" );
25938			if ( selectee ) {
25939				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
25940					!selectee.$element.hasClass( "ui-selected" );
25941				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
25942					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
25943				selectee.unselecting = !doSelect;
25944				selectee.selecting = doSelect;
25945				selectee.selected = doSelect;
25946
25947				// selectable (UN)SELECTING callback
25948				if ( doSelect ) {
25949					that._trigger( "selecting", event, {
25950						selecting: selectee.element
25951					} );
25952				} else {
25953					that._trigger( "unselecting", event, {
25954						unselecting: selectee.element
25955					} );
25956				}
25957				return false;
25958			}
25959		} );
25960
25961	},
25962
25963	_mouseDrag: function( event ) {
25964
25965		this.dragged = true;
25966
25967		if ( this.options.disabled ) {
25968			return;
25969		}
25970
25971		var tmp,
25972			that = this,
25973			options = this.options,
25974			x1 = this.opos[ 0 ],
25975			y1 = this.opos[ 1 ],
25976			x2 = event.pageX,
25977			y2 = event.pageY;
25978
25979		if ( x1 > x2 ) {
25980			tmp = x2; x2 = x1; x1 = tmp;
25981		}
25982		if ( y1 > y2 ) {
25983			tmp = y2; y2 = y1; y1 = tmp;
25984		}
25985		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
25986
25987		this.selectees.each( function() {
25988			var selectee = $.data( this, "selectable-item" ),
25989				hit = false,
25990				offset = {};
25991
25992			//prevent helper from being selected if appendTo: selectable
25993			if ( !selectee || selectee.element === that.element[ 0 ] ) {
25994				return;
25995			}
25996
25997			offset.left   = selectee.left   + that.elementPos.left;
25998			offset.right  = selectee.right  + that.elementPos.left;
25999			offset.top    = selectee.top    + that.elementPos.top;
26000			offset.bottom = selectee.bottom + that.elementPos.top;
26001
26002			if ( options.tolerance === "touch" ) {
26003				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
26004                    offset.bottom < y1 ) );
26005			} else if ( options.tolerance === "fit" ) {
26006				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
26007                    offset.bottom < y2 );
26008			}
26009
26010			if ( hit ) {
26011
26012				// SELECT
26013				if ( selectee.selected ) {
26014					that._removeClass( selectee.$element, "ui-selected" );
26015					selectee.selected = false;
26016				}
26017				if ( selectee.unselecting ) {
26018					that._removeClass( selectee.$element, "ui-unselecting" );
26019					selectee.unselecting = false;
26020				}
26021				if ( !selectee.selecting ) {
26022					that._addClass( selectee.$element, "ui-selecting" );
26023					selectee.selecting = true;
26024
26025					// selectable SELECTING callback
26026					that._trigger( "selecting", event, {
26027						selecting: selectee.element
26028					} );
26029				}
26030			} else {
26031
26032				// UNSELECT
26033				if ( selectee.selecting ) {
26034					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
26035						that._removeClass( selectee.$element, "ui-selecting" );
26036						selectee.selecting = false;
26037						that._addClass( selectee.$element, "ui-selected" );
26038						selectee.selected = true;
26039					} else {
26040						that._removeClass( selectee.$element, "ui-selecting" );
26041						selectee.selecting = false;
26042						if ( selectee.startselected ) {
26043							that._addClass( selectee.$element, "ui-unselecting" );
26044							selectee.unselecting = true;
26045						}
26046
26047						// selectable UNSELECTING callback
26048						that._trigger( "unselecting", event, {
26049							unselecting: selectee.element
26050						} );
26051					}
26052				}
26053				if ( selectee.selected ) {
26054					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
26055						that._removeClass( selectee.$element, "ui-selected" );
26056						selectee.selected = false;
26057
26058						that._addClass( selectee.$element, "ui-unselecting" );
26059						selectee.unselecting = true;
26060
26061						// selectable UNSELECTING callback
26062						that._trigger( "unselecting", event, {
26063							unselecting: selectee.element
26064						} );
26065					}
26066				}
26067			}
26068		} );
26069
26070		return false;
26071	},
26072
26073	_mouseStop: function( event ) {
26074		var that = this;
26075
26076		this.dragged = false;
26077
26078		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
26079			var selectee = $.data( this, "selectable-item" );
26080			that._removeClass( selectee.$element, "ui-unselecting" );
26081			selectee.unselecting = false;
26082			selectee.startselected = false;
26083			that._trigger( "unselected", event, {
26084				unselected: selectee.element
26085			} );
26086		} );
26087		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
26088			var selectee = $.data( this, "selectable-item" );
26089			that._removeClass( selectee.$element, "ui-selecting" )
26090				._addClass( selectee.$element, "ui-selected" );
26091			selectee.selecting = false;
26092			selectee.selected = true;
26093			selectee.startselected = true;
26094			that._trigger( "selected", event, {
26095				selected: selectee.element
26096			} );
26097		} );
26098		this._trigger( "stop", event );
26099
26100		this.helper.remove();
26101
26102		return false;
26103	}
26104
26105} );
26106
vendor: 1,979 bytes, lines 26107-26202
26107} );
26108
26109
26110
26111
26112
26113
26114
26115
26116
26117/*!
26118 * jQuery UI Selectmenu 1.13.0
26119 * http://jqueryui.com
26120 *
26121 * Copyright jQuery Foundation and other contributors
26122 * Released under the MIT license.
26123 * http://jquery.org/license
26124 */
26125
26126//>>label: Selectmenu
26127//>>group: Widgets
26128/* eslint-disable max-len */
26129//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
26130/* eslint-enable max-len */
26131//>>docs: http://api.jqueryui.com/selectmenu/
26132//>>demos: http://jqueryui.com/selectmenu/
26133//>>css.structure: ../../themes/base/core.css
26134//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
26135//>>css.theme: ../../themes/base/theme.css
26136
26137( function( factory ) {
26138	"use strict";
26139
26140	if ( typeof define === "function" && define.amd ) {
26141
26142		// AMD. Register as an anonymous module.
26143		define( [
26144			"jquery",
26145			"./menu",
26146			"../form-reset-mixin",
26147			"../keycode",
26148			"../labels",
26149			"../position",
26150			"../unique-id",
26151			"../version",
26152			"../widget"
26153		], factory );
26154	} else {
26155
26156		// Browser globals
26157		factory( jQuery );
26158	}
26159} )( function( $ ) {
26160"use strict";
26161
26162return $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
26163	version: "1.13.0",
26164	defaultElement: "<select>",
26165	options: {
26166		appendTo: null,
26167		classes: {
26168			"ui-selectmenu-button-open": "ui-corner-top",
26169			"ui-selectmenu-button-closed": "ui-corner-all"
26170		},
26171		disabled: null,
26172		icons: {
26173			button: "ui-icon-triangle-1-s"
26174		},
26175		position: {
26176			my: "left top",
26177			at: "left bottom",
26178			collision: "none"
26179		},
26180		width: false,
26181
26182		// Callbacks
26183		change: null,
26184		close: null,
26185		focus: null,
26186		open: null,
26187		select: null
26188	},
26189
26190	_create: function() {
26191		var selectmenuId = this.element.uniqueId().attr( "id" );
26192		this.ids = {
26193			element: selectmenuId,
26194			button: selectmenuId + "-button",
26195			menu: selectmenuId + "-menu"
26196		};
26197
26198		this._drawButton();
26199		this._drawMenu();
26200		this._bindFormResetHandler();
26201
26202		this._rendered = false;
vendor: 5,200 bytes, lines 26203-26409
26203		this.menuItems = $();
26204	},
26205
26206	_drawButton: function() {
26207		var icon,
26208			that = this,
26209			item = this._parseOption(
26210				this.element.find( "option:selected" ),
26211				this.element[ 0 ].selectedIndex
26212			);
26213
26214		// Associate existing label with the new button
26215		this.labels = this.element.labels().attr( "for", this.ids.button );
26216		this._on( this.labels, {
26217			click: function( event ) {
26218				this.button.trigger( "focus" );
26219				event.preventDefault();
26220			}
26221		} );
26222
26223		// Hide original select element
26224		this.element.hide();
26225
26226		// Create button
26227		this.button = $( "<span>", {
26228			tabindex: this.options.disabled ? -1 : 0,
26229			id: this.ids.button,
26230			role: "combobox",
26231			"aria-expanded": "false",
26232			"aria-autocomplete": "list",
26233			"aria-owns": this.ids.menu,
26234			"aria-haspopup": "true",
26235			title: this.element.attr( "title" )
26236		} )
26237			.insertAfter( this.element );
26238
26239		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
26240			"ui-button ui-widget" );
26241
26242		icon = $( "<span>" ).appendTo( this.button );
26243		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
26244		this.buttonItem = this._renderButtonItem( item )
26245			.appendTo( this.button );
26246
26247		if ( this.options.width !== false ) {
26248			this._resizeButton();
26249		}
26250
26251		this._on( this.button, this._buttonEvents );
26252		this.button.one( "focusin", function() {
26253
26254			// Delay rendering the menu items until the button receives focus.
26255			// The menu may have already been rendered via a programmatic open.
26256			if ( !that._rendered ) {
26257				that._refreshMenu();
26258			}
26259		} );
26260	},
26261
26262	_drawMenu: function() {
26263		var that = this;
26264
26265		// Create menu
26266		this.menu = $( "<ul>", {
26267			"aria-hidden": "true",
26268			"aria-labelledby": this.ids.button,
26269			id: this.ids.menu
26270		} );
26271
26272		// Wrap menu
26273		this.menuWrap = $( "<div>" ).append( this.menu );
26274		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
26275		this.menuWrap.appendTo( this._appendTo() );
26276
26277		// Initialize menu widget
26278		this.menuInstance = this.menu
26279			.menu( {
26280				classes: {
26281					"ui-menu": "ui-corner-bottom"
26282				},
26283				role: "listbox",
26284				select: function( event, ui ) {
26285					event.preventDefault();
26286
26287					// Support: IE8
26288					// If the item was selected via a click, the text selection
26289					// will be destroyed in IE
26290					that._setSelection();
26291
26292					that._select( ui.item.data( "ui-selectmenu-item" ), event );
26293				},
26294				focus: function( event, ui ) {
26295					var item = ui.item.data( "ui-selectmenu-item" );
26296
26297					// Prevent inital focus from firing and check if its a newly focused item
26298					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
26299						that._trigger( "focus", event, { item: item } );
26300						if ( !that.isOpen ) {
26301							that._select( item, event );
26302						}
26303					}
26304					that.focusIndex = item.index;
26305
26306					that.button.attr( "aria-activedescendant",
26307						that.menuItems.eq( item.index ).attr( "id" ) );
26308				}
26309			} )
26310			.menu( "instance" );
26311
26312		// Don't close the menu on mouseleave
26313		this.menuInstance._off( this.menu, "mouseleave" );
26314
26315		// Cancel the menu's collapseAll on document click
26316		this.menuInstance._closeOnDocumentClick = function() {
26317			return false;
26318		};
26319
26320		// Selects often contain empty items, but never contain dividers
26321		this.menuInstance._isDivider = function() {
26322			return false;
26323		};
26324	},
26325
26326	refresh: function() {
26327		this._refreshMenu();
26328		this.buttonItem.replaceWith(
26329			this.buttonItem = this._renderButtonItem(
26330
26331				// Fall back to an empty object in case there are no options
26332				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
26333			)
26334		);
26335		if ( this.options.width === null ) {
26336			this._resizeButton();
26337		}
26338	},
26339
26340	_refreshMenu: function() {
26341		var item,
26342			options = this.element.find( "option" );
26343
26344		this.menu.empty();
26345
26346		this._parseOptions( options );
26347		this._renderMenu( this.menu, this.items );
26348
26349		this.menuInstance.refresh();
26350		this.menuItems = this.menu.find( "li" )
26351			.not( ".ui-selectmenu-optgroup" )
26352				.find( ".ui-menu-item-wrapper" );
26353
26354		this._rendered = true;
26355
26356		if ( !options.length ) {
26357			return;
26358		}
26359
26360		item = this._getSelectedItem();
26361
26362		// Update the menu to have the correct item focused
26363		this.menuInstance.focus( null, item );
26364		this._setAria( item.data( "ui-selectmenu-item" ) );
26365
26366		// Set disabled state
26367		this._setOption( "disabled", this.element.prop( "disabled" ) );
26368	},
26369
26370	open: function( event ) {
26371		if ( this.options.disabled ) {
26372			return;
26373		}
26374
26375		// If this is the first time the menu is being opened, render the items
26376		if ( !this._rendered ) {
26377			this._refreshMenu();
26378		} else {
26379
26380			// Menu clears focus on close, reset focus to selected item
26381			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
26382			this.menuInstance.focus( null, this._getSelectedItem() );
26383		}
26384
26385		// If there are no options, don't open the menu
26386		if ( !this.menuItems.length ) {
26387			return;
26388		}
26389
26390		this.isOpen = true;
26391		this._toggleAttr();
26392		this._resizeMenu();
26393		this._position();
26394
26395		this._on( this.document, this._documentClick );
26396
26397		this._trigger( "open", event );
26398	},
26399
26400	_position: function() {
26401		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
26402	},
26403
26404	close: function( event ) {
26405		if ( !this.isOpen ) {
26406			return;
26407		}
26408
26409		this.isOpen = false;
vendor: 2,743 bytes, lines 26410-26536
26410		this._toggleAttr();
26411
26412		this.range = null;
26413		this._off( this.document );
26414
26415		this._trigger( "close", event );
26416	},
26417
26418	widget: function() {
26419		return this.button;
26420	},
26421
26422	menuWidget: function() {
26423		return this.menu;
26424	},
26425
26426	_renderButtonItem: function( item ) {
26427		var buttonItem = $( "<span>" );
26428
26429		this._setText( buttonItem, item.label );
26430		this._addClass( buttonItem, "ui-selectmenu-text" );
26431
26432		return buttonItem;
26433	},
26434
26435	_renderMenu: function( ul, items ) {
26436		var that = this,
26437			currentOptgroup = "";
26438
26439		$.each( items, function( index, item ) {
26440			var li;
26441
26442			if ( item.optgroup !== currentOptgroup ) {
26443				li = $( "<li>", {
26444					text: item.optgroup
26445				} );
26446				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
26447					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
26448						" ui-state-disabled" :
26449						"" ) );
26450
26451				li.appendTo( ul );
26452
26453				currentOptgroup = item.optgroup;
26454			}
26455
26456			that._renderItemData( ul, item );
26457		} );
26458	},
26459
26460	_renderItemData: function( ul, item ) {
26461		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
26462	},
26463
26464	_renderItem: function( ul, item ) {
26465		var li = $( "<li>" ),
26466			wrapper = $( "<div>", {
26467				title: item.element.attr( "title" )
26468			} );
26469
26470		if ( item.disabled ) {
26471			this._addClass( li, null, "ui-state-disabled" );
26472		}
26473		this._setText( wrapper, item.label );
26474
26475		return li.append( wrapper ).appendTo( ul );
26476	},
26477
26478	_setText: function( element, value ) {
26479		if ( value ) {
26480			element.text( value );
26481		} else {
26482			element.html( "&#160;" );
26483		}
26484	},
26485
26486	_move: function( direction, event ) {
26487		var item, next,
26488			filter = ".ui-menu-item";
26489
26490		if ( this.isOpen ) {
26491			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
26492		} else {
26493			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
26494			filter += ":not(.ui-state-disabled)";
26495		}
26496
26497		if ( direction === "first" || direction === "last" ) {
26498			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
26499		} else {
26500			next = item[ direction + "All" ]( filter ).eq( 0 );
26501		}
26502
26503		if ( next.length ) {
26504			this.menuInstance.focus( event, next );
26505		}
26506	},
26507
26508	_getSelectedItem: function() {
26509		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
26510	},
26511
26512	_toggle: function( event ) {
26513		this[ this.isOpen ? "close" : "open" ]( event );
26514	},
26515
26516	_setSelection: function() {
26517		var selection;
26518
26519		if ( !this.range ) {
26520			return;
26521		}
26522
26523		if ( window.getSelection ) {
26524			selection = window.getSelection();
26525			selection.removeAllRanges();
26526			selection.addRange( this.range );
26527
26528		// Support: IE8
26529		} else {
26530			this.range.select();
26531		}
26532
26533		// Support: IE
26534		// Setting the text selection kills the button focus in IE, but
26535		// restoring the focus doesn't kill the selection.
26536		this.button.focus(
vendor: 5,664 bytes, lines 26536-26777
26536);
26537	},
26538
26539	_documentClick: {
26540		mousedown: function( event ) {
26541			if ( !this.isOpen ) {
26542				return;
26543			}
26544
26545			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
26546				$.escapeSelector( this.ids.button ) ).length ) {
26547				this.close( event );
26548			}
26549		}
26550	},
26551
26552	_buttonEvents: {
26553
26554		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
26555		mousedown: function() {
26556			var selection;
26557
26558			if ( window.getSelection ) {
26559				selection = window.getSelection();
26560				if ( selection.rangeCount ) {
26561					this.range = selection.getRangeAt( 0 );
26562				}
26563
26564			// Support: IE8
26565			} else {
26566				this.range = document.selection.createRange();
26567			}
26568		},
26569
26570		click: function( event ) {
26571			this._setSelection();
26572			this._toggle( event );
26573		},
26574
26575		keydown: function( event ) {
26576			var preventDefault = true;
26577			switch ( event.keyCode ) {
26578			case $.ui.keyCode.TAB:
26579			case $.ui.keyCode.ESCAPE:
26580				this.close( event );
26581				preventDefault = false;
26582				break;
26583			case $.ui.keyCode.ENTER:
26584				if ( this.isOpen ) {
26585					this._selectFocusedItem( event );
26586				}
26587				break;
26588			case $.ui.keyCode.UP:
26589				if ( event.altKey ) {
26590					this._toggle( event );
26591				} else {
26592					this._move( "prev", event );
26593				}
26594				break;
26595			case $.ui.keyCode.DOWN:
26596				if ( event.altKey ) {
26597					this._toggle( event );
26598				} else {
26599					this._move( "next", event );
26600				}
26601				break;
26602			case $.ui.keyCode.SPACE:
26603				if ( this.isOpen ) {
26604					this._selectFocusedItem( event );
26605				} else {
26606					this._toggle( event );
26607				}
26608				break;
26609			case $.ui.keyCode.LEFT:
26610				this._move( "prev", event );
26611				break;
26612			case $.ui.keyCode.RIGHT:
26613				this._move( "next", event );
26614				break;
26615			case $.ui.keyCode.HOME:
26616			case $.ui.keyCode.PAGE_UP:
26617				this._move( "first", event );
26618				break;
26619			case $.ui.keyCode.END:
26620			case $.ui.keyCode.PAGE_DOWN:
26621				this._move( "last", event );
26622				break;
26623			default:
26624				this.menu.trigger( event );
26625				preventDefault = false;
26626			}
26627
26628			if ( preventDefault ) {
26629				event.preventDefault();
26630			}
26631		}
26632	},
26633
26634	_selectFocusedItem: function( event ) {
26635		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
26636		if ( !item.hasClass( "ui-state-disabled" ) ) {
26637			this._select( item.data( "ui-selectmenu-item" ), event );
26638		}
26639	},
26640
26641	_select: function( item, event ) {
26642		var oldIndex = this.element[ 0 ].selectedIndex;
26643
26644		// Change native select element
26645		this.element[ 0 ].selectedIndex = item.index;
26646		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
26647		this._setAria( item );
26648		this._trigger( "select", event, { item: item } );
26649
26650		if ( item.index !== oldIndex ) {
26651			this._trigger( "change", event, { item: item } );
26652		}
26653
26654		this.close( event );
26655	},
26656
26657	_setAria: function( item ) {
26658		var id = this.menuItems.eq( item.index ).attr( "id" );
26659
26660		this.button.attr( {
26661			"aria-labelledby": id,
26662			"aria-activedescendant": id
26663		} );
26664		this.menu.attr( "aria-activedescendant", id );
26665	},
26666
26667	_setOption: function( key, value ) {
26668		if ( key === "icons" ) {
26669			var icon = this.button.find( "span.ui-icon" );
26670			this._removeClass( icon, null, this.options.icons.button )
26671				._addClass( icon, null, value.button );
26672		}
26673
26674		this._super( key, value );
26675
26676		if ( key === "appendTo" ) {
26677			this.menuWrap.appendTo( this._appendTo() );
26678		}
26679
26680		if ( key === "width" ) {
26681			this._resizeButton();
26682		}
26683	},
26684
26685	_setOptionDisabled: function( value ) {
26686		this._super( value );
26687
26688		this.menuInstance.option( "disabled", value );
26689		this.button.attr( "aria-disabled", value );
26690		this._toggleClass( this.button, null, "ui-state-disabled", value );
26691
26692		this.element.prop( "disabled", value );
26693		if ( value ) {
26694			this.button.attr( "tabindex", -1 );
26695			this.close();
26696		} else {
26697			this.button.attr( "tabindex", 0 );
26698		}
26699	},
26700
26701	_appendTo: function() {
26702		var element = this.options.appendTo;
26703
26704		if ( element ) {
26705			element = element.jquery || element.nodeType ?
26706				$( element ) :
26707				this.document.find( element ).eq( 0 );
26708		}
26709
26710		if ( !element || !element[ 0 ] ) {
26711			element = this.element.closest( ".ui-front, dialog" );
26712		}
26713
26714		if ( !element.length ) {
26715			element = this.document[ 0 ].body;
26716		}
26717
26718		return element;
26719	},
26720
26721	_toggleAttr: function() {
26722		this.button.attr( "aria-expanded", this.isOpen );
26723
26724		// We can't use two _toggleClass() calls here, because we need to make sure
26725		// we always remove classes first and add them second, otherwise if both classes have the
26726		// same theme class, it will be removed after we add it.
26727		this._removeClass( this.button, "ui-selectmenu-button-" +
26728			( this.isOpen ? "closed" : "open" ) )
26729			._addClass( this.button, "ui-selectmenu-button-" +
26730				( this.isOpen ? "open" : "closed" ) )
26731			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
26732
26733		this.menu.attr( "aria-hidden", !this.isOpen );
26734	},
26735
26736	_resizeButton: function() {
26737		var width = this.options.width;
26738
26739		// For `width: false`, just remove inline style and stop
26740		if ( width === false ) {
26741			this.button.css( "width", "" );
26742			return;
26743		}
26744
26745		// For `width: null`, match the width of the original element
26746		if ( width === null ) {
26747			width = this.element.show().outerWidth();
26748			this.element.hide();
26749		}
26750
26751		this.button.outerWidth( width );
26752	},
26753
26754	_resizeMenu: function() {
26755		this.menu.outerWidth( Math.max(
26756			this.button.outerWidth(),
26757
26758			// Support: IE10
26759			// IE10 wraps long text (possibly a rounding bug)
26760			// so we add 1px to avoid the wrapping
26761			this.menu.width( "" ).outerWidth() + 1
26762		) );
26763	},
26764
26765	_getCreateOptions: function() {
26766		var options = this._super();
26767
26768		options.disabled = this.element.prop( "disabled" );
26769
26770		return options;
26771	},
26772
26773	_parseOptions: function( options ) {
26774		var that = this,
26775			data = [];
26776		options.each( function( index, item ) {
26777			
vendor: 3,996 bytes, lines 26777-26952
26777if ( item.hidden ) {
26778				return;
26779			}
26780
26781			data.push( that._parseOption( $( item ), index ) );
26782		} );
26783		this.items = data;
26784	},
26785
26786	_parseOption: function( option, index ) {
26787		var optgroup = option.parent( "optgroup" );
26788
26789		return {
26790			element: option,
26791			index: index,
26792			value: option.val(),
26793			label: option.text(),
26794			optgroup: optgroup.attr( "label" ) || "",
26795			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
26796		};
26797	},
26798
26799	_destroy: function() {
26800		this._unbindFormResetHandler();
26801		this.menuWrap.remove();
26802		this.button.remove();
26803		this.element.show();
26804		this.element.removeUniqueId();
26805		this.labels.attr( "for", this.ids.element );
26806	}
26807} ] );
26808
26809} );
26810
26811
26812
26813
26814
26815/*!
26816 * jQuery UI Slider 1.13.0
26817 * http://jqueryui.com
26818 *
26819 * Copyright jQuery Foundation and other contributors
26820 * Released under the MIT license.
26821 * http://jquery.org/license
26822 */
26823
26824//>>label: Slider
26825//>>group: Widgets
26826//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
26827//>>docs: http://api.jqueryui.com/slider/
26828//>>demos: http://jqueryui.com/slider/
26829//>>css.structure: ../../themes/base/core.css
26830//>>css.structure: ../../themes/base/slider.css
26831//>>css.theme: ../../themes/base/theme.css
26832
26833( function( factory ) {
26834	"use strict";
26835
26836	if ( typeof define === "function" && define.amd ) {
26837
26838		// AMD. Register as an anonymous module.
26839		define( [
26840			"jquery",
26841			"./mouse",
26842			"../keycode",
26843			"../version",
26844			"../widget"
26845		], factory );
26846	} else {
26847
26848		// Browser globals
26849		factory( jQuery );
26850	}
26851} )( function( $ ) {
26852"use strict";
26853
26854return $.widget( "ui.slider", $.ui.mouse, {
26855	version: "1.13.0",
26856	widgetEventPrefix: "slide",
26857
26858	options: {
26859		animate: false,
26860		classes: {
26861			"ui-slider": "ui-corner-all",
26862			"ui-slider-handle": "ui-corner-all",
26863
26864			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
26865			// element, but worked best visually with a variety of themes
26866			"ui-slider-range": "ui-corner-all ui-widget-header"
26867		},
26868		distance: 0,
26869		max: 100,
26870		min: 0,
26871		orientation: "horizontal",
26872		range: false,
26873		step: 1,
26874		value: 0,
26875		values: null,
26876
26877		// Callbacks
26878		change: null,
26879		slide: null,
26880		start: null,
26881		stop: null
26882	},
26883
26884	// Number of pages in a slider
26885	// (how many times can you page up/down to go through the whole range)
26886	numPages: 5,
26887
26888	_create: function() {
26889		this._keySliding = false;
26890		this._mouseSliding = false;
26891		this._animateOff = true;
26892		this._handleIndex = null;
26893		this._detectOrientation();
26894		this._mouseInit();
26895		this._calculateNewMax();
26896
26897		this._addClass( "ui-slider ui-slider-" + this.orientation,
26898			"ui-widget ui-widget-content" );
26899
26900		this._refresh();
26901
26902		this._animateOff = false;
26903	},
26904
26905	_refresh: function() {
26906		this._createRange();
26907		this._createHandles();
26908		this._setupEvents();
26909		this._refreshValue();
26910	},
26911
26912	_createHandles: function() {
26913		var i, handleCount,
26914			options = this.options,
26915			existingHandles = this.element.find( ".ui-slider-handle" ),
26916			handle = "<span tabindex='0'></span>",
26917			handles = [];
26918
26919		handleCount = ( options.values && options.values.length ) || 1;
26920
26921		if ( existingHandles.length > handleCount ) {
26922			existingHandles.slice( handleCount ).remove();
26923			existingHandles = existingHandles.slice( 0, handleCount );
26924		}
26925
26926		for ( i = existingHandles.length; i < handleCount; i++ ) {
26927			handles.push( handle );
26928		}
26929
26930		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
26931
26932		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
26933
26934		this.handle = this.handles.eq( 0 );
26935
26936		this.handles.each( function( i ) {
26937			$( this )
26938				.data( "ui-slider-handle-index", i )
26939				.attr( "tabIndex", 0 );
26940		} );
26941	},
26942
26943	_createRange: function() {
26944		var options = this.options;
26945
26946		if ( options.range ) {
26947			if ( options.range === true ) {
26948				if ( !options.values ) {
26949					options.values = [ this._valueMin(), this._valueMin() ];
26950				} else if ( options.values.length && options.values.length !== 2 ) {
26951					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
26952				} else if ( Array
vendor: 6,343 bytes, lines 26952-27198
26952.isArray( options.values ) ) {
26953					options.values = options.values.slice( 0 );
26954				}
26955			}
26956
26957			if ( !this.range || !this.range.length ) {
26958				this.range = $( "<div>" )
26959					.appendTo( this.element );
26960
26961				this._addClass( this.range, "ui-slider-range" );
26962			} else {
26963				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
26964
26965				// Handle range switching from true to min/max
26966				this.range.css( {
26967					"left": "",
26968					"bottom": ""
26969				} );
26970			}
26971			if ( options.range === "min" || options.range === "max" ) {
26972				this._addClass( this.range, "ui-slider-range-" + options.range );
26973			}
26974		} else {
26975			if ( this.range ) {
26976				this.range.remove();
26977			}
26978			this.range = null;
26979		}
26980	},
26981
26982	_setupEvents: function() {
26983		this._off( this.handles );
26984		this._on( this.handles, this._handleEvents );
26985		this._hoverable( this.handles );
26986		this._focusable( this.handles );
26987	},
26988
26989	_destroy: function() {
26990		this.handles.remove();
26991		if ( this.range ) {
26992			this.range.remove();
26993		}
26994
26995		this._mouseDestroy();
26996	},
26997
26998	_mouseCapture: function( event ) {
26999		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
27000			that = this,
27001			o = this.options;
27002
27003		if ( o.disabled ) {
27004			return false;
27005		}
27006
27007		this.elementSize = {
27008			width: this.element.outerWidth(),
27009			height: this.element.outerHeight()
27010		};
27011		this.elementOffset = this.element.offset();
27012
27013		position = { x: event.pageX, y: event.pageY };
27014		normValue = this._normValueFromMouse( position );
27015		distance = this._valueMax() - this._valueMin() + 1;
27016		this.handles.each( function( i ) {
27017			var thisDistance = Math.abs( normValue - that.values( i ) );
27018			if ( ( distance > thisDistance ) ||
27019				( distance === thisDistance &&
27020					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
27021				distance = thisDistance;
27022				closestHandle = $( this );
27023				index = i;
27024			}
27025		} );
27026
27027		allowed = this._start( event, index );
27028		if ( allowed === false ) {
27029			return false;
27030		}
27031		this._mouseSliding = true;
27032
27033		this._handleIndex = index;
27034
27035		this._addClass( closestHandle, null, "ui-state-active" );
27036		closestHandle.trigger( "focus" );
27037
27038		offset = closestHandle.offset();
27039		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
27040		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
27041			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
27042			top: event.pageY - offset.top -
27043				( closestHandle.height() / 2 ) -
27044				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
27045				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
27046				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
27047		};
27048
27049		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
27050			this._slide( event, index, normValue );
27051		}
27052		this._animateOff = true;
27053		return true;
27054	},
27055
27056	_mouseStart: function() {
27057		return true;
27058	},
27059
27060	_mouseDrag: function( event ) {
27061		var position = { x: event.pageX, y: event.pageY },
27062			normValue = this._normValueFromMouse( position );
27063
27064		this._slide( event, this._handleIndex, normValue );
27065
27066		return false;
27067	},
27068
27069	_mouseStop: function( event ) {
27070		this._removeClass( this.handles, null, "ui-state-active" );
27071		this._mouseSliding = false;
27072
27073		this._stop( event, this._handleIndex );
27074		this._change( event, this._handleIndex );
27075
27076		this._handleIndex = null;
27077		this._clickOffset = null;
27078		this._animateOff = false;
27079
27080		return false;
27081	},
27082
27083	_detectOrientation: function() {
27084		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
27085	},
27086
27087	_normValueFromMouse: function( position ) {
27088		var pixelTotal,
27089			pixelMouse,
27090			percentMouse,
27091			valueTotal,
27092			valueMouse;
27093
27094		if ( this.orientation === "horizontal" ) {
27095			pixelTotal = this.elementSize.width;
27096			pixelMouse = position.x - this.elementOffset.left -
27097				( this._clickOffset ? this._clickOffset.left : 0 );
27098		} else {
27099			pixelTotal = this.elementSize.height;
27100			pixelMouse = position.y - this.elementOffset.top -
27101				( this._clickOffset ? this._clickOffset.top : 0 );
27102		}
27103
27104		percentMouse = ( pixelMouse / pixelTotal );
27105		if ( percentMouse > 1 ) {
27106			percentMouse = 1;
27107		}
27108		if ( percentMouse < 0 ) {
27109			percentMouse = 0;
27110		}
27111		if ( this.orientation === "vertical" ) {
27112			percentMouse = 1 - percentMouse;
27113		}
27114
27115		valueTotal = this._valueMax() - this._valueMin();
27116		valueMouse = this._valueMin() + percentMouse * valueTotal;
27117
27118		return this._trimAlignValue( valueMouse );
27119	},
27120
27121	_uiHash: function( index, value, values ) {
27122		var uiHash = {
27123			handle: this.handles[ index ],
27124			handleIndex: index,
27125			value: value !== undefined ? value : this.value()
27126		};
27127
27128		if ( this._hasMultipleValues() ) {
27129			uiHash.value = value !== undefined ? value : this.values( index );
27130			uiHash.values = values || this.values();
27131		}
27132
27133		return uiHash;
27134	},
27135
27136	_hasMultipleValues: function() {
27137		return this.options.values && this.options.values.length;
27138	},
27139
27140	_start: function( event, index ) {
27141		return this._trigger( "start", event, this._uiHash( index ) );
27142	},
27143
27144	_slide: function( event, index, newVal ) {
27145		var allowed, otherVal,
27146			currentValue = this.value(),
27147			newValues = this.values();
27148
27149		if ( this._hasMultipleValues() ) {
27150			otherVal = this.values( index ? 0 : 1 );
27151			currentValue = this.values( index );
27152
27153			if ( this.options.values.length === 2 && this.options.range === true ) {
27154				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
27155			}
27156
27157			newValues[ index ] = newVal;
27158		}
27159
27160		if ( newVal === currentValue ) {
27161			return;
27162		}
27163
27164		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
27165
27166		// A slide can be canceled by returning false from the slide callback
27167		if ( allowed === false ) {
27168			return;
27169		}
27170
27171		if ( this._hasMultipleValues() ) {
27172			this.values( index, newVal );
27173		} else {
27174			this.value( newVal );
27175		}
27176	},
27177
27178	_stop: function( event, index ) {
27179		this._trigger( "stop", event, this._uiHash( index ) );
27180	},
27181
27182	_change: function( event, index ) {
27183		if ( !this._keySliding && !this._mouseSliding ) {
27184
27185			//store the last changed value index for reference when handles overlap
27186			this._lastChangedValue = index;
27187			this._trigger( "change", event, this._uiHash( index ) );
27188		}
27189	},
27190
27191	value: function( newValue ) {
27192		if ( arguments.length ) {
27193			this.options.value = this._trimAlignValue( newValue );
27194			this._refreshValue();
27195			this._change( null, 0 );
27196			return;
27197		}
27198
vendor: 4,358 bytes, lines 27199-27371
27199		return this._value();
27200	},
27201
27202	values: function( index, newValue ) {
27203		var vals,
27204			newValues,
27205			i;
27206
27207		if ( arguments.length > 1 ) {
27208			this.options.values[ index ] = this._trimAlignValue( newValue );
27209			this._refreshValue();
27210			this._change( null, index );
27211			return;
27212		}
27213
27214		if ( arguments.length ) {
27215			if ( Array.isArray( arguments[ 0 ] ) ) {
27216				vals = this.options.values;
27217				newValues = arguments[ 0 ];
27218				for ( i = 0; i < vals.length; i += 1 ) {
27219					vals[ i ] = this._trimAlignValue( newValues[ i ] );
27220					this._change( null, i );
27221				}
27222				this._refreshValue();
27223			} else {
27224				if ( this._hasMultipleValues() ) {
27225					return this._values( index );
27226				} else {
27227					return this.value();
27228				}
27229			}
27230		} else {
27231			return this._values();
27232		}
27233	},
27234
27235	_setOption: function( key, value ) {
27236		var i,
27237			valsLength = 0;
27238
27239		if ( key === "range" && this.options.range === true ) {
27240			if ( value === "min" ) {
27241				this.options.value = this._values( 0 );
27242				this.options.values = null;
27243			} else if ( value === "max" ) {
27244				this.options.value = this._values( this.options.values.length - 1 );
27245				this.options.values = null;
27246			}
27247		}
27248
27249		if ( Array.isArray( this.options.values ) ) {
27250			valsLength = this.options.values.length;
27251		}
27252
27253		this._super( key, value );
27254
27255		switch ( key ) {
27256			case "orientation":
27257				this._detectOrientation();
27258				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
27259					._addClass( "ui-slider-" + this.orientation );
27260				this._refreshValue();
27261				if ( this.options.range ) {
27262					this._refreshRange( value );
27263				}
27264
27265				// Reset positioning from previous orientation
27266				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
27267				break;
27268			case "value":
27269				this._animateOff = true;
27270				this._refreshValue();
27271				this._change( null, 0 );
27272				this._animateOff = false;
27273				break;
27274			case "values":
27275				this._animateOff = true;
27276				this._refreshValue();
27277
27278				// Start from the last handle to prevent unreachable handles (#9046)
27279				for ( i = valsLength - 1; i >= 0; i-- ) {
27280					this._change( null, i );
27281				}
27282				this._animateOff = false;
27283				break;
27284			case "step":
27285			case "min":
27286			case "max":
27287				this._animateOff = true;
27288				this._calculateNewMax();
27289				this._refreshValue();
27290				this._animateOff = false;
27291				break;
27292			case "range":
27293				this._animateOff = true;
27294				this._refresh();
27295				this._animateOff = false;
27296				break;
27297		}
27298	},
27299
27300	_setOptionDisabled: function( value ) {
27301		this._super( value );
27302
27303		this._toggleClass( null, "ui-state-disabled", !!value );
27304	},
27305
27306	//internal value getter
27307	// _value() returns value trimmed by min and max, aligned by step
27308	_value: function() {
27309		var val = this.options.value;
27310		val = this._trimAlignValue( val );
27311
27312		return val;
27313	},
27314
27315	//internal values getter
27316	// _values() returns array of values trimmed by min and max, aligned by step
27317	// _values( index ) returns single value trimmed by min and max, aligned by step
27318	_values: function( index ) {
27319		var val,
27320			vals,
27321			i;
27322
27323		if ( arguments.length ) {
27324			val = this.options.values[ index ];
27325			val = this._trimAlignValue( val );
27326
27327			return val;
27328		} else if ( this._hasMultipleValues() ) {
27329
27330			// .slice() creates a copy of the array
27331			// this copy gets trimmed by min and max and then returned
27332			vals = this.options.values.slice();
27333			for ( i = 0; i < vals.length; i += 1 ) {
27334				vals[ i ] = this._trimAlignValue( vals[ i ] );
27335			}
27336
27337			return vals;
27338		} else {
27339			return [];
27340		}
27341	},
27342
27343	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
27344	_trimAlignValue: function( val ) {
27345		if ( val <= this._valueMin() ) {
27346			return this._valueMin();
27347		}
27348		if ( val >= this._valueMax() ) {
27349			return this._valueMax();
27350		}
27351		var step = ( this.options.step > 0 ) ? this.options.step : 1,
27352			valModStep = ( val - this._valueMin() ) % step,
27353			alignValue = val - valModStep;
27354
27355		if ( Math.abs( valModStep ) * 2 >= step ) {
27356			alignValue += ( valModStep > 0 ) ? step : ( -step );
27357		}
27358
27359		// Since JavaScript has problems with large floats, round
27360		// the final value to 5 digits after the decimal point (see #4124)
27361		return parseFloat( alignValue.toFixed( 5 ) );
27362	},
27363
27364	_calculateNewMax: function() {
27365		var max = this.options.max,
27366			min = this._valueMin(),
27367			step = this.options.step,
27368			aboveMin = Math.round( ( max - min ) / step ) * step;
27369		max = aboveMin + min;
27370		if ( max > this.options.max ) {
27371
vendor: 5,564 bytes, lines 27372-27568
27372			//If max is not divisible by step, rounding off may increase its value
27373			max -= step;
27374		}
27375		this.max = parseFloat( max.toFixed( this._precision() ) );
27376	},
27377
27378	_precision: function() {
27379		var precision = this._precisionOf( this.options.step );
27380		if ( this.options.min !== null ) {
27381			precision = Math.max( precision, this._precisionOf( this.options.min ) );
27382		}
27383		return precision;
27384	},
27385
27386	_precisionOf: function( num ) {
27387		var str = num.toString(),
27388			decimal = str.indexOf( "." );
27389		return decimal === -1 ? 0 : str.length - decimal - 1;
27390	},
27391
27392	_valueMin: function() {
27393		return this.options.min;
27394	},
27395
27396	_valueMax: function() {
27397		return this.max;
27398	},
27399
27400	_refreshRange: function( orientation ) {
27401		if ( orientation === "vertical" ) {
27402			this.range.css( { "width": "", "left": "" } );
27403		}
27404		if ( orientation === "horizontal" ) {
27405			this.range.css( { "height": "", "bottom": "" } );
27406		}
27407	},
27408
27409	_refreshValue: function() {
27410		var lastValPercent, valPercent, value, valueMin, valueMax,
27411			oRange = this.options.range,
27412			o = this.options,
27413			that = this,
27414			animate = ( !this._animateOff ) ? o.animate : false,
27415			_set = {};
27416
27417		if ( this._hasMultipleValues() ) {
27418			this.handles.each( function( i ) {
27419				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
27420					that._valueMin() ) * 100;
27421				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
27422				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
27423				if ( that.options.range === true ) {
27424					if ( that.orientation === "horizontal" ) {
27425						if ( i === 0 ) {
27426							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27427								left: valPercent + "%"
27428							}, o.animate );
27429						}
27430						if ( i === 1 ) {
27431							that.range[ animate ? "animate" : "css" ]( {
27432								width: ( valPercent - lastValPercent ) + "%"
27433							}, {
27434								queue: false,
27435								duration: o.animate
27436							} );
27437						}
27438					} else {
27439						if ( i === 0 ) {
27440							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27441								bottom: ( valPercent ) + "%"
27442							}, o.animate );
27443						}
27444						if ( i === 1 ) {
27445							that.range[ animate ? "animate" : "css" ]( {
27446								height: ( valPercent - lastValPercent ) + "%"
27447							}, {
27448								queue: false,
27449								duration: o.animate
27450							} );
27451						}
27452					}
27453				}
27454				lastValPercent = valPercent;
27455			} );
27456		} else {
27457			value = this.value();
27458			valueMin = this._valueMin();
27459			valueMax = this._valueMax();
27460			valPercent = ( valueMax !== valueMin ) ?
27461					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
27462					0;
27463			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
27464			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
27465
27466			if ( oRange === "min" && this.orientation === "horizontal" ) {
27467				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27468					width: valPercent + "%"
27469				}, o.animate );
27470			}
27471			if ( oRange === "max" && this.orientation === "horizontal" ) {
27472				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27473					width: ( 100 - valPercent ) + "%"
27474				}, o.animate );
27475			}
27476			if ( oRange === "min" && this.orientation === "vertical" ) {
27477				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27478					height: valPercent + "%"
27479				}, o.animate );
27480			}
27481			if ( oRange === "max" && this.orientation === "vertical" ) {
27482				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
27483					height: ( 100 - valPercent ) + "%"
27484				}, o.animate );
27485			}
27486		}
27487	},
27488
27489	_handleEvents: {
27490		keydown: function( event ) {
27491			var allowed, curVal, newVal, step,
27492				index = $( event.target ).data( "ui-slider-handle-index" );
27493
27494			switch ( event.keyCode ) {
27495				case $.ui.keyCode.HOME:
27496				case $.ui.keyCode.END:
27497				case $.ui.keyCode.PAGE_UP:
27498				case $.ui.keyCode.PAGE_DOWN:
27499				case $.ui.keyCode.UP:
27500				case $.ui.keyCode.RIGHT:
27501				case $.ui.keyCode.DOWN:
27502				case $.ui.keyCode.LEFT:
27503					event.preventDefault();
27504					if ( !this._keySliding ) {
27505						this._keySliding = true;
27506						this._addClass( $( event.target ), null, "ui-state-active" );
27507						allowed = this._start( event, index );
27508						if ( allowed === false ) {
27509							return;
27510						}
27511					}
27512					break;
27513			}
27514
27515			step = this.options.step;
27516			if ( this._hasMultipleValues() ) {
27517				curVal = newVal = this.values( index );
27518			} else {
27519				curVal = newVal = this.value();
27520			}
27521
27522			switch ( event.keyCode ) {
27523				case $.ui.keyCode.HOME:
27524					newVal = this._valueMin();
27525					break;
27526				case $.ui.keyCode.END:
27527					newVal = this._valueMax();
27528					break;
27529				case $.ui.keyCode.PAGE_UP:
27530					newVal = this._trimAlignValue(
27531						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
27532					);
27533					break;
27534				case $.ui.keyCode.PAGE_DOWN:
27535					newVal = this._trimAlignValue(
27536						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
27537					break;
27538				case $.ui.keyCode.UP:
27539				case $.ui.keyCode.RIGHT:
27540					if ( curVal === this._valueMax() ) {
27541						return;
27542					}
27543					newVal = this._trimAlignValue( curVal + step );
27544					break;
27545				case $.ui.keyCode.DOWN:
27546				case $.ui.keyCode.LEFT:
27547					if ( curVal === this._valueMin() ) {
27548						return;
27549					}
27550					newVal = this._trimAlignValue( curVal - step );
27551					break;
27552			}
27553
27554			this._slide( event, index, newVal );
27555		},
27556		keyup: function( event ) {
27557			var index = $( event.target ).data( "ui-slider-handle-index" );
27558
27559			if ( this._keySliding ) {
27560				this._keySliding = false;
27561				this._stop( event, index );
27562				this._change( event, index );
27563				this._removeClass( $( event.target ), null, "ui-state-active" );
27564			}
27565		}
27566	}
27567} );
27568
vendor: 3,464 bytes, lines 27569-27739
27569} );
27570
27571
27572
27573
27574
27575
27576
27577/*!
27578 * jQuery UI Sortable 1.13.0
27579 * http://jqueryui.com
27580 *
27581 * Copyright jQuery Foundation and other contributors
27582 * Released under the MIT license.
27583 * http://jquery.org/license
27584 */
27585
27586//>>label: Sortable
27587//>>group: Interactions
27588//>>description: Enables items in a list to be sorted using the mouse.
27589//>>docs: http://api.jqueryui.com/sortable/
27590//>>demos: http://jqueryui.com/sortable/
27591//>>css.structure: ../../themes/base/sortable.css
27592
27593( function( factory ) {
27594	"use strict";
27595
27596	if ( typeof define === "function" && define.amd ) {
27597
27598		// AMD. Register as an anonymous module.
27599		define( [
27600			"jquery",
27601			"./mouse",
27602			"../data",
27603			"../ie",
27604			"../scroll-parent",
27605			"../version",
27606			"../widget"
27607		], factory );
27608	} else {
27609
27610		// Browser globals
27611		factory( jQuery );
27612	}
27613} )( function( $ ) {
27614"use strict";
27615
27616return $.widget( "ui.sortable", $.ui.mouse, {
27617	version: "1.13.0",
27618	widgetEventPrefix: "sort",
27619	ready: false,
27620	options: {
27621		appendTo: "parent",
27622		axis: false,
27623		connectWith: false,
27624		containment: false,
27625		cursor: "auto",
27626		cursorAt: false,
27627		dropOnEmpty: true,
27628		forcePlaceholderSize: false,
27629		forceHelperSize: false,
27630		grid: false,
27631		handle: false,
27632		helper: "original",
27633		items: "> *",
27634		opacity: false,
27635		placeholder: false,
27636		revert: false,
27637		scroll: true,
27638		scrollSensitivity: 20,
27639		scrollSpeed: 20,
27640		scope: "default",
27641		tolerance: "intersect",
27642		zIndex: 1000,
27643
27644		// Callbacks
27645		activate: null,
27646		beforeStop: null,
27647		change: null,
27648		deactivate: null,
27649		out: null,
27650		over: null,
27651		receive: null,
27652		remove: null,
27653		sort: null,
27654		start: null,
27655		stop: null,
27656		update: null
27657	},
27658
27659	_isOverAxis: function( x, reference, size ) {
27660		return ( x >= reference ) && ( x < ( reference + size ) );
27661	},
27662
27663	_isFloating: function( item ) {
27664		return ( /left|right/ ).test( item.css( "float" ) ) ||
27665			( /inline|table-cell/ ).test( item.css( "display" ) );
27666	},
27667
27668	_create: function() {
27669		this.containerCache = {};
27670		this._addClass( "ui-sortable" );
27671
27672		//Get the items
27673		this.refresh();
27674
27675		//Let's determine the parent's offset
27676		this.offset = this.element.offset();
27677
27678		//Initialize mouse events for interaction
27679		this._mouseInit();
27680
27681		this._setHandleClassName();
27682
27683		//We're ready to go
27684		this.ready = true;
27685
27686	},
27687
27688	_setOption: function( key, value ) {
27689		this._super( key, value );
27690
27691		if ( key === "handle" ) {
27692			this._setHandleClassName();
27693		}
27694	},
27695
27696	_setHandleClassName: function() {
27697		var that = this;
27698		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
27699		$.each( this.items, function() {
27700			that._addClass(
27701				this.instance.options.handle ?
27702					this.item.find( this.instance.options.handle ) :
27703					this.item,
27704				"ui-sortable-handle"
27705			);
27706		} );
27707	},
27708
27709	_destroy: function() {
27710		this._mouseDestroy();
27711
27712		for ( var i = this.items.length - 1; i >= 0; i-- ) {
27713			this.items[ i ].item.removeData( this.widgetName + "-item" );
27714		}
27715
27716		return this;
27717	},
27718
27719	_mouseCapture: function( event, overrideHandle ) {
27720		var currentItem = null,
27721			validHandle = false,
27722			that = this;
27723
27724		if ( this.reverting ) {
27725			return false;
27726		}
27727
27728		if ( this.options.disabled || this.options.type === "static" ) {
27729			return false;
27730		}
27731
27732		//We have to refresh the items data once first
27733		this._refreshItems( event );
27734
27735		//Find out if the clicked node (or one of its parents) is a actual item in this.items
27736		$( event.target ).parents().each( function() {
27737			if ( $.data( this, that.widgetName + "-item" ) === that ) {
27738				currentItem = $( this );
27739				return false;
vendor: 5,334 bytes, lines 27740-27936
27740			}
27741		} );
27742		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
27743			currentItem = $( event.target );
27744		}
27745
27746		if ( !currentItem ) {
27747			return false;
27748		}
27749		if ( this.options.handle && !overrideHandle ) {
27750			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
27751				if ( this === event.target ) {
27752					validHandle = true;
27753				}
27754			} );
27755			if ( !validHandle ) {
27756				return false;
27757			}
27758		}
27759
27760		this.currentItem = currentItem;
27761		this._removeCurrentsFromItems();
27762		return true;
27763
27764	},
27765
27766	_mouseStart: function( event, overrideHandle, noActivation ) {
27767
27768		var i, body,
27769			o = this.options;
27770
27771		this.currentContainer = this;
27772
27773		//We only need to call refreshPositions, because the refreshItems call has been moved to
27774		// mouseCapture
27775		this.refreshPositions();
27776
27777		//Prepare the dragged items parent
27778		this.appendTo = $( o.appendTo !== "parent" ?
27779				o.appendTo :
27780				this.currentItem.parent() );
27781
27782		//Create and append the visible helper
27783		this.helper = this._createHelper( event );
27784
27785		//Cache the helper size
27786		this._cacheHelperProportions();
27787
27788		/*
27789		 * - Position generation -
27790		 * This block generates everything position related - it's the core of draggables.
27791		 */
27792
27793		//Cache the margins of the original element
27794		this._cacheMargins();
27795
27796		//The element's absolute position on the page minus margins
27797		this.offset = this.currentItem.offset();
27798		this.offset = {
27799			top: this.offset.top - this.margins.top,
27800			left: this.offset.left - this.margins.left
27801		};
27802
27803		$.extend( this.offset, {
27804			click: { //Where the click happened, relative to the element
27805				left: event.pageX - this.offset.left,
27806				top: event.pageY - this.offset.top
27807			},
27808
27809			// This is a relative to absolute position minus the actual position calculation -
27810			// only used for relative positioned helper
27811			relative: this._getRelativeOffset()
27812		} );
27813
27814		// After we get the helper offset, but before we get the parent offset we can
27815		// change the helper's position to absolute
27816		// TODO: Still need to figure out a way to make relative sorting possible
27817		this.helper.css( "position", "absolute" );
27818		this.cssPosition = this.helper.css( "position" );
27819
27820		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
27821		if ( o.cursorAt ) {
27822			this._adjustOffsetFromHelper( o.cursorAt );
27823		}
27824
27825		//Cache the former DOM position
27826		this.domPosition = {
27827			prev: this.currentItem.prev()[ 0 ],
27828			parent: this.currentItem.parent()[ 0 ]
27829		};
27830
27831		// If the helper is not the original, hide the original so it's not playing any role during
27832		// the drag, won't cause anything bad this way
27833		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
27834			this.currentItem.hide();
27835		}
27836
27837		//Create the placeholder
27838		this._createPlaceholder();
27839
27840		//Get the next scrolling parent
27841		this.scrollParent = this.placeholder.scrollParent();
27842
27843		$.extend( this.offset, {
27844			parent: this._getParentOffset()
27845		} );
27846
27847		//Set a containment if given in the options
27848		if ( o.containment ) {
27849			this._setContainment();
27850		}
27851
27852		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
27853			body = this.document.find( "body" );
27854
27855			// Support: IE
27856			this.storedCursor = body.css( "cursor" );
27857			body.css( "cursor", o.cursor );
27858
27859			this.storedStylesheet =
27860				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
27861		}
27862
27863		// We need to make sure to grab the zIndex before setting the
27864		// opacity, because setting the opacity to anything lower than 1
27865		// causes the zIndex to change from "auto" to 0.
27866		if ( o.zIndex ) { // zIndex option
27867			if ( this.helper.css( "zIndex" ) ) {
27868				this._storedZIndex = this.helper.css( "zIndex" );
27869			}
27870			this.helper.css( "zIndex", o.zIndex );
27871		}
27872
27873		if ( o.opacity ) { // opacity option
27874			if ( this.helper.css( "opacity" ) ) {
27875				this._storedOpacity = this.helper.css( "opacity" );
27876			}
27877			this.helper.css( "opacity", o.opacity );
27878		}
27879
27880		//Prepare scrolling
27881		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
27882				this.scrollParent[ 0 ].tagName !== "HTML" ) {
27883			this.overflowOffset = this.scrollParent.offset();
27884		}
27885
27886		//Call callbacks
27887		this._trigger( "start", event, this._uiHash() );
27888
27889		//Recache the helper size
27890		if ( !this._preserveHelperProportions ) {
27891			this._cacheHelperProportions();
27892		}
27893
27894		//Post "activate" events to possible containers
27895		if ( !noActivation ) {
27896			for ( i = this.containers.length - 1; i >= 0; i-- ) {
27897				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
27898			}
27899		}
27900
27901		//Prepare possible droppables
27902		if ( $.ui.ddmanager ) {
27903			$.ui.ddmanager.current = this;
27904		}
27905
27906		if ( $.ui.ddmanager && !o.dropBehaviour ) {
27907			$.ui.ddmanager.prepareOffsets( this, event );
27908		}
27909
27910		this.dragging = true;
27911
27912		this._addClass( this.helper, "ui-sortable-helper" );
27913
27914		//Move the helper, if needed
27915		if ( !this.helper.parent().is( this.appendTo ) ) {
27916			this.helper.detach().appendTo( this.appendTo );
27917
27918			//Update position
27919			this.offset.parent = this._getParentOffset();
27920		}
27921
27922		//Generate the original position
27923		this.position = this.originalPosition = this._generatePosition( event );
27924		this.originalPageX = event.pageX;
27925		this.originalPageY = event.pageY;
27926		this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
27927
27928		this._mouseDrag( event );
27929
27930		return true;
27931
27932	},
27933
27934	_scroll: function( event ) {
27935		var o = this.options,
27936			scrolled = false;
vendor: 4,360 bytes, lines 27937-28071
27937
27938		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
27939				this.scrollParent[ 0 ].tagName !== "HTML" ) {
27940
27941			if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
27942					event.pageY < o.scrollSensitivity ) {
27943				this.scrollParent[ 0 ].scrollTop =
27944					scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
27945			} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
27946				this.scrollParent[ 0 ].scrollTop =
27947					scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
27948			}
27949
27950			if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
27951					event.pageX < o.scrollSensitivity ) {
27952				this.scrollParent[ 0 ].scrollLeft = scrolled =
27953					this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
27954			} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
27955				this.scrollParent[ 0 ].scrollLeft = scrolled =
27956					this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
27957			}
27958
27959		} else {
27960
27961			if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
27962				scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
27963			} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
27964					o.scrollSensitivity ) {
27965				scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
27966			}
27967
27968			if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
27969				scrolled = this.document.scrollLeft(
27970					this.document.scrollLeft() - o.scrollSpeed
27971				);
27972			} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
27973					o.scrollSensitivity ) {
27974				scrolled = this.document.scrollLeft(
27975					this.document.scrollLeft() + o.scrollSpeed
27976				);
27977			}
27978
27979		}
27980
27981		return scrolled;
27982	},
27983
27984	_mouseDrag: function( event ) {
27985		var i, item, itemElement, intersection,
27986			o = this.options;
27987
27988		//Compute the helpers position
27989		this.position = this._generatePosition( event );
27990		this.positionAbs = this._convertPositionTo( "absolute" );
27991
27992		//Set the helper position
27993		if ( !this.options.axis || this.options.axis !== "y" ) {
27994			this.helper[ 0 ].style.left = this.position.left + "px";
27995		}
27996		if ( !this.options.axis || this.options.axis !== "x" ) {
27997			this.helper[ 0 ].style.top = this.position.top + "px";
27998		}
27999
28000		//Post events to containers
28001		this._contactContainers( event );
28002
28003		if ( this.innermostContainer !== null ) {
28004
28005			//Do scrolling
28006			if ( o.scroll ) {
28007				if ( this._scroll( event ) !== false ) {
28008
28009					//Update item positions used in position checks
28010					this._refreshItemPositions( true );
28011
28012					if ( $.ui.ddmanager && !o.dropBehaviour ) {
28013						$.ui.ddmanager.prepareOffsets( this, event );
28014					}
28015				}
28016			}
28017
28018			this.dragDirection = {
28019				vertical: this._getDragVerticalDirection(),
28020				horizontal: this._getDragHorizontalDirection()
28021			};
28022
28023			//Rearrange
28024			for ( i = this.items.length - 1; i >= 0; i-- ) {
28025
28026				//Cache variables and intersection, continue if no intersection
28027				item = this.items[ i ];
28028				itemElement = item.item[ 0 ];
28029				intersection = this._intersectsWithPointer( item );
28030				if ( !intersection ) {
28031					continue;
28032				}
28033
28034				// Only put the placeholder inside the current Container, skip all
28035				// items from other containers. This works because when moving
28036				// an item from one container to another the
28037				// currentContainer is switched before the placeholder is moved.
28038				//
28039				// Without this, moving items in "sub-sortables" can cause
28040				// the placeholder to jitter between the outer and inner container.
28041				if ( item.instance !== this.currentContainer ) {
28042					continue;
28043				}
28044
28045				// Cannot intersect with itself
28046				// no useless actions that have been done before
28047				// no action if the item moved is the parent of the item checked
28048				if ( itemElement !== this.currentItem[ 0 ] &&
28049					this.placeholder[ intersection === 1 ?
28050					"next" : "prev" ]()[ 0 ] !== itemElement &&
28051					!$.contains( this.placeholder[ 0 ], itemElement ) &&
28052					( this.options.type === "semi-dynamic" ?
28053						!$.contains( this.element[ 0 ], itemElement ) :
28054						true
28055					)
28056				) {
28057
28058					this.direction = intersection === 1 ? "down" : "up";
28059
28060					if ( this.options.tolerance === "pointer" ||
28061							this._intersectsWithSides( item ) ) {
28062						this._rearrange( event, item );
28063					} else {
28064						break;
28065					}
28066
28067					this._trigger( "change", event, this._uiHash() );
28068					break;
28069				}
28070			}
28071		}
vendor: 5,297 bytes, lines 28071-28272
28071
28072
28073		//Interconnect with droppables
28074		if ( $.ui.ddmanager ) {
28075			$.ui.ddmanager.drag( this, event );
28076		}
28077
28078		//Call callbacks
28079		this._trigger( "sort", event, this._uiHash() );
28080
28081		this.lastPositionAbs = this.positionAbs;
28082		return false;
28083
28084	},
28085
28086	_mouseStop: function( event, noPropagation ) {
28087
28088		if ( !event ) {
28089			return;
28090		}
28091
28092		//If we are using droppables, inform the manager about the drop
28093		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
28094			$.ui.ddmanager.drop( this, event );
28095		}
28096
28097		if ( this.options.revert ) {
28098			var that = this,
28099				cur = this.placeholder.offset(),
28100				axis = this.options.axis,
28101				animation = {};
28102
28103			if ( !axis || axis === "x" ) {
28104				animation.left = cur.left - this.offset.parent.left - this.margins.left +
28105					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
28106						0 :
28107						this.offsetParent[ 0 ].scrollLeft
28108					);
28109			}
28110			if ( !axis || axis === "y" ) {
28111				animation.top = cur.top - this.offset.parent.top - this.margins.top +
28112					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
28113						0 :
28114						this.offsetParent[ 0 ].scrollTop
28115					);
28116			}
28117			this.reverting = true;
28118			$( this.helper ).animate(
28119				animation,
28120				parseInt( this.options.revert, 10 ) || 500,
28121				function() {
28122					that._clear( event );
28123				}
28124			);
28125		} else {
28126			this._clear( event, noPropagation );
28127		}
28128
28129		return false;
28130
28131	},
28132
28133	cancel: function() {
28134
28135		if ( this.dragging ) {
28136
28137			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
28138
28139			if ( this.options.helper === "original" ) {
28140				this.currentItem.css( this._storedCSS );
28141				this._removeClass( this.currentItem, "ui-sortable-helper" );
28142			} else {
28143				this.currentItem.show();
28144			}
28145
28146			//Post deactivating events to containers
28147			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
28148				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
28149				if ( this.containers[ i ].containerCache.over ) {
28150					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
28151					this.containers[ i ].containerCache.over = 0;
28152				}
28153			}
28154
28155		}
28156
28157		if ( this.placeholder ) {
28158
28159			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
28160			// it unbinds ALL events from the original node!
28161			if ( this.placeholder[ 0 ].parentNode ) {
28162				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
28163			}
28164			if ( this.options.helper !== "original" && this.helper &&
28165					this.helper[ 0 ].parentNode ) {
28166				this.helper.remove();
28167			}
28168
28169			$.extend( this, {
28170				helper: null,
28171				dragging: false,
28172				reverting: false,
28173				_noFinalSort: null
28174			} );
28175
28176			if ( this.domPosition.prev ) {
28177				$( this.domPosition.prev ).after( this.currentItem );
28178			} else {
28179				$( this.domPosition.parent ).prepend( this.currentItem );
28180			}
28181		}
28182
28183		return this;
28184
28185	},
28186
28187	serialize: function( o ) {
28188
28189		var items = this._getItemsAsjQuery( o && o.connected ),
28190			str = [];
28191		o = o || {};
28192
28193		$( items ).each( function() {
28194			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
28195				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
28196			if ( res ) {
28197				str.push(
28198					( o.key || res[ 1 ] + "[]" ) +
28199					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
28200			}
28201		} );
28202
28203		if ( !str.length && o.key ) {
28204			str.push( o.key + "=" );
28205		}
28206
28207		return str.join( "&" );
28208
28209	},
28210
28211	toArray: function( o ) {
28212
28213		var items = this._getItemsAsjQuery( o && o.connected ),
28214			ret = [];
28215
28216		o = o || {};
28217
28218		items.each( function() {
28219			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
28220		} );
28221		return ret;
28222
28223	},
28224
28225	/* Be careful with the following core functions */
28226	_intersectsWith: function( item ) {
28227
28228		var x1 = this.positionAbs.left,
28229			x2 = x1 + this.helperProportions.width,
28230			y1 = this.positionAbs.top,
28231			y2 = y1 + this.helperProportions.height,
28232			l = item.left,
28233			r = l + item.width,
28234			t = item.top,
28235			b = t + item.height,
28236			dyClick = this.offset.click.top,
28237			dxClick = this.offset.click.left,
28238			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
28239				( y1 + dyClick ) < b ),
28240			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
28241				( x1 + dxClick ) < r ),
28242			isOverElement = isOverElementHeight && isOverElementWidth;
28243
28244		if ( this.options.tolerance === "pointer" ||
28245			this.options.forcePointerForContainers ||
28246			( this.options.tolerance !== "pointer" &&
28247				this.helperProportions[ this.floating ? "width" : "height" ] >
28248				item[ this.floating ? "width" : "height" ] )
28249		) {
28250			return isOverElement;
28251		} else {
28252
28253			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
28254				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
28255				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
28256				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
28257
28258		}
28259	},
28260
28261	_intersectsWithPointer: function( item ) {
28262		var verticalDirection, horizontalDirection,
28263			isOverElementHeight = ( this.options.axis === "x" ) ||
28264				this._isOverAxis(
28265					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
28266			isOverElementWidth = ( this.options.axis === "y" ) ||
28267				this._isOverAxis(
28268					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
28269			isOverElement = isOverElementHeight && isOverElementWidth;
28270
28271		if ( !isOverElement ) {
28272			return false;
vendor: 5,624 bytes, lines 28273-28467
28273		}
28274
28275		verticalDirection = this.dragDirection.vertical;
28276		horizontalDirection = this.dragDirection.horizontal;
28277
28278		return this.floating ?
28279			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
28280			( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
28281
28282	},
28283
28284	_intersectsWithSides: function( item ) {
28285
28286		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
28287				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
28288			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
28289				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
28290			verticalDirection = this.dragDirection.vertical,
28291			horizontalDirection = this.dragDirection.horizontal;
28292
28293		if ( this.floating && horizontalDirection ) {
28294			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
28295				( horizontalDirection === "left" && !isOverRightHalf ) );
28296		} else {
28297			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
28298				( verticalDirection === "up" && !isOverBottomHalf ) );
28299		}
28300
28301	},
28302
28303	_getDragVerticalDirection: function() {
28304		var delta = this.positionAbs.top - this.lastPositionAbs.top;
28305		return delta !== 0 && ( delta > 0 ? "down" : "up" );
28306	},
28307
28308	_getDragHorizontalDirection: function() {
28309		var delta = this.positionAbs.left - this.lastPositionAbs.left;
28310		return delta !== 0 && ( delta > 0 ? "right" : "left" );
28311	},
28312
28313	refresh: function( event ) {
28314		this._refreshItems( event );
28315		this._setHandleClassName();
28316		this.refreshPositions();
28317		return this;
28318	},
28319
28320	_connectWith: function() {
28321		var options = this.options;
28322		return options.connectWith.constructor === String ?
28323			[ options.connectWith ] :
28324			options.connectWith;
28325	},
28326
28327	_getItemsAsjQuery: function( connected ) {
28328
28329		var i, j, cur, inst,
28330			items = [],
28331			queries = [],
28332			connectWith = this._connectWith();
28333
28334		if ( connectWith && connected ) {
28335			for ( i = connectWith.length - 1; i >= 0; i-- ) {
28336				cur = $( connectWith[ i ], this.document[ 0 ] );
28337				for ( j = cur.length - 1; j >= 0; j-- ) {
28338					inst = $.data( cur[ j ], this.widgetFullName );
28339					if ( inst && inst !== this && !inst.options.disabled ) {
28340						queries.push( [ typeof inst.options.items === "function" ?
28341							inst.options.items.call( inst.element ) :
28342							$( inst.options.items, inst.element )
28343								.not( ".ui-sortable-helper" )
28344								.not( ".ui-sortable-placeholder" ), inst ] );
28345					}
28346				}
28347			}
28348		}
28349
28350		queries.push( [ typeof this.options.items === "function" ?
28351			this.options.items
28352				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
28353			$( this.options.items, this.element )
28354				.not( ".ui-sortable-helper" )
28355				.not( ".ui-sortable-placeholder" ), this ] );
28356
28357		function addItems() {
28358			items.push( this );
28359		}
28360		for ( i = queries.length - 1; i >= 0; i-- ) {
28361			queries[ i ][ 0 ].each( addItems );
28362		}
28363
28364		return $( items );
28365
28366	},
28367
28368	_removeCurrentsFromItems: function() {
28369
28370		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
28371
28372		this.items = $.grep( this.items, function( item ) {
28373			for ( var j = 0; j < list.length; j++ ) {
28374				if ( list[ j ] === item.item[ 0 ] ) {
28375					return false;
28376				}
28377			}
28378			return true;
28379		} );
28380
28381	},
28382
28383	_refreshItems: function( event ) {
28384
28385		this.items = [];
28386		this.containers = [ this ];
28387
28388		var i, j, cur, inst, targetData, _queries, item, queriesLength,
28389			items = this.items,
28390			queries = [ [ typeof this.options.items === "function" ?
28391				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
28392				$( this.options.items, this.element ), this ] ],
28393			connectWith = this._connectWith();
28394
28395		//Shouldn't be run the first time through due to massive slow-down
28396		if ( connectWith && this.ready ) {
28397			for ( i = connectWith.length - 1; i >= 0; i-- ) {
28398				cur = $( connectWith[ i ], this.document[ 0 ] );
28399				for ( j = cur.length - 1; j >= 0; j-- ) {
28400					inst = $.data( cur[ j ], this.widgetFullName );
28401					if ( inst && inst !== this && !inst.options.disabled ) {
28402						queries.push( [ typeof inst.options.items === "function" ?
28403							inst.options.items
28404								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
28405							$( inst.options.items, inst.element ), inst ] );
28406						this.containers.push( inst );
28407					}
28408				}
28409			}
28410		}
28411
28412		for ( i = queries.length - 1; i >= 0; i-- ) {
28413			targetData = queries[ i ][ 1 ];
28414			_queries = queries[ i ][ 0 ];
28415
28416			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
28417				item = $( _queries[ j ] );
28418
28419				// Data for target checking (mouse manager)
28420				item.data( this.widgetName + "-item", targetData );
28421
28422				items.push( {
28423					item: item,
28424					instance: targetData,
28425					width: 0, height: 0,
28426					left: 0, top: 0
28427				} );
28428			}
28429		}
28430
28431	},
28432
28433	_refreshItemPositions: function( fast ) {
28434		var i, item, t, p;
28435
28436		for ( i = this.items.length - 1; i >= 0; i-- ) {
28437			item = this.items[ i ];
28438
28439			//We ignore calculating positions of all connected containers when we're not over them
28440			if ( this.currentContainer && item.instance !== this.currentContainer &&
28441					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
28442				continue;
28443			}
28444
28445			t = this.options.toleranceElement ?
28446				$( this.options.toleranceElement, item.item ) :
28447				item.item;
28448
28449			if ( !fast ) {
28450				item.width = t.outerWidth();
28451				item.height = t.outerHeight();
28452			}
28453
28454			p = t.offset();
28455			item.left = p.left;
28456			item.top = p.top;
28457		}
28458	},
28459
28460	refreshPositions: function( fast ) {
28461
28462		// Determine whether items are being displayed horizontally
28463		this.floating = this.items.length ?
28464			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
28465			false;
28466
28467		
vendor: 4,943 bytes, lines 28467-28617
28467if ( this.innermostContainer !== null ) {
28468			this._refreshItemPositions( fast );
28469		}
28470
28471		var i, p;
28472
28473		if ( this.options.custom && this.options.custom.refreshContainers ) {
28474			this.options.custom.refreshContainers.call( this );
28475		} else {
28476			for ( i = this.containers.length - 1; i >= 0; i-- ) {
28477				p = this.containers[ i ].element.offset();
28478				this.containers[ i ].containerCache.left = p.left;
28479				this.containers[ i ].containerCache.top = p.top;
28480				this.containers[ i ].containerCache.width =
28481					this.containers[ i ].element.outerWidth();
28482				this.containers[ i ].containerCache.height =
28483					this.containers[ i ].element.outerHeight();
28484			}
28485		}
28486
28487		return this;
28488	},
28489
28490	_createPlaceholder: function( that ) {
28491		that = that || this;
28492		var className, nodeName,
28493			o = that.options;
28494
28495		if ( !o.placeholder || o.placeholder.constructor === String ) {
28496			className = o.placeholder;
28497			nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
28498			o.placeholder = {
28499				element: function() {
28500
28501					var element = $( "<" + nodeName + ">", that.document[ 0 ] );
28502
28503					that._addClass( element, "ui-sortable-placeholder",
28504							className || that.currentItem[ 0 ].className )
28505						._removeClass( element, "ui-sortable-helper" );
28506
28507					if ( nodeName === "tbody" ) {
28508						that._createTrPlaceholder(
28509							that.currentItem.find( "tr" ).eq( 0 ),
28510							$( "<tr>", that.document[ 0 ] ).appendTo( element )
28511						);
28512					} else if ( nodeName === "tr" ) {
28513						that._createTrPlaceholder( that.currentItem, element );
28514					} else if ( nodeName === "img" ) {
28515						element.attr( "src", that.currentItem.attr( "src" ) );
28516					}
28517
28518					if ( !className ) {
28519						element.css( "visibility", "hidden" );
28520					}
28521
28522					return element;
28523				},
28524				update: function( container, p ) {
28525
28526					// 1. If a className is set as 'placeholder option, we don't force sizes -
28527					// the class is responsible for that
28528					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
28529					// class name is specified
28530					if ( className && !o.forcePlaceholderSize ) {
28531						return;
28532					}
28533
28534					// If the element doesn't have a actual height or width by itself (without
28535					// styles coming from a stylesheet), it receives the inline height and width
28536					// from the dragged item. Or, if it's a tbody or tr, it's going to have a height
28537					// anyway since we're populating them with <td>s above, but they're unlikely to
28538					// be the correct height on their own if the row heights are dynamic, so we'll
28539					// always assign the height of the dragged item given forcePlaceholderSize
28540					// is true.
28541					if ( !p.height() || ( o.forcePlaceholderSize &&
28542							( nodeName === "tbody" || nodeName === "tr" ) ) ) {
28543						p.height(
28544							that.currentItem.innerHeight() -
28545							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
28546							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
28547					}
28548					if ( !p.width() ) {
28549						p.width(
28550							that.currentItem.innerWidth() -
28551							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
28552							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
28553					}
28554				}
28555			};
28556		}
28557
28558		//Create the placeholder
28559		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
28560
28561		//Append it after the actual current item
28562		that.currentItem.after( that.placeholder );
28563
28564		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
28565		o.placeholder.update( that, that.placeholder );
28566
28567	},
28568
28569	_createTrPlaceholder: function( sourceTr, targetTr ) {
28570		var that = this;
28571
28572		sourceTr.children().each( function() {
28573			$( "<td>&#160;</td>", that.document[ 0 ] )
28574				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
28575				.appendTo( targetTr );
28576		} );
28577	},
28578
28579	_contactContainers: function( event ) {
28580		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
28581			floating, axis,
28582			innermostContainer = null,
28583			innermostIndex = null;
28584
28585		// Get innermost container that intersects with item
28586		for ( i = this.containers.length - 1; i >= 0; i-- ) {
28587
28588			// Never consider a container that's located within the item itself
28589			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
28590				continue;
28591			}
28592
28593			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
28594
28595				// If we've already found a container and it's more "inner" than this, then continue
28596				if ( innermostContainer &&
28597						$.contains(
28598							this.containers[ i ].element[ 0 ],
28599							innermostContainer.element[ 0 ] ) ) {
28600					continue;
28601				}
28602
28603				innermostContainer = this.containers[ i ];
28604				innermostIndex = i;
28605
28606			} else {
28607
28608				// container doesn't intersect. trigger "out" event if necessary
28609				if ( this.containers[ i ].containerCache.over ) {
28610					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
28611					this.containers[ i ].containerCache.over = 0;
28612				}
28613			}
28614
28615		}
28616
28617		this.innermostContainer = innermostContainer;
vendor: 9,708 bytes, lines 28617-28905
28617
28618
28619		// If no intersecting containers found, return
28620		if ( !innermostContainer ) {
28621			return;
28622		}
28623
28624		// Move the item into the container if it's not there already
28625		if ( this.containers.length === 1 ) {
28626			if ( !this.containers[ innermostIndex ].containerCache.over ) {
28627				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
28628				this.containers[ innermostIndex ].containerCache.over = 1;
28629			}
28630		} else {
28631
28632			// When entering a new container, we will find the item with the least distance and
28633			// append our item near it
28634			dist = 10000;
28635			itemWithLeastDistance = null;
28636			floating = innermostContainer.floating || this._isFloating( this.currentItem );
28637			posProperty = floating ? "left" : "top";
28638			sizeProperty = floating ? "width" : "height";
28639			axis = floating ? "pageX" : "pageY";
28640
28641			for ( j = this.items.length - 1; j >= 0; j-- ) {
28642				if ( !$.contains(
28643						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
28644				) {
28645					continue;
28646				}
28647				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
28648					continue;
28649				}
28650
28651				cur = this.items[ j ].item.offset()[ posProperty ];
28652				nearBottom = false;
28653				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
28654					nearBottom = true;
28655				}
28656
28657				if ( Math.abs( event[ axis ] - cur ) < dist ) {
28658					dist = Math.abs( event[ axis ] - cur );
28659					itemWithLeastDistance = this.items[ j ];
28660					this.direction = nearBottom ? "up" : "down";
28661				}
28662			}
28663
28664			//Check if dropOnEmpty is enabled
28665			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
28666				return;
28667			}
28668
28669			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
28670				if ( !this.currentContainer.containerCache.over ) {
28671					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
28672					this.currentContainer.containerCache.over = 1;
28673				}
28674				return;
28675			}
28676
28677			if ( itemWithLeastDistance ) {
28678				this._rearrange( event, itemWithLeastDistance, null, true );
28679			} else {
28680				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
28681			}
28682			this._trigger( "change", event, this._uiHash() );
28683			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
28684			this.currentContainer = this.containers[ innermostIndex ];
28685
28686			//Update the placeholder
28687			this.options.placeholder.update( this.currentContainer, this.placeholder );
28688
28689			//Update scrollParent
28690			this.scrollParent = this.placeholder.scrollParent();
28691
28692			//Update overflowOffset
28693			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28694					this.scrollParent[ 0 ].tagName !== "HTML" ) {
28695				this.overflowOffset = this.scrollParent.offset();
28696			}
28697
28698			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
28699			this.containers[ innermostIndex ].containerCache.over = 1;
28700		}
28701
28702	},
28703
28704	_createHelper: function( event ) {
28705
28706		var o = this.options,
28707			helper = typeof o.helper === "function" ?
28708				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
28709				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
28710
28711		//Add the helper to the DOM if that didn't happen already
28712		if ( !helper.parents( "body" ).length ) {
28713			this.appendTo[ 0 ].appendChild( helper[ 0 ] );
28714		}
28715
28716		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
28717			this._storedCSS = {
28718				width: this.currentItem[ 0 ].style.width,
28719				height: this.currentItem[ 0 ].style.height,
28720				position: this.currentItem.css( "position" ),
28721				top: this.currentItem.css( "top" ),
28722				left: this.currentItem.css( "left" )
28723			};
28724		}
28725
28726		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
28727			helper.width( this.currentItem.width() );
28728		}
28729		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
28730			helper.height( this.currentItem.height() );
28731		}
28732
28733		return helper;
28734
28735	},
28736
28737	_adjustOffsetFromHelper: function( obj ) {
28738		if ( typeof obj === "string" ) {
28739			obj = obj.split( " " );
28740		}
28741		if ( Array.isArray( obj ) ) {
28742			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
28743		}
28744		if ( "left" in obj ) {
28745			this.offset.click.left = obj.left + this.margins.left;
28746		}
28747		if ( "right" in obj ) {
28748			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
28749		}
28750		if ( "top" in obj ) {
28751			this.offset.click.top = obj.top + this.margins.top;
28752		}
28753		if ( "bottom" in obj ) {
28754			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
28755		}
28756	},
28757
28758	_getParentOffset: function() {
28759
28760		//Get the offsetParent and cache its position
28761		this.offsetParent = this.helper.offsetParent();
28762		var po = this.offsetParent.offset();
28763
28764		// This is a special case where we need to modify a offset calculated on start, since the
28765		// following happened:
28766		// 1. The position of the helper is absolute, so it's position is calculated based on the
28767		// next positioned parent
28768		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
28769		// the document, which means that the scroll is included in the initial calculation of the
28770		// offset of the parent, and never recalculated upon drag
28771		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28772				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
28773			po.left += this.scrollParent.scrollLeft();
28774			po.top += this.scrollParent.scrollTop();
28775		}
28776
28777		// This needs to be actually done for all browsers, since pageX/pageY includes this
28778		// information with an ugly IE fix
28779		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
28780				( this.offsetParent[ 0 ].tagName &&
28781				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
28782			po = { top: 0, left: 0 };
28783		}
28784
28785		return {
28786			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
28787			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
28788		};
28789
28790	},
28791
28792	_getRelativeOffset: function() {
28793
28794		if ( this.cssPosition === "relative" ) {
28795			var p = this.currentItem.position();
28796			return {
28797				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
28798					this.scrollParent.scrollTop(),
28799				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
28800					this.scrollParent.scrollLeft()
28801			};
28802		} else {
28803			return { top: 0, left: 0 };
28804		}
28805
28806	},
28807
28808	_cacheMargins: function() {
28809		this.margins = {
28810			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
28811			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
28812		};
28813	},
28814
28815	_cacheHelperProportions: function() {
28816		this.helperProportions = {
28817			width: this.helper.outerWidth(),
28818			height: this.helper.outerHeight()
28819		};
28820	},
28821
28822	_setContainment: function() {
28823
28824		var ce, co, over,
28825			o = this.options;
28826		if ( o.containment === "parent" ) {
28827			o.containment = this.helper[ 0 ].parentNode;
28828		}
28829		if ( o.containment === "document" || o.containment === "window" ) {
28830			this.containment = [
28831				0 - this.offset.relative.left - this.offset.parent.left,
28832				0 - this.offset.relative.top - this.offset.parent.top,
28833				o.containment === "document" ?
28834					this.document.width() :
28835					this.window.width() - this.helperProportions.width - this.margins.left,
28836				( o.containment === "document" ?
28837					( this.document.height() || document.body.parentNode.scrollHeight ) :
28838					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
28839				) - this.helperProportions.height - this.margins.top
28840			];
28841		}
28842
28843		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
28844			ce = $( o.containment )[ 0 ];
28845			co = $( o.containment ).offset();
28846			over = ( $( ce ).css( "overflow" ) !== "hidden" );
28847
28848			this.containment = [
28849				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
28850					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
28851				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
28852					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
28853				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
28854					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
28855					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
28856					this.helperProportions.width - this.margins.left,
28857				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
28858					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
28859					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
28860					this.helperProportions.height - this.margins.top
28861			];
28862		}
28863
28864	},
28865
28866	_convertPositionTo: function( d, pos ) {
28867
28868		if ( !pos ) {
28869			pos = this.position;
28870		}
28871		var mod = d === "absolute" ? 1 : -1,
28872			scroll = this.cssPosition === "absolute" &&
28873				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28874				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
28875					this.offsetParent :
28876					this.scrollParent,
28877			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
28878
28879		return {
28880			top: (
28881
28882				// The absolute mouse position
28883				pos.top	+
28884
28885				// Only for relative positioned nodes: Relative offset from element to offset parent
28886				this.offset.relative.top * mod +
28887
28888				// The offsetParent's offset without borders (offset + border)
28889				this.offset.parent.top * mod -
28890				( ( this.cssPosition === "fixed" ?
28891					-this.scrollParent.scrollTop() :
28892					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
28893			),
28894			left: (
28895
28896				// The absolute mouse position
28897				pos.left +
28898
28899				// Only for relative positioned nodes: Relative offset from element to offset parent
28900				this.offset.relative.left * mod +
28901
28902				// The offsetParent's offset without borders (offset + border)
28903				this.offset.parent.left * mod	-
28904				( ( this.cssPosition === "fixed" ?
28905					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 4,632 bytes, lines 28906-29049
28906					scroll.scrollLeft() ) * mod )
28907			)
28908		};
28909
28910	},
28911
28912	_generatePosition: function( event ) {
28913
28914		var top, left,
28915			o = this.options,
28916			pageX = event.pageX,
28917			pageY = event.pageY,
28918			scroll = this.cssPosition === "absolute" &&
28919				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28920				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
28921					this.offsetParent :
28922					this.scrollParent,
28923				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
28924
28925		// This is another very weird special case that only happens for relative elements:
28926		// 1. If the css position is relative
28927		// 2. and the scroll parent is the document or similar to the offset parent
28928		// we have to refresh the relative offset during the scroll so there are no jumps
28929		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
28930				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
28931			this.offset.relative = this._getRelativeOffset();
28932		}
28933
28934		/*
28935		 * - Position constraining -
28936		 * Constrain the position to a mix of grid, containment.
28937		 */
28938
28939		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
28940
28941			if ( this.containment ) {
28942				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
28943					pageX = this.containment[ 0 ] + this.offset.click.left;
28944				}
28945				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
28946					pageY = this.containment[ 1 ] + this.offset.click.top;
28947				}
28948				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
28949					pageX = this.containment[ 2 ] + this.offset.click.left;
28950				}
28951				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
28952					pageY = this.containment[ 3 ] + this.offset.click.top;
28953				}
28954			}
28955
28956			if ( o.grid ) {
28957				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
28958					o.grid[ 1 ] ) * o.grid[ 1 ];
28959				pageY = this.containment ?
28960					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
28961						top - this.offset.click.top <= this.containment[ 3 ] ) ?
28962							top :
28963							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
28964								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
28965								top;
28966
28967				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
28968					o.grid[ 0 ] ) * o.grid[ 0 ];
28969				pageX = this.containment ?
28970					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
28971						left - this.offset.click.left <= this.containment[ 2 ] ) ?
28972							left :
28973							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
28974								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
28975								left;
28976			}
28977
28978		}
28979
28980		return {
28981			top: (
28982
28983				// The absolute mouse position
28984				pageY -
28985
28986				// Click offset (relative to the element)
28987				this.offset.click.top -
28988
28989				// Only for relative positioned nodes: Relative offset from element to offset parent
28990				this.offset.relative.top -
28991
28992				// The offsetParent's offset without borders (offset + border)
28993				this.offset.parent.top +
28994				( ( this.cssPosition === "fixed" ?
28995					-this.scrollParent.scrollTop() :
28996					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
28997			),
28998			left: (
28999
29000				// The absolute mouse position
29001				pageX -
29002
29003				// Click offset (relative to the element)
29004				this.offset.click.left -
29005
29006				// Only for relative positioned nodes: Relative offset from element to offset parent
29007				this.offset.relative.left -
29008
29009				// The offsetParent's offset without borders (offset + border)
29010				this.offset.parent.left +
29011				( ( this.cssPosition === "fixed" ?
29012					-this.scrollParent.scrollLeft() :
29013					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
29014			)
29015		};
29016
29017	},
29018
29019	_rearrange: function( event, i, a, hardRefresh ) {
29020
29021		if ( a ) {
29022			a[ 0 ].appendChild( this.placeholder[ 0 ] );
29023		} else {
29024			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
29025				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
29026		}
29027
29028		//Various things done here to improve the performance:
29029		// 1. we create a setTimeout, that calls refreshPositions
29030		// 2. on the instance, we have a counter variable, that get's higher after every append
29031		// 3. on the local scope, we copy the counter variable, and check in the timeout,
29032		// if it's still the same
29033		// 4. this lets only the last addition to the timeout stack through
29034		this.counter = this.counter ? ++this.counter : 1;
29035		var counter = this.counter;
29036
29037		this._delay( function() {
29038			if ( counter === this.counter ) {
29039
29040				//Precompute after each DOM insertion, NOT on mousemove
29041				this.refreshPositions( !hardRefresh );
29042			}
29043		} );
29044
29045	},
29046
29047	_clear: function( event, noPropagation ) {
29048
29049		this.reverting = false;
vendor: 4,252 bytes, lines 29050-29191
29050
29051		// We delay all events that have to be triggered to after the point where the placeholder
29052		// has been removed and everything else normalized again
29053		var i,
29054			delayedTriggers = [];
29055
29056		// We first have to update the dom position of the actual currentItem
29057		// Note: don't do it if the current item is already removed (by a user), or it gets
29058		// reappended (see #4088)
29059		if ( !this._noFinalSort && this.currentItem.parent().length ) {
29060			this.placeholder.before( this.currentItem );
29061		}
29062		this._noFinalSort = null;
29063
29064		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
29065			for ( i in this._storedCSS ) {
29066				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
29067					this._storedCSS[ i ] = "";
29068				}
29069			}
29070			this.currentItem.css( this._storedCSS );
29071			this._removeClass( this.currentItem, "ui-sortable-helper" );
29072		} else {
29073			this.currentItem.show();
29074		}
29075
29076		if ( this.fromOutside && !noPropagation ) {
29077			delayedTriggers.push( function( event ) {
29078				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
29079			} );
29080		}
29081		if ( ( this.fromOutside ||
29082				this.domPosition.prev !==
29083				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
29084				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
29085
29086			// Trigger update callback if the DOM position has changed
29087			delayedTriggers.push( function( event ) {
29088				this._trigger( "update", event, this._uiHash() );
29089			} );
29090		}
29091
29092		// Check if the items Container has Changed and trigger appropriate
29093		// events.
29094		if ( this !== this.currentContainer ) {
29095			if ( !noPropagation ) {
29096				delayedTriggers.push( function( event ) {
29097					this._trigger( "remove", event, this._uiHash() );
29098				} );
29099				delayedTriggers.push( ( function( c ) {
29100					return function( event ) {
29101						c._trigger( "receive", event, this._uiHash( this ) );
29102					};
29103				} ).call( this, this.currentContainer ) );
29104				delayedTriggers.push( ( function( c ) {
29105					return function( event ) {
29106						c._trigger( "update", event, this._uiHash( this ) );
29107					};
29108				} ).call( this, this.currentContainer ) );
29109			}
29110		}
29111
29112		//Post events to containers
29113		function delayEvent( type, instance, container ) {
29114			return function( event ) {
29115				container._trigger( type, event, instance._uiHash( instance ) );
29116			};
29117		}
29118		for ( i = this.containers.length - 1; i >= 0; i-- ) {
29119			if ( !noPropagation ) {
29120				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
29121			}
29122			if ( this.containers[ i ].containerCache.over ) {
29123				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
29124				this.containers[ i ].containerCache.over = 0;
29125			}
29126		}
29127
29128		//Do what was originally in plugins
29129		if ( this.storedCursor ) {
29130			this.document.find( "body" ).css( "cursor", this.storedCursor );
29131			this.storedStylesheet.remove();
29132		}
29133		if ( this._storedOpacity ) {
29134			this.helper.css( "opacity", this._storedOpacity );
29135		}
29136		if ( this._storedZIndex ) {
29137			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
29138		}
29139
29140		this.dragging = false;
29141
29142		if ( !noPropagation ) {
29143			this._trigger( "beforeStop", event, this._uiHash() );
29144		}
29145
29146		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
29147		// it unbinds ALL events from the original node!
29148		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
29149
29150		if ( !this.cancelHelperRemoval ) {
29151			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
29152				this.helper.remove();
29153			}
29154			this.helper = null;
29155		}
29156
29157		if ( !noPropagation ) {
29158			for ( i = 0; i < delayedTriggers.length; i++ ) {
29159
29160				// Trigger all delayed events
29161				delayedTriggers[ i ].call( this, event );
29162			}
29163			this._trigger( "stop", event, this._uiHash() );
29164		}
29165
29166		this.fromOutside = false;
29167		return !this.cancelHelperRemoval;
29168
29169	},
29170
29171	_trigger: function() {
29172		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
29173			this.cancel();
29174		}
29175	},
29176
29177	_uiHash: function( _inst ) {
29178		var inst = _inst || this;
29179		return {
29180			helper: inst.helper,
29181			placeholder: inst.placeholder || $( [] ),
29182			position: inst.position,
29183			originalPosition: inst.originalPosition,
29184			offset: inst.positionAbs,
29185			item: inst.currentItem,
29186			sender: _inst ? _inst.element : null
29187		};
29188	}
29189
29190} );
29191
29192} );
29193
29194
29195
29196
29197
29198
29199/*!
29200 * jQuery UI Spinner 1.13.0
29201 * http://jqueryui.com
29202 *
29203 * Copyright jQuery Foundation and other contributors
29204 * Released under the MIT license.
29205 * http://jquery.org/license
29206 */
29207
29208//>>label: Spinner
29209//>>group: Widgets
29210//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
29211//>>docs: http://api.jqueryui.com/spinner/
29212//>>demos: http://jqueryui.com/spinner/
29213//>>css.structure: ../../themes/base/core.css
29214//>>css.structure: ../../themes/base/spinner.css
29215//>>css.theme: ../../themes/base/theme.css
29216
29217( function( factory ) {
29218	"use strict";
29219
29220	if ( typeof define === "function" && define.amd ) {
29221
29222		// AMD. Register as an anonymous module.
29223		define( [
29224			"jquery",
29225			"./button",
29226			"../version",
29227			"../keycode",
29228			"../safe-active-element",
29229			"../widget"
29230		], factory );
29231	} else {
29232
29233		// Browser globals
29234		factory( jQuery );
29235	}
29236} )( function( $ ) {
29237"use strict";
29238
29239function spinnerModifier( fn ) {
29240	return function() {
29241		var previous = this.element.val();
29242		fn.apply( this, arguments );
29243		this._refresh();
29244		if ( previous !== this.element.val() ) {
29245			this._trigger( "change" );
29246		}
29247	};
29248}
29249
29250$.widget( "ui.spinner", {
29251	version: "1.13.0
vendor: 13,246 bytes, lines 29251-29777
29251",
29252	defaultElement: "<input>",
29253	widgetEventPrefix: "spin",
29254	options: {
29255		classes: {
29256			"ui-spinner": "ui-corner-all",
29257			"ui-spinner-down": "ui-corner-br",
29258			"ui-spinner-up": "ui-corner-tr"
29259		},
29260		culture: null,
29261		icons: {
29262			down: "ui-icon-triangle-1-s",
29263			up: "ui-icon-triangle-1-n"
29264		},
29265		incremental: true,
29266		max: null,
29267		min: null,
29268		numberFormat: null,
29269		page: 10,
29270		step: 1,
29271
29272		change: null,
29273		spin: null,
29274		start: null,
29275		stop: null
29276	},
29277
29278	_create: function() {
29279
29280		// handle string values that need to be parsed
29281		this._setOption( "max", this.options.max );
29282		this._setOption( "min", this.options.min );
29283		this._setOption( "step", this.options.step );
29284
29285		// Only format if there is a value, prevents the field from being marked
29286		// as invalid in Firefox, see #9573.
29287		if ( this.value() !== "" ) {
29288
29289			// Format the value, but don't constrain.
29290			this._value( this.element.val(), true );
29291		}
29292
29293		this._draw();
29294		this._on( this._events );
29295		this._refresh();
29296
29297		// Turning off autocomplete prevents the browser from remembering the
29298		// value when navigating through history, so we re-enable autocomplete
29299		// if the page is unloaded before the widget is destroyed. #7790
29300		this._on( this.window, {
29301			beforeunload: function() {
29302				this.element.removeAttr( "autocomplete" );
29303			}
29304		} );
29305	},
29306
29307	_getCreateOptions: function() {
29308		var options = this._super();
29309		var element = this.element;
29310
29311		$.each( [ "min", "max", "step" ], function( i, option ) {
29312			var value = element.attr( option );
29313			if ( value != null && value.length ) {
29314				options[ option ] = value;
29315			}
29316		} );
29317
29318		return options;
29319	},
29320
29321	_events: {
29322		keydown: function( event ) {
29323			if ( this._start( event ) && this._keydown( event ) ) {
29324				event.preventDefault();
29325			}
29326		},
29327		keyup: "_stop",
29328		focus: function() {
29329			this.previous = this.element.val();
29330		},
29331		blur: function( event ) {
29332			if ( this.cancelBlur ) {
29333				delete this.cancelBlur;
29334				return;
29335			}
29336
29337			this._stop();
29338			this._refresh();
29339			if ( this.previous !== this.element.val() ) {
29340				this._trigger( "change", event );
29341			}
29342		},
29343		mousewheel: function( event, delta ) {
29344			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] );
29345			var isActive = this.element[ 0 ] === activeElement;
29346
29347			if ( !isActive || !delta ) {
29348				return;
29349			}
29350
29351			if ( !this.spinning && !this._start( event ) ) {
29352				return false;
29353			}
29354
29355			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
29356			clearTimeout( this.mousewheelTimer );
29357			this.mousewheelTimer = this._delay( function() {
29358				if ( this.spinning ) {
29359					this._stop( event );
29360				}
29361			}, 100 );
29362			event.preventDefault();
29363		},
29364		"mousedown .ui-spinner-button": function( event ) {
29365			var previous;
29366
29367			// We never want the buttons to have focus; whenever the user is
29368			// interacting with the spinner, the focus should be on the input.
29369			// If the input is focused then this.previous is properly set from
29370			// when the input first received focus. If the input is not focused
29371			// then we need to set this.previous based on the value before spinning.
29372			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
29373				this.previous : this.element.val();
29374			function checkFocus() {
29375				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
29376				if ( !isActive ) {
29377					this.element.trigger( "focus" );
29378					this.previous = previous;
29379
29380					// support: IE
29381					// IE sets focus asynchronously, so we need to check if focus
29382					// moved off of the input because the user clicked on the button.
29383					this._delay( function() {
29384						this.previous = previous;
29385					} );
29386				}
29387			}
29388
29389			// Ensure focus is on (or stays on) the text field
29390			event.preventDefault();
29391			checkFocus.call( this );
29392
29393			// Support: IE
29394			// IE doesn't prevent moving focus even with event.preventDefault()
29395			// so we set a flag to know when we should ignore the blur event
29396			// and check (again) if focus moved off of the input.
29397			this.cancelBlur = true;
29398			this._delay( function() {
29399				delete this.cancelBlur;
29400				checkFocus.call( this );
29401			} );
29402
29403			if ( this._start( event ) === false ) {
29404				return;
29405			}
29406
29407			this._repeat( null, $( event.currentTarget )
29408				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
29409		},
29410		"mouseup .ui-spinner-button": "_stop",
29411		"mouseenter .ui-spinner-button": function( event ) {
29412
29413			// button will add ui-state-active if mouse was down while mouseleave and kept down
29414			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
29415				return;
29416			}
29417
29418			if ( this._start( event ) === false ) {
29419				return false;
29420			}
29421			this._repeat( null, $( event.currentTarget )
29422				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
29423		},
29424
29425		// TODO: do we really want to consider this a stop?
29426		// shouldn't we just stop the repeater and wait until mouseup before
29427		// we trigger the stop event?
29428		"mouseleave .ui-spinner-button": "_stop"
29429	},
29430
29431	// Support mobile enhanced option and make backcompat more sane
29432	_enhance: function() {
29433		this.uiSpinner = this.element
29434			.attr( "autocomplete", "off" )
29435			.wrap( "<span>" )
29436			.parent()
29437
29438				// Add buttons
29439				.append(
29440					"<a></a><a></a>"
29441				);
29442	},
29443
29444	_draw: function() {
29445		this._enhance();
29446
29447		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
29448		this._addClass( "ui-spinner-input" );
29449
29450		this.element.attr( "role", "spinbutton" );
29451
29452		// Button bindings
29453		this.buttons = this.uiSpinner.children( "a" )
29454			.attr( "tabIndex", -1 )
29455			.attr( "aria-hidden", true )
29456			.button( {
29457				classes: {
29458					"ui-button": ""
29459				}
29460			} );
29461
29462		// TODO: Right now button does not support classes this is already updated in button PR
29463		this._removeClass( this.buttons, "ui-corner-all" );
29464
29465		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
29466		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
29467		this.buttons.first().button( {
29468			"icon": this.options.icons.up,
29469			"showLabel": false
29470		} );
29471		this.buttons.last().button( {
29472			"icon": this.options.icons.down,
29473			"showLabel": false
29474		} );
29475
29476		// IE 6 doesn't understand height: 50% for the buttons
29477		// unless the wrapper has an explicit height
29478		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
29479				this.uiSpinner.height() > 0 ) {
29480			this.uiSpinner.height( this.uiSpinner.height() );
29481		}
29482	},
29483
29484	_keydown: function( event ) {
29485		var options = this.options,
29486			keyCode = $.ui.keyCode;
29487
29488		switch ( event.keyCode ) {
29489		case keyCode.UP:
29490			this._repeat( null, 1, event );
29491			return true;
29492		case keyCode.DOWN:
29493			this._repeat( null, -1, event );
29494			return true;
29495		case keyCode.PAGE_UP:
29496			this._repeat( null, options.page, event );
29497			return true;
29498		case keyCode.PAGE_DOWN:
29499			this._repeat( null, -options.page, event );
29500			return true;
29501		}
29502
29503		return false;
29504	},
29505
29506	_start: function( event ) {
29507		if ( !this.spinning && this._trigger( "start", event ) === false ) {
29508			return false;
29509		}
29510
29511		if ( !this.counter ) {
29512			this.counter = 1;
29513		}
29514		this.spinning = true;
29515		return true;
29516	},
29517
29518	_repeat: function( i, steps, event ) {
29519		i = i || 500;
29520
29521		clearTimeout( this.timer );
29522		this.timer = this._delay( function() {
29523			this._repeat( 40, steps, event );
29524		}, i );
29525
29526		this._spin( steps * this.options.step, event );
29527	},
29528
29529	_spin: function( step, event ) {
29530		var value = this.value() || 0;
29531
29532		if ( !this.counter ) {
29533			this.counter = 1;
29534		}
29535
29536		value = this._adjustValue( value + step * this._increment( this.counter ) );
29537
29538		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
29539			this._value( value );
29540			this.counter++;
29541		}
29542	},
29543
29544	_increment: function( i ) {
29545		var incremental = this.options.incremental;
29546
29547		if ( incremental ) {
29548			return typeof incremental === "function" ?
29549				incremental( i ) :
29550				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
29551		}
29552
29553		return 1;
29554	},
29555
29556	_precision: function() {
29557		var precision = this._precisionOf( this.options.step );
29558		if ( this.options.min !== null ) {
29559			precision = Math.max( precision, this._precisionOf( this.options.min ) );
29560		}
29561		return precision;
29562	},
29563
29564	_precisionOf: function( num ) {
29565		var str = num.toString(),
29566			decimal = str.indexOf( "." );
29567		return decimal === -1 ? 0 : str.length - decimal - 1;
29568	},
29569
29570	_adjustValue: function( value ) {
29571		var base, aboveMin,
29572			options = this.options;
29573
29574		// Make sure we're at a valid step
29575		// - find out where we are relative to the base (min or 0)
29576		base = options.min !== null ? options.min : 0;
29577		aboveMin = value - base;
29578
29579		// - round to the nearest step
29580		aboveMin = Math.round( aboveMin / options.step ) * options.step;
29581
29582		// - rounding is based on 0, so adjust back to our base
29583		value = base + aboveMin;
29584
29585		// Fix precision from bad JS floating point math
29586		value = parseFloat( value.toFixed( this._precision() ) );
29587
29588		// Clamp the value
29589		if ( options.max !== null && value > options.max ) {
29590			return options.max;
29591		}
29592		if ( options.min !== null && value < options.min ) {
29593			return options.min;
29594		}
29595
29596		return value;
29597	},
29598
29599	_stop: function( event ) {
29600		if ( !this.spinning ) {
29601			return;
29602		}
29603
29604		clearTimeout( this.timer );
29605		clearTimeout( this.mousewheelTimer );
29606		this.counter = 0;
29607		this.spinning = false;
29608		this._trigger( "stop", event );
29609	},
29610
29611	_setOption: function( key, value ) {
29612		var prevValue, first, last;
29613
29614		if ( key === "culture" || key === "numberFormat" ) {
29615			prevValue = this._parse( this.element.val() );
29616			this.options[ key ] = value;
29617			this.element.val( this._format( prevValue ) );
29618			return;
29619		}
29620
29621		if ( key === "max" || key === "min" || key === "step" ) {
29622			if ( typeof value === "string" ) {
29623				value = this._parse( value );
29624			}
29625		}
29626		if ( key === "icons" ) {
29627			first = this.buttons.first().find( ".ui-icon" );
29628			this._removeClass( first, null, this.options.icons.up );
29629			this._addClass( first, null, value.up );
29630			last = this.buttons.last().find( ".ui-icon" );
29631			this._removeClass( last, null, this.options.icons.down );
29632			this._addClass( last, null, value.down );
29633		}
29634
29635		this._super( key, value );
29636	},
29637
29638	_setOptionDisabled: function( value ) {
29639		this._super( value );
29640
29641		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
29642		this.element.prop( "disabled", !!value );
29643		this.buttons.button( value ? "disable" : "enable" );
29644	},
29645
29646	_setOptions: spinnerModifier( function( options ) {
29647		this._super( options );
29648	} ),
29649
29650	_parse: function( val ) {
29651		if ( typeof val === "string" && val !== "" ) {
29652			val = window.Globalize && this.options.numberFormat ?
29653				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
29654		}
29655		return val === "" || isNaN( val ) ? null : val;
29656	},
29657
29658	_format: function( value ) {
29659		if ( value === "" ) {
29660			return "";
29661		}
29662		return window.Globalize && this.options.numberFormat ?
29663			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
29664			value;
29665	},
29666
29667	_refresh: function() {
29668		this.element.attr( {
29669			"aria-valuemin": this.options.min,
29670			"aria-valuemax": this.options.max,
29671
29672			// TODO: what should we do with values that can't be parsed?
29673			"aria-valuenow": this._parse( this.element.val() )
29674		} );
29675	},
29676
29677	isValid: function() {
29678		var value = this.value();
29679
29680		// Null is invalid
29681		if ( value === null ) {
29682			return false;
29683		}
29684
29685		// If value gets adjusted, it's invalid
29686		return value === this._adjustValue( value );
29687	},
29688
29689	// Update the value without triggering change
29690	_value: function( value, allowAny ) {
29691		var parsed;
29692		if ( value !== "" ) {
29693			parsed = this._parse( value );
29694			if ( parsed !== null ) {
29695				if ( !allowAny ) {
29696					parsed = this._adjustValue( parsed );
29697				}
29698				value = this._format( parsed );
29699			}
29700		}
29701		this.element.val( value );
29702		this._refresh();
29703	},
29704
29705	_destroy: function() {
29706		this.element
29707			.prop( "disabled", false )
29708			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
29709
29710		this.uiSpinner.replaceWith( this.element );
29711	},
29712
29713	stepUp: spinnerModifier( function( steps ) {
29714		this._stepUp( steps );
29715	} ),
29716	_stepUp: function( steps ) {
29717		if ( this._start() ) {
29718			this._spin( ( steps || 1 ) * this.options.step );
29719			this._stop();
29720		}
29721	},
29722
29723	stepDown: spinnerModifier( function( steps ) {
29724		this._stepDown( steps );
29725	} ),
29726	_stepDown: function( steps ) {
29727		if ( this._start() ) {
29728			this._spin( ( steps || 1 ) * -this.options.step );
29729			this._stop();
29730		}
29731	},
29732
29733	pageUp: spinnerModifier( function( pages ) {
29734		this._stepUp( ( pages || 1 ) * this.options.page );
29735	} ),
29736
29737	pageDown: spinnerModifier( function( pages ) {
29738		this._stepDown( ( pages || 1 ) * this.options.page );
29739	} ),
29740
29741	value: function( newVal ) {
29742		if ( !arguments.length ) {
29743			return this._parse( this.element.val() );
29744		}
29745		spinnerModifier( this._value ).call( this, newVal );
29746	},
29747
29748	widget: function() {
29749		return this.uiSpinner;
29750	}
29751} );
29752
29753// DEPRECATED
29754// TODO: switch return back to widget declaration at top of file when this is removed
29755if ( $.uiBackCompat !== false ) {
29756
29757	// Backcompat for spinner html extension points
29758	$.widget( "ui.spinner", $.ui.spinner, {
29759		_enhance: function() {
29760			this.uiSpinner = this.element
29761				.attr( "autocomplete", "off" )
29762				.wrap( this._uiSpinnerHtml() )
29763				.parent()
29764
29765					// Add buttons
29766					.append( this._buttonHtml() );
29767		},
29768		_uiSpinnerHtml: function() {
29769			return "<span>";
29770		},
29771
29772		_buttonHtml: function() {
29773			return "<a></a><a></a>";
29774		}
29775	} );
29776}
29777
29778return $.ui.spinner;
29779
29780} );
29781
29782
29783
29784
29785
29786
29787/*!
29788 * jQuery UI Tabs 1.13.0
29789 * http://jqueryui.com
29790 *
29791 * Copyright jQuery Foundation and other contributors
29792 * Released under the MIT license.
29793 * http://jquery.org/license
29794 */
29795
29796//>>label: Tabs
29797//>>group: Widgets
29798//>>description: Transforms a set of container elements into a tab structure.
29799//>>docs: http://api.jqueryui.com/tabs/
29800//>>demos: http://jqueryui.com/tabs/
29801//>>css.structure: ../../themes/base/core.css
29802//>>css.structure: ../../themes/base/tabs.css
29803//>>css.theme: ../../themes/base/theme.css
29804
29805( function( factory ) {
29806	"use strict";
29807
29808	if ( typeof define === "function" && define.amd ) {
29809
29810		// AMD. Register as an anonymous module.
29811		define( [
29812			"jquery",
29813			"../keycode",
29814			"../safe-active-element",
29815			"../unique-id",
29816			"../version",
29817			"../widget"
29818		], factory );
29819	} else {
29820
29821		// Browser globals
29822		factory( jQuery );
29823	}
29824} )( function( $ ) {
29825"use strict";
29826
29827$.widget( "ui.tabs", {
29828	version: "1.13.0
vendor: 21,408 bytes, lines 29828-30657
29828",
29829	delay: 300,
29830	options: {
29831		active: null,
29832		classes: {
29833			"ui-tabs": "ui-corner-all",
29834			"ui-tabs-nav": "ui-corner-all",
29835			"ui-tabs-panel": "ui-corner-bottom",
29836			"ui-tabs-tab": "ui-corner-top"
29837		},
29838		collapsible: false,
29839		event: "click",
29840		heightStyle: "content",
29841		hide: null,
29842		show: null,
29843
29844		// Callbacks
29845		activate: null,
29846		beforeActivate: null,
29847		beforeLoad: null,
29848		load: null
29849	},
29850
29851	_isLocal: ( function() {
29852		var rhash = /#.*$/;
29853
29854		return function( anchor ) {
29855			var anchorUrl, locationUrl;
29856
29857			anchorUrl = anchor.href.replace( rhash, "" );
29858			locationUrl = location.href.replace( rhash, "" );
29859
29860			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
29861			try {
29862				anchorUrl = decodeURIComponent( anchorUrl );
29863			} catch ( error ) {}
29864			try {
29865				locationUrl = decodeURIComponent( locationUrl );
29866			} catch ( error ) {}
29867
29868			return anchor.hash.length > 1 && anchorUrl === locationUrl;
29869		};
29870	} )(),
29871
29872	_create: function() {
29873		var that = this,
29874			options = this.options;
29875
29876		this.running = false;
29877
29878		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
29879		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
29880
29881		this._processTabs();
29882		options.active = this._initialActive();
29883
29884		// Take disabling tabs via class attribute from HTML
29885		// into account and update option properly.
29886		if ( Array.isArray( options.disabled ) ) {
29887			options.disabled = $.uniqueSort( options.disabled.concat(
29888				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
29889					return that.tabs.index( li );
29890				} )
29891			) ).sort();
29892		}
29893
29894		// Check for length avoids error when initializing empty list
29895		if ( this.options.active !== false && this.anchors.length ) {
29896			this.active = this._findActive( options.active );
29897		} else {
29898			this.active = $();
29899		}
29900
29901		this._refresh();
29902
29903		if ( this.active.length ) {
29904			this.load( options.active );
29905		}
29906	},
29907
29908	_initialActive: function() {
29909		var active = this.options.active,
29910			collapsible = this.options.collapsible,
29911			locationHash = location.hash.substring( 1 );
29912
29913		if ( active === null ) {
29914
29915			// check the fragment identifier in the URL
29916			if ( locationHash ) {
29917				this.tabs.each( function( i, tab ) {
29918					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
29919						active = i;
29920						return false;
29921					}
29922				} );
29923			}
29924
29925			// Check for a tab marked active via a class
29926			if ( active === null ) {
29927				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
29928			}
29929
29930			// No active tab, set to false
29931			if ( active === null || active === -1 ) {
29932				active = this.tabs.length ? 0 : false;
29933			}
29934		}
29935
29936		// Handle numbers: negative, out of range
29937		if ( active !== false ) {
29938			active = this.tabs.index( this.tabs.eq( active ) );
29939			if ( active === -1 ) {
29940				active = collapsible ? false : 0;
29941			}
29942		}
29943
29944		// Don't allow collapsible: false and active: false
29945		if ( !collapsible && active === false && this.anchors.length ) {
29946			active = 0;
29947		}
29948
29949		return active;
29950	},
29951
29952	_getCreateEventData: function() {
29953		return {
29954			tab: this.active,
29955			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
29956		};
29957	},
29958
29959	_tabKeydown: function( event ) {
29960		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
29961			selectedIndex = this.tabs.index( focusedTab ),
29962			goingForward = true;
29963
29964		if ( this._handlePageNav( event ) ) {
29965			return;
29966		}
29967
29968		switch ( event.keyCode ) {
29969		case $.ui.keyCode.RIGHT:
29970		case $.ui.keyCode.DOWN:
29971			selectedIndex++;
29972			break;
29973		case $.ui.keyCode.UP:
29974		case $.ui.keyCode.LEFT:
29975			goingForward = false;
29976			selectedIndex--;
29977			break;
29978		case $.ui.keyCode.END:
29979			selectedIndex = this.anchors.length - 1;
29980			break;
29981		case $.ui.keyCode.HOME:
29982			selectedIndex = 0;
29983			break;
29984		case $.ui.keyCode.SPACE:
29985
29986			// Activate only, no collapsing
29987			event.preventDefault();
29988			clearTimeout( this.activating );
29989			this._activate( selectedIndex );
29990			return;
29991		case $.ui.keyCode.ENTER:
29992
29993			// Toggle (cancel delayed activation, allow collapsing)
29994			event.preventDefault();
29995			clearTimeout( this.activating );
29996
29997			// Determine if we should collapse or activate
29998			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
29999			return;
30000		default:
30001			return;
30002		}
30003
30004		// Focus the appropriate tab, based on which key was pressed
30005		event.preventDefault();
30006		clearTimeout( this.activating );
30007		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
30008
30009		// Navigating with control/command key will prevent automatic activation
30010		if ( !event.ctrlKey && !event.metaKey ) {
30011
30012			// Update aria-selected immediately so that AT think the tab is already selected.
30013			// Otherwise AT may confuse the user by stating that they need to activate the tab,
30014			// but the tab will already be activated by the time the announcement finishes.
30015			focusedTab.attr( "aria-selected", "false" );
30016			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
30017
30018			this.activating = this._delay( function() {
30019				this.option( "active", selectedIndex );
30020			}, this.delay );
30021		}
30022	},
30023
30024	_panelKeydown: function( event ) {
30025		if ( this._handlePageNav( event ) ) {
30026			return;
30027		}
30028
30029		// Ctrl+up moves focus to the current tab
30030		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
30031			event.preventDefault();
30032			this.active.trigger( "focus" );
30033		}
30034	},
30035
30036	// Alt+page up/down moves focus to the previous/next tab (and activates)
30037	_handlePageNav: function( event ) {
30038		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
30039			this._activate( this._focusNextTab( this.options.active - 1, false ) );
30040			return true;
30041		}
30042		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
30043			this._activate( this._focusNextTab( this.options.active + 1, true ) );
30044			return true;
30045		}
30046	},
30047
30048	_findNextTab: function( index, goingForward ) {
30049		var lastTabIndex = this.tabs.length - 1;
30050
30051		function constrain() {
30052			if ( index > lastTabIndex ) {
30053				index = 0;
30054			}
30055			if ( index < 0 ) {
30056				index = lastTabIndex;
30057			}
30058			return index;
30059		}
30060
30061		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
30062			index = goingForward ? index + 1 : index - 1;
30063		}
30064
30065		return index;
30066	},
30067
30068	_focusNextTab: function( index, goingForward ) {
30069		index = this._findNextTab( index, goingForward );
30070		this.tabs.eq( index ).trigger( "focus" );
30071		return index;
30072	},
30073
30074	_setOption: function( key, value ) {
30075		if ( key === "active" ) {
30076
30077			// _activate() will handle invalid values and update this.options
30078			this._activate( value );
30079			return;
30080		}
30081
30082		this._super( key, value );
30083
30084		if ( key === "collapsible" ) {
30085			this._toggleClass( "ui-tabs-collapsible", null, value );
30086
30087			// Setting collapsible: false while collapsed; open first panel
30088			if ( !value && this.options.active === false ) {
30089				this._activate( 0 );
30090			}
30091		}
30092
30093		if ( key === "event" ) {
30094			this._setupEvents( value );
30095		}
30096
30097		if ( key === "heightStyle" ) {
30098			this._setupHeightStyle( value );
30099		}
30100	},
30101
30102	_sanitizeSelector: function( hash ) {
30103		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
30104	},
30105
30106	refresh: function() {
30107		var options = this.options,
30108			lis = this.tablist.children( ":has(a[href])" );
30109
30110		// Get disabled tabs from class attribute from HTML
30111		// this will get converted to a boolean if needed in _refresh()
30112		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
30113			return lis.index( tab );
30114		} );
30115
30116		this._processTabs();
30117
30118		// Was collapsed or no tabs
30119		if ( options.active === false || !this.anchors.length ) {
30120			options.active = false;
30121			this.active = $();
30122
30123		// was active, but active tab is gone
30124		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
30125
30126			// all remaining tabs are disabled
30127			if ( this.tabs.length === options.disabled.length ) {
30128				options.active = false;
30129				this.active = $();
30130
30131			// activate previous tab
30132			} else {
30133				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
30134			}
30135
30136		// was active, active tab still exists
30137		} else {
30138
30139			// make sure active index is correct
30140			options.active = this.tabs.index( this.active );
30141		}
30142
30143		this._refresh();
30144	},
30145
30146	_refresh: function() {
30147		this._setOptionDisabled( this.options.disabled );
30148		this._setupEvents( this.options.event );
30149		this._setupHeightStyle( this.options.heightStyle );
30150
30151		this.tabs.not( this.active ).attr( {
30152			"aria-selected": "false",
30153			"aria-expanded": "false",
30154			tabIndex: -1
30155		} );
30156		this.panels.not( this._getPanelForTab( this.active ) )
30157			.hide()
30158			.attr( {
30159				"aria-hidden": "true"
30160			} );
30161
30162		// Make sure one tab is in the tab order
30163		if ( !this.active.length ) {
30164			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
30165		} else {
30166			this.active
30167				.attr( {
30168					"aria-selected": "true",
30169					"aria-expanded": "true",
30170					tabIndex: 0
30171				} );
30172			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
30173			this._getPanelForTab( this.active )
30174				.show()
30175				.attr( {
30176					"aria-hidden": "false"
30177				} );
30178		}
30179	},
30180
30181	_processTabs: function() {
30182		var that = this,
30183			prevTabs = this.tabs,
30184			prevAnchors = this.anchors,
30185			prevPanels = this.panels;
30186
30187		this.tablist = this._getList().attr( "role", "tablist" );
30188		this._addClass( this.tablist, "ui-tabs-nav",
30189			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
30190
30191		// Prevent users from focusing disabled tabs via click
30192		this.tablist
30193			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
30194				if ( $( this ).is( ".ui-state-disabled" ) ) {
30195					event.preventDefault();
30196				}
30197			} )
30198
30199			// Support: IE <9
30200			// Preventing the default action in mousedown doesn't prevent IE
30201			// from focusing the element, so if the anchor gets focused, blur.
30202			// We don't have to worry about focusing the previously focused
30203			// element since clicking on a non-focusable element should focus
30204			// the body anyway.
30205			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
30206				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
30207					this.blur();
30208				}
30209			} );
30210
30211		this.tabs = this.tablist.find( "> li:has(a[href])" )
30212			.attr( {
30213				role: "tab",
30214				tabIndex: -1
30215			} );
30216		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
30217
30218		this.anchors = this.tabs.map( function() {
30219			return $( "a", this )[ 0 ];
30220		} )
30221			.attr( {
30222				tabIndex: -1
30223			} );
30224		this._addClass( this.anchors, "ui-tabs-anchor" );
30225
30226		this.panels = $();
30227
30228		this.anchors.each( function( i, anchor ) {
30229			var selector, panel, panelId,
30230				anchorId = $( anchor ).uniqueId().attr( "id" ),
30231				tab = $( anchor ).closest( "li" ),
30232				originalAriaControls = tab.attr( "aria-controls" );
30233
30234			// Inline tab
30235			if ( that._isLocal( anchor ) ) {
30236				selector = anchor.hash;
30237				panelId = selector.substring( 1 );
30238				panel = that.element.find( that._sanitizeSelector( selector ) );
30239
30240			// remote tab
30241			} else {
30242
30243				// If the tab doesn't already have aria-controls,
30244				// generate an id by using a throw-away element
30245				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
30246				selector = "#" + panelId;
30247				panel = that.element.find( selector );
30248				if ( !panel.length ) {
30249					panel = that._createPanel( panelId );
30250					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
30251				}
30252				panel.attr( "aria-live", "polite" );
30253			}
30254
30255			if ( panel.length ) {
30256				that.panels = that.panels.add( panel );
30257			}
30258			if ( originalAriaControls ) {
30259				tab.data( "ui-tabs-aria-controls", originalAriaControls );
30260			}
30261			tab.attr( {
30262				"aria-controls": panelId,
30263				"aria-labelledby": anchorId
30264			} );
30265			panel.attr( "aria-labelledby", anchorId );
30266		} );
30267
30268		this.panels.attr( "role", "tabpanel" );
30269		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
30270
30271		// Avoid memory leaks (#10056)
30272		if ( prevTabs ) {
30273			this._off( prevTabs.not( this.tabs ) );
30274			this._off( prevAnchors.not( this.anchors ) );
30275			this._off( prevPanels.not( this.panels ) );
30276		}
30277	},
30278
30279	// Allow overriding how to find the list for rare usage scenarios (#7715)
30280	_getList: function() {
30281		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
30282	},
30283
30284	_createPanel: function( id ) {
30285		return $( "<div>" )
30286			.attr( "id", id )
30287			.data( "ui-tabs-destroy", true );
30288	},
30289
30290	_setOptionDisabled: function( disabled ) {
30291		var currentItem, li, i;
30292
30293		if ( Array.isArray( disabled ) ) {
30294			if ( !disabled.length ) {
30295				disabled = false;
30296			} else if ( disabled.length === this.anchors.length ) {
30297				disabled = true;
30298			}
30299		}
30300
30301		// Disable tabs
30302		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
30303			currentItem = $( li );
30304			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
30305				currentItem.attr( "aria-disabled", "true" );
30306				this._addClass( currentItem, null, "ui-state-disabled" );
30307			} else {
30308				currentItem.removeAttr( "aria-disabled" );
30309				this._removeClass( currentItem, null, "ui-state-disabled" );
30310			}
30311		}
30312
30313		this.options.disabled = disabled;
30314
30315		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
30316			disabled === true );
30317	},
30318
30319	_setupEvents: function( event ) {
30320		var events = {};
30321		if ( event ) {
30322			$.each( event.split( " " ), function( index, eventName ) {
30323				events[ eventName ] = "_eventHandler";
30324			} );
30325		}
30326
30327		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
30328
30329		// Always prevent the default action, even when disabled
30330		this._on( true, this.anchors, {
30331			click: function( event ) {
30332				event.preventDefault();
30333			}
30334		} );
30335		this._on( this.anchors, events );
30336		this._on( this.tabs, { keydown: "_tabKeydown" } );
30337		this._on( this.panels, { keydown: "_panelKeydown" } );
30338
30339		this._focusable( this.tabs );
30340		this._hoverable( this.tabs );
30341	},
30342
30343	_setupHeightStyle: function( heightStyle ) {
30344		var maxHeight,
30345			parent = this.element.parent();
30346
30347		if ( heightStyle === "fill" ) {
30348			maxHeight = parent.height();
30349			maxHeight -= this.element.outerHeight() - this.element.height();
30350
30351			this.element.siblings( ":visible" ).each( function() {
30352				var elem = $( this ),
30353					position = elem.css( "position" );
30354
30355				if ( position === "absolute" || position === "fixed" ) {
30356					return;
30357				}
30358				maxHeight -= elem.outerHeight( true );
30359			} );
30360
30361			this.element.children().not( this.panels ).each( function() {
30362				maxHeight -= $( this ).outerHeight( true );
30363			} );
30364
30365			this.panels.each( function() {
30366				$( this ).height( Math.max( 0, maxHeight -
30367					$( this ).innerHeight() + $( this ).height() ) );
30368			} )
30369				.css( "overflow", "auto" );
30370		} else if ( heightStyle === "auto" ) {
30371			maxHeight = 0;
30372			this.panels.each( function() {
30373				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
30374			} ).height( maxHeight );
30375		}
30376	},
30377
30378	_eventHandler: function( event ) {
30379		var options = this.options,
30380			active = this.active,
30381			anchor = $( event.currentTarget ),
30382			tab = anchor.closest( "li" ),
30383			clickedIsActive = tab[ 0 ] === active[ 0 ],
30384			collapsing = clickedIsActive && options.collapsible,
30385			toShow = collapsing ? $() : this._getPanelForTab( tab ),
30386			toHide = !active.length ? $() : this._getPanelForTab( active ),
30387			eventData = {
30388				oldTab: active,
30389				oldPanel: toHide,
30390				newTab: collapsing ? $() : tab,
30391				newPanel: toShow
30392			};
30393
30394		event.preventDefault();
30395
30396		if ( tab.hasClass( "ui-state-disabled" ) ||
30397
30398				// tab is already loading
30399				tab.hasClass( "ui-tabs-loading" ) ||
30400
30401				// can't switch durning an animation
30402				this.running ||
30403
30404				// click on active header, but not collapsible
30405				( clickedIsActive && !options.collapsible ) ||
30406
30407				// allow canceling activation
30408				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
30409			return;
30410		}
30411
30412		options.active = collapsing ? false : this.tabs.index( tab );
30413
30414		this.active = clickedIsActive ? $() : tab;
30415		if ( this.xhr ) {
30416			this.xhr.abort();
30417		}
30418
30419		if ( !toHide.length && !toShow.length ) {
30420			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
30421		}
30422
30423		if ( toShow.length ) {
30424			this.load( this.tabs.index( tab ), event );
30425		}
30426		this._toggle( event, eventData );
30427	},
30428
30429	// Handles show/hide for selecting tabs
30430	_toggle: function( event, eventData ) {
30431		var that = this,
30432			toShow = eventData.newPanel,
30433			toHide = eventData.oldPanel;
30434
30435		this.running = true;
30436
30437		function complete() {
30438			that.running = false;
30439			that._trigger( "activate", event, eventData );
30440		}
30441
30442		function show() {
30443			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
30444
30445			if ( toShow.length && that.options.show ) {
30446				that._show( toShow, that.options.show, complete );
30447			} else {
30448				toShow.show();
30449				complete();
30450			}
30451		}
30452
30453		// Start out by hiding, then showing, then completing
30454		if ( toHide.length && this.options.hide ) {
30455			this._hide( toHide, this.options.hide, function() {
30456				that._removeClass( eventData.oldTab.closest( "li" ),
30457					"ui-tabs-active", "ui-state-active" );
30458				show();
30459			} );
30460		} else {
30461			this._removeClass( eventData.oldTab.closest( "li" ),
30462				"ui-tabs-active", "ui-state-active" );
30463			toHide.hide();
30464			show();
30465		}
30466
30467		toHide.attr( "aria-hidden", "true" );
30468		eventData.oldTab.attr( {
30469			"aria-selected": "false",
30470			"aria-expanded": "false"
30471		} );
30472
30473		// If we're switching tabs, remove the old tab from the tab order.
30474		// If we're opening from collapsed state, remove the previous tab from the tab order.
30475		// If we're collapsing, then keep the collapsing tab in the tab order.
30476		if ( toShow.length && toHide.length ) {
30477			eventData.oldTab.attr( "tabIndex", -1 );
30478		} else if ( toShow.length ) {
30479			this.tabs.filter( function() {
30480				return $( this ).attr( "tabIndex" ) === 0;
30481			} )
30482				.attr( "tabIndex", -1 );
30483		}
30484
30485		toShow.attr( "aria-hidden", "false" );
30486		eventData.newTab.attr( {
30487			"aria-selected": "true",
30488			"aria-expanded": "true",
30489			tabIndex: 0
30490		} );
30491	},
30492
30493	_activate: function( index ) {
30494		var anchor,
30495			active = this._findActive( index );
30496
30497		// Trying to activate the already active panel
30498		if ( active[ 0 ] === this.active[ 0 ] ) {
30499			return;
30500		}
30501
30502		// Trying to collapse, simulate a click on the current active header
30503		if ( !active.length ) {
30504			active = this.active;
30505		}
30506
30507		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
30508		this._eventHandler( {
30509			target: anchor,
30510			currentTarget: anchor,
30511			preventDefault: $.noop
30512		} );
30513	},
30514
30515	_findActive: function( index ) {
30516		return index === false ? $() : this.tabs.eq( index );
30517	},
30518
30519	_getIndex: function( index ) {
30520
30521		// meta-function to give users option to provide a href string instead of a numerical index.
30522		if ( typeof index === "string" ) {
30523			index = this.anchors.index( this.anchors.filter( "[href$='" +
30524				$.escapeSelector( index ) + "']" ) );
30525		}
30526
30527		return index;
30528	},
30529
30530	_destroy: function() {
30531		if ( this.xhr ) {
30532			this.xhr.abort();
30533		}
30534
30535		this.tablist
30536			.removeAttr( "role" )
30537			.off( this.eventNamespace );
30538
30539		this.anchors
30540			.removeAttr( "role tabIndex" )
30541			.removeUniqueId();
30542
30543		this.tabs.add( this.panels ).each( function() {
30544			if ( $.data( this, "ui-tabs-destroy" ) ) {
30545				$( this ).remove();
30546			} else {
30547				$( this ).removeAttr( "role tabIndex " +
30548					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
30549			}
30550		} );
30551
30552		this.tabs.each( function() {
30553			var li = $( this ),
30554				prev = li.data( "ui-tabs-aria-controls" );
30555			if ( prev ) {
30556				li
30557					.attr( "aria-controls", prev )
30558					.removeData( "ui-tabs-aria-controls" );
30559			} else {
30560				li.removeAttr( "aria-controls" );
30561			}
30562		} );
30563
30564		this.panels.show();
30565
30566		if ( this.options.heightStyle !== "content" ) {
30567			this.panels.css( "height", "" );
30568		}
30569	},
30570
30571	enable: function( index ) {
30572		var disabled = this.options.disabled;
30573		if ( disabled === false ) {
30574			return;
30575		}
30576
30577		if ( index === undefined ) {
30578			disabled = false;
30579		} else {
30580			index = this._getIndex( index );
30581			if ( Array.isArray( disabled ) ) {
30582				disabled = $.map( disabled, function( num ) {
30583					return num !== index ? num : null;
30584				} );
30585			} else {
30586				disabled = $.map( this.tabs, function( li, num ) {
30587					return num !== index ? num : null;
30588				} );
30589			}
30590		}
30591		this._setOptionDisabled( disabled );
30592	},
30593
30594	disable: function( index ) {
30595		var disabled = this.options.disabled;
30596		if ( disabled === true ) {
30597			return;
30598		}
30599
30600		if ( index === undefined ) {
30601			disabled = true;
30602		} else {
30603			index = this._getIndex( index );
30604			if ( $.inArray( index, disabled ) !== -1 ) {
30605				return;
30606			}
30607			if ( Array.isArray( disabled ) ) {
30608				disabled = $.merge( [ index ], disabled ).sort();
30609			} else {
30610				disabled = [ index ];
30611			}
30612		}
30613		this._setOptionDisabled( disabled );
30614	},
30615
30616	load: function( index, event ) {
30617		index = this._getIndex( index );
30618		var that = this,
30619			tab = this.tabs.eq( index ),
30620			anchor = tab.find( ".ui-tabs-anchor" ),
30621			panel = this._getPanelForTab( tab ),
30622			eventData = {
30623				tab: tab,
30624				panel: panel
30625			},
30626			complete = function( jqXHR, status ) {
30627				if ( status === "abort" ) {
30628					that.panels.stop( false, true );
30629				}
30630
30631				that._removeClass( tab, "ui-tabs-loading" );
30632				panel.removeAttr( "aria-busy" );
30633
30634				if ( jqXHR === that.xhr ) {
30635					delete that.xhr;
30636				}
30637			};
30638
30639		// Not remote
30640		if ( this._isLocal( anchor[ 0 ] ) ) {
30641			return;
30642		}
30643
30644		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
30645
30646		// Support: jQuery <1.8
30647		// jQuery <1.8 returns false if the request is canceled in beforeSend,
30648		// but as of 1.8, $.ajax() always returns a jqXHR object.
30649		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
30650			this._addClass( tab, "ui-tabs-loading" );
30651			panel.attr( "aria-busy", "true" );
30652
30653			this.xhr
30654				.done( function( response, status, jqXHR ) {
30655
30656					// support: jQuery <1.8
30657					// http
30657://bugs.jquery.com/ticket/11778
30658					setTimeout( function() {
30659						panel.html( response );
30660						that._trigger( "load", event, eventData );
30661
30662						complete( jqXHR, status );
30663					}, 1 );
30664				} )
30665				.fail( function( jqXHR, status ) {
30666
30667					// support: jQuery <1.8
30668					// http://bugs.jquery.com/ticket/11778
30669					setTimeout( function() {
30670						complete( jqXHR, status );
30671					}, 1 );
30672				} );
30673		}
30674	},
30675
30676	_ajaxSettings: function( anchor, event, eventData ) {
30677		var that = this;
30678		return {
30679
vendor: 18,280 bytes, lines 30680-31366
30680			// Support: IE <11 only
30681			// Strip any hash that exists to prevent errors with the Ajax request
30682			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
30683			beforeSend: function( jqXHR, settings ) {
30684				return that._trigger( "beforeLoad", event,
30685					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
30686			}
30687		};
30688	},
30689
30690	_getPanelForTab: function( tab ) {
30691		var id = $( tab ).attr( "aria-controls" );
30692		return this.element.find( this._sanitizeSelector( "#" + id ) );
30693	}
30694} );
30695
30696// DEPRECATED
30697// TODO: Switch return back to widget declaration at top of file when this is removed
30698if ( $.uiBackCompat !== false ) {
30699
30700	// Backcompat for ui-tab class (now ui-tabs-tab)
30701	$.widget( "ui.tabs", $.ui.tabs, {
30702		_processTabs: function() {
30703			this._superApply( arguments );
30704			this._addClass( this.tabs, "ui-tab" );
30705		}
30706	} );
30707}
30708
30709return $.ui.tabs;
30710
30711} );
30712
30713
30714
30715
30716
30717
30718/*!
30719 * jQuery UI Tooltip 1.13.0
30720 * http://jqueryui.com
30721 *
30722 * Copyright jQuery Foundation and other contributors
30723 * Released under the MIT license.
30724 * http://jquery.org/license
30725 */
30726
30727//>>label: Tooltip
30728//>>group: Widgets
30729//>>description: Shows additional information for any element on hover or focus.
30730//>>docs: http://api.jqueryui.com/tooltip/
30731//>>demos: http://jqueryui.com/tooltip/
30732//>>css.structure: ../../themes/base/core.css
30733//>>css.structure: ../../themes/base/tooltip.css
30734//>>css.theme: ../../themes/base/theme.css
30735
30736( function( factory ) {
30737	"use strict";
30738
30739	if ( typeof define === "function" && define.amd ) {
30740
30741		// AMD. Register as an anonymous module.
30742		define( [
30743			"jquery",
30744			"../keycode",
30745			"../position",
30746			"../unique-id",
30747			"../version",
30748			"../widget"
30749		], factory );
30750	} else {
30751
30752		// Browser globals
30753		factory( jQuery );
30754	}
30755} )( function( $ ) {
30756"use strict";
30757
30758$.widget( "ui.tooltip", {
30759	version: "1.13.0",
30760	options: {
30761		classes: {
30762			"ui-tooltip": "ui-corner-all ui-widget-shadow"
30763		},
30764		content: function() {
30765			var title = $( this ).attr( "title" );
30766
30767			// Escape title, since we're going from an attribute to raw HTML
30768			return $( "<a>" ).text( title ).html();
30769		},
30770		hide: true,
30771
30772		// Disabled elements have inconsistent behavior across browsers (#8661)
30773		items: "[title]:not([disabled])",
30774		position: {
30775			my: "left top+15",
30776			at: "left bottom",
30777			collision: "flipfit flip"
30778		},
30779		show: true,
30780		track: false,
30781
30782		// Callbacks
30783		close: null,
30784		open: null
30785	},
30786
30787	_addDescribedBy: function( elem, id ) {
30788		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
30789		describedby.push( id );
30790		elem
30791			.data( "ui-tooltip-id", id )
30792			.attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
30793	},
30794
30795	_removeDescribedBy: function( elem ) {
30796		var id = elem.data( "ui-tooltip-id" ),
30797			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
30798			index = $.inArray( id, describedby );
30799
30800		if ( index !== -1 ) {
30801			describedby.splice( index, 1 );
30802		}
30803
30804		elem.removeData( "ui-tooltip-id" );
30805		describedby = String.prototype.trim.call( describedby.join( " " ) );
30806		if ( describedby ) {
30807			elem.attr( "aria-describedby", describedby );
30808		} else {
30809			elem.removeAttr( "aria-describedby" );
30810		}
30811	},
30812
30813	_create: function() {
30814		this._on( {
30815			mouseover: "open",
30816			focusin: "open"
30817		} );
30818
30819		// IDs of generated tooltips, needed for destroy
30820		this.tooltips = {};
30821
30822		// IDs of parent tooltips where we removed the title attribute
30823		this.parents = {};
30824
30825		// Append the aria-live region so tooltips announce correctly
30826		this.liveRegion = $( "<div>" )
30827			.attr( {
30828				role: "log",
30829				"aria-live": "assertive",
30830				"aria-relevant": "additions"
30831			} )
30832			.appendTo( this.document[ 0 ].body );
30833		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
30834
30835		this.disabledTitles = $( [] );
30836	},
30837
30838	_setOption: function( key, value ) {
30839		var that = this;
30840
30841		this._super( key, value );
30842
30843		if ( key === "content" ) {
30844			$.each( this.tooltips, function( id, tooltipData ) {
30845				that._updateContent( tooltipData.element );
30846			} );
30847		}
30848	},
30849
30850	_setOptionDisabled: function( value ) {
30851		this[ value ? "_disable" : "_enable" ]();
30852	},
30853
30854	_disable: function() {
30855		var that = this;
30856
30857		// Close open tooltips
30858		$.each( this.tooltips, function( id, tooltipData ) {
30859			var event = $.Event( "blur" );
30860			event.target = event.currentTarget = tooltipData.element[ 0 ];
30861			that.close( event, true );
30862		} );
30863
30864		// Remove title attributes to prevent native tooltips
30865		this.disabledTitles = this.disabledTitles.add(
30866			this.element.find( this.options.items ).addBack()
30867				.filter( function() {
30868					var element = $( this );
30869					if ( element.is( "[title]" ) ) {
30870						return element
30871							.data( "ui-tooltip-title", element.attr( "title" ) )
30872							.removeAttr( "title" );
30873					}
30874				} )
30875		);
30876	},
30877
30878	_enable: function() {
30879
30880		// restore title attributes
30881		this.disabledTitles.each( function() {
30882			var element = $( this );
30883			if ( element.data( "ui-tooltip-title" ) ) {
30884				element.attr( "title", element.data( "ui-tooltip-title" ) );
30885			}
30886		} );
30887		this.disabledTitles = $( [] );
30888	},
30889
30890	open: function( event ) {
30891		var that = this,
30892			target = $( event ? event.target : this.element )
30893
30894				// we need closest here due to mouseover bubbling,
30895				// but always pointing at the same event target
30896				.closest( this.options.items );
30897
30898		// No element to show a tooltip for or the tooltip is already open
30899		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
30900			return;
30901		}
30902
30903		if ( target.attr( "title" ) ) {
30904			target.data( "ui-tooltip-title", target.attr( "title" ) );
30905		}
30906
30907		target.data( "ui-tooltip-open", true );
30908
30909		// Kill parent tooltips, custom or native, for hover
30910		if ( event && event.type === "mouseover" ) {
30911			target.parents().each( function() {
30912				var parent = $( this ),
30913					blurEvent;
30914				if ( parent.data( "ui-tooltip-open" ) ) {
30915					blurEvent = $.Event( "blur" );
30916					blurEvent.target = blurEvent.currentTarget = this;
30917					that.close( blurEvent, true );
30918				}
30919				if ( parent.attr( "title" ) ) {
30920					parent.uniqueId();
30921					that.parents[ this.id ] = {
30922						element: this,
30923						title: parent.attr( "title" )
30924					};
30925					parent.attr( "title", "" );
30926				}
30927			} );
30928		}
30929
30930		this._registerCloseHandlers( event, target );
30931		this._updateContent( target, event );
30932	},
30933
30934	_updateContent: function( target, event ) {
30935		var content,
30936			contentOption = this.options.content,
30937			that = this,
30938			eventType = event ? event.type : null;
30939
30940		if ( typeof contentOption === "string" || contentOption.nodeType ||
30941				contentOption.jquery ) {
30942			return this._open( event, target, contentOption );
30943		}
30944
30945		content = contentOption.call( target[ 0 ], function( response ) {
30946
30947			// IE may instantly serve a cached response for ajax requests
30948			// delay this call to _open so the other call to _open runs first
30949			that._delay( function() {
30950
30951				// Ignore async response if tooltip was closed already
30952				if ( !target.data( "ui-tooltip-open" ) ) {
30953					return;
30954				}
30955
30956				// JQuery creates a special event for focusin when it doesn't
30957				// exist natively. To improve performance, the native event
30958				// object is reused and the type is changed. Therefore, we can't
30959				// rely on the type being correct after the event finished
30960				// bubbling, so we set it back to the previous value. (#8740)
30961				if ( event ) {
30962					event.type = eventType;
30963				}
30964				this._open( event, target, response );
30965			} );
30966		} );
30967		if ( content ) {
30968			this._open( event, target, content );
30969		}
30970	},
30971
30972	_open: function( event, target, content ) {
30973		var tooltipData, tooltip, delayedShow, a11yContent,
30974			positionOption = $.extend( {}, this.options.position );
30975
30976		if ( !content ) {
30977			return;
30978		}
30979
30980		// Content can be updated multiple times. If the tooltip already
30981		// exists, then just update the content and bail.
30982		tooltipData = this._find( target );
30983		if ( tooltipData ) {
30984			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
30985			return;
30986		}
30987
30988		// If we have a title, clear it to prevent the native tooltip
30989		// we have to check first to avoid defining a title if none exists
30990		// (we don't want to cause an element to start matching [title])
30991		//
30992		// We use removeAttr only for key events, to allow IE to export the correct
30993		// accessible attributes. For mouse events, set to empty string to avoid
30994		// native tooltip showing up (happens only when removing inside mouseover).
30995		if ( target.is( "[title]" ) ) {
30996			if ( event && event.type === "mouseover" ) {
30997				target.attr( "title", "" );
30998			} else {
30999				target.removeAttr( "title" );
31000			}
31001		}
31002
31003		tooltipData = this._tooltip( target );
31004		tooltip = tooltipData.tooltip;
31005		this._addDescribedBy( target, tooltip.attr( "id" ) );
31006		tooltip.find( ".ui-tooltip-content" ).html( content );
31007
31008		// Support: Voiceover on OS X, JAWS on IE <= 9
31009		// JAWS announces deletions even when aria-relevant="additions"
31010		// Voiceover will sometimes re-read the entire log region's contents from the beginning
31011		this.liveRegion.children().hide();
31012		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
31013		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
31014		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
31015		a11yContent.appendTo( this.liveRegion );
31016
31017		function position( event ) {
31018			positionOption.of = event;
31019			if ( tooltip.is( ":hidden" ) ) {
31020				return;
31021			}
31022			tooltip.position( positionOption );
31023		}
31024		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
31025			this._on( this.document, {
31026				mousemove: position
31027			} );
31028
31029			// trigger once to override element-relative positioning
31030			position( event );
31031		} else {
31032			tooltip.position( $.extend( {
31033				of: target
31034			}, this.options.position ) );
31035		}
31036
31037		tooltip.hide();
31038
31039		this._show( tooltip, this.options.show );
31040
31041		// Handle tracking tooltips that are shown with a delay (#8644). As soon
31042		// as the tooltip is visible, position the tooltip using the most recent
31043		// event.
31044		// Adds the check to add the timers only when both delay and track options are set (#14682)
31045		if ( this.options.track && this.options.show && this.options.show.delay ) {
31046			delayedShow = this.delayedShow = setInterval( function() {
31047				if ( tooltip.is( ":visible" ) ) {
31048					position( positionOption.of );
31049					clearInterval( delayedShow );
31050				}
31051			}, 13 );
31052		}
31053
31054		this._trigger( "open", event, { tooltip: tooltip } );
31055	},
31056
31057	_registerCloseHandlers: function( event, target ) {
31058		var events = {
31059			keyup: function( event ) {
31060				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
31061					var fakeEvent = $.Event( event );
31062					fakeEvent.currentTarget = target[ 0 ];
31063					this.close( fakeEvent, true );
31064				}
31065			}
31066		};
31067
31068		// Only bind remove handler for delegated targets. Non-delegated
31069		// tooltips will handle this in destroy.
31070		if ( target[ 0 ] !== this.element[ 0 ] ) {
31071			events.remove = function() {
31072				this._removeTooltip( this._find( target ).tooltip );
31073			};
31074		}
31075
31076		if ( !event || event.type === "mouseover" ) {
31077			events.mouseleave = "close";
31078		}
31079		if ( !event || event.type === "focusin" ) {
31080			events.focusout = "close";
31081		}
31082		this._on( true, target, events );
31083	},
31084
31085	close: function( event ) {
31086		var tooltip,
31087			that = this,
31088			target = $( event ? event.currentTarget : this.element ),
31089			tooltipData = this._find( target );
31090
31091		// The tooltip may already be closed
31092		if ( !tooltipData ) {
31093
31094			// We set ui-tooltip-open immediately upon open (in open()), but only set the
31095			// additional data once there's actually content to show (in _open()). So even if the
31096			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
31097			// the period between open() and _open().
31098			target.removeData( "ui-tooltip-open" );
31099			return;
31100		}
31101
31102		tooltip = tooltipData.tooltip;
31103
31104		// Disabling closes the tooltip, so we need to track when we're closing
31105		// to avoid an infinite loop in case the tooltip becomes disabled on close
31106		if ( tooltipData.closing ) {
31107			return;
31108		}
31109
31110		// Clear the interval for delayed tracking tooltips
31111		clearInterval( this.delayedShow );
31112
31113		// Only set title if we had one before (see comment in _open())
31114		// If the title attribute has changed since open(), don't restore
31115		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
31116			target.attr( "title", target.data( "ui-tooltip-title" ) );
31117		}
31118
31119		this._removeDescribedBy( target );
31120
31121		tooltipData.hiding = true;
31122		tooltip.stop( true );
31123		this._hide( tooltip, this.options.hide, function() {
31124			that._removeTooltip( $( this ) );
31125		} );
31126
31127		target.removeData( "ui-tooltip-open" );
31128		this._off( target, "mouseleave focusout keyup" );
31129
31130		// Remove 'remove' binding only on delegated targets
31131		if ( target[ 0 ] !== this.element[ 0 ] ) {
31132			this._off( target, "remove" );
31133		}
31134		this._off( this.document, "mousemove" );
31135
31136		if ( event && event.type === "mouseleave" ) {
31137			$.each( this.parents, function( id, parent ) {
31138				$( parent.element ).attr( "title", parent.title );
31139				delete that.parents[ id ];
31140			} );
31141		}
31142
31143		tooltipData.closing = true;
31144		this._trigger( "close", event, { tooltip: tooltip } );
31145		if ( !tooltipData.hiding ) {
31146			tooltipData.closing = false;
31147		}
31148	},
31149
31150	_tooltip: function( element ) {
31151		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
31152			content = $( "<div>" ).appendTo( tooltip ),
31153			id = tooltip.uniqueId().attr( "id" );
31154
31155		this._addClass( content, "ui-tooltip-content" );
31156		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
31157
31158		tooltip.appendTo( this._appendTo( element ) );
31159
31160		return this.tooltips[ id ] = {
31161			element: element,
31162			tooltip: tooltip
31163		};
31164	},
31165
31166	_find: function( target ) {
31167		var id = target.data( "ui-tooltip-id" );
31168		return id ? this.tooltips[ id ] : null;
31169	},
31170
31171	_removeTooltip: function( tooltip ) {
31172
31173		// Clear the interval for delayed tracking tooltips
31174		clearInterval( this.delayedShow );
31175
31176		tooltip.remove();
31177		delete this.tooltips[ tooltip.attr( "id" ) ];
31178	},
31179
31180	_appendTo: function( target ) {
31181		var element = target.closest( ".ui-front, dialog" );
31182
31183		if ( !element.length ) {
31184			element = this.document[ 0 ].body;
31185		}
31186
31187		return element;
31188	},
31189
31190	_destroy: function() {
31191		var that = this;
31192
31193		// Close open tooltips
31194		$.each( this.tooltips, function( id, tooltipData ) {
31195
31196			// Delegate to close method to handle common cleanup
31197			var event = $.Event( "blur" ),
31198				element = tooltipData.element;
31199			event.target = event.currentTarget = element[ 0 ];
31200			that.close( event, true );
31201
31202			// Remove immediately; destroying an open tooltip doesn't use the
31203			// hide animation
31204			$( "#" + id ).remove();
31205
31206			// Restore the title
31207			if ( element.data( "ui-tooltip-title" ) ) {
31208
31209				// If the title attribute has changed since open(), don't restore
31210				if ( !element.attr( "title" ) ) {
31211					element.attr( "title", element.data( "ui-tooltip-title" ) );
31212				}
31213				element.removeData( "ui-tooltip-title" );
31214			}
31215		} );
31216		this.liveRegion.remove();
31217	}
31218} );
31219
31220// DEPRECATED
31221// TODO: Switch return back to widget declaration at top of file when this is removed
31222if ( $.uiBackCompat !== false ) {
31223
31224	// Backcompat for tooltipClass option
31225	$.widget( "ui.tooltip", $.ui.tooltip, {
31226		options: {
31227			tooltipClass: null
31228		},
31229		_tooltip: function() {
31230			var tooltipData = this._superApply( arguments );
31231			if ( this.options.tooltipClass ) {
31232				tooltipData.tooltip.addClass( this.options.tooltipClass );
31233			}
31234			return tooltipData;
31235		}
31236	} );
31237}
31238
31239return $.ui.tooltip;
31240
31241} );
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
31257
31258
31259
31260
31261
31262
31263
31264
31265
31266
31267
31268
31269
31270
31271
31272
31273
31274
31275
31276
31277
31278
31279
31280
31281
31282
31283
31284
31285
31286
31287
31288
31289
31290
31291
31292
31293
31294
31295
31296
31297
31298
31299/* jshint node: true */
31300
31301/**
31302 * Unobtrusive scripting adapter for jQuery
31303 * https://github.com/rails/jquery-ujs
31304 *
31305 * Requires jQuery 1.8.0 or later.
31306 *
31307 * Released under the MIT license
31308 *
31309 */
31310
31311
31312(function() {
31313  'use strict';
31314
31315  var jqueryUjsInit = function($, undefined) {
31316
31317  // Cut down on the number of issues from people inadvertently including jquery_ujs twice
31318  // by detecting and raising an error when it happens.
31319  if ( $.rails !== undefined ) {
31320    $.error('jquery-ujs has already been loaded!');
31321  }
31322
31323  // Shorthand to make it a little easier to call public rails functions from within rails.js
31324  var rails;
31325  var $document = $(document);
31326
31327  $.rails = rails = {
31328    // Link elements bound by jquery-ujs
31329    linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]',
31330
31331    // Button elements bound by jquery-ujs
31332    buttonClickSelector: 'button[data-remote]:not([form]):not(form button), button[data-confirm]:not([form]):not(form button)',
31333
31334    // Select elements bound by jquery-ujs
31335    inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]',
31336
31337    // Form elements bound by jquery-ujs
31338    formSubmitSelector: 'form:not([data-turbo=true])',
31339
31340    // Form input elements bound by jquery-ujs
31341    formInputClickSelector: 'form:not([data-turbo=true]) input[type=submit], form:not([data-turbo=true]) input[type=image], form:not([data-turbo=true]) button[type=submit], form:not([data-turbo=true]) button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])',
31342
31343    // Form input elements disabled during form submission
31344    disableSelector: 'input[data-disable-with]:enabled, button[data-disable-with]:enabled, textarea[data-disable-with]:enabled, input[data-disable]:enabled, button[data-disable]:enabled, textarea[data-disable]:enabled',
31345
31346    // Form input elements re-enabled after form submission
31347    enableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled',
31348
31349    // Form required input elements
31350    requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])',
31351
31352    // Form file input elements
31353    fileInputSelector: 'input[name][type=file]:not([disabled])',
31354
31355    // Link onClick disable selector with possible reenable after remote submission
31356    linkDisableSelector: 'a[data-disable-with], a[data-disable]',
31357
31358    // Button onClick disable selector with possible reenable after remote submission
31359    buttonDisableSelector: 'button[data-remote][data-disable-with], button[data-remote][data-disable]',
31360
31361    // Up-to-date Cross-Site Request Forgery token
31362    csrfToken: function() {
31363     return $('meta[name=csrf-token]').attr('content');
31364    },
31365
31366    // URL param that must contain the CSRF token
31367    csrfParam: function() {
31368     return $('meta[name=csrf-param]').attr('content');
31369    },
31370
31371    // Make sure that every Ajax request sends the CSRF token
31372    CSRFProtection: function(xhr) {
31373      var token = rails.csrfToken();
31374      if (token) xhr.setRequestHeader('X-CSRF-Token', token);
31375    },
31376
31377    // Make sure that all forms have actual up-to-date tokens (cached forms contain old ones)
31378    refreshCSRFTokens: function(){
31379      $('form input[name="' + rails.csrfParam() + '"]').val(rails.csrfToken());
31380    },
31381
31382    // Triggers an event on an element and returns false if the event result is false
31383    fire: function(obj, name, data) {
31384      var event = $.Event(name);
31385      obj.trigger(event, data);
31386      return event.result !== false;
31387    },
31388
31389    // Default confirm dialog, may be overridden with custom confirm dialog in $.rails.confirm
31390    confirm: function(message) {
31391      return confirm(message);
31392    },
31393
31394    // Default ajax function, may be overridden with custom function in $.rails.ajax
31395    ajax: function(options) {
31396      return $.ajax(options);
31397    },
31398
31399    // Default way to get an element's href. May be overridden at $.rails.href.
31400    href: function(element) {
31401      return element[0].href;
31402    },
31403
31404    // Checks "data-remote" if true to handle the request through a XHR request.
31405    isRemote: function(element) {
31406      return element.data('remote') !== undefined && element.data('remote') !== false;
31407    },
31408
31409    // Submits "remote" forms and links with ajax
31410    handleRemote: function(element) {
31411      var method, url, data, withCredentials, dataType, options;
31412
31413      if (rails.fire(element, 'ajax:before')) {
31414        withCredentials = element.data('with-credentials') || null;
31415        dataType = element.data('type') || ($.ajaxSettings && $.ajaxSettings.dataType);
31416
31417        if (element.is('form')) {
31418          method = element.data('ujs:submit-button-formmethod') || element.attr('method');
31419          url = element.data('ujs:submit-button-formaction') || element.attr('action');
31420          data = $(element[0]).serializeArray();
31421          // memoized value from clicked submit button
31422          var button = element.data('ujs:submit-button');
31423          if (button) {
31424            data.push(button);
31425            element.data('ujs:submit-button', null);
31426          }
31427          element.data('ujs:submit-button-formmethod', null);
31428          element.data('ujs:submit-button-formaction', null);
31429        } else if (element.is(rails.inputChangeSelector)) {
31430          method = element.data('method');
31431          url = element.data('url');
31432          data = element.serialize();
31433          if (element.data('params')) data = data + '&' + element.data('params');
31434        } else if (element.is(rails.buttonClickSelector)) {
31435          method = element.data('method') || 'get';
31436          url = element.data('url');
31437          data = element.serialize();
31438          if (element.data('params')) data = data + '&' + element.data('params');
31439        } else {
31440          method = element.data('method');
31441          url = rails.href(element);
31442          data = element.data('params') || null;
31443        }
31444
31445        options = {
31446          type: method || 'GET', data: data, dataType: dataType,
31447          // stopping the "ajax:beforeSend" event will cancel the ajax request
31448          beforeSend: function(xhr, settings) {
31449            if (settings.dataType === undefined) {
31450              xhr.setRequestHeader('accept', '*/*;q=0.5, ' + settings.accepts.script);
31451            }
31452            if (rails.fire(element, 'ajax:beforeSend', [xhr, settings])) {
31453              element.trigger('ajax:send', xhr);
31454            } else {
31455              return false;
31456            }
31457          },
31458          success: function(data, status, xhr) {
31459            element.trigger('ajax:success', [data, status, xhr]);
31460          },
31461          complete: function(xhr, status) {
31462            element.trigger('ajax:complete', [xhr, status]);
31463          },
31464          error: function(xhr, status, error) {
31465            element.trigger('ajax:error', [xhr, status, error]);
31466          },
31467          crossDomain: rails.isCrossDomain(url)
31468        };
31469
31470        // There is no withCredentials for IE6-8 when
31471        // "Enable native XMLHTTP support" is disabled
31472        if (withCredentials) {
31473          options.xhrFields = {
31474            withCredentials: withCredentials
31475          };
31476        }
31477
31478        // Only pass url to `ajax` options if not blank
31479        if (url) { options.url = url; }
31480
31481        return rails.ajax(options);
31482      } else {
31483        return false;
31484      }
31485    },
31486
31487    // Determines if the request is a cross domain request.
31488    isCrossDomain: function(url) {
31489      var originAnchor = document.createElement('a');
31490      originAnchor.href = location.href;
31491      var urlAnchor = document.createElement('a');
31492
31493      try {
31494        urlAnchor.href = url;
31495        // This is a workaround to a IE bug.
31496        urlAnchor.href = urlAnchor.href;
31497
31498        // If URL protocol is false or is a string containing a single colon
31499        // *and* host are false, assume it is not a cross-domain request
31500        // (should only be the case for IE7 and IE compatibility mode).
31501        // Otherwise, evaluate protocol and host of the URL against the origin
31502        // protocol and host.
31503        return !(((!urlAnchor.protocol || urlAnchor.protocol === ':') && !urlAnchor.host) ||
31504          (originAnchor.protocol + '//' + originAnchor.host ===
31505            urlAnchor.protocol + '//' + urlAnchor.host));
31506      } catch (e) {
31507        // If there is an error parsing the URL, assume it is crossDomain.
31508        return true;
31509      }
31510    },
31511
31512    // Handles "data-method" on links such as:
31513    // <a href="/users/5" data-method="delete" rel="nofollow" data-confirm="Are you sure?">Delete</a>
31514    handleMethod: function(link) {
31515      var href = rails.href(link),
31516        method = link.data('method'),
31517        target = link.attr('target'),
31518        csrfToken = rails.csrfToken(),
31519        csrfParam = rails.csrfParam(),
31520        form = $('<form method="post" action="' + href + '"></form>'),
31521        metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
31522
31523      if (csrfParam !== undefined && csrfToken !== undefined && !rails.isCrossDomain(href)) {
31524        metadataInput += '<input name="' + csrfParam + '" value="' + csrfToken + '" type="hidden" />';
31525      }
31526
31527      if (target) { form.attr('target', target); }
31528
31529      form.hide().append(metadataInput).appendTo('body');
31530      form.submit();
31531    },
31532
31533    // Helper function that returns form elements that match the specified CSS selector
31534    // If form is actually a "form" element this will return associated elements outside the from that have
31535    // the html form attribute set
31536    formElements: function(form, selector) {
31537      return form.is('form') ? $(form[0].elements).filter(selector) : form.find(selector);
31538    },
31539
31540    /* Disables form elements:
31541      - Caches element value in 'ujs:enable-with' data store
31542      - Replaces element text with value of 'data-disable-with' attribute
31543      - Sets disabled property to true
31544    */
31545    disableFormElements: function(form) {
31546      rails.formElements(form, rails.disableSelector).each(function() {
31547        rails.disableFormElement($(this));
31548      });
31549    },
31550
31551    disableFormElement: function(element) {
31552      var method, replacement;
31553
31554      method = element.is('button') ? 'html' : 'val';
31555      replacement = element.data('disable-with');
31556
31557      if (replacement !== undefined) {
31558        element.data('ujs:enable-with', element[method]());
31559        element[method](replacement);
31560      }
31561
31562      element.prop('disabled', true);
31563      element.data('ujs:disabled', true);
31564    },
31565
31566    /* Re-enables disabled form elements:
31567      - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
31568      - Sets disabled property to false
31569    */
31570    enableFormElements: function(form) {
31571      rails.formElements(form, rails.enableSelector).each(function() {
31572        rails.enableFormElement($(this));
31573      });
31574    },
31575
31576    enableFormElement: function(element) {
31577      var method = element.is('button') ? 'html' : 'val';
31578      if (element.data('ujs:enable-with') !== undefined) {
31579        element[method](element.data('ujs:enable-with'));
31580        element.removeData('ujs:enable-with'); // clean up cache
31581      }
31582      element.prop('disabled', false);
31583      element.removeData('ujs:disabled');
31584    },
31585
31586   /* For 'data-confirm' attribute:
31587      - Fires `confirm` event
31588      - Shows the confirmation dialog
31589      - Fires the `confirm:complete` event
31590
31591      Returns `true` if no function stops the chain and user chose yes; `false` otherwise.
31592      Attaching a handler to the element's `confirm` event that returns a `falsy` value cancels the confirmation dialog.
31593      Attaching a handler to the element's `confirm:complete` event that returns a `falsy` value makes this function
31594      return false. The `confirm:complete` event is fired whether or not the user answered true or false to the dialog.
31595   */
31596    allowAction: function(element) {
31597      var message = element.data('confirm'),
31598          answer = false, callback;
31599      if (!message) { return true; }
31600
31601      if (rails.fire(element, 'confirm')) {
31602        try {
31603          answer = rails.confirm(message);
31604        } catch (e) {
31605          (console.error || console.log).call(console, e.stack || e);
31606        }
31607        callback = rails.fire(element, 'confirm:complete', [answer]);
31608      }
31609      return answer && callback;
31610    },
31611
31612    // Helper function which checks for blank inputs in a form that match the specified CSS selector
31613    blankInputs: function(form, specifiedSelector, nonBlank) {
31614      var foundInputs = $(),
31615        input,
31616        valueToCheck,
31617        radiosForNameWithNoneSelected,
31618        radioName,
31619        selector = specifiedSelector || 'input,textarea',
31620        requiredInputs = form.find(selector),
31621        checkedRadioButtonNames = {};
31622
31623      requiredInputs.each(function() {
31624        input = $(this);
31625        if (input.is('input[type=radio]')) {
31626
31627          // Don't count unchecked required radio as blank if other radio with same name is checked,
31628          // regardless of whether same-name radio input has required attribute or not. The spec
31629          // states https://www.w3.org/TR/html5/forms.html#the-required-attribute
31630          radioName = input.attr('name');
31631
31632          // Skip if we've already seen the radio with this name.
31633          if (!checkedRadioButtonNames[radioName]) {
31634
31635            // If none checked
31636            if (form.find('input[type=radio]:checked[name="' + radioName + '"]').length === 0) {
31637              radiosForNameWithNoneSelected = form.find(
31638                'input[type=radio][name="' + radioName + '"]');
31639              foundInputs = foundInputs.add(radiosForNameWithNoneSelected);
31640            }
31641
31642            // We only need to check each name once.
31643            checkedRadioButtonNames[radioName] = radioName;
31644          }
31645        } else {
31646          valueToCheck = input.is('input[type=checkbox],input[type=radio]') ? input.is(':checked') : !!input.val();
31647          if (valueToCheck === nonBlank) {
31648            foundInputs = foundInputs.add(input);
31649          }
31650        }
31651      });
31652      return foundInputs.length ? foundInputs : false;
31653    },
31654
31655    // Helper function which checks for non-blank inputs in a form that match the specified CSS selector
31656    nonBlankInputs: function(form, specifiedSelector) {
31657      return rails.blankInputs(form, specifiedSelector, true); // true specifies nonBlank
31658    },
31659
31660    // Helper function, needed to provide consistent behavior in IE
31661    stopEverything: function(e) {
31662      $(e.target).trigger('ujs:everythingStopped');
31663      e.stopImmediatePropagation();
31664      return false;
31665    },
31666
31667    //  Replace element's html with the 'data-disable-with' after storing original html
31668    //  and prevent clicking on it
31669    disableElement: function(element) {
31670      var replacement = element.data('disable-with');
31671
31672      if (replacement !== undefined) {
31673        element.data('ujs:enable-with', element.html()); // store enabled state
31674        element.html(replacement);
31675      }
31676
31677      element.on('click.railsDisable', function(e) { // prevent further clicking
31678        return rails.stopEverything(e);
31679      });
31680      element.data('ujs:disabled', true);
31681    },
31682
31683    // Restore element to its original state which was disabled by 'disableElement' above
31684    enableElement: function(element) {
31685      if (element.data('ujs:enable-with') !== undefined) {
31686        element.html(element.data('ujs:enable-with')); // set to old enabled state
31687        element.removeData('ujs:enable-with'); // clean up cache
31688      }
31689      element.off('click.railsDisable'); // enable element
31690      element.removeData('ujs:disabled');
31691    }
31692  };
31693
31694  if (rails.fire($document, 'rails:attachBindings')) {
31695
31696    $.ajaxPrefilter(function(options, originalOptions, xhr){ if ( !options.crossDomain ) { rails.CSRFProtection(xhr); }});
31697
31698    // This event works the same as the load event, except that it fires every
31699    // time the page is loaded.
31700    //
31701    // See https://github.com/rails/jquery-ujs/issues/357
31702    // See https://developer.mozilla.org/en-US/docs/Using_Firefox_1.5_caching
31703    $(window).on('pageshow.rails', function () {
31704      $($.rails.enableSelector).each(function () {
31705        var element = $(this);
31706
31707        if (element.data('ujs:disabled')) {
31708          $.rails.enableFormElement(element);
31709        }
31710      });
31711
31712      $($.rails.linkDisableSelector).each(function () {
31713        var element = $(this);
31714
31715        if (element.data('ujs:disabled')) {
31716          $.rails.enableElement(element);
31717        }
31718      });
31719    });
31720
31721    $document.on('ajax:complete', rails.linkDisableSelector, function() {
31722        rails.enableElement($(this));
31723    });
31724
31725    $document.on('ajax:complete', rails.buttonDisableSelector, function() {
31726        rails.enableFormElement($(this));
31727    });
31728
31729    $document.on('click.rails', rails.linkClickSelector, function(e) {
31730      var link = $(this), method = link.data('method'), data = link.data('params'), metaClick = e.metaKey || e.ctrlKey;
31731      if (!rails.allowAction(link)) return rails.stopEverything(e);
31732
31733      if (!metaClick && link.is(rails.linkDisableSelector)) rails.disableElement(link);
31734
31735      if (rails.isRemote(link)) {
31736        if (metaClick && (!method || method === 'GET') && !data) { return true; }
31737
31738        var handleRemote = rails.handleRemote(link);
31739        // Response from rails.handleRemote() will either be false or a deferred object promise.
31740        if (handleRemote === false) {
31741          rails.enableElement(link);
31742        } else {
31743          handleRemote.fail( function() { rails.enableElement(link); } );
31744        }
31745        return false;
31746
31747      } else if (method) {
31748        rails.handleMethod(link);
31749        return false;
31750      }
31751    });
31752
31753    $document.on('click.rails', rails.buttonClickSelector, function(e) {
31754      var button = $(this);
31755
31756      if (!rails.allowAction(button) || !rails.isRemote(button)) return rails.stopEverything(e);
31757
31758      if (button.is(rails.buttonDisableSelector)) rails.disableFormElement(button);
31759
31760      var handleRemote = rails.handleRemote(button);
31761      // Response from rails.handleRemote() will either be false or a deferred object promise.
31762      if (handleRemote === false) {
31763        rails.enableFormElement(button);
31764      } else {
31765        handleRemote.fail( function() { rails.enableFormElement(button); } );
31766      }
31767      return false;
31768    });
31769
31770    $document.on('change.rails', rails.inputChangeSelector, function(e) {
31771      var link = $(this);
31772      if (!rails.allowAction(link) || !rails.isRemote(link)) return rails.stopEverything(e);
31773
31774      rails.handleRemote(link);
31775      return false;
31776    });
31777
31778    $document.on('submit.rails', rails.formSubmitSelector, function(e) {
31779      var form = $(this),
31780        remote = rails.isRemote(form),
31781        blankRequiredInputs,
31782        nonBlankFileInputs;
31783
31784      if (!rails.allowAction(form)) return rails.stopEverything(e);
31785
31786      // Skip other logic when required values are missing or file upload is present
31787      if (form.attr('novalidate') === undefined) {
31788        if (form.data('ujs:formnovalidate-button') === undefined) {
31789          blankRequiredInputs = rails.blankInputs(form, rails.requiredInputSelector, false);
31790          if (blankRequiredInputs && rails.fire(form, 'ajax:aborted:required', [blankRequiredInputs])) {
31791            return rails.stopEverything(e);
31792          }
31793        } else {
31794          // Clear the formnovalidate in case the next button click is not on a formnovalidate button
31795          // Not strictly necessary to do here, since it is also reset on each button click, but just to be certain
31796          form.data('ujs:formnovalidate-button', undefined);
31797        }
31798      }
31799
31800      if (remote) {
31801        nonBlankFileInputs = rails.nonBlankInputs(form, rails.fileInputSelector);
31802        if (nonBlankFileInputs) {
31803          // Slight timeout so that the submit button gets properly serialized
31804          // (make it easy for event handler to serialize form without disabled values)
31805          setTimeout(function(){ rails.disableFormElements(form); }, 13);
31806          var aborted = rails.fire(form, 'ajax:aborted:file', [nonBlankFileInputs]);
31807
31808          // Re-enable form elements if event bindings return false (canceling normal form submission)
31809          if (!aborted) { setTimeout(function(){ rails.enableFormElements(form); }, 13); }
31810
31811          return aborted;
31812        }
31813
31814        rails.handleRemote(form);
31815        return false;
31816
31817      } else {
31818        // Slight timeout so that the submit button gets properly serialized
31819        setTimeout(function(){ rails.disableFormElements(form); }, 13);
31820      }
31821    });
31822
31823    $document.on('click.rails', rails.formInputClickSelector, function(event) {
31824      var button = $(this);
31825
31826      if (!rails.allowAction(button)) return rails.stopEverything(event);
31827
31828      // Register the pressed submit button
31829      var name = button.attr('name'),
31830        data = name ? {name:name, value:button.val()} : null;
31831
31832      var form = button.closest('form');
31833      if (form.length === 0) {
31834        form = $('#' + button.attr('form'));
31835      }
31836      form.data('ujs:submit-button', data);
31837
31838      // Save attributes from button
31839      form.data('ujs:formnovalidate-button', button.attr('formnovalidate'));
31840      form.data('ujs:submit-button-formaction', button.attr('formaction'));
31841      form.data('ujs:submit-button-formmethod', button.attr('formmethod'));
31842    });
31843
31844    $document.on('ajax:send.rails', rails.formSubmitSelector, function(event) {
31845      if (this === event.target) rails.disableFormElements($(this));
31846    });
31847
31848    $document.on('ajax:complete.rails', rails.formSubmitSelector, function(event) {
31849      if (this === event.target) rails.enableFormElements($(this));
31850    });
31851
31852    $(function(){
31853      rails.refreshCSRFTokens();
31854    });
31855  }
31856
31857  };
31858
31859  if (window.jQuery) {
31860    jqueryUjsInit(jQuery);
31861  } else if (typeof exports === 'object' && typeof module === 'object') {
31862    module.exports = jqueryUjsInit;
31863  }
31864})();
31865/*!
31866 * jQuery Validation Plugin v1.19.0
31867 *
31868 * https://jqueryvalidation.org/
31869 *
31870 * Copyright (c) 2018 Jörn Zaefferer
31871 * Released under the MIT license
31872 */
31873
31874(function( factory ) {
31875	if ( typeof define === "function" && define.amd ) {
31876		define( ["jquery"], factory );
31877	} else if (typeof module === "object" && module.exports) {
31878		module.exports = factory( require( "jquery" ) );
31879	} else {
31880		factory( jQuery );
31881	}
31882}(function( $ ) {
31883
31884$.extend( $.fn, {
31885
31886	// https://jqueryvalidation.org/validate/
31887	validate: function( options ) {
31888
31889		// If nothing is selected, return nothing; can't chain anyway
31890		if ( !this.length ) {
31891			if ( options && options.debug && window.console ) {
31892				console.warn( "Nothing selected, can't validate, returning nothing." );
31893			}
31894			return;
31895		}
31896
31897		// Check if a validator for this form was already created
vendor: 26,206 bytes, lines 31898-32777
31898		var validator = $.data( this[ 0 ], "validator" );
31899		if ( validator ) {
31900			return validator;
31901		}
31902
31903		// Add novalidate tag if HTML5.
31904		this.attr( "novalidate", "novalidate" );
31905
31906		validator = new $.validator( options, this[ 0 ] );
31907		$.data( this[ 0 ], "validator", validator );
31908
31909		if ( validator.settings.onsubmit ) {
31910
31911			this.on( "click.validate", ":submit", function( event ) {
31912
31913				// Track the used submit button to properly handle scripted
31914				// submits later.
31915				validator.submitButton = event.currentTarget;
31916
31917				// Allow suppressing validation by adding a cancel class to the submit button
31918				if ( $( this ).hasClass( "cancel" ) ) {
31919					validator.cancelSubmit = true;
31920				}
31921
31922				// Allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
31923				if ( $( this ).attr( "formnovalidate" ) !== undefined ) {
31924					validator.cancelSubmit = true;
31925				}
31926			} );
31927
31928			// Validate the form on submit
31929			this.on( "submit.validate", function( event ) {
31930				if ( validator.settings.debug ) {
31931
31932					// Prevent form submit to be able to see console output
31933					event.preventDefault();
31934				}
31935
31936				function handle() {
31937					var hidden, result;
31938
31939					// Insert a hidden input as a replacement for the missing submit button
31940					// The hidden input is inserted in two cases:
31941					//   - A user defined a `submitHandler`
31942					//   - There was a pending request due to `remote` method and `stopRequest()`
31943					//     was called to submit the form in case it's valid
31944					if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
31945						hidden = $( "<input type='hidden'/>" )
31946							.attr( "name", validator.submitButton.name )
31947							.val( $( validator.submitButton ).val() )
31948							.appendTo( validator.currentForm );
31949					}
31950
31951					if ( validator.settings.submitHandler && !validator.settings.debug ) {
31952						result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
31953						if ( hidden ) {
31954
31955							// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
31956							hidden.remove();
31957						}
31958						if ( result !== undefined ) {
31959							return result;
31960						}
31961						return false;
31962					}
31963					return true;
31964				}
31965
31966				// Prevent submit for invalid forms or custom submit handlers
31967				if ( validator.cancelSubmit ) {
31968					validator.cancelSubmit = false;
31969					return handle();
31970				}
31971				if ( validator.form() ) {
31972					if ( validator.pendingRequest ) {
31973						validator.formSubmitted = true;
31974						return false;
31975					}
31976					return handle();
31977				} else {
31978					validator.focusInvalid();
31979					return false;
31980				}
31981			} );
31982		}
31983
31984		return validator;
31985	},
31986
31987	// https://jqueryvalidation.org/valid/
31988	valid: function() {
31989		var valid, validator, errorList;
31990
31991		if ( $( this[ 0 ] ).is( "form" ) ) {
31992			valid = this.validate().form();
31993		} else {
31994			errorList = [];
31995			valid = true;
31996			validator = $( this[ 0 ].form ).validate();
31997			this.each( function() {
31998				valid = validator.element( this ) && valid;
31999				if ( !valid ) {
32000					errorList = errorList.concat( validator.errorList );
32001				}
32002			} );
32003			validator.errorList = errorList;
32004		}
32005		return valid;
32006	},
32007
32008	// https://jqueryvalidation.org/rules/
32009	rules: function( command, argument ) {
32010		var element = this[ 0 ],
32011			isContentEditable = typeof this.attr( "contenteditable" ) !== "undefined" && this.attr( "contenteditable" ) !== "false",
32012			settings, staticRules, existingRules, data, param, filtered;
32013
32014		// If nothing is selected, return empty object; can't chain anyway
32015		if ( element == null ) {
32016			return;
32017		}
32018
32019		if ( !element.form && isContentEditable ) {
32020			element.form = this.closest( "form" )[ 0 ];
32021			element.name = this.attr( "name" );
32022		}
32023
32024		if ( element.form == null ) {
32025			return;
32026		}
32027
32028		if ( command ) {
32029			settings = $.data( element.form, "validator" ).settings;
32030			staticRules = settings.rules;
32031			existingRules = $.validator.staticRules( element );
32032			switch ( command ) {
32033			case "add":
32034				$.extend( existingRules, $.validator.normalizeRule( argument ) );
32035
32036				// Remove messages from rules, but allow them to be set separately
32037				delete existingRules.messages;
32038				staticRules[ element.name ] = existingRules;
32039				if ( argument.messages ) {
32040					settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
32041				}
32042				break;
32043			case "remove":
32044				if ( !argument ) {
32045					delete staticRules[ element.name ];
32046					return existingRules;
32047				}
32048				filtered = {};
32049				$.each( argument.split( /\s/ ), function( index, method ) {
32050					filtered[ method ] = existingRules[ method ];
32051					delete existingRules[ method ];
32052				} );
32053				return filtered;
32054			}
32055		}
32056
32057		data = $.validator.normalizeRules(
32058		$.extend(
32059			{},
32060			$.validator.classRules( element ),
32061			$.validator.attributeRules( element ),
32062			$.validator.dataRules( element ),
32063			$.validator.staticRules( element )
32064		), element );
32065
32066		// Make sure required is at front
32067		if ( data.required ) {
32068			param = data.required;
32069			delete data.required;
32070			data = $.extend( { required: param }, data );
32071		}
32072
32073		// Make sure remote is at back
32074		if ( data.remote ) {
32075			param = data.remote;
32076			delete data.remote;
32077			data = $.extend( data, { remote: param } );
32078		}
32079
32080		return data;
32081	}
32082} );
32083
32084// Custom selectors
32085$.extend( $.expr.pseudos || $.expr[ ":" ], {		// '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
32086
32087	// https://jqueryvalidation.org/blank-selector/
32088	blank: function( a ) {
32089		return !$.trim( "" + $( a ).val() );
32090	},
32091
32092	// https://jqueryvalidation.org/filled-selector/
32093	filled: function( a ) {
32094		var val = $( a ).val();
32095		return val !== null && !!$.trim( "" + val );
32096	},
32097
32098	// https://jqueryvalidation.org/unchecked-selector/
32099	unchecked: function( a ) {
32100		return !$( a ).prop( "checked" );
32101	}
32102} );
32103
32104// Constructor for validator
32105$.validator = function( options, form ) {
32106	this.settings = $.extend( true, {}, $.validator.defaults, options );
32107	this.currentForm = form;
32108	this.init();
32109};
32110
32111// https://jqueryvalidation.org/jQuery.validator.format/
32112$.validator.format = function( source, params ) {
32113	if ( arguments.length === 1 ) {
32114		return function() {
32115			var args = $.makeArray( arguments );
32116			args.unshift( source );
32117			return $.validator.format.apply( this, args );
32118		};
32119	}
32120	if ( params === undefined ) {
32121		return source;
32122	}
32123	if ( arguments.length > 2 && params.constructor !== Array  ) {
32124		params = $.makeArray( arguments ).slice( 1 );
32125	}
32126	if ( params.constructor !== Array ) {
32127		params = [ params ];
32128	}
32129	$.each( params, function( i, n ) {
32130		source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
32131			return n;
32132		} );
32133	} );
32134	return source;
32135};
32136
32137$.extend( $.validator, {
32138
32139	defaults: {
32140		messages: {},
32141		groups: {},
32142		rules: {},
32143		errorClass: "error",
32144		pendingClass: "pending",
32145		validClass: "valid",
32146		errorElement: "label",
32147		focusCleanup: false,
32148		focusInvalid: true,
32149		errorContainer: $( [] ),
32150		errorLabelContainer: $( [] ),
32151		onsubmit: true,
32152		ignore: ":hidden",
32153		ignoreTitle: false,
32154		onfocusin: function( element ) {
32155			this.lastActive = element;
32156
32157			// Hide error label and remove error class on focus if enabled
32158			if ( this.settings.focusCleanup ) {
32159				if ( this.settings.unhighlight ) {
32160					this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
32161				}
32162				this.hideThese( this.errorsFor( element ) );
32163			}
32164		},
32165		onfocusout: function( element ) {
32166			if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
32167				this.element( element );
32168			}
32169		},
32170		onkeyup: function( element, event ) {
32171
32172			// Avoid revalidate the field when pressing one of the following keys
32173			// Shift       => 16
32174			// Ctrl        => 17
32175			// Alt         => 18
32176			// Caps lock   => 20
32177			// End         => 35
32178			// Home        => 36
32179			// Left arrow  => 37
32180			// Up arrow    => 38
32181			// Right arrow => 39
32182			// Down arrow  => 40
32183			// Insert      => 45
32184			// Num lock    => 144
32185			// AltGr key   => 225
32186			var excludedKeys = [
32187				16, 17, 18, 20, 35, 36, 37,
32188				38, 39, 40, 45, 144, 225
32189			];
32190
32191			if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
32192				return;
32193			} else if ( element.name in this.submitted || element.name in this.invalid ) {
32194				this.element( element );
32195			}
32196		},
32197		onclick: function( element ) {
32198
32199			// Click on selects, radiobuttons and checkboxes
32200			if ( element.name in this.submitted ) {
32201				this.element( element );
32202
32203			// Or option elements, check parent select in that case
32204			} else if ( element.parentNode.name in this.submitted ) {
32205				this.element( element.parentNode );
32206			}
32207		},
32208		highlight: function( element, errorClass, validClass ) {
32209			if ( element.type === "radio" ) {
32210				this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
32211			} else {
32212				$( element ).addClass( errorClass ).removeClass( validClass );
32213			}
32214		},
32215		unhighlight: function( element, errorClass, validClass ) {
32216			if ( element.type === "radio" ) {
32217				this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
32218			} else {
32219				$( element ).removeClass( errorClass ).addClass( validClass );
32220			}
32221		}
32222	},
32223
32224	// https://jqueryvalidation.org/jQuery.validator.setDefaults/
32225	setDefaults: function( settings ) {
32226		$.extend( $.validator.defaults, settings );
32227	},
32228
32229	messages: {
32230		required: "This field is required.",
32231		remote: "Please fix this field.",
32232		email: "Please enter a valid email address.",
32233		url: "Please enter a valid URL.",
32234		date: "Please enter a valid date.",
32235		dateISO: "Please enter a valid date (ISO).",
32236		number: "Please enter a valid number.",
32237		digits: "Please enter only digits.",
32238		equalTo: "Please enter the same value again.",
32239		maxlength: $.validator.format( "Please enter no more than {0} characters." ),
32240		minlength: $.validator.format( "Please enter at least {0} characters." ),
32241		rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
32242		range: $.validator.format( "Please enter a value between {0} and {1}." ),
32243		max: $.validator.format( "Please enter a value less than or equal to {0}." ),
32244		min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
32245		step: $.validator.format( "Please enter a multiple of {0}." )
32246	},
32247
32248	autoCreateRanges: false,
32249
32250	prototype: {
32251
32252		init: function() {
32253			this.labelContainer = $( this.settings.errorLabelContainer );
32254			this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
32255			this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
32256			this.submitted = {};
32257			this.valueCache = {};
32258			this.pendingRequest = 0;
32259			this.pending = {};
32260			this.invalid = {};
32261			this.reset();
32262
32263			var currentForm = this.currentForm,
32264				groups = ( this.groups = {} ),
32265				rules;
32266			$.each( this.settings.groups, function( key, value ) {
32267				if ( typeof value === "string" ) {
32268					value = value.split( /\s/ );
32269				}
32270				$.each( value, function( index, name ) {
32271					groups[ name ] = key;
32272				} );
32273			} );
32274			rules = this.settings.rules;
32275			$.each( rules, function( key, value ) {
32276				rules[ key ] = $.validator.normalizeRule( value );
32277			} );
32278
32279			function delegate( event ) {
32280				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
32281
32282				// Set form expando on contenteditable
32283				if ( !this.form && isContentEditable ) {
32284					this.form = $( this ).closest( "form" )[ 0 ];
32285					this.name = $( this ).attr( "name" );
32286				}
32287
32288				// Ignore the element if it belongs to another form. This will happen mainly
32289				// when setting the `form` attribute of an input to the id of another form.
32290				if ( currentForm !== this.form ) {
32291					return;
32292				}
32293
32294				var validator = $.data( this.form, "validator" ),
32295					eventType = "on" + event.type.replace( /^validate/, "" ),
32296					settings = validator.settings;
32297				if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
32298					settings[ eventType ].call( validator, this, event );
32299				}
32300			}
32301
32302			$( this.currentForm )
32303				.on( "focusin.validate focusout.validate keyup.validate",
32304					":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
32305					"[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
32306					"[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
32307					"[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
32308
32309				// Support: Chrome, oldIE
32310				// "select" is provided as event.target when clicking a option
32311				.on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
32312
32313			if ( this.settings.invalidHandler ) {
32314				$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
32315			}
32316		},
32317
32318		// https://jqueryvalidation.org/Validator.form/
32319		form: function() {
32320			this.checkForm();
32321			$.extend( this.submitted, this.errorMap );
32322			this.invalid = $.extend( {}, this.errorMap );
32323			if ( !this.valid() ) {
32324				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
32325			}
32326			this.showErrors();
32327			return this.valid();
32328		},
32329
32330		checkForm: function() {
32331			this.prepareForm();
32332			for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
32333				this.check( elements[ i ] );
32334			}
32335			return this.valid();
32336		},
32337
32338		// https://jqueryvalidation.org/Validator.element/
32339		element: function( element ) {
32340			var cleanElement = this.clean( element ),
32341				checkElement = this.validationTargetFor( cleanElement ),
32342				v = this,
32343				result = true,
32344				rs, group;
32345
32346			if ( checkElement === undefined ) {
32347				delete this.invalid[ cleanElement.name ];
32348			} else {
32349				this.prepareElement( checkElement );
32350				this.currentElements = $( checkElement );
32351
32352				// If this element is grouped, then validate all group elements already
32353				// containing a value
32354				group = this.groups[ checkElement.name ];
32355				if ( group ) {
32356					$.each( this.groups, function( name, testgroup ) {
32357						if ( testgroup === group && name !== checkElement.name ) {
32358							cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
32359							if ( cleanElement && cleanElement.name in v.invalid ) {
32360								v.currentElements.push( cleanElement );
32361								result = v.check( cleanElement ) && result;
32362							}
32363						}
32364					} );
32365				}
32366
32367				rs = this.check( checkElement ) !== false;
32368				result = result && rs;
32369				if ( rs ) {
32370					this.invalid[ checkElement.name ] = false;
32371				} else {
32372					this.invalid[ checkElement.name ] = true;
32373				}
32374
32375				if ( !this.numberOfInvalids() ) {
32376
32377					// Hide error containers on last error
32378					this.toHide = this.toHide.add( this.containers );
32379				}
32380				this.showErrors();
32381
32382				// Add aria-invalid status for screen readers
32383				$( element ).attr( "aria-invalid", !rs );
32384			}
32385
32386			return result;
32387		},
32388
32389		// https://jqueryvalidation.org/Validator.showErrors/
32390		showErrors: function( errors ) {
32391			if ( errors ) {
32392				var validator = this;
32393
32394				// Add items to error list and map
32395				$.extend( this.errorMap, errors );
32396				this.errorList = $.map( this.errorMap, function( message, name ) {
32397					return {
32398						message: message,
32399						element: validator.findByName( name )[ 0 ]
32400					};
32401				} );
32402
32403				// Remove items from success list
32404				this.successList = $.grep( this.successList, function( element ) {
32405					return !( element.name in errors );
32406				} );
32407			}
32408			if ( this.settings.showErrors ) {
32409				this.settings.showErrors.call( this, this.errorMap, this.errorList );
32410			} else {
32411				this.defaultShowErrors();
32412			}
32413		},
32414
32415		// https://jqueryvalidation.org/Validator.resetForm/
32416		resetForm: function() {
32417			if ( $.fn.resetForm ) {
32418				$( this.currentForm ).resetForm();
32419			}
32420			this.invalid = {};
32421			this.submitted = {};
32422			this.prepareForm();
32423			this.hideErrors();
32424			var elements = this.elements()
32425				.removeData( "previousValue" )
32426				.removeAttr( "aria-invalid" );
32427
32428			this.resetElements( elements );
32429		},
32430
32431		resetElements: function( elements ) {
32432			var i;
32433
32434			if ( this.settings.unhighlight ) {
32435				for ( i = 0; elements[ i ]; i++ ) {
32436					this.settings.unhighlight.call( this, elements[ i ],
32437						this.settings.errorClass, "" );
32438					this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
32439				}
32440			} else {
32441				elements
32442					.removeClass( this.settings.errorClass )
32443					.removeClass( this.settings.validClass );
32444			}
32445		},
32446
32447		numberOfInvalids: function() {
32448			return this.objectLength( this.invalid );
32449		},
32450
32451		objectLength: function( obj ) {
32452			/* jshint unused: false */
32453			var count = 0,
32454				i;
32455			for ( i in obj ) {
32456
32457				// This check allows counting elements with empty error
32458				// message as invalid elements
32459				if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
32460					count++;
32461				}
32462			}
32463			return count;
32464		},
32465
32466		hideErrors: function() {
32467			this.hideThese( this.toHide );
32468		},
32469
32470		hideThese: function( errors ) {
32471			errors.not( this.containers ).text( "" );
32472			this.addWrapper( errors ).hide();
32473		},
32474
32475		valid: function() {
32476			return this.size() === 0;
32477		},
32478
32479		size: function() {
32480			return this.errorList.length;
32481		},
32482
32483		focusInvalid: function() {
32484			if ( this.settings.focusInvalid ) {
32485				try {
32486					$( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
32487					.filter( ":visible" )
32488					.focus()
32489
32490					// Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
32491					.trigger( "focusin" );
32492				} catch ( e ) {
32493
32494					// Ignore IE throwing errors when focusing hidden elements
32495				}
32496			}
32497		},
32498
32499		findLastActive: function() {
32500			var lastActive = this.lastActive;
32501			return lastActive && $.grep( this.errorList, function( n ) {
32502				return n.element.name === lastActive.name;
32503			} ).length === 1 && lastActive;
32504		},
32505
32506		elements: function() {
32507			var validator = this,
32508				rulesCache = {};
32509
32510			// Select all valid inputs inside the form (no submit or reset buttons)
32511			return $( this.currentForm )
32512			.find( "input, select, textarea, [contenteditable]" )
32513			.not( ":submit, :reset, :image, :disabled" )
32514			.not( this.settings.ignore )
32515			.filter( function() {
32516				var name = this.name || $( this ).attr( "name" ); // For contenteditable
32517				var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false";
32518
32519				if ( !name && validator.settings.debug && window.console ) {
32520					console.error( "%o has no name assigned", this );
32521				}
32522
32523				// Set form expando on contenteditable
32524				if ( isContentEditable ) {
32525					this.form = $( this ).closest( "form" )[ 0 ];
32526					this.name = name;
32527				}
32528
32529				// Ignore elements that belong to other/nested forms
32530				if ( this.form !== validator.currentForm ) {
32531					return false;
32532				}
32533
32534				// Select only the first element for each name, and only those with rules specified
32535				if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
32536					return false;
32537				}
32538
32539				rulesCache[ name ] = true;
32540				return true;
32541			} );
32542		},
32543
32544		clean: function( selector ) {
32545			return $( selector )[ 0 ];
32546		},
32547
32548		errors: function() {
32549			var errorClass = this.settings.errorClass.split( " " ).join( "." );
32550			return $( this.settings.errorElement + "." + errorClass, this.errorContext );
32551		},
32552
32553		resetInternals: function() {
32554			this.successList = [];
32555			this.errorList = [];
32556			this.errorMap = {};
32557			this.toShow = $( [] );
32558			this.toHide = $( [] );
32559		},
32560
32561		reset: function() {
32562			this.resetInternals();
32563			this.currentElements = $( [] );
32564		},
32565
32566		prepareForm: function() {
32567			this.reset();
32568			this.toHide = this.errors().add( this.containers );
32569		},
32570
32571		prepareElement: function( element ) {
32572			this.reset();
32573			this.toHide = this.errorsFor( element );
32574		},
32575
32576		elementValue: function( element ) {
32577			var $element = $( element ),
32578				type = element.type,
32579				isContentEditable = typeof $element.attr( "contenteditable" ) !== "undefined" && $element.attr( "contenteditable" ) !== "false",
32580				val, idx;
32581
32582			if ( type === "radio" || type === "checkbox" ) {
32583				return this.findByName( element.name ).filter( ":checked" ).val();
32584			} else if ( type === "number" && typeof element.validity !== "undefined" ) {
32585				return element.validity.badInput ? "NaN" : $element.val();
32586			}
32587
32588			if ( isContentEditable ) {
32589				val = $element.text();
32590			} else {
32591				val = $element.val();
32592			}
32593
32594			if ( type === "file" ) {
32595
32596				// Modern browser (chrome & safari)
32597				if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
32598					return val.substr( 12 );
32599				}
32600
32601				// Legacy browsers
32602				// Unix-based path
32603				idx = val.lastIndexOf( "/" );
32604				if ( idx >= 0 ) {
32605					return val.substr( idx + 1 );
32606				}
32607
32608				// Windows-based path
32609				idx = val.lastIndexOf( "\\" );
32610				if ( idx >= 0 ) {
32611					return val.substr( idx + 1 );
32612				}
32613
32614				// Just the file name
32615				return val;
32616			}
32617
32618			if ( typeof val === "string" ) {
32619				return val.replace( /\r/g, "" );
32620			}
32621			return val;
32622		},
32623
32624		check: function( element ) {
32625			element = this.validationTargetFor( this.clean( element ) );
32626
32627			var rules = $( element ).rules(),
32628				rulesCount = $.map( rules, function( n, i ) {
32629					return i;
32630				} ).length,
32631				dependencyMismatch = false,
32632				val = this.elementValue( element ),
32633				result, method, rule, normalizer;
32634
32635			// Prioritize the local normalizer defined for this element over the global one
32636			// if the former exists, otherwise user the global one in case it exists.
32637			if ( typeof rules.normalizer === "function" ) {
32638				normalizer = rules.normalizer;
32639			} else if (	typeof this.settings.normalizer === "function" ) {
32640				normalizer = this.settings.normalizer;
32641			}
32642
32643			// If normalizer is defined, then call it to retreive the changed value instead
32644			// of using the real one.
32645			// Note that `this` in the normalizer is `element`.
32646			if ( normalizer ) {
32647				val = normalizer.call( element, val );
32648
32649				// Delete the normalizer from rules to avoid treating it as a pre-defined method.
32650				delete rules.normalizer;
32651			}
32652
32653			for ( method in rules ) {
32654				rule = { method: method, parameters: rules[ method ] };
32655				try {
32656					result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
32657
32658					// If a method indicates that the field is optional and therefore valid,
32659					// don't mark it as valid when there are no other rules
32660					if ( result === "dependency-mismatch" && rulesCount === 1 ) {
32661						dependencyMismatch = true;
32662						continue;
32663					}
32664					dependencyMismatch = false;
32665
32666					if ( result === "pending" ) {
32667						this.toHide = this.toHide.not( this.errorsFor( element ) );
32668						return;
32669					}
32670
32671					if ( !result ) {
32672						this.formatAndAdd( element, rule );
32673						return false;
32674					}
32675				} catch ( e ) {
32676					if ( this.settings.debug && window.console ) {
32677						console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
32678					}
32679					if ( e instanceof TypeError ) {
32680						e.message += ".  Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
32681					}
32682
32683					throw e;
32684				}
32685			}
32686			if ( dependencyMismatch ) {
32687				return;
32688			}
32689			if ( this.objectLength( rules ) ) {
32690				this.successList.push( element );
32691			}
32692			return true;
32693		},
32694
32695		// Return the custom message for the given element and validation method
32696		// specified in the element's HTML5 data attribute
32697		// return the generic message if present and no method specific message is present
32698		customDataMessage: function( element, method ) {
32699			return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
32700				method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
32701		},
32702
32703		// Return the custom message for the given element name and validation method
32704		customMessage: function( name, method ) {
32705			var m = this.settings.messages[ name ];
32706			return m && ( m.constructor === String ? m : m[ method ] );
32707		},
32708
32709		// Return the first defined argument, allowing empty strings
32710		findDefined: function() {
32711			for ( var i = 0; i < arguments.length; i++ ) {
32712				if ( arguments[ i ] !== undefined ) {
32713					return arguments[ i ];
32714				}
32715			}
32716			return undefined;
32717		},
32718
32719		// The second parameter 'rule' used to be a string, and extended to an object literal
32720		// of the following form:
32721		// rule = {
32722		//     method: "method name",
32723		//     parameters: "the given method parameters"
32724		// }
32725		//
32726		// The old behavior still supported, kept to maintain backward compatibility with
32727		// old code, and will be removed in the next major release.
32728		defaultMessage: function( element, rule ) {
32729			if ( typeof rule === "string" ) {
32730				rule = { method: rule };
32731			}
32732
32733			var message = this.findDefined(
32734					this.customMessage( element.name, rule.method ),
32735					this.customDataMessage( element, rule.method ),
32736
32737					// 'title' is never undefined, so handle empty string as undefined
32738					!this.settings.ignoreTitle && element.title || undefined,
32739					$.validator.messages[ rule.method ],
32740					"<strong>Warning: No message defined for " + element.name + "</strong>"
32741				),
32742				theregex = /\$?\{(\d+)\}/g;
32743			if ( typeof message === "function" ) {
32744				message = message.call( this, rule.parameters, element );
32745			} else if ( theregex.test( message ) ) {
32746				message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
32747			}
32748
32749			return message;
32750		},
32751
32752		formatAndAdd: function( element, rule ) {
32753			var message = this.defaultMessage( element, rule );
32754
32755			this.errorList.push( {
32756				message: message,
32757				element: element,
32758				method: rule.method
32759			} );
32760
32761			this.errorMap[ element.name ] = message;
32762			this.submitted[ element.name ] = message;
32763		},
32764
32765		addWrapper: function( toToggle ) {
32766			if ( this.settings.wrapper ) {
32767				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
32768			}
32769			return toToggle;
32770		},
32771
32772		defaultShowErrors: function() {
32773			var i, elements, error;
32774			for ( i = 0; this.errorList[ i ]; i++ ) {
32775				error = this.errorList[ i ];
32776				if ( this.settings.highlight ) {
32777					this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.val
32777idClass );
32778				}
32779				this.showLabel( error.element, error.message );
32780			}
32781			if ( this.errorList.length ) {
32782				this.toShow = this.toShow.add( this.containers );
32783			}
32784			if ( this.settings.success ) {
32785				for ( i = 0; this.successList[ i ]; i++ ) {
32786					this.showLabel( this.successList[ i ] );
32787				}
32788			}
32789			if ( this.settings.unhighlight ) {
32790				for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
32791					this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
32792				}
32793			}
32794			this.toHide = this.toHide.not( this.toShow );
32795			this.hideErrors();
32796			this.addWrapper( this.toShow ).show();
32797		},
32798
32799		validElements: function() {
32800			return this.currentElements.not( this.invalidElements() );
32801		},
32802
32803		invalidElements: function() {
32804			return $( this.errorList ).map( function() {
32805				return this.element;
32806			} );
32807		},
32808
32809		showLabel: function( element, message ) {
32810			var place, group, errorID, v,
32811				error = this.errorsFor( element ),
32812				elementID = this.idOrName( element ),
32813				describedBy = $( element ).attr( "aria-describedby" );
32814
32815			if ( error.length ) {
32816
32817				// Refresh error/success class
32818				error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
32819
32820				// Replace message on existing label
32821				error.html( message );
32822			} else {
32823
32824				// Create error element
32825				error = $( "<" + this.settings.errorElement + ">" )
32826					.attr( "id", elementID + "-error" )
32827					.addClass( this.settings.errorClass )
32828					.html( message || "" );
32829
32830				// Maintain reference to the element to be placed into the DOM
32831				place = error;
32832				if ( this.settings.wrapper ) {
32833
32834					// Make sure the element is visible, even in IE
32835					// actually showing the wrapped element is handled elsewhere
32836					place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
32837				}
32838				if ( this.labelContainer.length ) {
32839					this.labelContainer.append( place );
32840				} else if ( this.settings.errorPlacement ) {
32841					this.settings.errorPlacement.call( this, place, $( element ) );
32842				} else {
32843					place.insertAfter( element );
32844				}
32845
32846				// Link error back to the element
32847				if ( error.is( "label" ) ) {
32848
32849					// If the error is a label, then associate using 'for'
32850					error.attr( "for", elementID );
32851
32852					// If the element is not a child of an associated label, then it's necessary
32853					// to explicitly apply aria-describedby
32854				} else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
32855					errorID = error.attr( "id" );
32856
32857					// Respect existing non-error aria-describedby
32858					if ( !describedBy ) {
32859						describedBy = errorID;
32860					} else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
32861
32862						// Add to end of list if not already present
32863						describedBy += " " + errorID;
32864					}
32865					$( element ).attr( "aria-describedby", describedBy );
32866
32867					// If this element is grouped, then assign to all elements in the same group
32868					group = this.groups[ element.name ];
32869					if ( group ) {
32870						v = this;
32871						$.each( v.groups, function( name, testgroup ) {
32872							if ( testgroup === group ) {
32873								$( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
32874									.attr( "aria-describedby", error.attr( "id" ) );
32875							}
32876						} );
32877					}
32878				}
32879			}
32880			if ( !message && this.settings.success ) {
32881				error.text( "" );
32882				if ( typeof this.settings.success === "string" ) {
32883					error.addClass( this.settings.success );
32884				} else {
32885					this.settings.success( error, element );
32886				}
32887			}
32888			this.toShow = this.toShow.add( error );
32889		},
32890
32891		errorsFor: function( element ) {
32892			var name = this.escapeCssMeta( this.idOrName( element ) ),
32893				describer = $( element ).attr( "aria-describedby" ),
32894				selector = "label[for='" + name + "'], label[for='" + name + "'] *";
32895
32896			// 'aria-describedby' should directly reference the error element
32897			if ( describer ) {
32898				selector = selector + ", #" + this.escapeCssMeta( describer )
32899					.replace( /\s+/g, ", #" );
32900			}
32901
32902			return this
32903				.errors()
32904				.filter( selector );
32905		},
32906
32907		// See https://api.jquery.com/category/selectors/, for CSS
32908		// meta-characters that should be escaped in order to be used with JQuery
32909		// as a literal part of a name/id or any selector.
32910		escapeCssMeta: function( string ) {
32911			return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
32912		},
32913
32914		idOrName: function( element ) {
32915			return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.i
vendor: 15,429 bytes, lines 32915-33396
32915d || element.name );
32916		},
32917
32918		validationTargetFor: function( element ) {
32919
32920			// If radio/checkbox, validate first element in group instead
32921			if ( this.checkable( element ) ) {
32922				element = this.findByName( element.name );
32923			}
32924
32925			// Always apply ignore filter
32926			return $( element ).not( this.settings.ignore )[ 0 ];
32927		},
32928
32929		checkable: function( element ) {
32930			return ( /radio|checkbox/i ).test( element.type );
32931		},
32932
32933		findByName: function( name ) {
32934			return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
32935		},
32936
32937		getLength: function( value, element ) {
32938			switch ( element.nodeName.toLowerCase() ) {
32939			case "select":
32940				return $( "option:selected", element ).length;
32941			case "input":
32942				if ( this.checkable( element ) ) {
32943					return this.findByName( element.name ).filter( ":checked" ).length;
32944				}
32945			}
32946			return value.length;
32947		},
32948
32949		depend: function( param, element ) {
32950			return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
32951		},
32952
32953		dependTypes: {
32954			"boolean": function( param ) {
32955				return param;
32956			},
32957			"string": function( param, element ) {
32958				return !!$( param, element.form ).length;
32959			},
32960			"function": function( param, element ) {
32961				return param( element );
32962			}
32963		},
32964
32965		optional: function( element ) {
32966			var val = this.elementValue( element );
32967			return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
32968		},
32969
32970		startRequest: function( element ) {
32971			if ( !this.pending[ element.name ] ) {
32972				this.pendingRequest++;
32973				$( element ).addClass( this.settings.pendingClass );
32974				this.pending[ element.name ] = true;
32975			}
32976		},
32977
32978		stopRequest: function( element, valid ) {
32979			this.pendingRequest--;
32980
32981			// Sometimes synchronization fails, make sure pendingRequest is never < 0
32982			if ( this.pendingRequest < 0 ) {
32983				this.pendingRequest = 0;
32984			}
32985			delete this.pending[ element.name ];
32986			$( element ).removeClass( this.settings.pendingClass );
32987			if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
32988				$( this.currentForm ).submit();
32989
32990				// Remove the hidden input that was used as a replacement for the
32991				// missing submit button. The hidden input is added by `handle()`
32992				// to ensure that the value of the used submit button is passed on
32993				// for scripted submits triggered by this method
32994				if ( this.submitButton ) {
32995					$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
32996				}
32997
32998				this.formSubmitted = false;
32999			} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
33000				$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
33001				this.formSubmitted = false;
33002			}
33003		},
33004
33005		previousValue: function( element, method ) {
33006			method = typeof method === "string" && method || "remote";
33007
33008			return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
33009				old: null,
33010				valid: true,
33011				message: this.defaultMessage( element, { method: method } )
33012			} );
33013		},
33014
33015		// Cleans up all forms and elements, removes validator-specific events
33016		destroy: function() {
33017			this.resetForm();
33018
33019			$( this.currentForm )
33020				.off( ".validate" )
33021				.removeData( "validator" )
33022				.find( ".validate-equalTo-blur" )
33023					.off( ".validate-equalTo" )
33024					.removeClass( "validate-equalTo-blur" )
33025				.find( ".validate-lessThan-blur" )
33026					.off( ".validate-lessThan" )
33027					.removeClass( "validate-lessThan-blur" )
33028				.find( ".validate-lessThanEqual-blur" )
33029					.off( ".validate-lessThanEqual" )
33030					.removeClass( "validate-lessThanEqual-blur" )
33031				.find( ".validate-greaterThanEqual-blur" )
33032					.off( ".validate-greaterThanEqual" )
33033					.removeClass( "validate-greaterThanEqual-blur" )
33034				.find( ".validate-greaterThan-blur" )
33035					.off( ".validate-greaterThan" )
33036					.removeClass( "validate-greaterThan-blur" );
33037		}
33038
33039	},
33040
33041	classRuleSettings: {
33042		required: { required: true },
33043		email: { email: true },
33044		url: { url: true },
33045		date: { date: true },
33046		dateISO: { dateISO: true },
33047		number: { number: true },
33048		digits: { digits: true },
33049		creditcard: { creditcard: true }
33050	},
33051
33052	addClassRules: function( className, rules ) {
33053		if ( className.constructor === String ) {
33054			this.classRuleSettings[ className ] = rules;
33055		} else {
33056			$.extend( this.classRuleSettings, className );
33057		}
33058	},
33059
33060	classRules: function( element ) {
33061		var rules = {},
33062			classes = $( element ).attr( "class" );
33063
33064		if ( classes ) {
33065			$.each( classes.split( " " ), function() {
33066				if ( this in $.validator.classRuleSettings ) {
33067					$.extend( rules, $.validator.classRuleSettings[ this ] );
33068				}
33069			} );
33070		}
33071		return rules;
33072	},
33073
33074	normalizeAttributeRule: function( rules, type, method, value ) {
33075
33076		// Convert the value to a number for number inputs, and for text for backwards compability
33077		// allows type="date" and others to be compared as strings
33078		if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
33079			value = Number( value );
33080
33081			// Support Opera Mini, which returns NaN for undefined minlength
33082			if ( isNaN( value ) ) {
33083				value = undefined;
33084			}
33085		}
33086
33087		if ( value || value === 0 ) {
33088			rules[ method ] = value;
33089		} else if ( type === method && type !== "range" ) {
33090
33091			// Exception: the jquery validate 'range' method
33092			// does not test for the html5 'range' type
33093			rules[ method ] = true;
33094		}
33095	},
33096
33097	attributeRules: function( element ) {
33098		var rules = {},
33099			$element = $( element ),
33100			type = element.getAttribute( "type" ),
33101			method, value;
33102
33103		for ( method in $.validator.methods ) {
33104
33105			// Support for <input required> in both html5 and older browsers
33106			if ( method === "required" ) {
33107				value = element.getAttribute( method );
33108
33109				// Some browsers return an empty string for the required attribute
33110				// and non-HTML5 browsers might have required="" markup
33111				if ( value === "" ) {
33112					value = true;
33113				}
33114
33115				// Force non-HTML5 browsers to return bool
33116				value = !!value;
33117			} else {
33118				value = $element.attr( method );
33119			}
33120
33121			this.normalizeAttributeRule( rules, type, method, value );
33122		}
33123
33124		// 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
33125		if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
33126			delete rules.maxlength;
33127		}
33128
33129		return rules;
33130	},
33131
33132	dataRules: function( element ) {
33133		var rules = {},
33134			$element = $( element ),
33135			type = element.getAttribute( "type" ),
33136			method, value;
33137
33138		for ( method in $.validator.methods ) {
33139			value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
33140
33141			// Cast empty attributes like `data-rule-required` to `true`
33142			if ( value === "" ) {
33143				value = true;
33144			}
33145
33146			this.normalizeAttributeRule( rules, type, method, value );
33147		}
33148		return rules;
33149	},
33150
33151	staticRules: function( element ) {
33152		var rules = {},
33153			validator = $.data( element.form, "validator" );
33154
33155		if ( validator.settings.rules ) {
33156			rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
33157		}
33158		return rules;
33159	},
33160
33161	normalizeRules: function( rules, element ) {
33162
33163		// Handle dependency check
33164		$.each( rules, function( prop, val ) {
33165
33166			// Ignore rule when param is explicitly false, eg. required:false
33167			if ( val === false ) {
33168				delete rules[ prop ];
33169				return;
33170			}
33171			if ( val.param || val.depends ) {
33172				var keepRule = true;
33173				switch ( typeof val.depends ) {
33174				case "string":
33175					keepRule = !!$( val.depends, element.form ).length;
33176					break;
33177				case "function":
33178					keepRule = val.depends.call( element, element );
33179					break;
33180				}
33181				if ( keepRule ) {
33182					rules[ prop ] = val.param !== undefined ? val.param : true;
33183				} else {
33184					$.data( element.form, "validator" ).resetElements( $( element ) );
33185					delete rules[ prop ];
33186				}
33187			}
33188		} );
33189
33190		// Evaluate parameters
33191		$.each( rules, function( rule, parameter ) {
33192			rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
33193		} );
33194
33195		// Clean number parameters
33196		$.each( [ "minlength", "maxlength" ], function() {
33197			if ( rules[ this ] ) {
33198				rules[ this ] = Number( rules[ this ] );
33199			}
33200		} );
33201		$.each( [ "rangelength", "range" ], function() {
33202			var parts;
33203			if ( rules[ this ] ) {
33204				if ( $.isArray( rules[ this ] ) ) {
33205					rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
33206				} else if ( typeof rules[ this ] === "string" ) {
33207					parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
33208					rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
33209				}
33210			}
33211		} );
33212
33213		if ( $.validator.autoCreateRanges ) {
33214
33215			// Auto-create ranges
33216			if ( rules.min != null && rules.max != null ) {
33217				rules.range = [ rules.min, rules.max ];
33218				delete rules.min;
33219				delete rules.max;
33220			}
33221			if ( rules.minlength != null && rules.maxlength != null ) {
33222				rules.rangelength = [ rules.minlength, rules.maxlength ];
33223				delete rules.minlength;
33224				delete rules.maxlength;
33225			}
33226		}
33227
33228		return rules;
33229	},
33230
33231	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
33232	normalizeRule: function( data ) {
33233		if ( typeof data === "string" ) {
33234			var transformed = {};
33235			$.each( data.split( /\s/ ), function() {
33236				transformed[ this ] = true;
33237			} );
33238			data = transformed;
33239		}
33240		return data;
33241	},
33242
33243	// https://jqueryvalidation.org/jQuery.validator.addMethod/
33244	addMethod: function( name, method, message ) {
33245		$.validator.methods[ name ] = method;
33246		$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
33247		if ( method.length < 3 ) {
33248			$.validator.addClassRules( name, $.validator.normalizeRule( name ) );
33249		}
33250	},
33251
33252	// https://jqueryvalidation.org/jQuery.validator.methods/
33253	methods: {
33254
33255		// https://jqueryvalidation.org/required-method/
33256		required: function( value, element, param ) {
33257
33258			// Check if dependency is met
33259			if ( !this.depend( param, element ) ) {
33260				return "dependency-mismatch";
33261			}
33262			if ( element.nodeName.toLowerCase() === "select" ) {
33263
33264				// Could be an array for select-multiple or a string, both are fine this way
33265				var val = $( element ).val();
33266				return val && val.length > 0;
33267			}
33268			if ( this.checkable( element ) ) {
33269				return this.getLength( value, element ) > 0;
33270			}
33271			return value !== undefined && value !== null && value.length > 0;
33272		},
33273
33274		// https://jqueryvalidation.org/email-method/
33275		email: function( value, element ) {
33276
33277			// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
33278			// Retrieved 2014-01-14
33279			// If you have a problem with this implementation, report a bug against the above spec
33280			// Or use custom methods to implement your own email validation
33281			return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
33282		},
33283
33284		// https://jqueryvalidation.org/url-method/
33285		url: function( value, element ) {
33286
33287			// Copyright (c) 2010-2013 Diego Perini, MIT licensed
33288			// https://gist.github.com/dperini/729294
33289			// see also https://mathiasbynens.be/demo/url-regex
33290			// modified to allow protocol-relative URLs
33291			return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
33292		},
33293
33294		// https://jqueryvalidation.org/date-method/
33295		date: ( function() {
33296			var called = false;
33297
33298			return function( value, element ) {
33299				if ( !called ) {
33300					called = true;
33301					if ( this.settings.debug && window.console ) {
33302						console.warn(
33303							"The `date` method is deprecated and will be removed in version '2.0.0'.\n" +
33304							"Please don't use it, since it relies on the Date constructor, which\n" +
33305							"behaves very differently across browsers and locales. Use `dateISO`\n" +
33306							"instead or one of the locale specific methods in `localizations/`\n" +
33307							"and `additional-methods.js`."
33308						);
33309					}
33310				}
33311
33312				return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
33313			};
33314		}() ),
33315
33316		// https://jqueryvalidation.org/dateISO-method/
33317		dateISO: function( value, element ) {
33318			return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
33319		},
33320
33321		// https://jqueryvalidation.org/number-method/
33322		number: function( value, element ) {
33323			return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
33324		},
33325
33326		// https://jqueryvalidation.org/digits-method/
33327		digits: function( value, element ) {
33328			return this.optional( element ) || /^\d+$/.test( value );
33329		},
33330
33331		// https://jqueryvalidation.org/minlength-method/
33332		minlength: function( value, element, param ) {
33333			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
33334			return this.optional( element ) || length >= param;
33335		},
33336
33337		// https://jqueryvalidation.org/maxlength-method/
33338		maxlength: function( value, element, param ) {
33339			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
33340			return this.optional( element ) || length <= param;
33341		},
33342
33343		// https://jqueryvalidation.org/rangelength-method/
33344		rangelength: function( value, element, param ) {
33345			var length = $.isArray( value ) ? value.length : this.getLength( value, element );
33346			return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
33347		},
33348
33349		// https://jqueryvalidation.org/min-method/
33350		min: function( value, element, param ) {
33351			return this.optional( element ) || value >= param;
33352		},
33353
33354		// https://jqueryvalidation.org/max-method/
33355		max: function( value, element, param ) {
33356			return this.optional( element ) || value <= param;
33357		},
33358
33359		// https://jqueryvalidation.org/range-method/
33360		range: function( value, element, param ) {
33361			return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
33362		},
33363
33364		// https://jqueryvalidation.org/step-method/
33365		step: function( value, element, param ) {
33366			var type = $( element ).attr( "type" ),
33367				errorMessage = "Step attribute on input type " + type + " is not supported.",
33368				supportedTypes = [ "text", "number", "range" ],
33369				re = new RegExp( "\\b" + type + "\\b" ),
33370				notSupported = type && !re.test( supportedTypes.join() ),
33371				decimalPlaces = function( num ) {
33372					var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
33373					if ( !match ) {
33374						return 0;
33375					}
33376
33377					// Number of digits right of decimal point.
33378					return match[ 1 ] ? match[ 1 ].length : 0;
33379				},
33380				toInt = function( num ) {
33381					return Math.round( num * Math.pow( 10, decimals ) );
33382				},
33383				valid = true,
33384				decimals;
33385
33386			// Works only for text, number and range input types
33387			// TODO find a way to support input types date, datetime, datetime-local, month, time and week
33388			if ( notSupported ) {
33389				throw new Error( errorMessage );
33390			}
33391
33392			decimals = decimalPlaces( param );
33393
33394			// Value can't have too many decimals
33395			if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
33396				valid = false;
33397			}
33398
33399			return this.optional( element ) || valid;
33400		},
33401
33402		// https://jqueryvalidation.org/equalTo-method/
33403		equalTo: function( value, element, param ) {
33404
33405			// Bind to the blur event of the target in order to revalidate whenever the target field is updated
33406			var target = $( param );
33407			if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
33408				target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
33409					$( element ).valid();
33410				} );
33411			}
33412			return value === target.val();
33413		},
33414
33415		// https://jqueryvalidation.org/remote-method/
33416		remote: function( value, element, param, method ) {
33417			if ( this.optional( element ) ) {
33418				return "dependency-mismatch";
33419			}
33420
33421			method = typeof method === "string" && method || "remote";
33422
33423			var previous = this.previousValue( element, method ),
33424				validator, data, optionDataString;
33425
33426			if ( !this.settings.messages[ element.name ] ) {
33427				this.settings.messages[ element.name ] = {};
33428			}
33429			previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
33430			this.settings.messages[ element.name ][ method ] = previous.message;
33431
33432			param = typeof param === "string" && { url: param } || param;
33433			optionDataString = $.param( $.extend( { data: value }, param.data ) );
33434			if ( previous.old === optionDataString ) {
33435				return previous.valid;
33436			}
33437
33438			previous.old = optionDataString;
33439			validator = this;
33440			this.startRequest( element );
33441			data = {};
33442			data[ element.name ] = value;
33443			$.ajax( $.extend( true, {
33444				mode: "abort",
33445				port: "validate" + element.name,
33446				dataType: "json",
33447				data: data,
33448				context: validator.currentForm,
33449				success: function( response ) {
33450					var valid = response === true || response === "true",
33451						errors, message, submitted;
33452
33453					validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
33454					if ( valid ) {
33455						submitted = validator.formSubmitted;
33456						validator.resetInternals();
33457						validator.toHide = validator.errorsFor( element );
33458						validator.formSubmitted = submitted;
33459						validator.successList.push( element );
33460						validator.invalid[ element.name ] = false;
33461						validator.showErrors();
33462					} else {
33463						errors = {};
33464						message = response || validator.defaultMessage( element, { method: method, parameters: value } );
33465						errors[ element.name ] = previous.message = message;
33466						validator.invalid[ element.name ] = true;
33467						validator.showErrors( errors );
33468					}
33469					previous.valid = valid;
33470					validator.stopRequest( element, valid );
33471				}
33472			}, param ) );
33473			return "pending";
33474		}
33475	}
33476
33477} );
33478
33479// Ajax mode: abort
33480// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
33481// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
33482
33483var pendingRequests = {},
33484	ajax;
33485
33486// Use a prefilter if available (1.5+)
33487if ( $.ajaxPrefilter ) {
33488	$.ajaxPrefilter( function( settings, _, xhr ) {
33489		var port = settings.port;
33490		if ( settings.mode === "abort" ) {
33491			if ( pendingRequests[ port ] ) {
33492				pendingRequests[ port ].abort();
33493			}
33494			pendingRequests[ port ] = xhr;
33495		}
33496	} );
33497} else {
33498
33499	// Proxy ajax
33500	ajax = $.ajax;
33501	$.ajax = function( settings ) {
33502		var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
33503			port = ( "port" in settings ? settings : $.ajaxSettings ).port;
33504		if ( mode === "abort" ) {
33505			if ( pendingRequests[ port ] ) {
33506				pendingRequests[ port ].abort();
33507			}
33508			pendingRequests[ port ] = ajax.apply( this, arguments );
33509			return pendingRequests[ port ];
33510		}
33511		return ajax.apply( this, arguments );
33512	};
33513}
33514return $;
33515}));
33516/*!
33517 * jQuery Validation Plugin v1.19.0
33518 *
33519 * https://jqueryvalidation.org/
33520 *
33521 * Copyright (c) 2018 Jörn Zaefferer
33522 * Released under the MIT license
33523 */
33524
33525(function( factory ) {
33526	if ( typeof define === "function" && define.amd ) {
33527		define( ["jquery", "./jquery.validate"], factory );
33528	} else if (typeof module === "object" && module.exports) {
33529		module.exports = factory( require( "jquery" ) );
33530	} else {
33531		factory( jQuery );
33532	}
33533}(function( $ ) {
33534
33535( function() {
33536
33537	function stripHtml( value ) {
33538
33539		// Remove html tags and space chars
33540		return value.replace( /<.[^<>]*?>/g, " " ).replace( /&nbsp;|&#160;/gi, " " )
33541
33542		// Remove punctuation
33543		.replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" );
33544	}
33545
33546	$.validator.addMethod( "maxWords", function( value, element, params ) {
vendor: 4,581 bytes, lines 33547-33679
33547		return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params;
33548	}, $.validator.format( "Please enter {0} words or less." ) );
33549
33550	$.validator.addMethod( "minWords", function( value, element, params ) {
33551		return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params;
33552	}, $.validator.format( "Please enter at least {0} words." ) );
33553
33554	$.validator.addMethod( "rangeWords", function( value, element, params ) {
33555		var valueStripped = stripHtml( value ),
33556			regex = /\b\w+\b/g;
33557		return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ];
33558	}, $.validator.format( "Please enter between {0} and {1} words." ) );
33559
33560}() );
33561
33562/**
33563 * This is used in the United States to process payments, deposits,
33564 * or transfers using the Automated Clearing House (ACH) or Fedwire
33565 * systems. A very common use case would be to validate a form for
33566 * an ACH bill payment.
33567 */
33568$.validator.addMethod( "abaRoutingNumber", function( value ) {
33569	var checksum = 0;
33570	var tokens = value.split( "" );
33571	var length = tokens.length;
33572
33573	// Length Check
33574	if ( length !== 9 ) {
33575		return false;
33576	}
33577
33578	// Calc the checksum
33579	// https://en.wikipedia.org/wiki/ABA_routing_transit_number
33580	for ( var i = 0; i < length; i += 3 ) {
33581		checksum +=	parseInt( tokens[ i ], 10 )     * 3 +
33582					parseInt( tokens[ i + 1 ], 10 ) * 7 +
33583					parseInt( tokens[ i + 2 ], 10 );
33584	}
33585
33586	// If not zero and divisible by 10 then valid
33587	if ( checksum !== 0 && checksum % 10 === 0 ) {
33588		return true;
33589	}
33590
33591	return false;
33592}, "Please enter a valid routing number." );
33593
33594// Accept a value from a file input based on a required mimetype
33595$.validator.addMethod( "accept", function( value, element, param ) {
33596
33597	// Split mime on commas in case we have multiple types we can accept
33598	var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*",
33599		optionalValue = this.optional( element ),
33600		i, file, regex;
33601
33602	// Element is optional
33603	if ( optionalValue ) {
33604		return optionalValue;
33605	}
33606
33607	if ( $( element ).attr( "type" ) === "file" ) {
33608
33609		// Escape string to be used in the regex
33610		// see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
33611		// Escape also "/*" as "/.*" as a wildcard
33612		typeParam = typeParam
33613				.replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" )
33614				.replace( /,/g, "|" )
33615				.replace( /\/\*/g, "/.*" );
33616
33617		// Check if the element has a FileList before checking each file
33618		if ( element.files && element.files.length ) {
33619			regex = new RegExp( ".?(" + typeParam + ")$", "i" );
33620			for ( i = 0; i < element.files.length; i++ ) {
33621				file = element.files[ i ];
33622
33623				// Grab the mimetype from the loaded file, verify it matches
33624				if ( !file.type.match( regex ) ) {
33625					return false;
33626				}
33627			}
33628		}
33629	}
33630
33631	// Either return true because we've validated each file, or because the
33632	// browser does not support element.files and the FileList feature
33633	return true;
33634}, $.validator.format( "Please enter a value with a valid mimetype." ) );
33635
33636$.validator.addMethod( "alphanumeric", function( value, element ) {
33637	return this.optional( element ) || /^\w+$/i.test( value );
33638}, "Letters, numbers, and underscores only please" );
33639
33640/*
33641 * Dutch bank account numbers (not 'giro' numbers) have 9 digits
33642 * and pass the '11 check'.
33643 * We accept the notation with spaces, as that is common.
33644 * acceptable: 123456789 or 12 34 56 789
33645 */
33646$.validator.addMethod( "bankaccountNL", function( value, element ) {
33647	if ( this.optional( element ) ) {
33648		return true;
33649	}
33650	if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) {
33651		return false;
33652	}
33653
33654	// Now '11 check'
33655	var account = value.replace( / /g, "" ), // Remove spaces
33656		sum = 0,
33657		len = account.length,
33658		pos, factor, digit;
33659	for ( pos = 0; pos < len; pos++ ) {
33660		factor = len - pos;
33661		digit = account.substring( pos, pos + 1 );
33662		sum = sum + factor * digit;
33663	}
33664	return sum % 11 === 0;
33665}, "Please specify a valid bank account number" );
33666
33667$.validator.addMethod( "bankorgiroaccountNL", function( value, element ) {
33668	return this.optional( element ) ||
33669			( $.validator.methods.bankaccountNL.call( this, value, element ) ) ||
33670			( $.validator.methods.giroaccountNL.call( this, value, element ) );
33671}, "Please specify a valid bank or giro account number" );
33672
33673/**
33674 * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
33675 *
33676 * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
33677 *
33678 * Validation is case-insensitive. Please make sure to normalize input yourself.
33679 *
33680 * BIC definition in detail:
33681 * - First 4 characters - bank code (only letters)
33682 * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
33683 * - Next 2 characters - location code (letters and digits)
33684 *   a. shall not start with '0' or '1'
33685 *   b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing)
33686 * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
33687 */
33688$.validator.addMethod( "bic", function( value, element ) {
33689    return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() );
33690}, "Please specify a valid BIC code" );
33691
33692/*
33693 * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
33694 * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
33695 *
33696 * Spanish CIF structure:
33697 *
33698 * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ]
33699 *
33700 * Where:
33701 *
33702 * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW]
33703 * P: 2 characters. Province.
33704 * N: 5 characters. Secuencial Number within the province.
33705 * C: 1 character. Control Digit: [0-9A-J].
33706 *
33707 * [ T ]: Kind of Organizations. Possible values:
33708 *
33709 *   A. Corporations
33710 *   B. LLCs
33711 *   C. General partnerships
33712 *   D. Companies limited partnerships
33713 *   E. Communities of goods
33714 *   F. Cooperative Societies
33715 *   G. Associations
33716 *   H. Communities of homeowners in horizontal property regime
33717 *   J. Civil Societies
33718 *   K. Old format
33719 *   L. Old format
33720 *   M. Old format
33721 *   N. Nonresident entities
33722 *   P. Local authorities
33723 *   Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
33724 *   R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
33725 *   S. Organs of State Administration and regions
33726 *   V. Agrarian Transformation
33727 *   W. Permanent establishments of non-resident in Spain
33728 *
33729 * [ C ]: Control Digit. It can be a number or a letter depending on T value:
33730 * [ T ]  -->  [ C ]
33731 * ------    ----------
33732 *   A         Number
33733 *   B         Number
33734 *   E         Number
33735 *   H         Number
33736 *   K         Letter
33737 *   P         Letter
33738 *   Q         Letter
33739 *   S         Letter
33740 *
33741 */
33742$.validator.addMethod( "cifES", function( value, element ) {
33743	"use strict";
33744
33745	if ( this.optional( element ) ) {
33746		return true;
33747	}
33748
33749	var cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi );
33750	var letter  = value.substring( 0, 1 ), // [ T ]
33751		number  = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ]
33752		control = value.substring( 8, 9 ), // [ C ]
33753		all_sum = 0,
33754		even_sum = 0,
33755		odd_sum = 0,
33756		i, n,
33757		control_digit,
33758		control_letter;
33759
33760	function isOdd( n ) {
33761		return n % 2 === 0;
33762	}
33763
33764	// Quick format test
33765	if ( value.length !== 9 || !cifRegEx.test( value ) ) {
33766		return false;
33767	}
33768
33769	for ( i = 0; i < number.length; i++ ) {
33770		n = parseInt( number[ i ], 10 );
33771
33772		// Odd positions
33773		if ( isOdd( i ) ) {
33774
33775			// Odd positions are multiplied first.
33776			n *= 2;
33777
33778			// If the multiplication is bigger than 10 we need to adjust
33779			odd_sum += n < 10 ? n : n - 9;
33780
33781		// Even positions
33782		// Just sum them
33783		} else {
33784			even_sum += n;
33785		}
33786	}
33787
33788	all_sum = even_sum + odd_sum;
33789	control_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString();
33790	control_digit = parseInt( control_digit, 10 ) > 9 ? "0" : control_digit;
33791	control_letter = "JABCDEFGHI".substr( control_digit, 1 ).toString();
33792
33793	// Control must be a digit
33794	if ( letter.match( /[ABEH]/ ) ) {
33795		return control === control_digit;
33796
33797	// Control must be a letter
33798	} else if ( letter.match( /[KPQS]/ ) ) {
33799		return control === control_letter;
33800	}
33801
33802	// Can be either
33803	return control === control_digit || control === control_letter;
33804
33805}, "Please specify a valid CIF number." );
33806
33807/*
33808 * Brazillian CNH number (Carteira Nacional de Habilitacao) is the License Driver number.
33809 * CNH numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.
33810 */
33811$.validator.addMethod( "cnhBR", function( value ) {
33812
33813  // Removing special characters from value
33814  value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
33815
33816  // Checking value to have 11 digits only
33817  if ( value.length !== 11 ) {
33818    return false;
vendor: 28,001 bytes, lines 33819-34710
33819  }
33820
33821  var sum = 0, dsc = 0, firstChar,
33822		firstCN, secondCN, i, j, v;
33823
33824  firstChar = value.charAt( 0 );
33825
33826  if ( new Array( 12 ).join( firstChar ) === value ) {
33827    return false;
33828  }
33829
33830  // Step 1 - using first Check Number:
33831  for ( i = 0, j = 9, v = 0; i < 9; ++i, --j ) {
33832    sum += +( value.charAt( i ) * j );
33833  }
33834
33835  firstCN = sum % 11;
33836  if ( firstCN >= 10 ) {
33837    firstCN = 0;
33838    dsc = 2;
33839  }
33840
33841  sum = 0;
33842  for ( i = 0, j = 1, v = 0; i < 9; ++i, ++j ) {
33843    sum += +( value.charAt( i ) * j );
33844  }
33845
33846  secondCN = sum % 11;
33847  if ( secondCN >= 10 ) {
33848    secondCN = 0;
33849  } else {
33850    secondCN = secondCN - dsc;
33851  }
33852
33853  return ( String( firstCN ).concat( secondCN ) === value.substr( -2 ) );
33854
33855}, "Please specify a valid CNH number" );
33856
33857/*
33858 * Brazillian value number (Cadastrado de Pessoas Juridica).
33859 * value numbers have 14 digits in total: 12 numbers followed by 2 check numbers that are being used for validation.
33860 */
33861$.validator.addMethod( "cnpjBR", function( value, element ) {
33862	"use strict";
33863
33864	if ( this.optional( element ) ) {
33865		return true;
33866	}
33867
33868	// Removing no number
33869	value = value.replace( /[^\d]+/g, "" );
33870
33871	// Checking value to have 14 digits only
33872	if ( value.length !== 14 ) {
33873		return false;
33874	}
33875
33876	// Elimina values invalidos conhecidos
33877	if ( value === "00000000000000" ||
33878		value === "11111111111111" ||
33879		value === "22222222222222" ||
33880		value === "33333333333333" ||
33881		value === "44444444444444" ||
33882		value === "55555555555555" ||
33883		value === "66666666666666" ||
33884		value === "77777777777777" ||
33885		value === "88888888888888" ||
33886		value === "99999999999999" ) {
33887		return false;
33888	}
33889
33890	// Valida DVs
33891	var tamanho = ( value.length - 2 );
33892	var numeros = value.substring( 0, tamanho );
33893	var digitos = value.substring( tamanho );
33894	var soma = 0;
33895	var pos = tamanho - 7;
33896
33897	for ( var i = tamanho; i >= 1; i-- ) {
33898		soma += numeros.charAt( tamanho - i ) * pos--;
33899		if ( pos < 2 ) {
33900			pos = 9;
33901		}
33902	}
33903
33904	var resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
33905
33906	if ( resultado !== parseInt( digitos.charAt( 0 ), 10 ) ) {
33907		return false;
33908	}
33909
33910	tamanho = tamanho + 1;
33911	numeros = value.substring( 0, tamanho );
33912	soma = 0;
33913	pos = tamanho - 7;
33914
33915	for ( var il = tamanho; il >= 1; il-- ) {
33916		soma += numeros.charAt( tamanho - il ) * pos--;
33917		if ( pos < 2 ) {
33918			pos = 9;
33919		}
33920	}
33921
33922	resultado = soma % 11 < 2 ? 0 : 11 - soma % 11;
33923
33924	if ( resultado !== parseInt( digitos.charAt( 1 ), 10 ) ) {
33925		return false;
33926	}
33927
33928	return true;
33929
33930}, "Please specify a CNPJ value number" );
33931
33932/*
33933 * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.
33934 * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.
33935 */
33936$.validator.addMethod( "cpfBR", function( value, element ) {
33937	"use strict";
33938
33939	if ( this.optional( element ) ) {
33940		return true;
33941	}
33942
33943	// Removing special characters from value
33944	value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
33945
33946	// Checking value to have 11 digits only
33947	if ( value.length !== 11 ) {
33948		return false;
33949	}
33950
33951	var sum = 0,
33952		firstCN, secondCN, checkResult, i;
33953
33954	firstCN = parseInt( value.substring( 9, 10 ), 10 );
33955	secondCN = parseInt( value.substring( 10, 11 ), 10 );
33956
33957	checkResult = function( sum, cn ) {
33958		var result = ( sum * 10 ) % 11;
33959		if ( ( result === 10 ) || ( result === 11 ) ) {
33960			result = 0;
33961		}
33962		return ( result === cn );
33963	};
33964
33965	// Checking for dump data
33966	if ( value === "" ||
33967		value === "00000000000" ||
33968		value === "11111111111" ||
33969		value === "22222222222" ||
33970		value === "33333333333" ||
33971		value === "44444444444" ||
33972		value === "55555555555" ||
33973		value === "66666666666" ||
33974		value === "77777777777" ||
33975		value === "88888888888" ||
33976		value === "99999999999"
33977	) {
33978		return false;
33979	}
33980
33981	// Step 1 - using first Check Number:
33982	for ( i = 1; i <= 9; i++ ) {
33983		sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i );
33984	}
33985
33986	// If first Check Number (CN) is valid, move to Step 2 - using second Check Number:
33987	if ( checkResult( sum, firstCN ) ) {
33988		sum = 0;
33989		for ( i = 1; i <= 10; i++ ) {
33990			sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i );
33991		}
33992		return checkResult( sum, secondCN );
33993	}
33994	return false;
33995
33996}, "Please specify a valid CPF number" );
33997
33998// https://jqueryvalidation.org/creditcard-method/
33999// based on https://en.wikipedia.org/wiki/Luhn_algorithm
34000$.validator.addMethod( "creditcard", function( value, element ) {
34001	if ( this.optional( element ) ) {
34002		return "dependency-mismatch";
34003	}
34004
34005	// Accept only spaces, digits and dashes
34006	if ( /[^0-9 \-]+/.test( value ) ) {
34007		return false;
34008	}
34009
34010	var nCheck = 0,
34011		nDigit = 0,
34012		bEven = false,
34013		n, cDigit;
34014
34015	value = value.replace( /\D/g, "" );
34016
34017	// Basing min and max length on
34018	// https://dev.ean.com/general-info/valid-card-types/
34019	if ( value.length < 13 || value.length > 19 ) {
34020		return false;
34021	}
34022
34023	for ( n = value.length - 1; n >= 0; n-- ) {
34024		cDigit = value.charAt( n );
34025		nDigit = parseInt( cDigit, 10 );
34026		if ( bEven ) {
34027			if ( ( nDigit *= 2 ) > 9 ) {
34028				nDigit -= 9;
34029			}
34030		}
34031
34032		nCheck += nDigit;
34033		bEven = !bEven;
34034	}
34035
34036	return ( nCheck % 10 ) === 0;
34037}, "Please enter a valid credit card number." );
34038
34039/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
34040 * Redistributed under the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
34041 * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
34042 */
34043$.validator.addMethod( "creditcardtypes", function( value, element, param ) {
34044	if ( /[^0-9\-]+/.test( value ) ) {
34045		return false;
34046	}
34047
34048	value = value.replace( /\D/g, "" );
34049
34050	var validTypes = 0x0000;
34051
34052	if ( param.mastercard ) {
34053		validTypes |= 0x0001;
34054	}
34055	if ( param.visa ) {
34056		validTypes |= 0x0002;
34057	}
34058	if ( param.amex ) {
34059		validTypes |= 0x0004;
34060	}
34061	if ( param.dinersclub ) {
34062		validTypes |= 0x0008;
34063	}
34064	if ( param.enroute ) {
34065		validTypes |= 0x0010;
34066	}
34067	if ( param.discover ) {
34068		validTypes |= 0x0020;
34069	}
34070	if ( param.jcb ) {
34071		validTypes |= 0x0040;
34072	}
34073	if ( param.unknown ) {
34074		validTypes |= 0x0080;
34075	}
34076	if ( param.all ) {
34077		validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
34078	}
34079	if ( validTypes & 0x0001 && ( /^(5[12345])/.test( value ) || /^(2[234567])/.test( value ) ) ) { // Mastercard
34080		return value.length === 16;
34081	}
34082	if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa
34083		return value.length === 16;
34084	}
34085	if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex
34086		return value.length === 15;
34087	}
34088	if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub
34089		return value.length === 14;
34090	}
34091	if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute
34092		return value.length === 15;
34093	}
34094	if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover
34095		return value.length === 16;
34096	}
34097	if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb
34098		return value.length === 16;
34099	}
34100	if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb
34101		return value.length === 15;
34102	}
34103	if ( validTypes & 0x0080 ) { // Unknown
34104		return true;
34105	}
34106	return false;
34107}, "Please enter a valid credit card number." );
34108
34109/**
34110 * Validates currencies with any given symbols by @jameslouiz
34111 * Symbols can be optional or required. Symbols required by default
34112 *
34113 * Usage examples:
34114 *  currency: ["£", false] - Use false for soft currency validation
34115 *  currency: ["$", false]
34116 *  currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
34117 *
34118 *  <input class="currencyInput" name="currencyInput">
34119 *
34120 * Soft symbol checking
34121 *  currencyInput: {
34122 *     currency: ["$", false]
34123 *  }
34124 *
34125 * Strict symbol checking (default)
34126 *  currencyInput: {
34127 *     currency: "$"
34128 *     //OR
34129 *     currency: ["$", true]
34130 *  }
34131 *
34132 * Multiple Symbols
34133 *  currencyInput: {
34134 *     currency: "$,£,¢"
34135 *  }
34136 */
34137$.validator.addMethod( "currency", function( value, element, param ) {
34138    var isParamString = typeof param === "string",
34139        symbol = isParamString ? param : param[ 0 ],
34140        soft = isParamString ? true : param[ 1 ],
34141        regex;
34142
34143    symbol = symbol.replace( /,/g, "" );
34144    symbol = soft ? symbol + "]" : symbol + "]?";
34145    regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
34146    regex = new RegExp( regex );
34147    return this.optional( element ) || regex.test( value );
34148
34149}, "Please specify a valid currency" );
34150
34151$.validator.addMethod( "dateFA", function( value, element ) {
34152	return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value );
34153}, $.validator.messages.date );
34154
34155/**
34156 * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
34157 *
34158 * @example $.validator.methods.date("01/01/1900")
34159 * @result true
34160 *
34161 * @example $.validator.methods.date("01/13/1990")
34162 * @result false
34163 *
34164 * @example $.validator.methods.date("01.01.1900")
34165 * @result false
34166 *
34167 * @example <input name="pippo" class="{dateITA:true}" />
34168 * @desc Declares an optional input element whose value must be a valid date.
34169 *
34170 * @name $.validator.methods.dateITA
34171 * @type Boolean
34172 * @cat Plugins/Validate/Methods
34173 */
34174$.validator.addMethod( "dateITA", function( value, element ) {
34175	var check = false,
34176		re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
34177		adata, gg, mm, aaaa, xdata;
34178	if ( re.test( value ) ) {
34179		adata = value.split( "/" );
34180		gg = parseInt( adata[ 0 ], 10 );
34181		mm = parseInt( adata[ 1 ], 10 );
34182		aaaa = parseInt( adata[ 2 ], 10 );
34183		xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );
34184		if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
34185			check = true;
34186		} else {
34187			check = false;
34188		}
34189	} else {
34190		check = false;
34191	}
34192	return this.optional( element ) || check;
34193}, $.validator.messages.date );
34194
34195$.validator.addMethod( "dateNL", function( value, element ) {
34196	return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value );
34197}, $.validator.messages.date );
34198
34199// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
34200$.validator.addMethod( "extension", function( value, element, param ) {
34201	param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif";
34202	return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) );
34203}, $.validator.format( "Please enter a value with a valid extension." ) );
34204
34205/**
34206 * Dutch giro account numbers (not bank numbers) have max 7 digits
34207 */
34208$.validator.addMethod( "giroaccountNL", function( value, element ) {
34209	return this.optional( element ) || /^[0-9]{1,7}$/.test( value );
34210}, "Please specify a valid giro account number" );
34211
34212$.validator.addMethod( "greaterThan", function( value, element, param ) {
34213    var target = $( param );
34214
34215    if ( this.settings.onfocusout && target.not( ".validate-greaterThan-blur" ).length ) {
34216        target.addClass( "validate-greaterThan-blur" ).on( "blur.validate-greaterThan", function() {
34217            $( element ).valid();
34218        } );
34219    }
34220
34221    return value > target.val();
34222}, "Please enter a greater value." );
34223
34224$.validator.addMethod( "greaterThanEqual", function( value, element, param ) {
34225    var target = $( param );
34226
34227    if ( this.settings.onfocusout && target.not( ".validate-greaterThanEqual-blur" ).length ) {
34228        target.addClass( "validate-greaterThanEqual-blur" ).on( "blur.validate-greaterThanEqual", function() {
34229            $( element ).valid();
34230        } );
34231    }
34232
34233    return value >= target.val();
34234}, "Please enter a greater value." );
34235
34236/**
34237 * IBAN is the international bank account number.
34238 * It has a country - specific format, that is checked here too
34239 *
34240 * Validation is case-insensitive. Please make sure to normalize input yourself.
34241 */
34242$.validator.addMethod( "iban", function( value, element ) {
34243
34244	// Some quick simple tests to prevent needless work
34245	if ( this.optional( element ) ) {
34246		return true;
34247	}
34248
34249	// Remove spaces and to upper case
34250	var iban = value.replace( / /g, "" ).toUpperCase(),
34251		ibancheckdigits = "",
34252		leadingZeroes = true,
34253		cRest = "",
34254		cOperator = "",
34255		countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
34256
34257	// Check for IBAN code length.
34258	// It contains:
34259	// country code ISO 3166-1 - two letters,
34260	// two check digits,
34261	// Basic Bank Account Number (BBAN) - up to 30 chars
34262	var minimalIBANlength = 5;
34263	if ( iban.length < minimalIBANlength ) {
34264		return false;
34265	}
34266
34267	// Check the country code and find the country specific format
34268	countrycode = iban.substring( 0, 2 );
34269	bbancountrypatterns = {
34270		"AL": "\\d{8}[\\dA-Z]{16}",
34271		"AD": "\\d{8}[\\dA-Z]{12}",
34272		"AT": "\\d{16}",
34273		"AZ": "[\\dA-Z]{4}\\d{20}",
34274		"BE": "\\d{12}",
34275		"BH": "[A-Z]{4}[\\dA-Z]{14}",
34276		"BA": "\\d{16}",
34277		"BR": "\\d{23}[A-Z][\\dA-Z]",
34278		"BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
34279		"CR": "\\d{17}",
34280		"HR": "\\d{17}",
34281		"CY": "\\d{8}[\\dA-Z]{16}",
34282		"CZ": "\\d{20}",
34283		"DK": "\\d{14}",
34284		"DO": "[A-Z]{4}\\d{20}",
34285		"EE": "\\d{16}",
34286		"FO": "\\d{14}",
34287		"FI": "\\d{14}",
34288		"FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
34289		"GE": "[\\dA-Z]{2}\\d{16}",
34290		"DE": "\\d{18}",
34291		"GI": "[A-Z]{4}[\\dA-Z]{15}",
34292		"GR": "\\d{7}[\\dA-Z]{16}",
34293		"GL": "\\d{14}",
34294		"GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
34295		"HU": "\\d{24}",
34296		"IS": "\\d{22}",
34297		"IE": "[\\dA-Z]{4}\\d{14}",
34298		"IL": "\\d{19}",
34299		"IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
34300		"KZ": "\\d{3}[\\dA-Z]{13}",
34301		"KW": "[A-Z]{4}[\\dA-Z]{22}",
34302		"LV": "[A-Z]{4}[\\dA-Z]{13}",
34303		"LB": "\\d{4}[\\dA-Z]{20}",
34304		"LI": "\\d{5}[\\dA-Z]{12}",
34305		"LT": "\\d{16}",
34306		"LU": "\\d{3}[\\dA-Z]{13}",
34307		"MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
34308		"MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
34309		"MR": "\\d{23}",
34310		"MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
34311		"MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
34312		"MD": "[\\dA-Z]{2}\\d{18}",
34313		"ME": "\\d{18}",
34314		"NL": "[A-Z]{4}\\d{10}",
34315		"NO": "\\d{11}",
34316		"PK": "[\\dA-Z]{4}\\d{16}",
34317		"PS": "[\\dA-Z]{4}\\d{21}",
34318		"PL": "\\d{24}",
34319		"PT": "\\d{21}",
34320		"RO": "[A-Z]{4}[\\dA-Z]{16}",
34321		"SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
34322		"SA": "\\d{2}[\\dA-Z]{18}",
34323		"RS": "\\d{18}",
34324		"SK": "\\d{20}",
34325		"SI": "\\d{15}",
34326		"ES": "\\d{20}",
34327		"SE": "\\d{20}",
34328		"CH": "\\d{5}[\\dA-Z]{12}",
34329		"TN": "\\d{20}",
34330		"TR": "\\d{5}[\\dA-Z]{17}",
34331		"AE": "\\d{3}\\d{16}",
34332		"GB": "[A-Z]{4}\\d{14}",
34333		"VG": "[\\dA-Z]{4}\\d{16}"
34334	};
34335
34336	bbanpattern = bbancountrypatterns[ countrycode ];
34337
34338	// As new countries will start using IBAN in the
34339	// future, we only check if the countrycode is known.
34340	// This prevents false negatives, while almost all
34341	// false positives introduced by this, will be caught
34342	// by the checksum validation below anyway.
34343	// Strict checking should return FALSE for unknown
34344	// countries.
34345	if ( typeof bbanpattern !== "undefined" ) {
34346		ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" );
34347		if ( !( ibanregexp.test( iban ) ) ) {
34348			return false; // Invalid country specific format
34349		}
34350	}
34351
34352	// Now check the checksum, first convert to digits
34353	ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 );
34354	for ( i = 0; i < ibancheck.length; i++ ) {
34355		charAt = ibancheck.charAt( i );
34356		if ( charAt !== "0" ) {
34357			leadingZeroes = false;
34358		}
34359		if ( !leadingZeroes ) {
34360			ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt );
34361		}
34362	}
34363
34364	// Calculate the result of: ibancheckdigits % 97
34365	for ( p = 0; p < ibancheckdigits.length; p++ ) {
34366		cChar = ibancheckdigits.charAt( p );
34367		cOperator = "" + cRest + "" + cChar;
34368		cRest = cOperator % 97;
34369	}
34370	return cRest === 1;
34371}, "Please specify a valid IBAN" );
34372
34373$.validator.addMethod( "integer", function( value, element ) {
34374	return this.optional( element ) || /^-?\d+$/.test( value );
34375}, "A positive or negative non-decimal number please" );
34376
34377$.validator.addMethod( "ipv4", function( value, element ) {
34378	return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value );
34379}, "Please enter a valid IP v4 address." );
34380
34381$.validator.addMethod( "ipv6", function( value, element ) {
34382	return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value );
34383}, "Please enter a valid IP v6 address." );
34384
34385$.validator.addMethod( "lessThan", function( value, element, param ) {
34386    var target = $( param );
34387
34388    if ( this.settings.onfocusout && target.not( ".validate-lessThan-blur" ).length ) {
34389        target.addClass( "validate-lessThan-blur" ).on( "blur.validate-lessThan", function() {
34390            $( element ).valid();
34391        } );
34392    }
34393
34394    return value < target.val();
34395}, "Please enter a lesser value." );
34396
34397$.validator.addMethod( "lessThanEqual", function( value, element, param ) {
34398    var target = $( param );
34399
34400    if ( this.settings.onfocusout && target.not( ".validate-lessThanEqual-blur" ).length ) {
34401        target.addClass( "validate-lessThanEqual-blur" ).on( "blur.validate-lessThanEqual", function() {
34402            $( element ).valid();
34403        } );
34404    }
34405
34406    return value <= target.val();
34407}, "Please enter a lesser value." );
34408
34409$.validator.addMethod( "lettersonly", function( value, element ) {
34410	return this.optional( element ) || /^[a-z]+$/i.test( value );
34411}, "Letters only please" );
34412
34413$.validator.addMethod( "letterswithbasicpunc", function( value, element ) {
34414	return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value );
34415}, "Letters or punctuation only please" );
34416
34417// Limit the number of files in a FileList.
34418$.validator.addMethod( "maxfiles", function( value, element, param ) {
34419	if ( this.optional( element ) ) {
34420		return true;
34421	}
34422
34423	if ( $( element ).attr( "type" ) === "file" ) {
34424		if ( element.files && element.files.length > param ) {
34425			return false;
34426		}
34427	}
34428
34429	return true;
34430}, $.validator.format( "Please select no more than {0} files." ) );
34431
34432// Limit the size of each individual file in a FileList.
34433$.validator.addMethod( "maxsize", function( value, element, param ) {
34434	if ( this.optional( element ) ) {
34435		return true;
34436	}
34437
34438	if ( $( element ).attr( "type" ) === "file" ) {
34439		if ( element.files && element.files.length ) {
34440			for ( var i = 0; i < element.files.length; i++ ) {
34441				if ( element.files[ i ].size > param ) {
34442					return false;
34443				}
34444			}
34445		}
34446	}
34447
34448	return true;
34449}, $.validator.format( "File size must not exceed {0} bytes each." ) );
34450
34451// Limit the size of all files in a FileList.
34452$.validator.addMethod( "maxsizetotal", function( value, element, param ) {
34453	if ( this.optional( element ) ) {
34454		return true;
34455	}
34456
34457	if ( $( element ).attr( "type" ) === "file" ) {
34458		if ( element.files && element.files.length ) {
34459			var totalSize = 0;
34460
34461			for ( var i = 0; i < element.files.length; i++ ) {
34462				totalSize += element.files[ i ].size;
34463				if ( totalSize > param ) {
34464					return false;
34465				}
34466			}
34467		}
34468	}
34469
34470	return true;
34471}, $.validator.format( "Total size of all files must not exceed {0} bytes." ) );
34472
34473
34474$.validator.addMethod( "mobileNL", function( value, element ) {
34475	return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
34476}, "Please specify a valid mobile number" );
34477
34478$.validator.addMethod( "mobileRU", function( phone_number, element ) {
34479	var ruPhone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
34480	return this.optional( element ) || ruPhone_number.length > 9 && /^((\+7|7|8)+([0-9]){10})$/.test( ruPhone_number );
34481}, "Please specify a valid mobile number" );
34482
34483/* For UK phone functions, do the following server side processing:
34484 * Compare original input with this RegEx pattern:
34485 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
34486 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
34487 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
34488 * A number of very detailed GB telephone number RegEx patterns can also be found at:
34489 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
34490 */
34491$.validator.addMethod( "mobileUK", function( phone_number, element ) {
34492	phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
34493	return this.optional( element ) || phone_number.length > 9 &&
34494		phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ );
34495}, "Please specify a valid mobile number" );
34496
34497$.validator.addMethod( "netmask", function( value, element ) {
34498    return this.optional( element ) || /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test( value );
34499}, "Please enter a valid netmask." );
34500
34501/*
34502 * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish
34503 * authorities to any foreigner.
34504 *
34505 * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal
34506 * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to
34507 * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter.
34508 */
34509$.validator.addMethod( "nieES", function( value, element ) {
34510	"use strict";
34511
34512	if ( this.optional( element ) ) {
34513		return true;
34514	}
34515
34516	var nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi );
34517	var validChars = "TRWAGMYFPDXBNJZSQVHLCKET",
34518		letter = value.substr( value.length - 1 ).toUpperCase(),
34519		number;
34520
34521	value = value.toString().toUpperCase();
34522
34523	// Quick format test
34524	if ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) {
34525		return false;
34526	}
34527
34528	// X means same number
34529	// Y means number + 10000000
34530	// Z means number + 20000000
34531	value = value.replace( /^[X]/, "0" )
34532		.replace( /^[Y]/, "1" )
34533		.replace( /^[Z]/, "2" );
34534
34535	number = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 );
34536
34537	return validChars.charAt( parseInt( number, 10 ) % 23 ) === letter;
34538
34539}, "Please specify a valid NIE number." );
34540
34541/*
34542 * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
34543 */
34544$.validator.addMethod( "nifES", function( value, element ) {
34545	"use strict";
34546
34547	if ( this.optional( element ) ) {
34548		return true;
34549	}
34550
34551	value = value.toUpperCase();
34552
34553	// Basic format test
34554	if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
34555		return false;
34556	}
34557
34558	// Test NIF
34559	if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
34560		return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
34561	}
34562
34563	// Test specials NIF (starts with K, L or M)
34564	if ( /^[KLM]{1}/.test( value ) ) {
34565		return ( value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 1 ) % 23 ) );
34566	}
34567
34568	return false;
34569
34570}, "Please specify a valid NIF number." );
34571
34572/*
34573 * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies
34574 */
34575$.validator.addMethod( "nipPL", function( value ) {
34576	"use strict";
34577
34578	value = value.replace( /[^0-9]/g, "" );
34579
34580	if ( value.length !== 10 ) {
34581		return false;
34582	}
34583
34584	var arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ];
34585	var intSum = 0;
34586	for ( var i = 0; i < 9; i++ ) {
34587		intSum += arrSteps[ i ] * value[ i ];
34588	}
34589	var int2 = intSum % 11;
34590	var intControlNr = ( int2 === 10 ) ? 0 : int2;
34591
34592	return ( intControlNr === parseInt( value[ 9 ], 10 ) );
34593}, "Please specify a valid NIP number." );
34594
34595/**
34596 * Created for project jquery-validation.
34597 * @Description Brazillian PIS or NIS number (Número de Identificação Social Pis ou Pasep) is the equivalent of a
34598 * Brazilian tax registration number NIS of PIS numbers have 11 digits in total: 10 numbers followed by 1 check numbers
34599 * that are being used for validation.
34600 * @copyright (c) 21/08/2018 13:14, Cleiton da Silva Mendonça
34601 * @author Cleiton da Silva Mendonça <[email protected]>
34602 * @link http://gitlab.com/csmendonca Gitlab of Cleiton da Silva Mendonça
34603 * @link http://github.com/csmendonca Github of Cleiton da Silva Mendonça
34604 */
34605$.validator.addMethod( "nisBR", function( value ) {
34606	var number;
34607	var cn;
34608	var sum = 0;
34609	var dv;
34610	var count;
34611	var multiplier;
34612
34613	// Removing special characters from value
34614	value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
34615
34616	// Checking value to have 11 digits only
34617	if ( value.length !== 11 ) {
34618		return false;
34619	}
34620
34621	//Get check number of value
34622	cn = parseInt( value.substring( 10, 11 ), 10 );
34623
34624	//Get number with 10 digits of the value
34625	number = parseInt( value.substring( 0, 10 ), 10 );
34626
34627	for ( count = 2; count < 12; count++ ) {
34628		multiplier = count;
34629		if ( count === 10 ) {
34630			multiplier = 2;
34631		}
34632		if ( count === 11 ) {
34633			multiplier = 3;
34634		}
34635		sum += ( ( number % 10 ) * multiplier );
34636		number = parseInt( number / 10, 10 );
34637	}
34638	dv = ( sum % 11 );
34639
34640	if ( dv > 1 ) {
34641		dv = ( 11 - dv );
34642	} else {
34643		dv = 0;
34644	}
34645
34646	if ( cn === dv ) {
34647		return true;
34648	} else {
34649		return false;
34650	}
34651}, "Please specify a valid NIS/PIS number" );
34652
34653$.validator.addMethod( "notEqualTo", function( value, element, param ) {
34654	return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param );
34655}, "Please enter a different value, values must not be the same." );
34656
34657$.validator.addMethod( "nowhitespace", function( value, element ) {
34658	return this.optional( element ) || /^\S+$/i.test( value );
34659}, "No white space please" );
34660
34661/**
34662* Return true if the field value matches the given format RegExp
34663*
34664* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
34665* @result true
34666*
34667* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
34668* @result false
34669*
34670* @name $.validator.methods.pattern
34671* @type Boolean
34672* @cat Plugins/Validate/Methods
34673*/
34674$.validator.addMethod( "pattern", function( value, element, param ) {
34675	if ( this.optional( element ) ) {
34676		return true;
34677	}
34678	if ( typeof param === "string" ) {
34679		param = new RegExp( "^(?:" + param + ")$" );
34680	}
34681	return param.test( value );
34682}, "Invalid format." );
34683
34684/**
34685 * Dutch phone numbers have 10 digits (or 11 and start with +31).
34686 */
34687$.validator.addMethod( "phoneNL", function( value, element ) {
34688	return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
34689}, "Please specify a valid phone number." );
34690
34691/**
34692 * Polish telephone numbers have 9 digits.
34693 *
34694 * Mobile phone numbers starts with following digits:
34695 * 45, 50, 51, 53, 57, 60, 66, 69, 72, 73, 78, 79, 88.
34696 *
34697 * Fixed-line numbers starts with area codes:
34698 * 12, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 29, 32, 33,
34699 * 34, 41, 42, 43, 44, 46, 48, 52, 54, 55, 56, 58, 59, 61,
34700 * 62, 63, 65, 67, 68, 71, 74, 75, 76, 77, 81, 82, 83, 84,
34701 * 85, 86, 87, 89, 91, 94, 95.
34702 *
34703 * Ministry of National Defence numbers and VoIP numbers starts with 26 and 39.
34704 *
34705 * Excludes intelligent networks (premium rate, shared cost, free phone numbers).
34706 *
34707 * Poland National Numbering Plan http://www.itu.int/oth/T02020000A8/en
34708 */
34709$.validator.addMethod( "phonePL", function( phone_number, element ) {
34710	phone_number = phone_number.replace( /\s+/g, "" );
34711	var regexp = /^(?:(?:(?:\+|00)?48)|(?:\(\+?48\)))?(?:1[2-8]|2[2-69]|3[2-49]|4[1-68]|5[0-9]|6[0-35-9]|[7-8][1-9]|9[145])\d{7}$/;
34712	return this.optional( element ) || regexp.test( phone_number );
34713}, "Please specify a valid phone number" );
34714
34715/* For UK phone functions, do the following server side processing:
34716 * Compare original input with this RegEx pattern:
34717 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
34718 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
34719 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
34720 * A number of very detailed GB telephone number RegEx patterns can also be found at:
34721 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
34722 */
34723
34724// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
34725$.validator.addMethod( "phonesUK", function( phone_number, element ) {
34726	phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
34727	return this.optional( element ) || phone_number.length > 9 &&
34728		phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ );
34729}, "Please specify a valid uk phone number" );
34730
34731/* For UK phone functions, do the following server side processing:
34732 * Compare original input with this RegEx pattern:
34733 * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
34734 * Extract $1 and set $prefix to '+44<space>' if $1 is '44', otherwise set $prefix to '0'
34735 * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
34736 * A number of very detailed GB telephone number RegEx patterns can also be found at:
34737 * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
34738 */
34739$.validator.addMethod( "phoneUK", function( phone_number, element ) {
34740	phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
34741	return this.optional( element ) || phone_number.length > 9 &&
34742		phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ );
34743}, "Please specify a valid phone number" );
34744
34745/**
34746 * Matches US phone number format
34747 *
34748 * where the area code may not start with 1 and the prefix may not start with 1
34749 * allows '-' or ' ' as a separator and allows parens around area code
34750 * some people may want to put a '1' in front of their number
34751 *
34752 * 1(212)-999-2345 or
34753 * 212 999 2344 or
34754 * 212-999-0983
34755 *
34756 * but not
34757 * 111-123-5434
34758 * and not
34759 * 212 123 4567
34760 */
34761$.validator.addMethod( "phoneUS", function( phone_number, element ) {
34762	phone_number = phone_number.replace( /\s+/g, "" );
34763	return this.optional( element ) || phone_number.length > 9 &&
34764		phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]\d{2}-?\d{4}$/ );
34765}, "Please specify a valid phone number" );
34766
34767/*
34768* Valida CEPs do brasileiros:
34769*
34770* Formatos aceitos:
34771* 99999-999
34772* 99.999-999
34773* 99999999
34774*/
34775$.validator.addMethod( "postalcodeBR", function( cep_value, element ) {
34776	return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
34777}, "Informe um CEP válido." );
34778
34779/**
34780 * Matches a valid Canadian Postal Code
34781 *
34782 * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
34783 * @result true
34784 *
34785 * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
34786 * @result false
34787 *
34788 * @name jQuery.validator.methods.postalCodeCA
34789 * @type Boolean
34790 * @cat Plugins/Validate/Methods
34791 */
34792$.validator.addMethod( "postalCodeCA", function( value, element ) {
34793	return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value );
34794}, "Please specify a valid postal code" );
34795
34796/* Matches Italian postcode (CAP) */
34797$.validator.addMethod( "postalcodeIT", function( value, element ) {
34798	return this.optional( element ) || /^\d{5}$/.test( value );
34799}, "Please specify a valid postal code" );
34800
34801$.validator.addMethod( "postalcodeNL", function( value, element ) {
34802	return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value );
34803}, "Please specify a valid postal code" );
34804
34805// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
34806$.validator.addMethod( "postcodeUK", function( value, element ) {
34807	return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value );
34808}, "Please specify a valid UK postcode
vendor: 5,517 bytes, lines 34808-34945
34808" );
34809
34810/*
34811 * Lets you say "at least X inputs that match selector Y must be filled."
34812 *
34813 * The end result is that neither of these inputs:
34814 *
34815 *	<input class="productinfo" name="partnumber">
34816 *	<input class="productinfo" name="description">
34817 *
34818 *	...will validate unless at least one of them is filled.
34819 *
34820 * partnumber:	{require_from_group: [1,".productinfo"]},
34821 * description: {require_from_group: [1,".productinfo"]}
34822 *
34823 * options[0]: number of fields that must be filled in the group
34824 * options[1]: CSS selector that defines the group of conditionally required fields
34825 */
34826$.validator.addMethod( "require_from_group", function( value, element, options ) {
34827	var $fields = $( options[ 1 ], element.form ),
34828		$fieldsFirst = $fields.eq( 0 ),
34829		validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ),
34830		isValid = $fields.filter( function() {
34831			return validator.elementValue( this );
34832		} ).length >= options[ 0 ];
34833
34834	// Store the cloned validator for future validation
34835	$fieldsFirst.data( "valid_req_grp", validator );
34836
34837	// If element isn't being validated, run each require_from_group field's validation rules
34838	if ( !$( element ).data( "being_validated" ) ) {
34839		$fields.data( "being_validated", true );
34840		$fields.each( function() {
34841			validator.element( this );
34842		} );
34843		$fields.data( "being_validated", false );
34844	}
34845	return isValid;
34846}, $.validator.format( "Please fill at least {0} of these fields." ) );
34847
34848/*
34849 * Lets you say "either at least X inputs that match selector Y must be filled,
34850 * OR they must all be skipped (left blank)."
34851 *
34852 * The end result, is that none of these inputs:
34853 *
34854 *	<input class="productinfo" name="partnumber">
34855 *	<input class="productinfo" name="description">
34856 *	<input class="productinfo" name="color">
34857 *
34858 *	...will validate unless either at least two of them are filled,
34859 *	OR none of them are.
34860 *
34861 * partnumber:	{skip_or_fill_minimum: [2,".productinfo"]},
34862 * description: {skip_or_fill_minimum: [2,".productinfo"]},
34863 * color:		{skip_or_fill_minimum: [2,".productinfo"]}
34864 *
34865 * options[0]: number of fields that must be filled in the group
34866 * options[1]: CSS selector that defines the group of conditionally required fields
34867 *
34868 */
34869$.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) {
34870	var $fields = $( options[ 1 ], element.form ),
34871		$fieldsFirst = $fields.eq( 0 ),
34872		validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ),
34873		numberFilled = $fields.filter( function() {
34874			return validator.elementValue( this );
34875		} ).length,
34876		isValid = numberFilled === 0 || numberFilled >= options[ 0 ];
34877
34878	// Store the cloned validator for future validation
34879	$fieldsFirst.data( "valid_skip", validator );
34880
34881	// If element isn't being validated, run each skip_or_fill_minimum field's validation rules
34882	if ( !$( element ).data( "being_validated" ) ) {
34883		$fields.data( "being_validated", true );
34884		$fields.each( function() {
34885			validator.element( this );
34886		} );
34887		$fields.data( "being_validated", false );
34888	}
34889	return isValid;
34890}, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) );
34891
34892/* Validates US States and/or Territories by @jdforsythe
34893 * Can be case insensitive or require capitalization - default is case insensitive
34894 * Can include US Territories or not - default does not
34895 * Can include US Military postal abbreviations (AA, AE, AP) - default does not
34896 *
34897 * Note: "States" always includes DC (District of Colombia)
34898 *
34899 * Usage examples:
34900 *
34901 *  This is the default - case insensitive, no territories, no military zones
34902 *  stateInput: {
34903 *     caseSensitive: false,
34904 *     includeTerritories: false,
34905 *     includeMilitary: false
34906 *  }
34907 *
34908 *  Only allow capital letters, no territories, no military zones
34909 *  stateInput: {
34910 *     caseSensitive: false
34911 *  }
34912 *
34913 *  Case insensitive, include territories but not military zones
34914 *  stateInput: {
34915 *     includeTerritories: true
34916 *  }
34917 *
34918 *  Only allow capital letters, include territories and military zones
34919 *  stateInput: {
34920 *     caseSensitive: true,
34921 *     includeTerritories: true,
34922 *     includeMilitary: true
34923 *  }
34924 *
34925 */
34926$.validator.addMethod( "stateUS", function( value, element, options ) {
34927	var isDefault = typeof options === "undefined",
34928		caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
34929		includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
34930		includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
34931		regex;
34932
34933	if ( !includeTerritories && !includeMilitary ) {
34934		regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
34935	} else if ( includeTerritories && includeMilitary ) {
34936		regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
34937	} else if ( includeTerritories ) {
34938		regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
34939	} else {
34940		regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
34941	}
34942
34943	regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" );
34944	return this.optional( element ) || regex.test( value );
34945}, "Please specify a valid state
vendor: 2,891 bytes, lines 34945-34986
34945" );
34946
34947// TODO check if value starts with <, otherwise don't try stripping anything
34948$.validator.addMethod( "strippedminlength", function( value, element, param ) {
34949	return $( value ).text().length >= param;
34950}, $.validator.format( "Please enter at least {0} characters" ) );
34951
34952$.validator.addMethod( "time", function( value, element ) {
34953	return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
34954}, "Please enter a valid time, between 00:00 and 23:59" );
34955
34956$.validator.addMethod( "time12h", function( value, element ) {
34957	return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value );
34958}, "Please enter a valid time in 12-hour am/pm format" );
34959
34960// Same as url, but TLD is optional
34961$.validator.addMethod( "url2", function( value, element ) {
34962	return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
34963}, $.validator.messages.url );
34964
34965/**
34966 * Return true, if the value is a valid vehicle identification number (VIN).
34967 *
34968 * Works with all kind of text inputs.
34969 *
34970 * @example <input type="text" size="20" name="VehicleID" class="{required:true,vinUS:true}" />
34971 * @desc Declares a required input element whose value must be a valid vehicle identification number.
34972 *
34973 * @name $.validator.methods.vinUS
34974 * @type Boolean
34975 * @cat Plugins/Validate/Methods
34976 */
34977$.validator.addMethod( "vinUS", function( v ) {
34978	if ( v.length !== 17 ) {
34979		return false;
34980	}
34981
34982	var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
34983		VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
34984		FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
34985		rs = 0,
34986		i, n, d, f, cd, cdv;
34987
34988	for ( i = 0; i < 17; i++ ) {
34989		f = FL[ i ];
34990		d = v.slice( i, i + 1 );
34991		if ( i === 8 ) {
34992			cdv = d;
34993		}
34994		if ( !isNaN( d ) ) {
34995			d *= f;
34996		} else {
34997			for ( n = 0; n < LL.length; n++ ) {
34998				if ( d.toUpperCase() === LL[ n ] ) {
34999					d = VL[ n ];
35000					d *= f;
35001					if ( isNaN( cdv ) && n === 8 ) {
35002						cdv = LL[ n ];
35003					}
35004					break;
35005				}
35006			}
35007		}
35008		rs += d;
35009	}
35010	cd = rs % 11;
35011	if ( cd === 10 ) {
35012		cd = "X";
35013	}
35014	if ( cd === cdv ) {
35015		return true;
35016	}
35017	return false;
35018}, "The specified vehicle identification number (VIN) is invalid." );
35019
35020$.validator.addMethod( "zipcodeUS", function( value, element ) {
35021	return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value );
35022}, "The specified US ZIP Code is invalid" );
35023
35024$.validator.addMethod( "ziprange", function( value, element ) {
35025	return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value );
35026}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" );
35027return $;
35028}));
35029/* ========================================================================
35030 * Bootstrap: transition.js v3.3.5
35031 * http://getbootstrap.com/javascript/#transitions
35032 * ========================================================================
35033 * Copyright 2011-2015 Twitter, Inc.
35034 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35035 * ======================================================================== */
35036
35037
35038
35039+function ($) {
35040  'use strict';
35041
35042  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
35043  // ============================================================
35044
35045  function transitionEnd() {
35046    var el = document.createElement('bootstrap')
35047
35048    var transEndEventNames = {
35049      WebkitTransition : 'webkitTransitionEnd',
35050      MozTransition    : 'transitionend',
35051      OTransition      : 'oTransitionEnd otransitionend',
35052      transition       : 'transitionend'
35053    }
35054
35055    for (var name in transEndEventNames) {
35056      if (el.style[name] !== undefined) {
35057        return { end: transEndEventNames[name] }
35058      }
35059    }
35060
35061    return false // explicit for ie8 (  ._.)
35062  }
35063
35064  // http://blog.alexmaccaw.com/css-transitions
35065  $.fn.emulateTransitionEnd = function (duration) {
35066    var called = false
35067    var $el = this
35068    $(this).one('bsTransitionEnd', function () { called = true })
35069    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
35070    setTimeout(callback, duration)
35071    return this
35072  }
35073
35074  $(function () {
35075    $.support.transition = transitionEnd()
35076
35077    if (!$.support.transition) return
35078
35079    $.event.special.bsTransitionEnd = {
35080      bindType: $.support.transition.end,
35081      delegateType: $.support.transition.end,
35082      handle: function (e) {
35083        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
35084      }
35085    }
35086  })
35087
35088}(jQuery);
35089/* ========================================================================
35090 * Bootstrap: alert.js v3.3.5
35091 * http://getbootstrap.com/javascript/#alerts
35092 * ========================================================================
35093 * Copyright 2011-2015 Twitter, Inc.
35094 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35095 * ======================================================================== */
35096
35097
35098
35099+function ($) {
35100  'use strict';
35101
35102  // ALERT CLASS DEFINITION
35103  // ======================
35104
35105  var dismiss = '[data-dismiss="alert"]'
35106  var Alert   = function (el) {
35107    $(el).on('click', dismiss, this.close)
35108  }
35109
35110  Alert.VERSION = '3.3.5'
35111
35112  Alert.TRANSITION_DURATION = 150
35113
35114  Alert.prototype.close = function (e) {
35115    var $this    = $(this)
35116    var selector = $this.attr('data-target')
35117
35118    if (!selector) {
35119      selector = $this.attr('href')
35120      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
35121    }
35122
35123    var $parent = $(selector)
35124
35125    if (e) e.preventDefault()
35126
35127    if (!$parent.length) {
35128      $parent = $this.closest('.alert')
35129    }
35130
35131    $parent.trigger(e = $.Event('close.bs.alert'))
35132
35133    if (e.isDefaultPrevented()) return
35134
35135    $parent.removeClass('in')
35136
35137    function removeElement() {
35138      // detach from parent, fire event then clean up data
35139      $parent.detach().trigger('closed.bs.alert').remove()
35140    }
35141
35142    $.support.transition && $parent.hasClass('fade') ?
35143      $parent
35144        .one('bsTransitionEnd', removeElement)
35145        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
35146      removeElement()
35147  }
35148
35149
35150  // ALERT PLUGIN DEFINITION
35151  // =======================
35152
35153  function Plugin(option) {
35154    return this.each(function () {
35155      var $this = $(this)
35156      var data  = $this.data('bs.alert')
35157
vendor: 4,196 bytes, lines 35158-35307
35158      if (!data) $this.data('bs.alert', (data = new Alert(this)))
35159      if (typeof option == 'string') data[option].call($this)
35160    })
35161  }
35162
35163  var old = $.fn.alert
35164
35165  $.fn.alert             = Plugin
35166  $.fn.alert.Constructor = Alert
35167
35168
35169  // ALERT NO CONFLICT
35170  // =================
35171
35172  $.fn.alert.noConflict = function () {
35173    $.fn.alert = old
35174    return this
35175  }
35176
35177
35178  // ALERT DATA-API
35179  // ==============
35180
35181  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
35182
35183}(jQuery);
35184/* ========================================================================
35185 * Bootstrap: button.js v3.3.5
35186 * http://getbootstrap.com/javascript/#buttons
35187 * ========================================================================
35188 * Copyright 2011-2015 Twitter, Inc.
35189 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35190 * ======================================================================== */
35191
35192
35193
35194+function ($) {
35195  'use strict';
35196
35197  // BUTTON PUBLIC CLASS DEFINITION
35198  // ==============================
35199
35200  var Button = function (element, options) {
35201    this.$element  = $(element)
35202    this.options   = $.extend({}, Button.DEFAULTS, options)
35203    this.isLoading = false
35204  }
35205
35206  Button.VERSION  = '3.3.5'
35207
35208  Button.DEFAULTS = {
35209    loadingText: 'loading...'
35210  }
35211
35212  Button.prototype.setState = function (state) {
35213    var d    = 'disabled'
35214    var $el  = this.$element
35215    var val  = $el.is('input') ? 'val' : 'html'
35216    var data = $el.data()
35217
35218    state += 'Text'
35219
35220    if (data.resetText == null) $el.data('resetText', $el[val]())
35221
35222    // push to event loop to allow forms to submit
35223    setTimeout($.proxy(function () {
35224      $el[val](data[state] == null ? this.options[state] : data[state])
35225
35226      if (state == 'loadingText') {
35227        this.isLoading = true
35228        $el.addClass(d).attr(d, d)
35229      } else if (this.isLoading) {
35230        this.isLoading = false
35231        $el.removeClass(d).removeAttr(d)
35232      }
35233    }, this), 0)
35234  }
35235
35236  Button.prototype.toggle = function () {
35237    var changed = true
35238    var $parent = this.$element.closest('[data-toggle="buttons"]')
35239
35240    if ($parent.length) {
35241      var $input = this.$element.find('input')
35242      if ($input.prop('type') == 'radio') {
35243        if ($input.prop('checked')) changed = false
35244        $parent.find('.active').removeClass('active')
35245        this.$element.addClass('active')
35246      } else if ($input.prop('type') == 'checkbox') {
35247        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
35248        this.$element.toggleClass('active')
35249      }
35250      $input.prop('checked', this.$element.hasClass('active'))
35251      if (changed) $input.trigger('change')
35252    } else {
35253      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
35254      this.$element.toggleClass('active')
35255    }
35256  }
35257
35258
35259  // BUTTON PLUGIN DEFINITION
35260  // ========================
35261
35262  function Plugin(option) {
35263    return this.each(function () {
35264      var $this   = $(this)
35265      var data    = $this.data('bs.button')
35266      var options = typeof option == 'object' && option
35267
35268      if (!data) $this.data('bs.button', (data = new Button(this, options)))
35269
35270      if (option == 'toggle') data.toggle()
35271      else if (option) data.setState(option)
35272    })
35273  }
35274
35275  var old = $.fn.button
35276
35277  $.fn.button             = Plugin
35278  $.fn.button.Constructor = Button
35279
35280
35281  // BUTTON NO CONFLICT
35282  // ==================
35283
35284  $.fn.button.noConflict = function () {
35285    $.fn.button = old
35286    return this
35287  }
35288
35289
35290  // BUTTON DATA-API
35291  // ===============
35292
35293  $(document)
35294    .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
35295      var $btn = $(e.target)
35296      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
35297      Plugin.call($btn, 'toggle')
35298      if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
35299    })
35300    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
35301      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
35302    })
35303
35304}(jQuery);
35305/* ========================================================================
35306 * Bootstrap: carousel.js v3.3.5
35307 * http://getbootstrap.com/javascript/#carousel
vendor: 4,376 bytes, lines 35308-35449
35308 * ========================================================================
35309 * Copyright 2011-2015 Twitter, Inc.
35310 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35311 * ======================================================================== */
35312
35313
35314
35315+function ($) {
35316  'use strict';
35317
35318  // CAROUSEL CLASS DEFINITION
35319  // =========================
35320
35321  var Carousel = function (element, options) {
35322    this.$element    = $(element)
35323    this.$indicators = this.$element.find('.carousel-indicators')
35324    this.options     = options
35325    this.paused      = null
35326    this.sliding     = null
35327    this.interval    = null
35328    this.$active     = null
35329    this.$items      = null
35330
35331    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
35332
35333    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
35334      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
35335      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
35336  }
35337
35338  Carousel.VERSION  = '3.3.5'
35339
35340  Carousel.TRANSITION_DURATION = 600
35341
35342  Carousel.DEFAULTS = {
35343    interval: 5000,
35344    pause: 'hover',
35345    wrap: true,
35346    keyboard: true
35347  }
35348
35349  Carousel.prototype.keydown = function (e) {
35350    if (/input|textarea/i.test(e.target.tagName)) return
35351    switch (e.which) {
35352      case 37: this.prev(); break
35353      case 39: this.next(); break
35354      default: return
35355    }
35356
35357    e.preventDefault()
35358  }
35359
35360  Carousel.prototype.cycle = function (e) {
35361    e || (this.paused = false)
35362
35363    this.interval && clearInterval(this.interval)
35364
35365    this.options.interval
35366      && !this.paused
35367      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
35368
35369    return this
35370  }
35371
35372  Carousel.prototype.getItemIndex = function (item) {
35373    this.$items = item.parent().children('.item')
35374    return this.$items.index(item || this.$active)
35375  }
35376
35377  Carousel.prototype.getItemForDirection = function (direction, active) {
35378    var activeIndex = this.getItemIndex(active)
35379    var willWrap = (direction == 'prev' && activeIndex === 0)
35380                || (direction == 'next' && activeIndex == (this.$items.length - 1))
35381    if (willWrap && !this.options.wrap) return active
35382    var delta = direction == 'prev' ? -1 : 1
35383    var itemIndex = (activeIndex + delta) % this.$items.length
35384    return this.$items.eq(itemIndex)
35385  }
35386
35387  Carousel.prototype.to = function (pos) {
35388    var that        = this
35389    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
35390
35391    if (pos > (this.$items.length - 1) || pos < 0) return
35392
35393    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
35394    if (activeIndex == pos) return this.pause().cycle()
35395
35396    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
35397  }
35398
35399  Carousel.prototype.pause = function (e) {
35400    e || (this.paused = true)
35401
35402    if (this.$element.find('.next, .prev').length && $.support.transition) {
35403      this.$element.trigger($.support.transition.end)
35404      this.cycle(true)
35405    }
35406
35407    this.interval = clearInterval(this.interval)
35408
35409    return this
35410  }
35411
35412  Carousel.prototype.next = function () {
35413    if (this.sliding) return
35414    return this.slide('next')
35415  }
35416
35417  Carousel.prototype.prev = function () {
35418    if (this.sliding) return
35419    return this.slide('prev')
35420  }
35421
35422  Carousel.prototype.slide = function (type, next) {
35423    var $active   = this.$element.find('.item.active')
35424    var $next     = next || this.getItemForDirection(type, $active)
35425    var isCycling = this.interval
35426    var direction = type == 'next' ? 'left' : 'right'
35427    var that      = this
35428
35429    if ($next.hasClass('active')) return (this.sliding = false)
35430
35431    var relatedTarget = $next[0]
35432    var slideEvent = $.Event('slide.bs.carousel', {
35433      relatedTarget: relatedTarget,
35434      direction: direction
35435    })
35436    this.$element.trigger(slideEvent)
35437    if (slideEvent.isDefaultPrevented()) return
35438
35439    this.sliding = true
35440
35441    isCycling && this.pause()
35442
35443    if (this.$indicators.length) {
35444      this.$indicators.find('.active').removeClass('active')
35445      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
35446      $nextIndicator && $nextIndicator.addClass('active')
35447    }
35448
35449    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
vendor: 23,719 bytes, lines 35450-36266
35450    if ($.support.transition && this.$element.hasClass('slide')) {
35451      $next.addClass(type)
35452      $next[0].offsetWidth // force reflow
35453      $active.addClass(direction)
35454      $next.addClass(direction)
35455      $active
35456        .one('bsTransitionEnd', function () {
35457          $next.removeClass([type, direction].join(' ')).addClass('active')
35458          $active.removeClass(['active', direction].join(' '))
35459          that.sliding = false
35460          setTimeout(function () {
35461            that.$element.trigger(slidEvent)
35462          }, 0)
35463        })
35464        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
35465    } else {
35466      $active.removeClass('active')
35467      $next.addClass('active')
35468      this.sliding = false
35469      this.$element.trigger(slidEvent)
35470    }
35471
35472    isCycling && this.cycle()
35473
35474    return this
35475  }
35476
35477
35478  // CAROUSEL PLUGIN DEFINITION
35479  // ==========================
35480
35481  function Plugin(option) {
35482    return this.each(function () {
35483      var $this   = $(this)
35484      var data    = $this.data('bs.carousel')
35485      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
35486      var action  = typeof option == 'string' ? option : options.slide
35487
35488      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
35489      if (typeof option == 'number') data.to(option)
35490      else if (action) data[action]()
35491      else if (options.interval) data.pause().cycle()
35492    })
35493  }
35494
35495  var old = $.fn.carousel
35496
35497  $.fn.carousel             = Plugin
35498  $.fn.carousel.Constructor = Carousel
35499
35500
35501  // CAROUSEL NO CONFLICT
35502  // ====================
35503
35504  $.fn.carousel.noConflict = function () {
35505    $.fn.carousel = old
35506    return this
35507  }
35508
35509
35510  // CAROUSEL DATA-API
35511  // =================
35512
35513  var clickHandler = function (e) {
35514    var href
35515    var $this   = $(this)
35516    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
35517    if (!$target.hasClass('carousel')) return
35518    var options = $.extend({}, $target.data(), $this.data())
35519    var slideIndex = $this.attr('data-slide-to')
35520    if (slideIndex) options.interval = false
35521
35522    Plugin.call($target, options)
35523
35524    if (slideIndex) {
35525      $target.data('bs.carousel').to(slideIndex)
35526    }
35527
35528    e.preventDefault()
35529  }
35530
35531  $(document)
35532    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
35533    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
35534
35535  $(window).on('load', function () {
35536    $('[data-ride="carousel"]').each(function () {
35537      var $carousel = $(this)
35538      Plugin.call($carousel, $carousel.data())
35539    })
35540  })
35541
35542}(jQuery);
35543/* ========================================================================
35544 * Bootstrap: collapse.js v3.3.5
35545 * http://getbootstrap.com/javascript/#collapse
35546 * ========================================================================
35547 * Copyright 2011-2015 Twitter, Inc.
35548 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35549 * ======================================================================== */
35550
35551
35552
35553+function ($) {
35554  'use strict';
35555
35556  // COLLAPSE PUBLIC CLASS DEFINITION
35557  // ================================
35558
35559  var Collapse = function (element, options) {
35560    this.$element      = $(element)
35561    this.options       = $.extend({}, Collapse.DEFAULTS, options)
35562    this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
35563                           '[data-toggle="collapse"][data-target="#' + element.id + '"]')
35564    this.transitioning = null
35565
35566    if (this.options.parent) {
35567      this.$parent = this.getParent()
35568    } else {
35569      this.addAriaAndCollapsedClass(this.$element, this.$trigger)
35570    }
35571
35572    if (this.options.toggle) this.toggle()
35573  }
35574
35575  Collapse.VERSION  = '3.3.5'
35576
35577  Collapse.TRANSITION_DURATION = 350
35578
35579  Collapse.DEFAULTS = {
35580    toggle: true
35581  }
35582
35583  Collapse.prototype.dimension = function () {
35584    var hasWidth = this.$element.hasClass('width')
35585    return hasWidth ? 'width' : 'height'
35586  }
35587
35588  Collapse.prototype.show = function () {
35589    if (this.transitioning || this.$element.hasClass('in')) return
35590
35591    var activesData
35592    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
35593
35594    if (actives && actives.length) {
35595      activesData = actives.data('bs.collapse')
35596      if (activesData && activesData.transitioning) return
35597    }
35598
35599    var startEvent = $.Event('show.bs.collapse')
35600    this.$element.trigger(startEvent)
35601    if (startEvent.isDefaultPrevented()) return
35602
35603    if (actives && actives.length) {
35604      Plugin.call(actives, 'hide')
35605      activesData || actives.data('bs.collapse', null)
35606    }
35607
35608    var dimension = this.dimension()
35609
35610    this.$element
35611      .removeClass('collapse')
35612      .addClass('collapsing')[dimension](0)
35613      .attr('aria-expanded', true)
35614
35615    this.$trigger
35616      .removeClass('collapsed')
35617      .attr('aria-expanded', true)
35618
35619    this.transitioning = 1
35620
35621    var complete = function () {
35622      this.$element
35623        .removeClass('collapsing')
35624        .addClass('collapse in')[dimension]('')
35625      this.transitioning = 0
35626      this.$element
35627        .trigger('shown.bs.collapse')
35628    }
35629
35630    if (!$.support.transition) return complete.call(this)
35631
35632    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
35633
35634    this.$element
35635      .one('bsTransitionEnd', $.proxy(complete, this))
35636      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
35637  }
35638
35639  Collapse.prototype.hide = function () {
35640    if (this.transitioning || !this.$element.hasClass('in')) return
35641
35642    var startEvent = $.Event('hide.bs.collapse')
35643    this.$element.trigger(startEvent)
35644    if (startEvent.isDefaultPrevented()) return
35645
35646    var dimension = this.dimension()
35647
35648    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
35649
35650    this.$element
35651      .addClass('collapsing')
35652      .removeClass('collapse in')
35653      .attr('aria-expanded', false)
35654
35655    this.$trigger
35656      .addClass('collapsed')
35657      .attr('aria-expanded', false)
35658
35659    this.transitioning = 1
35660
35661    var complete = function () {
35662      this.transitioning = 0
35663      this.$element
35664        .removeClass('collapsing')
35665        .addClass('collapse')
35666        .trigger('hidden.bs.collapse')
35667    }
35668
35669    if (!$.support.transition) return complete.call(this)
35670
35671    this.$element
35672      [dimension](0)
35673      .one('bsTransitionEnd', $.proxy(complete, this))
35674      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
35675  }
35676
35677  Collapse.prototype.toggle = function () {
35678    this[this.$element.hasClass('in') ? 'hide' : 'show']()
35679  }
35680
35681  Collapse.prototype.getParent = function () {
35682    return $(this.options.parent)
35683      .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
35684      .each($.proxy(function (i, element) {
35685        var $element = $(element)
35686        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
35687      }, this))
35688      .end()
35689  }
35690
35691  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
35692    var isOpen = $element.hasClass('in')
35693
35694    $element.attr('aria-expanded', isOpen)
35695    $trigger
35696      .toggleClass('collapsed', !isOpen)
35697      .attr('aria-expanded', isOpen)
35698  }
35699
35700  function getTargetFromTrigger($trigger) {
35701    var href
35702    var target = $trigger.attr('data-target')
35703      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
35704
35705    return $(target)
35706  }
35707
35708
35709  // COLLAPSE PLUGIN DEFINITION
35710  // ==========================
35711
35712  function Plugin(option) {
35713    return this.each(function () {
35714      var $this   = $(this)
35715      var data    = $this.data('bs.collapse')
35716      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
35717
35718      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
35719      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
35720      if (typeof option == 'string') data[option]()
35721    })
35722  }
35723
35724  var old = $.fn.collapse
35725
35726  $.fn.collapse             = Plugin
35727  $.fn.collapse.Constructor = Collapse
35728
35729
35730  // COLLAPSE NO CONFLICT
35731  // ====================
35732
35733  $.fn.collapse.noConflict = function () {
35734    $.fn.collapse = old
35735    return this
35736  }
35737
35738
35739  // COLLAPSE DATA-API
35740  // =================
35741
35742  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
35743    var $this   = $(this)
35744
35745    if (!$this.attr('data-target')) e.preventDefault()
35746
35747    var $target = getTargetFromTrigger($this)
35748    var data    = $target.data('bs.collapse')
35749    var option  = data ? 'toggle' : $this.data()
35750
35751    Plugin.call($target, option)
35752  })
35753
35754}(jQuery);
35755/* ========================================================================
35756 * Bootstrap: dropdown.js v3.3.5
35757 * http://getbootstrap.com/javascript/#dropdowns
35758 * ========================================================================
35759 * Copyright 2011-2015 Twitter, Inc.
35760 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35761 * ======================================================================== */
35762
35763
35764
35765+function ($) {
35766  'use strict';
35767
35768  // DROPDOWN CLASS DEFINITION
35769  // =========================
35770
35771  var backdrop = '.dropdown-backdrop'
35772  var toggle   = '[data-toggle="dropdown"]'
35773  var Dropdown = function (element) {
35774    $(element).on('click.bs.dropdown', this.toggle)
35775  }
35776
35777  Dropdown.VERSION = '3.3.5'
35778
35779  function getParent($this) {
35780    var selector = $this.attr('data-target')
35781
35782    if (!selector) {
35783      selector = $this.attr('href')
35784      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
35785    }
35786
35787    var $parent = selector && $(selector)
35788
35789    return $parent && $parent.length ? $parent : $this.parent()
35790  }
35791
35792  function clearMenus(e) {
35793    if (e && e.which === 3) return
35794    $(backdrop).remove()
35795    $(toggle).each(function () {
35796      var $this         = $(this)
35797      var $parent       = getParent($this)
35798      var relatedTarget = { relatedTarget: this }
35799
35800      if (!$parent.hasClass('open')) return
35801
35802      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
35803
35804      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
35805
35806      if (e.isDefaultPrevented()) return
35807
35808      $this.attr('aria-expanded', 'false')
35809      $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
35810    })
35811  }
35812
35813  Dropdown.prototype.toggle = function (e) {
35814    var $this = $(this)
35815
35816    if ($this.is('.disabled, :disabled')) return
35817
35818    var $parent  = getParent($this)
35819    var isActive = $parent.hasClass('open')
35820
35821    clearMenus()
35822
35823    if (!isActive) {
35824      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
35825        // if mobile we use a backdrop because click events don't delegate
35826        $(document.createElement('div'))
35827          .addClass('dropdown-backdrop')
35828          .insertAfter($(this))
35829          .on('click', clearMenus)
35830      }
35831
35832      var relatedTarget = { relatedTarget: this }
35833      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
35834
35835      if (e.isDefaultPrevented()) return
35836
35837      $this
35838        .trigger('focus')
35839        .attr('aria-expanded', 'true')
35840
35841      $parent
35842        .toggleClass('open')
35843        .trigger('shown.bs.dropdown', relatedTarget)
35844    }
35845
35846    return false
35847  }
35848
35849  Dropdown.prototype.keydown = function (e) {
35850    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
35851
35852    var $this = $(this)
35853
35854    e.preventDefault()
35855    e.stopPropagation()
35856
35857    if ($this.is('.disabled, :disabled')) return
35858
35859    var $parent  = getParent($this)
35860    var isActive = $parent.hasClass('open')
35861
35862    if (!isActive && e.which != 27 || isActive && e.which == 27) {
35863      if (e.which == 27) $parent.find(toggle).trigger('focus')
35864      return $this.trigger('click')
35865    }
35866
35867    var desc = ' li:not(.disabled):visible a'
35868    var $items = $parent.find('.dropdown-menu' + desc)
35869
35870    if (!$items.length) return
35871
35872    var index = $items.index(e.target)
35873
35874    if (e.which == 38 && index > 0)                 index--         // up
35875    if (e.which == 40 && index < $items.length - 1) index++         // down
35876    if (!~index)                                    index = 0
35877
35878    $items.eq(index).trigger('focus')
35879  }
35880
35881
35882  // DROPDOWN PLUGIN DEFINITION
35883  // ==========================
35884
35885  function Plugin(option) {
35886    return this.each(function () {
35887      var $this = $(this)
35888      var data  = $this.data('bs.dropdown')
35889
35890      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
35891      if (typeof option == 'string') data[option].call($this)
35892    })
35893  }
35894
35895  var old = $.fn.dropdown
35896
35897  $.fn.dropdown             = Plugin
35898  $.fn.dropdown.Constructor = Dropdown
35899
35900
35901  // DROPDOWN NO CONFLICT
35902  // ====================
35903
35904  $.fn.dropdown.noConflict = function () {
35905    $.fn.dropdown = old
35906    return this
35907  }
35908
35909
35910  // APPLY TO STANDARD DROPDOWN ELEMENTS
35911  // ===================================
35912
35913  $(document)
35914    .on('click.bs.dropdown.data-api', clearMenus)
35915    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
35916    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
35917    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
35918    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
35919
35920}(jQuery);
35921/* ========================================================================
35922 * Bootstrap: modal.js v3.3.5
35923 * http://getbootstrap.com/javascript/#modals
35924 * ========================================================================
35925 * Copyright 2011-2015 Twitter, Inc.
35926 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
35927 * ======================================================================== */
35928
35929
35930
35931+function ($) {
35932  'use strict';
35933
35934  // MODAL CLASS DEFINITION
35935  // ======================
35936
35937  var Modal = function (element, options) {
35938    this.options             = options
35939    this.$body               = $(document.body)
35940    this.$element            = $(element)
35941    this.$dialog             = this.$element.find('.modal-dialog')
35942    this.$backdrop           = null
35943    this.isShown             = null
35944    this.originalBodyPad     = null
35945    this.scrollbarWidth      = 0
35946    this.ignoreBackdropClick = false
35947
35948    if (this.options.remote) {
35949      this.$element
35950        .find('.modal-content')
35951        .load(this.options.remote, $.proxy(function () {
35952          this.$element.trigger('loaded.bs.modal')
35953        }, this))
35954    }
35955  }
35956
35957  Modal.VERSION  = '3.3.5'
35958
35959  Modal.TRANSITION_DURATION = 300
35960  Modal.BACKDROP_TRANSITION_DURATION = 150
35961
35962  Modal.DEFAULTS = {
35963    backdrop: true,
35964    keyboard: true,
35965    show: true
35966  }
35967
35968  Modal.prototype.toggle = function (_relatedTarget) {
35969    return this.isShown ? this.hide() : this.show(_relatedTarget)
35970  }
35971
35972  Modal.prototype.show = function (_relatedTarget) {
35973    var that = this
35974    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
35975
35976    this.$element.trigger(e)
35977
35978    if (this.isShown || e.isDefaultPrevented()) return
35979
35980    this.isShown = true
35981
35982    this.checkScrollbar()
35983    this.setScrollbar()
35984    this.$body.addClass('modal-open')
35985
35986    this.escape()
35987    this.resize()
35988
35989    this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
35990
35991    this.$dialog.on('mousedown.dismiss.bs.modal', function () {
35992      that.$element.one('mouseup.dismiss.bs.modal', function (e) {
35993        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
35994      })
35995    })
35996
35997    this.backdrop(function () {
35998      var transition = $.support.transition && that.$element.hasClass('fade')
35999
36000      if (!that.$element.parent().length) {
36001        that.$element.appendTo(that.$body) // don't move modals dom position
36002      }
36003
36004      that.$element
36005        .show()
36006        .scrollTop(0)
36007
36008      that.adjustDialog()
36009
36010      if (transition) {
36011        that.$element[0].offsetWidth // force reflow
36012      }
36013
36014      that.$element.addClass('in')
36015
36016      that.enforceFocus()
36017
36018      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
36019
36020      transition ?
36021        that.$dialog // wait for modal to slide in
36022          .one('bsTransitionEnd', function () {
36023            that.$element.trigger('focus').trigger(e)
36024          })
36025          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
36026        that.$element.trigger('focus').trigger(e)
36027    })
36028  }
36029
36030  Modal.prototype.hide = function (e) {
36031    if (e) e.preventDefault()
36032
36033    e = $.Event('hide.bs.modal')
36034
36035    this.$element.trigger(e)
36036
36037    if (!this.isShown || e.isDefaultPrevented()) return
36038
36039    this.isShown = false
36040
36041    this.escape()
36042    this.resize()
36043
36044    $(document).off('focusin.bs.modal')
36045
36046    this.$element
36047      .removeClass('in')
36048      .off('click.dismiss.bs.modal')
36049      .off('mouseup.dismiss.bs.modal')
36050
36051    this.$dialog.off('mousedown.dismiss.bs.modal')
36052
36053    $.support.transition && this.$element.hasClass('fade') ?
36054      this.$element
36055        .one('bsTransitionEnd', $.proxy(this.hideModal, this))
36056        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
36057      this.hideModal()
36058  }
36059
36060  Modal.prototype.enforceFocus = function () {
36061    $(document)
36062      .off('focusin.bs.modal') // guard against infinite focus loop
36063      .on('focusin.bs.modal', $.proxy(function (e) {
36064        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
36065          this.$element.trigger('focus')
36066        }
36067      }, this))
36068  }
36069
36070  Modal.prototype.escape = function () {
36071    if (this.isShown && this.options.keyboard) {
36072      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
36073        e.which == 27 && this.hide()
36074      }, this))
36075    } else if (!this.isShown) {
36076      this.$element.off('keydown.dismiss.bs.modal')
36077    }
36078  }
36079
36080  Modal.prototype.resize = function () {
36081    if (this.isShown) {
36082      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
36083    } else {
36084      $(window).off('resize.bs.modal')
36085    }
36086  }
36087
36088  Modal.prototype.hideModal = function () {
36089    var that = this
36090    this.$element.hide()
36091    this.backdrop(function () {
36092      that.$body.removeClass('modal-open')
36093      that.resetAdjustments()
36094      that.resetScrollbar()
36095      that.$element.trigger('hidden.bs.modal')
36096    })
36097  }
36098
36099  Modal.prototype.removeBackdrop = function () {
36100    this.$backdrop && this.$backdrop.remove()
36101    this.$backdrop = null
36102  }
36103
36104  Modal.prototype.backdrop = function (callback) {
36105    var that = this
36106    var animate = this.$element.hasClass('fade') ? 'fade' : ''
36107
36108    if (this.isShown && this.options.backdrop) {
36109      var doAnimate = $.support.transition && animate
36110
36111      this.$backdrop = $(document.createElement('div'))
36112        .addClass('modal-backdrop ' + animate)
36113        .appendTo(this.$body)
36114
36115      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
36116        if (this.ignoreBackdropClick) {
36117          this.ignoreBackdropClick = false
36118          return
36119        }
36120        if (e.target !== e.currentTarget) return
36121        this.options.backdrop == 'static'
36122          ? this.$element[0].focus()
36123          : this.hide()
36124      }, this))
36125
36126      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
36127
36128      this.$backdrop.addClass('in')
36129
36130      if (!callback) return
36131
36132      doAnimate ?
36133        this.$backdrop
36134          .one('bsTransitionEnd', callback)
36135          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
36136        callback()
36137
36138    } else if (!this.isShown && this.$backdrop) {
36139      this.$backdrop.removeClass('in')
36140
36141      var callbackRemove = function () {
36142        that.removeBackdrop()
36143        callback && callback()
36144      }
36145      $.support.transition && this.$element.hasClass('fade') ?
36146        this.$backdrop
36147          .one('bsTransitionEnd', callbackRemove)
36148          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
36149        callbackRemove()
36150
36151    } else if (callback) {
36152      callback()
36153    }
36154  }
36155
36156  // these following methods are used to handle overflowing modals
36157
36158  Modal.prototype.handleUpdate = function () {
36159    this.adjustDialog()
36160  }
36161
36162  Modal.prototype.adjustDialog = function () {
36163    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
36164
36165    this.$element.css({
36166      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
36167      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
36168    })
36169  }
36170
36171  Modal.prototype.resetAdjustments = function () {
36172    this.$element.css({
36173      paddingLeft: '',
36174      paddingRight: ''
36175    })
36176  }
36177
36178  Modal.prototype.checkScrollbar = function () {
36179    var fullWindowWidth = window.innerWidth
36180    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
36181      var documentElementRect = document.documentElement.getBoundingClientRect()
36182      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
36183    }
36184    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
36185    this.scrollbarWidth = this.measureScrollbar()
36186  }
36187
36188  Modal.prototype.setScrollbar = function () {
36189    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
36190    this.originalBodyPad = document.body.style.paddingRight || ''
36191    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
36192  }
36193
36194  Modal.prototype.resetScrollbar = function () {
36195    this.$body.css('padding-right', this.originalBodyPad)
36196  }
36197
36198  Modal.prototype.measureScrollbar = function () { // thx walsh
36199    var scrollDiv = document.createElement('div')
36200    scrollDiv.className = 'modal-scrollbar-measure'
36201    this.$body.append(scrollDiv)
36202    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
36203    this.$body[0].removeChild(scrollDiv)
36204    return scrollbarWidth
36205  }
36206
36207
36208  // MODAL PLUGIN DEFINITION
36209  // =======================
36210
36211  function Plugin(option, _relatedTarget) {
36212    return this.each(function () {
36213      var $this   = $(this)
36214      var data    = $this.data('bs.modal')
36215      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
36216
36217      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
36218      if (typeof option == 'string') data[option](_relatedTarget)
36219      else if (options.show) data.show(_relatedTarget)
36220    })
36221  }
36222
36223  var old = $.fn.modal
36224
36225  $.fn.modal             = Plugin
36226  $.fn.modal.Constructor = Modal
36227
36228
36229  // MODAL NO CONFLICT
36230  // =================
36231
36232  $.fn.modal.noConflict = function () {
36233    $.fn.modal = old
36234    return this
36235  }
36236
36237
36238  // MODAL DATA-API
36239  // ==============
36240
36241  $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
36242    var $this   = $(this)
36243    var href    = $this.attr('href')
36244    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
36245    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
36246
36247    if ($this.is('a')) e.preventDefault()
36248
36249    $target.one('show.bs.modal', function (showEvent) {
36250      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
36251      $target.one('hidden.bs.modal', function () {
36252        $this.is(':visible') && $this.trigger('focus')
36253      })
36254    })
36255    Plugin.call($target, option, this)
36256  })
36257
36258}(jQuery);
36259/* ========================================================================
36260 * Bootstrap: tooltip.js v3.3.5
36261 * http://getbootstrap.com/javascript/#tooltip
36262 * Inspired by the original jQuery.tipsy by Jason Frame
36263 * ========================================================================
36264 * Copyright 2011-2015 Twitter, Inc.
36265 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
36266 * ======================================================================== */
vendor: 15,865 bytes, lines 36267-36773
36267
36268
36269
36270+function ($) {
36271  'use strict';
36272
36273  // TOOLTIP PUBLIC CLASS DEFINITION
36274  // ===============================
36275
36276  var Tooltip = function (element, options) {
36277    this.type       = null
36278    this.options    = null
36279    this.enabled    = null
36280    this.timeout    = null
36281    this.hoverState = null
36282    this.$element   = null
36283    this.inState    = null
36284
36285    this.init('tooltip', element, options)
36286  }
36287
36288  Tooltip.VERSION  = '3.3.5'
36289
36290  Tooltip.TRANSITION_DURATION = 150
36291
36292  Tooltip.DEFAULTS = {
36293    animation: true,
36294    placement: 'top',
36295    selector: false,
36296    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
36297    trigger: 'hover focus',
36298    title: '',
36299    delay: 0,
36300    html: false,
36301    container: false,
36302    viewport: {
36303      selector: 'body',
36304      padding: 0
36305    }
36306  }
36307
36308  Tooltip.prototype.init = function (type, element, options) {
36309    this.enabled   = true
36310    this.type      = type
36311    this.$element  = $(element)
36312    this.options   = this.getOptions(options)
36313    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
36314    this.inState   = { click: false, hover: false, focus: false }
36315
36316    if (this.$element[0] instanceof document.constructor && !this.options.selector) {
36317      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
36318    }
36319
36320    var triggers = this.options.trigger.split(' ')
36321
36322    for (var i = triggers.length; i--;) {
36323      var trigger = triggers[i]
36324
36325      if (trigger == 'click') {
36326        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
36327      } else if (trigger != 'manual') {
36328        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
36329        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
36330
36331        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
36332        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
36333      }
36334    }
36335
36336    this.options.selector ?
36337      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
36338      this.fixTitle()
36339  }
36340
36341  Tooltip.prototype.getDefaults = function () {
36342    return Tooltip.DEFAULTS
36343  }
36344
36345  Tooltip.prototype.getOptions = function (options) {
36346    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
36347
36348    if (options.delay && typeof options.delay == 'number') {
36349      options.delay = {
36350        show: options.delay,
36351        hide: options.delay
36352      }
36353    }
36354
36355    return options
36356  }
36357
36358  Tooltip.prototype.getDelegateOptions = function () {
36359    var options  = {}
36360    var defaults = this.getDefaults()
36361
36362    this._options && $.each(this._options, function (key, value) {
36363      if (defaults[key] != value) options[key] = value
36364    })
36365
36366    return options
36367  }
36368
36369  Tooltip.prototype.enter = function (obj) {
36370    var self = obj instanceof this.constructor ?
36371      obj : $(obj.currentTarget).data('bs.' + this.type)
36372
36373    if (!self) {
36374      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
36375      $(obj.currentTarget).data('bs.' + this.type, self)
36376    }
36377
36378    if (obj instanceof $.Event) {
36379      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
36380    }
36381
36382    if (self.tip().hasClass('in') || self.hoverState == 'in') {
36383      self.hoverState = 'in'
36384      return
36385    }
36386
36387    clearTimeout(self.timeout)
36388
36389    self.hoverState = 'in'
36390
36391    if (!self.options.delay || !self.options.delay.show) return self.show()
36392
36393    self.timeout = setTimeout(function () {
36394      if (self.hoverState == 'in') self.show()
36395    }, self.options.delay.show)
36396  }
36397
36398  Tooltip.prototype.isInStateTrue = function () {
36399    for (var key in this.inState) {
36400      if (this.inState[key]) return true
36401    }
36402
36403    return false
36404  }
36405
36406  Tooltip.prototype.leave = function (obj) {
36407    var self = obj instanceof this.constructor ?
36408      obj : $(obj.currentTarget).data('bs.' + this.type)
36409
36410    if (!self) {
36411      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
36412      $(obj.currentTarget).data('bs.' + this.type, self)
36413    }
36414
36415    if (obj instanceof $.Event) {
36416      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
36417    }
36418
36419    if (self.isInStateTrue()) return
36420
36421    clearTimeout(self.timeout)
36422
36423    self.hoverState = 'out'
36424
36425    if (!self.options.delay || !self.options.delay.hide) return self.hide()
36426
36427    self.timeout = setTimeout(function () {
36428      if (self.hoverState == 'out') self.hide()
36429    }, self.options.delay.hide)
36430  }
36431
36432  Tooltip.prototype.show = function () {
36433    var e = $.Event('show.bs.' + this.type)
36434
36435    if (this.hasContent() && this.enabled) {
36436      this.$element.trigger(e)
36437
36438      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
36439      if (e.isDefaultPrevented() || !inDom) return
36440      var that = this
36441
36442      var $tip = this.tip()
36443
36444      var tipId = this.getUID(this.type)
36445
36446      this.setContent()
36447      $tip.attr('id', tipId)
36448      this.$element.attr('aria-describedby', tipId)
36449
36450      if (this.options.animation) $tip.addClass('fade')
36451
36452      var placement = typeof this.options.placement == 'function' ?
36453        this.options.placement.call(this, $tip[0], this.$element[0]) :
36454        this.options.placement
36455
36456      var autoToken = /\s?auto?\s?/i
36457      var autoPlace = autoToken.test(placement)
36458      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
36459
36460      $tip
36461        .detach()
36462        .css({ top: 0, left: 0, display: 'block' })
36463        .addClass(placement)
36464        .data('bs.' + this.type, this)
36465
36466      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
36467      this.$element.trigger('inserted.bs.' + this.type)
36468
36469      var pos          = this.getPosition()
36470      var actualWidth  = $tip[0].offsetWidth
36471      var actualHeight = $tip[0].offsetHeight
36472
36473      if (autoPlace) {
36474        var orgPlacement = placement
36475        var viewportDim = this.getPosition(this.$viewport)
36476
36477        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
36478                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
36479                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
36480                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
36481                    placement
36482
36483        $tip
36484          .removeClass(orgPlacement)
36485          .addClass(placement)
36486      }
36487
36488      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
36489
36490      this.applyPlacement(calculatedOffset, placement)
36491
36492      var complete = function () {
36493        var prevHoverState = that.hoverState
36494        that.$element.trigger('shown.bs.' + that.type)
36495        that.hoverState = null
36496
36497        if (prevHoverState == 'out') that.leave(that)
36498      }
36499
36500      $.support.transition && this.$tip.hasClass('fade') ?
36501        $tip
36502          .one('bsTransitionEnd', complete)
36503          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
36504        complete()
36505    }
36506  }
36507
36508  Tooltip.prototype.applyPlacement = function (offset, placement) {
36509    var $tip   = this.tip()
36510    var width  = $tip[0].offsetWidth
36511    var height = $tip[0].offsetHeight
36512
36513    // manually read margins because getBoundingClientRect includes difference
36514    var marginTop = parseInt($tip.css('margin-top'), 10)
36515    var marginLeft = parseInt($tip.css('margin-left'), 10)
36516
36517    // we must check for NaN for ie 8/9
36518    if (isNaN(marginTop))  marginTop  = 0
36519    if (isNaN(marginLeft)) marginLeft = 0
36520
36521    offset.top  += marginTop
36522    offset.left += marginLeft
36523
36524    // $.fn.offset doesn't round pixel values
36525    // so we use setOffset directly with our own function B-0
36526    $.offset.setOffset($tip[0], $.extend({
36527      using: function (props) {
36528        $tip.css({
36529          top: Math.round(props.top),
36530          left: Math.round(props.left)
36531        })
36532      }
36533    }, offset), 0)
36534
36535    $tip.addClass('in')
36536
36537    // check to see if placing tip in new offset caused the tip to resize itself
36538    var actualWidth  = $tip[0].offsetWidth
36539    var actualHeight = $tip[0].offsetHeight
36540
36541    if (placement == 'top' && actualHeight != height) {
36542      offset.top = offset.top + height - actualHeight
36543    }
36544
36545    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
36546
36547    if (delta.left) offset.left += delta.left
36548    else offset.top += delta.top
36549
36550    var isVertical          = /top|bottom/.test(placement)
36551    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
36552    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
36553
36554    $tip.offset(offset)
36555    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
36556  }
36557
36558  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
36559    this.arrow()
36560      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
36561      .css(isVertical ? 'top' : 'left', '')
36562  }
36563
36564  Tooltip.prototype.setContent = function () {
36565    var $tip  = this.tip()
36566    var title = this.getTitle()
36567
36568    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
36569    $tip.removeClass('fade in top bottom left right')
36570  }
36571
36572  Tooltip.prototype.hide = function (callback) {
36573    var that = this
36574    var $tip = $(this.$tip)
36575    var e    = $.Event('hide.bs.' + this.type)
36576
36577    function complete() {
36578      if (that.hoverState != 'in') $tip.detach()
36579      that.$element
36580        .removeAttr('aria-describedby')
36581        .trigger('hidden.bs.' + that.type)
36582      callback && callback()
36583    }
36584
36585    this.$element.trigger(e)
36586
36587    if (e.isDefaultPrevented()) return
36588
36589    $tip.removeClass('in')
36590
36591    $.support.transition && $tip.hasClass('fade') ?
36592      $tip
36593        .one('bsTransitionEnd', complete)
36594        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
36595      complete()
36596
36597    this.hoverState = null
36598
36599    return this
36600  }
36601
36602  Tooltip.prototype.fixTitle = function () {
36603    var $e = this.$element
36604    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
36605      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
36606    }
36607  }
36608
36609  Tooltip.prototype.hasContent = function () {
36610    return this.getTitle()
36611  }
36612
36613  Tooltip.prototype.getPosition = function ($element) {
36614    $element   = $element || this.$element
36615
36616    var el     = $element[0]
36617    var isBody = el.tagName == 'BODY'
36618
36619    var elRect    = el.getBoundingClientRect()
36620    if (elRect.width == null) {
36621      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
36622      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
36623    }
36624    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
36625    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
36626    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
36627
36628    return $.extend({}, elRect, scroll, outerDims, elOffset)
36629  }
36630
36631  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
36632    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
36633           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
36634           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
36635        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
36636
36637  }
36638
36639  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
36640    var delta = { top: 0, left: 0 }
36641    if (!this.$viewport) return delta
36642
36643    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
36644    var viewportDimensions = this.getPosition(this.$viewport)
36645
36646    if (/right|left/.test(placement)) {
36647      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
36648      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
36649      if (topEdgeOffset < viewportDimensions.top) { // top overflow
36650        delta.top = viewportDimensions.top - topEdgeOffset
36651      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
36652        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
36653      }
36654    } else {
36655      var leftEdgeOffset  = pos.left - viewportPadding
36656      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
36657      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
36658        delta.left = viewportDimensions.left - leftEdgeOffset
36659      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
36660        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
36661      }
36662    }
36663
36664    return delta
36665  }
36666
36667  Tooltip.prototype.getTitle = function () {
36668    var title
36669    var $e = this.$element
36670    var o  = this.options
36671
36672    title = $e.attr('data-original-title')
36673      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
36674
36675    return title
36676  }
36677
36678  Tooltip.prototype.getUID = function (prefix) {
36679    do prefix += ~~(Math.random() * 1000000)
36680    while (document.getElementById(prefix))
36681    return prefix
36682  }
36683
36684  Tooltip.prototype.tip = function () {
36685    if (!this.$tip) {
36686      this.$tip = $(this.options.template)
36687      if (this.$tip.length != 1) {
36688        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
36689      }
36690    }
36691    return this.$tip
36692  }
36693
36694  Tooltip.prototype.arrow = function () {
36695    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
36696  }
36697
36698  Tooltip.prototype.enable = function () {
36699    this.enabled = true
36700  }
36701
36702  Tooltip.prototype.disable = function () {
36703    this.enabled = false
36704  }
36705
36706  Tooltip.prototype.toggleEnabled = function () {
36707    this.enabled = !this.enabled
36708  }
36709
36710  Tooltip.prototype.toggle = function (e) {
36711    var self = this
36712    if (e) {
36713      self = $(e.currentTarget).data('bs.' + this.type)
36714      if (!self) {
36715        self = new this.constructor(e.currentTarget, this.getDelegateOptions())
36716        $(e.currentTarget).data('bs.' + this.type, self)
36717      }
36718    }
36719
36720    if (e) {
36721      self.inState.click = !self.inState.click
36722      if (self.isInStateTrue()) self.enter(self)
36723      else self.leave(self)
36724    } else {
36725      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
36726    }
36727  }
36728
36729  Tooltip.prototype.destroy = function () {
36730    var that = this
36731    clearTimeout(this.timeout)
36732    this.hide(function () {
36733      that.$element.off('.' + that.type).removeData('bs.' + that.type)
36734      if (that.$tip) {
36735        that.$tip.detach()
36736      }
36737      that.$tip = null
36738      that.$arrow = null
36739      that.$viewport = null
36740    })
36741  }
36742
36743
36744  // TOOLTIP PLUGIN DEFINITION
36745  // =========================
36746
36747  function Plugin(option) {
36748    return this.each(function () {
36749      var $this   = $(this)
36750      var data    = $this.data('bs.tooltip')
36751      var options = typeof option == 'object' && option
36752
36753      if (!data && /destroy|hide/.test(option)) return
36754      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
36755      if (typeof option == 'string') data[option]()
36756    })
36757  }
36758
36759  var old = $.fn.tooltip
36760
36761  $.fn.tooltip             = Plugin
36762  $.fn.tooltip.Constructor = Tooltip
36763
36764
36765  // TOOLTIP NO CONFLICT
36766  // ===================
36767
36768  $.fn.tooltip.noConflict = function () {
36769    $.fn.tooltip = old
36770    return this
36771  }
36772
36773}(jQuery);
vendor: 14,836 bytes, lines 36774-37298
36774/* ========================================================================
36775 * Bootstrap: popover.js v3.3.5
36776 * http://getbootstrap.com/javascript/#popovers
36777 * ========================================================================
36778 * Copyright 2011-2015 Twitter, Inc.
36779 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
36780 * ======================================================================== */
36781
36782
36783
36784+function ($) {
36785  'use strict';
36786
36787  // POPOVER PUBLIC CLASS DEFINITION
36788  // ===============================
36789
36790  var Popover = function (element, options) {
36791    this.init('popover', element, options)
36792  }
36793
36794  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
36795
36796  Popover.VERSION  = '3.3.5'
36797
36798  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
36799    placement: 'right',
36800    trigger: 'click',
36801    content: '',
36802    template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
36803  })
36804
36805
36806  // NOTE: POPOVER EXTENDS tooltip.js
36807  // ================================
36808
36809  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
36810
36811  Popover.prototype.constructor = Popover
36812
36813  Popover.prototype.getDefaults = function () {
36814    return Popover.DEFAULTS
36815  }
36816
36817  Popover.prototype.setContent = function () {
36818    var $tip    = this.tip()
36819    var title   = this.getTitle()
36820    var content = this.getContent()
36821
36822    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
36823    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
36824      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
36825    ](content)
36826
36827    $tip.removeClass('fade top bottom left right in')
36828
36829    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
36830    // this manually by checking the contents.
36831    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
36832  }
36833
36834  Popover.prototype.hasContent = function () {
36835    return this.getTitle() || this.getContent()
36836  }
36837
36838  Popover.prototype.getContent = function () {
36839    var $e = this.$element
36840    var o  = this.options
36841
36842    return $e.attr('data-content')
36843      || (typeof o.content == 'function' ?
36844            o.content.call($e[0]) :
36845            o.content)
36846  }
36847
36848  Popover.prototype.arrow = function () {
36849    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
36850  }
36851
36852
36853  // POPOVER PLUGIN DEFINITION
36854  // =========================
36855
36856  function Plugin(option) {
36857    return this.each(function () {
36858      var $this   = $(this)
36859      var data    = $this.data('bs.popover')
36860      var options = typeof option == 'object' && option
36861
36862      if (!data && /destroy|hide/.test(option)) return
36863      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
36864      if (typeof option == 'string') data[option]()
36865    })
36866  }
36867
36868  var old = $.fn.popover
36869
36870  $.fn.popover             = Plugin
36871  $.fn.popover.Constructor = Popover
36872
36873
36874  // POPOVER NO CONFLICT
36875  // ===================
36876
36877  $.fn.popover.noConflict = function () {
36878    $.fn.popover = old
36879    return this
36880  }
36881
36882}(jQuery);
36883/* ========================================================================
36884 * Bootstrap: scrollspy.js v3.3.5
36885 * http://getbootstrap.com/javascript/#scrollspy
36886 * ========================================================================
36887 * Copyright 2011-2015 Twitter, Inc.
36888 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
36889 * ======================================================================== */
36890
36891
36892
36893+function ($) {
36894  'use strict';
36895
36896  // SCROLLSPY CLASS DEFINITION
36897  // ==========================
36898
36899  function ScrollSpy(element, options) {
36900    this.$body          = $(document.body)
36901    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
36902    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
36903    this.selector       = (this.options.target || '') + ' .nav li > a'
36904    this.offsets        = []
36905    this.targets        = []
36906    this.activeTarget   = null
36907    this.scrollHeight   = 0
36908
36909    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
36910    this.refresh()
36911    this.process()
36912  }
36913
36914  ScrollSpy.VERSION  = '3.3.5'
36915
36916  ScrollSpy.DEFAULTS = {
36917    offset: 10
36918  }
36919
36920  ScrollSpy.prototype.getScrollHeight = function () {
36921    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
36922  }
36923
36924  ScrollSpy.prototype.refresh = function () {
36925    var that          = this
36926    var offsetMethod  = 'offset'
36927    var offsetBase    = 0
36928
36929    this.offsets      = []
36930    this.targets      = []
36931    this.scrollHeight = this.getScrollHeight()
36932
36933    if (!$.isWindow(this.$scrollElement[0])) {
36934      offsetMethod = 'position'
36935      offsetBase   = this.$scrollElement.scrollTop()
36936    }
36937
36938    this.$body
36939      .find(this.selector)
36940      .map(function () {
36941        var $el   = $(this)
36942        var href  = $el.data('target') || $el.attr('href')
36943        var $href = /^#./.test(href) && $(href)
36944
36945        return ($href
36946          && $href.length
36947          && $href.is(':visible')
36948          && [[$href[offsetMethod]().top + offsetBase, href]]) || null
36949      })
36950      .sort(function (a, b) { return a[0] - b[0] })
36951      .each(function () {
36952        that.offsets.push(this[0])
36953        that.targets.push(this[1])
36954      })
36955  }
36956
36957  ScrollSpy.prototype.process = function () {
36958    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
36959    var scrollHeight = this.getScrollHeight()
36960    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
36961    var offsets      = this.offsets
36962    var targets      = this.targets
36963    var activeTarget = this.activeTarget
36964    var i
36965
36966    if (this.scrollHeight != scrollHeight) {
36967      this.refresh()
36968    }
36969
36970    if (scrollTop >= maxScroll) {
36971      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
36972    }
36973
36974    if (activeTarget && scrollTop < offsets[0]) {
36975      this.activeTarget = null
36976      return this.clear()
36977    }
36978
36979    for (i = offsets.length; i--;) {
36980      activeTarget != targets[i]
36981        && scrollTop >= offsets[i]
36982        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
36983        && this.activate(targets[i])
36984    }
36985  }
36986
36987  ScrollSpy.prototype.activate = function (target) {
36988    this.activeTarget = target
36989
36990    this.clear()
36991
36992    var selector = this.selector +
36993      '[data-target="' + target + '"],' +
36994      this.selector + '[href="' + target + '"]'
36995
36996    var active = $(selector)
36997      .parents('li')
36998      .addClass('active')
36999
37000    if (active.parent('.dropdown-menu').length) {
37001      active = active
37002        .closest('li.dropdown')
37003        .addClass('active')
37004    }
37005
37006    active.trigger('activate.bs.scrollspy')
37007  }
37008
37009  ScrollSpy.prototype.clear = function () {
37010    $(this.selector)
37011      .parentsUntil(this.options.target, '.active')
37012      .removeClass('active')
37013  }
37014
37015
37016  // SCROLLSPY PLUGIN DEFINITION
37017  // ===========================
37018
37019  function Plugin(option) {
37020    return this.each(function () {
37021      var $this   = $(this)
37022      var data    = $this.data('bs.scrollspy')
37023      var options = typeof option == 'object' && option
37024
37025      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
37026      if (typeof option == 'string') data[option]()
37027    })
37028  }
37029
37030  var old = $.fn.scrollspy
37031
37032  $.fn.scrollspy             = Plugin
37033  $.fn.scrollspy.Constructor = ScrollSpy
37034
37035
37036  // SCROLLSPY NO CONFLICT
37037  // =====================
37038
37039  $.fn.scrollspy.noConflict = function () {
37040    $.fn.scrollspy = old
37041    return this
37042  }
37043
37044
37045  // SCROLLSPY DATA-API
37046  // ==================
37047
37048  $(window).on('load.bs.scrollspy.data-api', function () {
37049    $('[data-spy="scroll"]').each(function () {
37050      var $spy = $(this)
37051      Plugin.call($spy, $spy.data())
37052    })
37053  })
37054
37055}(jQuery);
37056/* ========================================================================
37057 * Bootstrap: tab.js v3.3.5
37058 * http://getbootstrap.com/javascript/#tabs
37059 * ========================================================================
37060 * Copyright 2011-2015 Twitter, Inc.
37061 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
37062 * ======================================================================== */
37063
37064
37065
37066+function ($) {
37067  'use strict';
37068
37069  // TAB CLASS DEFINITION
37070  // ====================
37071
37072  var Tab = function (element) {
37073    // jscs:disable requireDollarBeforejQueryAssignment
37074    this.element = $(element)
37075    // jscs:enable requireDollarBeforejQueryAssignment
37076  }
37077
37078  Tab.VERSION = '3.3.5'
37079
37080  Tab.TRANSITION_DURATION = 150
37081
37082  Tab.prototype.show = function () {
37083    var $this    = this.element
37084    var $ul      = $this.closest('ul:not(.dropdown-menu)')
37085    var selector = $this.data('target')
37086
37087    if (!selector) {
37088      selector = $this.attr('href')
37089      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
37090    }
37091
37092    if ($this.parent('li').hasClass('active')) return
37093
37094    var $previous = $ul.find('.active:last a')
37095    var hideEvent = $.Event('hide.bs.tab', {
37096      relatedTarget: $this[0]
37097    })
37098    var showEvent = $.Event('show.bs.tab', {
37099      relatedTarget: $previous[0]
37100    })
37101
37102    $previous.trigger(hideEvent)
37103    $this.trigger(showEvent)
37104
37105    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
37106
37107    var $target = $(selector)
37108
37109    this.activate($this.closest('li'), $ul)
37110    this.activate($target, $target.parent(), function () {
37111      $previous.trigger({
37112        type: 'hidden.bs.tab',
37113        relatedTarget: $this[0]
37114      })
37115      $this.trigger({
37116        type: 'shown.bs.tab',
37117        relatedTarget: $previous[0]
37118      })
37119    })
37120  }
37121
37122  Tab.prototype.activate = function (element, container, callback) {
37123    var $active    = container.find('> .active')
37124    var transition = callback
37125      && $.support.transition
37126      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
37127
37128    function next() {
37129      $active
37130        .removeClass('active')
37131        .find('> .dropdown-menu > .active')
37132          .removeClass('active')
37133        .end()
37134        .find('[data-toggle="tab"]')
37135          .attr('aria-expanded', false)
37136
37137      element
37138        .addClass('active')
37139        .find('[data-toggle="tab"]')
37140          .attr('aria-expanded', true)
37141
37142      if (transition) {
37143        element[0].offsetWidth // reflow for transition
37144        element.addClass('in')
37145      } else {
37146        element.removeClass('fade')
37147      }
37148
37149      if (element.parent('.dropdown-menu').length) {
37150        element
37151          .closest('li.dropdown')
37152            .addClass('active')
37153          .end()
37154          .find('[data-toggle="tab"]')
37155            .attr('aria-expanded', true)
37156      }
37157
37158      callback && callback()
37159    }
37160
37161    $active.length && transition ?
37162      $active
37163        .one('bsTransitionEnd', next)
37164        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
37165      next()
37166
37167    $active.removeClass('in')
37168  }
37169
37170
37171  // TAB PLUGIN DEFINITION
37172  // =====================
37173
37174  function Plugin(option) {
37175    return this.each(function () {
37176      var $this = $(this)
37177      var data  = $this.data('bs.tab')
37178
37179      if (!data) $this.data('bs.tab', (data = new Tab(this)))
37180      if (typeof option == 'string') data[option]()
37181    })
37182  }
37183
37184  var old = $.fn.tab
37185
37186  $.fn.tab             = Plugin
37187  $.fn.tab.Constructor = Tab
37188
37189
37190  // TAB NO CONFLICT
37191  // ===============
37192
37193  $.fn.tab.noConflict = function () {
37194    $.fn.tab = old
37195    return this
37196  }
37197
37198
37199  // TAB DATA-API
37200  // ============
37201
37202  var clickHandler = function (e) {
37203    e.preventDefault()
37204    Plugin.call($(this), 'show')
37205  }
37206
37207  $(document)
37208    .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
37209    .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
37210
37211}(jQuery);
37212/* ========================================================================
37213 * Bootstrap: affix.js v3.3.5
37214 * http://getbootstrap.com/javascript/#affix
37215 * ========================================================================
37216 * Copyright 2011-2015 Twitter, Inc.
37217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
37218 * ======================================================================== */
37219
37220
37221
37222+function ($) {
37223  'use strict';
37224
37225  // AFFIX CLASS DEFINITION
37226  // ======================
37227
37228  var Affix = function (element, options) {
37229    this.options = $.extend({}, Affix.DEFAULTS, options)
37230
37231    this.$target = $(this.options.target)
37232      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
37233      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
37234
37235    this.$element     = $(element)
37236    this.affixed      = null
37237    this.unpin        = null
37238    this.pinnedOffset = null
37239
37240    this.checkPosition()
37241  }
37242
37243  Affix.VERSION  = '3.3.5'
37244
37245  Affix.RESET    = 'affix affix-top affix-bottom'
37246
37247  Affix.DEFAULTS = {
37248    offset: 0,
37249    target: window
37250  }
37251
37252  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
37253    var scrollTop    = this.$target.scrollTop()
37254    var position     = this.$element.offset()
37255    var targetHeight = this.$target.height()
37256
37257    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
37258
37259    if (this.affixed == 'bottom') {
37260      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
37261      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
37262    }
37263
37264    var initializing   = this.affixed == null
37265    var colliderTop    = initializing ? scrollTop : position.top
37266    var colliderHeight = initializing ? targetHeight : height
37267
37268    if (offsetTop != null && scrollTop <= offsetTop) return 'top'
37269    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
37270
37271    return false
37272  }
37273
37274  Affix.prototype.getPinnedOffset = function () {
37275    if (this.pinnedOffset) return this.pinnedOffset
37276    this.$element.removeClass(Affix.RESET).addClass('affix')
37277    var scrollTop = this.$target.scrollTop()
37278    var position  = this.$element.offset()
37279    return (this.pinnedOffset = position.top - scrollTop)
37280  }
37281
37282  Affix.prototype.checkPositionWithEventLoop = function () {
37283    setTimeout($.proxy(this.checkPosition, this), 1)
37284  }
37285
37286  Affix.prototype.checkPosition = function () {
37287    if (!this.$element.is(':visible')) return
37288
37289    var height       = this.$element.height()
37290    var offset       = this.options.offset
37291    var offsetTop    = offset.top
37292    var offsetBottom = offset.bottom
37293    var scrollHeight = Math.max($(document).height(), $(document.body).height())
37294
37295    if (typeof offset != 'object')         offsetBottom = offsetTop = offset
37296    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
37297    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
37298
37299    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
37300
37301    if (this.affixed != affix) {
37302      if (this.unpin != null) this.$element.css('top', '')
37303
37304      var affixType = 'affix' + (affix ? '-' + affix : '')
37305      var e         = $.Event(affixType + '.bs.affix')
37306
37307      this.$element.trigger(e)
37308
37309      if (e.isDefaultPrevented()) return
37310
37311      this.affixed = affix
37312      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
37313
37314      this.$element
37315        .removeClass(Affix.RESET)
37316        .addClass(affixType)
37317        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
37318    }
37319
37320    if (affix == 'bottom') {
37321      this.$element.offset({
37322        top: scrollHeight - height - offsetBottom
37323      })
37324    }
37325  }
37326
37327
37328  // AFFIX PLUGIN DEFINITION
37329  // =======================
37330
37331  function Plugin(option) {
37332    return this.each(function () {
37333      var $this   = $(this)
37334      var data    = $this.data('bs.affix')
37335      var options = typeof option == 'object' && option
37336
37337      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
37338      if (typeof option == 'string') data[option]()
37339    })
37340  }
37341
37342  var old = $.fn.affix
37343
37344  $.fn.affix             = Plugin
37345  $.fn.affix.Constructor = Affix
37346
37347
37348  // AFFIX NO CONFLICT
37349  // =================
37350
37351  $.fn.affix.noConflict = function () {
37352    $.fn.affix = old
37353    return this
37354  }
37355
37356
37357  // AFFIX DATA-API
37358  // ==============
37359
37360  $(window).on('load', function () {
37361    $('[data-spy="affix"]').each(function () {
37362      var $spy = $(this)
37363      var data = $spy.data()
37364
37365      data.offset = data.offset || {}
37366
37367      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
37368      if (data.offsetTop    != null) data.offset.top    = data.offsetTop
37369
37370      Plugin.call($spy, data)
37371    })
37372  })
37373
37374}(jQuery);
37375
37376
37377
37378
37379
37380
37381
37382
37383
37384
37385
37386
37387//     Underscore.js 1.4.4
37388//     http://underscorejs.org
37389//     (c) 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
37390//     Underscore may be freely distributed under the MIT license.
37391
37392(function() {
37393
37394  // Baseline setup
37395  // --------------
37396
37397  // Establish the root object, `window` in the browser, or `global` on the server.
37398  var root = this;
37399
37400  // Save the previous value of the `_` variable.
37401  var previousUnderscore = root._;
37402
37403  // Establish the object that gets returned to break out of a loop iteration.
37404  var breaker = {};
37405
37406  // Save bytes in the minified (but not gzipped) version:
37407  var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
37408
37409  // Create quick reference variables for speed access to core prototypes.
37410  var push             = ArrayProto.push,
37411      slice            = ArrayProto.slice,
37412      concat           = ArrayProto.concat,
37413      toString         = ObjProto.toString,
37414      hasOwnProperty   = ObjProto.hasOwnProperty;
37415
37416  // All **ECMAScript 5** native function implementations that we hope to use
37417  // are declared here.
37418  var
37419    nativeForEach      = ArrayProto.forEach,
37420    nativeMap          = ArrayProto.map,
37421    nativeReduce       = ArrayProto.reduce,
37422    nativeReduceRight  = ArrayProto.reduceRight,
37423    nativeFilter       = ArrayProto.filter,
37424    nativeEvery        = ArrayProto.every,
37425    nativeSome         = ArrayProto.some,
37426    nativeIndexOf      = ArrayProto.indexOf,
37427    nativeLastIndexOf  = ArrayProto.lastIndexOf,
37428    nativeIsArray      = Array.isArray,
37429    nativeKeys         = Object.keys,
37430    nativeBind         = FuncProto.bind;
37431
37432  // Create a safe reference to the Underscore object for use below.
37433  var _ = function(obj) {
37434    if (obj instanceof _) return obj;
37435    if (!(this instanceof _)) return new _(obj);
37436    this._wrapped = obj;
37437  };
37438
37439  // Export the Underscore object for **Node.js**, with
37440  // backwards-compatibility for the old `require()` API. If we're in
37441  // the browser, add `_` as a global object via a string identifier,
37442  // for Closure Compiler "advanced" mode.
37443  if (typeof exports !== 'undefined') {
37444    if (typeof module !== 'undefined' && module.exports) {
37445      exports = module.exports = _;
37446    }
37447    exports._ = _;
37448  } else {
37449    root._ = _;
37450  }
37451
37452  // Current version.
37453  _.VERSION = '1.4.4';
37454
37455  // Collection Functions
37456  // --------------------
37457
37458  // The cornerstone, an `each` implementation, aka `forEach`.
37459  // Handles objects with the built-in `forEach`, arrays, and raw objects.
37460  // Delegates to **ECMAScript 5**'s native `forEach` if available.
37461  var each = _.each = _.forEach = function(obj, iterator, context) {
37462    if (obj == null) return;
37463    if (nativeForEach && obj.forEach === nativeForEach) {
37464      obj.forEach(iterator, context);
37465    } else if (obj.length === +obj.length) {
37466      for (var i = 0, l = obj.length; i < l; i++) {
37467        if (iterator.call(context, obj[i], i, obj) === breaker) return;
37468      }
37469    } else {
37470      for (var key in obj) {
37471        if (_.has(obj, key)) {
37472          if (iterator.call(context, obj[key], key, obj) === breaker) return;
37473        }
37474      }
37475    }
37476  };
37477
37478  // Return the results of applying the iterator to each element.
37479  // Delegates to **ECMAScript 5**'s native `map` if available.
37480  _.map = _.collect = function(obj, iterator, context) {
37481    var results = [];
37482    if (obj == null) return results;
37483    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
37484    each(obj, function(value, index, list) {
37485      results[results.length] = iterator.call(context, value, index, list);
37486    });
37487    return results;
37488  };
37489
37490  var reduceError = 'Reduce of empty array with no initial value';
37491
37492  // **Reduce** builds up a single result from a list of values, aka `inject`,
37493  // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
37494  _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
37495    var initial = arguments.length > 2;
37496    if (obj == null) obj = [];
37497    if (nativeReduce && obj.reduce === nativeReduce) {
37498      if (context) iterator = _.bind(iterator, context);
37499      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
37500    }
37501    each(obj, function(value, index, list) {
37502      if (!initial) {
37503        memo = value;
37504        initial = true;
37505      } else {
37506        memo = iterator.call(context, memo, value, index, list);
37507      }
37508    });
37509    if (!initial) throw new TypeError(reduceError);
37510    return memo;
37511  };
37512
37513  // The right-associative version of reduce, also known as `foldr`.
37514  // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
37515  _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
37516    var initial = arguments.length > 2;
37517    if (obj == null) obj = [];
37518    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
37519      if (context) iterator = _.bind(iterator, context);
37520      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
37521    }
37522    var length = obj.length;
37523    if (length !== +length) {
37524      var keys = _.keys(obj);
37525      length = keys.length;
37526    }
37527    each(obj, function(value, index, list) {
37528      index = keys ? keys[--length] : --length;
37529      if (!initial) {
37530        memo = obj[index];
37531        initial = true;
37532      } else {
37533        memo = iterator.call(context, memo, obj[index], index, list);
37534      }
37535    });
37536    if (!initial) throw new TypeError(reduceError);
37537    return memo;
37538  };
37539
37540  // Return the first value which passes a truth test. Aliased as `detect`.
37541  _.find = _.detect = function(obj, iterator, context) {
37542    var result;
37543    any(obj, function(value, index, list) {
37544      if (iterator.call(context, value, index, list)) {
37545        result = value;
37546        return true;
37547      }
37548    });
37549    return result;
37550  };
37551
37552  // Return all the elements that pass a truth test.
37553  // Delegates to **ECMAScript 5**'s native `filter` if available.
37554  // Aliased as `select`.
37555  _.filter = _.select = function(obj, iterator, context) {
37556    var results = [];
37557    if (obj == null) return results;
37558    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
37559    each(obj, function(value, index, list) {
37560      if (iterator.call(context, value, index, list)) results[results.length] = value;
37561    });
37562    return results;
37563  };
37564
37565  // Return all the elements for which a truth test fails.
37566  _.reject = function(obj, iterator, context) {
37567    return _.filter(obj, function(value, index, list) {
37568      return !iterator.call(context, value, index, list);
37569    }, context);
37570  };
37571
37572  // Determine whether all of the elements match a truth test.
37573  // Delegates to **ECMAScript 5**'s native `every` if available.
37574  // Aliased as `all`.
37575  _.every = _.all = function(obj, iterator, context) {
37576    iterator || (iterator = _.identity);
37577    var result = true;
37578    if (obj == null) return result;
37579    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
37580    each(obj, function(value, index, list) {
37581      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
37582    });
37583    return !!result;
37584  };
37585
37586  // Determine if at least one element in the object matches a truth test.
37587  // Delegates to **ECMAScript 5**'s native `some` if available.
37588  // Aliased as `any`.
37589  var any = _.some = _.any = function(obj, iterator, context) {
37590    iterator || (iterator = _.identity);
37591    var result = false;
37592    if (obj == null) return result;
37593    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
37594    each(obj, function(value, index, list) {
37595      if (result || (result = iterator.call(context, value, index, list))) return breaker;
37596    });
37597    return !!result;
37598  };
37599
37600  // Determine if the array or object contains a given value (using `===`).
37601  // Aliased as `include`.
37602  _.contains = _.include = function(obj, target) {
37603    if (obj == null) return false;
37604    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
37605    return any(obj, function(value) {
37606      return value === target;
37607    });
37608  };
37609
37610  // Invoke a method (with arguments) on every item in a collection.
37611  _.invoke = function(obj, method) {
37612    var args = slice.call(arguments, 2);
37613    var isFunc = _.isFunction(method);
37614    return _.map(obj, function(value) {
37615      return (isFunc ? method : value[method]).apply(value, args);
37616    });
37617  };
37618
37619  // Convenience version of a common use case of `map`: fetching a property.
37620  _.pluck = function(obj, key) {
37621    return _.map(obj, function(value){ return value[key]; });
37622  };
37623
37624  // Convenience version of a common use case of `filter`: selecting only objects
37625  // containing specific `key:value` pairs.
37626  _.where = function(obj, attrs, first) {
37627    if (_.isEmpty(attrs)) return first ? null : [];
37628    return _[first ? 'find' : 'filter'](obj, function(value) {
37629      for (var key in attrs) {
37630        if (attrs[key] !== value[key]) return false;
37631      }
37632      return true;
37633    });
37634  };
37635
37636  // Convenience version of a common use case of `find`: getting the first object
37637  // containing specific `key:value` pairs.
37638  _.findWhere = function(obj, attrs) {
37639    return _.where(obj, attrs, true);
37640  };
37641
37642  // Return the maximum element or (element-based computation).
37643  // Can't optimize arrays of integers longer than 65,535 elements.
37644  // See: https://bugs.webkit.org/show_bug.cgi?id=80797
37645  _.max = function(obj, iterator, context) {
37646    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
37647      return Math.max.apply(Math, obj);
37648    }
37649    if (!iterator && _.isEmpty(obj)) return -Infinity;
37650    var result = {computed : -Infinity, value: -Infinity};
37651    each(obj, function(value, index, list) {
37652      var computed = iterator ? iterator.call(context, value, index, list) : value;
37653      computed >= result.computed && (result = {value : value, computed : computed});
37654    });
37655    return result.value;
37656  };
37657
37658  // Return the minimum element (or element-based computation).
37659  _.min = function(obj, iterator, context) {
37660    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
37661      return Math.min.apply(Math, obj);
37662    }
37663    if (!iterator && _.isEmpty(obj)) return Infinity;
37664    var result = {computed : Infinity, value: Infinity};
37665    each(obj, function(value, index, list) {
37666      var computed = iterator ? iterator.call(context, value, index, list) : value;
37667      computed < result.computed && (result = {value : value, computed : computed});
37668    });
37669    return result.value;
37670  };
37671
37672  // Shuffle an array.
37673  _.shuffle = function(obj) {
37674    var rand;
37675    var index = 0;
37676    var shuffled = [];
37677    each(obj, function(value) {
37678      rand = _.random(index++);
37679      shuffled[index - 1] = shuffled[rand];
37680      shuffled[rand] = value;
37681    });
37682    return shuffled;
37683  };
37684
37685  // An internal function to generate lookup iterators.
37686  var lookupIterator = function(value) {
37687    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
37688  };
37689
37690  // Sort the object's values by a criterion produced by an iterator.
37691  _.sortBy = function(obj, value, context) {
37692    var iterator = lookupIterator(value);
37693    return _.pluck(_.map(obj, function(value, index, list) {
37694      return {
37695        value : value,
37696        index : index,
37697        criteria : iterator.call(context, value, index, list)
37698      };
37699    }).sort(function(left, right) {
37700      var a = left.criteria;
37701      var b = right.criteria;
37702      if (a !== b) {
37703        if (a > b || a === void 0) return 1;
37704        if (a < b || b === void 0) return -1;
37705      }
37706      return left.index < right.index ? -1 : 1;
37707    }), 'value');
37708  };
37709
37710  // An internal function used for aggregate "group by" operations.
37711  var group = function(obj, value, context, behavior) {
37712    var result = {};
37713    var iterator = lookupIterator(value || _.identity);
37714    each(obj, function(value, index) {
37715      var key = iterator.call(context, value, index, obj);
37716      behavior(result, key, value);
37717    });
37718    return result;
37719  };
37720
37721  // Groups the object's values by a criterion. Pass either a string attribute
37722  // to group by, or a function that returns the criterion.
37723  _.groupBy = function(obj, value, context) {
37724    return group(obj, value, context, function(result, key, value) {
37725      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
37726    });
37727  };
37728
37729  // Counts instances of an object that group by a certain criterion. Pass
37730  // either a string attribute to count by, or a function that returns the
37731  // criterion.
37732  _.countBy = function(obj, value, context) {
37733    return group(obj, value, context, function(result, key) {
37734      if (!_.has(result, key)) result[key] = 0;
37735      result[key]++;
37736    });
37737  };
37738
37739  // Use a comparator function to figure out the smallest index at which
37740  // an object should be inserted so as to maintain order. Uses binary search.
37741  _.sortedIndex = function(array, obj, iterator, context) {
37742    iterator = iterator == null ? _.identity : lookupIterator(iterator);
37743    var value = iterator.call(context, obj);
37744    var low = 0, high = array.length;
37745    while (low < high) {
37746      var mid = (low + high) >>> 1;
37747      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
37748    }
37749    return low;
37750  };
37751
37752  // Safely convert anything iterable into a real, live array.
37753  _.toArray = function(obj) {
37754    if (!obj) return [];
37755    if (_.isArray(obj)) return slice.call(obj);
37756    if (obj.length === +obj.length) return _.map(obj, _.identity);
37757    return _.values(obj);
37758  };
37759
37760  // Return the number of elements in an object.
37761  _.size = function(obj) {
37762    if (obj == null) return 0;
37763    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
37764  };
37765
37766  // Array Functions
37767  // ---------------
37768
37769  // Get the first element of an array. Passing **n** will return the first N
37770  // values in the array. Aliased as `head` and `take`. The **guard** check
37771  // allows it to work with `_.map`.
37772  _.first = _.head = _.take = function(array, n, guard) {
37773    if (array == null) return void 0;
37774    return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
37775  };
37776
37777  // Returns everything but the last entry of the array. Especially useful on
37778  // the arguments object. Passing **n** will return all the values in
37779  // the array, excluding the last N. The **guard** check allows it to work with
37780  // `_.map`.
37781  _.initial = function(array, n, guard) {
37782    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
37783  };
37784
37785  // Get the last element of an array. Passing **n** will return the last N
37786  // values in the array. The **guard** check allows it to work with `_.map`.
37787  _.last = function(array, n, guard) {
37788    if (array == null) return void 0;
37789    if ((n != null) && !guard) {
37790      return slice.call(array, Math.max(array.length - n, 0));
37791    } else {
37792      return array[array.length - 1];
37793    }
37794  };
37795
37796  // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
37797  // Especially useful on the arguments object. Passing an **n** will return
37798  // the rest N values in the array. The **guard**
37799  // check allows it to work with `_.map`.
37800  _.rest = _.tail = _.drop = function(array, n, guard) {
37801    return slice.call(array, (n == null) || guard ? 1 : n);
37802  };
37803
37804  // Trim out all falsy values from an array.
37805  _.compact = function(array) {
37806    return _.filter(array, _.identity);
37807  };
37808
37809  // Internal implementation of a recursive `flatten` function.
37810  var flatten = function(input, shallow, output) {
37811    each(input, function(value) {
37812      if (_.isArray(value)) {
37813        shallow ? push.apply(output, value) : flatten(value, shallow, output);
37814      } else {
37815        output.push(value);
37816      }
37817    });
37818    return output;
37819  };
37820
37821  // Return a completely flattened version of an array.
37822  _.flatten = function(array, shallow) {
37823    return flatten(array, shallow, []);
37824  };
37825
37826  // Return a version of the array that does not contain the specified value(s).
37827  _.without = function(array) {
37828    return _.difference(array, slice.call(arguments, 1));
37829  };
37830
37831  // Produce a duplicate-free version of the array. If the array has already
37832  // been sorted, you have the option of using a faster algorithm.
37833  // Aliased as `unique`.
37834  _.uniq = _.unique = function(array, isSorted, iterator, context) {
37835    if (_.isFunction(isSorted)) {
37836      context = iterator;
37837      iterator = isSorted;
37838      isSorted = false;
37839    }
37840    var initial = iterator ? _.map(array, iterator, context) : array;
37841    var results = [];
37842    var seen = [];
37843    each(initial, function(value, index) {
37844      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
37845        seen.push(value);
37846        results.push(array[index]);
37847      }
37848    });
37849    return results;
37850  };
37851
37852  // Produce an array that contains the union: each distinct element from all of
37853  // the passed-in arrays.
37854  _.union = function() {
37855    return _.uniq(concat.apply(ArrayProto, arguments));
37856  };
37857
37858  // Produce an array that contains every item shared between all the
37859  // passed-in arrays.
37860  _.intersection = function(array) {
37861    var rest = slice.call(arguments, 1);
37862    return _.filter(_.uniq(array), function(item) {
37863      return _.every(rest, function(other) {
37864        return _.indexOf(other, item) >= 0;
37865      });
37866    });
37867  };
37868
37869  // Take the difference between one array and a number of other arrays.
37870  // Only the elements present in just the first array will remain.
37871  _.difference = function(array) {
37872    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
37873    return _.filter(array, function(value){ return !_.contains(rest, value); });
37874  };
37875
37876  // Zip together multiple lists into a single array -- elements that share
37877  // an index go together.
37878  _.zip = function() {
37879    var args = slice.call(arguments);
37880    var length = _.max(_.pluck(args, 'length'));
37881    var results = new Array(length);
37882    for (var i = 0; i < length; i++) {
37883      results[i] = _.pluck(args, "" + i);
37884    }
37885    return results;
37886  };
37887
37888  // Converts lists into objects. Pass either a single array of `[key, value]`
37889  // pairs, or two parallel arrays of the same length -- one of keys, and one of
37890  // the corresponding values.
37891  _.object = function(list, values) {
37892    if (list == null) return {};
37893    var result = {};
37894    for (var i = 0, l = list.length; i < l; i++) {
37895      if (values) {
37896        result[list[i]] = values[i];
37897      } else {
37898        result[list[i][0]] = list[i][1];
37899      }
37900    }
37901    return result;
37902  };
37903
37904  // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
37905  // we need this function. Return the position of the first occurrence of an
37906  // item in an array, or -1 if the item is not included in the array.
37907  // Delegates to **ECMAScript 5**'s native `indexOf` if available.
37908  // If the array is large and already in sort order, pass `true`
37909  // for **isSorted** to use binary search.
37910  _.indexOf = function(array, item, isSorted) {
37911    if (array == null) return -1;
37912    var i = 0, l = array.length;
37913    if (isSorted) {
37914      if (typeof isSorted == 'number') {
37915        i = (isSorted < 0 ? Math.max(0, l + isSorted) : isSorted);
37916      } else {
37917        i = _.sortedIndex(array, item);
37918        return array[i] === item ? i : -1;
37919      }
37920    }
37921    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
37922    for (; i < l; i++) if (array[i] === item) return i;
37923    return -1;
37924  };
37925
37926  // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
37927  _.lastIndexOf = function(array, item, from) {
37928    if (array == null) return -1;
37929    var hasIndex = from != null;
37930    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
37931      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
37932    }
37933    var i = (hasIndex ? from : array.length);
37934    while (i--) if (array[i] === item) return i;
37935    return -1;
37936  };
37937
37938  // Generate an integer Array containing an arithmetic progression. A port of
37939  // the native Python `range()` function. See
37940  // [the Python documentation](http://docs.python.org/library/functions.html#range).
37941  _.range = function(start, stop, step) {
37942    if (arguments.length <= 1) {
37943      stop = start || 0;
37944      start = 0;
37945    }
37946    step = arguments[2] || 1;
37947
37948    var len = Math.max(Math.ceil((stop - start) / step), 0);
37949    var idx = 0;
37950    var range = new Array(len);
37951
37952    while(idx < len) {
37953      range[idx++] = start;
37954      start += step;
37955    }
37956
37957    return range;
37958  };
37959
37960  // Function (ahem) Functions
37961  // ------------------
37962
37963  // Create a function bound to a given object (assigning `this`, and arguments,
37964  // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if
37965  // available.
37966  _.bind = function(func, context) {
37967    if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
37968    var args = slice.call(arguments, 2);
37969    return function() {
37970      return func.apply(context, args.concat(slice.call(arguments)));
37971    };
37972  };
37973
37974  // Partially apply a function by creating a version that has had some of its
37975  // arguments pre-filled, without changing its dynamic `this` context.
37976  _.partial = function(func) {
37977    var args = slice.call(arguments, 1);
37978    return function() {
37979      return func.apply(this, args.concat(slice.call(arguments)));
37980    };
37981  };
37982
37983  // Bind all of an object's methods to that object. Useful for ensuring that
37984  // all callbacks defined on an object belong to it.
37985  _.bindAll = function(obj) {
37986    var funcs = slice.call(arguments, 1);
37987    if (funcs.length === 0) funcs = _.functions(obj);
37988    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
37989    return obj;
37990  };
37991
37992  // Memoize an expensive function by storing its results.
37993  _.memoize = function(func, hasher) {
37994    var memo = {};
37995    hasher || (hasher = _.identity);
37996    return function() {
37997      var key = hasher.apply(this, arguments);
37998      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
37999    };
38000  };
38001
38002  // Delays a function for the given number of milliseconds, and then calls
38003  // it with the arguments supplied.
38004  _.delay = function(func, wait) {
38005    var args = slice.call(arguments, 2);
38006    return setTimeout(function(){ return func.apply(null, args); }, wait);
38007  };
38008
38009  // Defers a function, scheduling it to run after the current call stack has
38010  // cleared.
38011  _.defer = function(func) {
38012    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
38013  };
38014
38015  // Returns a function, that, when invoked, will only be triggered at most once
38016  // during a given window of time.
38017  _.throttle = function(func, wait) {
38018    var context, args, timeout, result;
38019    var previous = 0;
38020    var later = function() {
38021      previous = new Date;
38022      timeout = null;
38023      result = func.apply(context, args);
38024    };
38025    return function() {
38026      var now = new Date;
38027      var remaining = wait - (now - previous);
38028      context = this;
38029      args = arguments;
38030      if (remaining <= 0) {
38031        clearTimeout(timeout);
38032        timeout = null;
38033        previous = now;
38034        result = func.apply(context, args);
38035      } else if (!timeout) {
38036        timeout = setTimeout(later, remaining);
38037      }
38038      return result;
38039    };
38040  };
38041
38042  // Returns a function, that, as long as it continues to be invoked, will not
38043  // be triggered. The function will be called after it stops being called for
38044  // N milliseconds. If `immediate` is passed, trigger the function on the
38045  // leading edge, instead of the trailing.
38046  _.debounce = function(func, wait, immediate) {
38047    var timeout, result;
38048    return function() {
38049      var context = this, args = arguments;
38050      var later = function() {
38051        timeout = null;
38052        if (!immediate) result = func.apply(context, args);
38053      };
38054      var callNow = immediate && !timeout;
38055      clearTimeout(timeout);
38056      timeout = setTimeout(later, wait);
38057      if (callNow) result = func.apply(context, args);
38058      return result;
38059    };
38060  };
38061
38062  // Returns a function that will be executed at most one time, no matter how
38063  // often you call it. Useful for lazy initialization.
38064  _.once = function(func) {
38065    var ran = false, memo;
38066    return function() {
38067      if (ran) return memo;
38068      ran = true;
38069      memo = func.apply(this, arguments);
38070      func = null;
38071      return memo;
38072    };
38073  };
38074
38075  // Returns the first function passed as an argument to the second,
38076  // allowing you to adjust arguments, run code before and after, and
38077  // conditionally execute the original function.
38078  _.wrap = function(func, wrapper) {
38079    return function() {
38080      var args = [func];
38081      push.apply(args, arguments);
38082      return wrapper.apply(this, args);
38083    };
38084  };
38085
38086  // Returns a function that is the composition of a list of functions, each
38087  // consuming the return value of the function that follows.
38088  _.compose = function() {
38089    var funcs = arguments;
38090    return function() {
38091      var args = arguments;
38092      for (var i = funcs.length - 1; i >= 0; i--) {
38093        args = [funcs[i].apply(this, args)];
38094      }
38095      return args[0];
38096    };
38097  };
38098
38099  // Returns a function that will only be executed after being called N times.
38100  _.after = function(times, func) {
38101    if (times <= 0) return func();
38102    return function() {
38103      if (--times < 1) {
38104        return func.apply(this, arguments);
38105      }
38106    };
38107  };
38108
38109  // Object Functions
38110  // ----------------
38111
38112  // Retrieve the names of an object's properties.
38113  // Delegates to **ECMAScript 5**'s native `Object.keys`
38114  _.keys = nativeKeys || function(obj) {
38115    if (obj !== Object(obj)) throw new TypeError('Invalid object');
38116    var keys = [];
38117    for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key;
38118    return keys;
38119  };
38120
38121  // Retrieve the values of an object's properties.
38122  _.values = function(obj) {
38123    var values = [];
38124    for (var key in obj) if (_.has(obj, key)) values.push(obj[key]);
38125    return values;
38126  };
38127
38128  // Convert an object into a list of `[key, value]` pairs.
38129  _.pairs = function(obj) {
38130    var pairs = [];
38131    for (var key in obj) if (_.has(obj, key)) pairs.push([key, obj[key]]);
38132    return pairs;
38133  };
38134
38135  // Invert the keys and values of an object. The values must be serializable.
38136  _.invert = function(obj) {
38137    var result = {};
38138    for (var key in obj) if (_.has(obj, key)) result[obj[key]] = key;
38139    return result;
38140  };
38141
38142  // Return a sorted list of the function names available on the object.
38143  // Aliased as `methods`
38144  _.functions = _.methods = function(obj) {
38145    var names = [];
38146    for (var key in obj) {
38147      if (_.isFunction(obj[key])) names.push(key);
38148    }
38149    return names.sort();
38150  };
38151
38152  // Extend a given object with all the properties in passed-in object(s).
38153  _.extend = function(obj) {
38154    each(slice.call(arguments, 1), function(source) {
38155      if (source) {
38156        for (var prop in source) {
38157          obj[prop] = source[prop];
38158        }
38159      }
38160    });
38161    return obj;
38162  };
38163
38164  // Return a copy of the object only containing the whitelisted properties.
38165  _.pick = function(obj) {
38166    var copy = {};
38167    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
38168    each(keys, function(key) {
38169      if (key in obj) copy[key] = obj[key];
38170    });
38171    return copy;
38172  };
38173
38174   // Return a copy of the object without the blacklisted properties.
38175  _.omit = function(obj) {
38176    var copy = {};
38177    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
38178    for (var key in obj) {
38179      if (!_.contains(keys, key)) copy[key] = obj[key];
38180    }
38181    return copy;
38182  };
38183
38184  // Fill in a given object with default properties.
38185  _.defaults = function(obj) {
38186    each(slice.call(arguments, 1), function(source) {
38187      if (source) {
38188        for (var prop in source) {
38189          if (obj[prop] == null) obj[prop] = source[prop];
38190        }
38191      }
38192    });
38193    return obj;
38194  };
38195
38196  // Create a (shallow-cloned) duplicate of an object.
38197  _.clone = function(obj) {
38198    if (!_.isObject(obj)) return obj;
38199    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
38200  };
38201
38202  // Invokes interceptor with the obj, and then returns obj.
38203  // The primary purpose of this method is to "tap into" a method chain, in
38204  // order to perform operations on intermediate results within the chain.
38205  _.tap = function(obj, interceptor) {
38206    interceptor(obj);
38207    return obj;
38208  };
38209
38210  // Internal recursive comparison function for `isEqual`.
38211  var eq = function(a, b, aStack, bStack) {
38212    // Identical objects are equal. `0 === -0`, but they aren't identical.
38213    // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal.
38214    if (a === b) return a !== 0 || 1 / a == 1 / b;
38215    // A strict comparison is necessary because `null == undefined`.
38216    if (a == null || b == null) return a === b;
38217    // Unwrap any wrapped objects.
38218    if (a instanceof _) a = a._wrapped;
38219    if (b instanceof _) b = b._wrapped;
38220    // Compare `[[Class]]` names.
38221    var className = toString.call(a);
38222    if (className != toString.call(b)) return false;
38223    switch (className) {
38224      // Strings, numbers, dates, and booleans are compared by value.
38225      case '[object String]':
38226        // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
38227        // equivalent to `new String("5")`.
38228        return a == String(b);
38229      case '[object Number]':
38230        // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
38231        // other numeric values.
38232        return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
38233      case '[object Date]':
38234      case '[object Boolean]':
38235        // Coerce dates and booleans to numeric primitive values. Dates are compared by their
38236        // millisecond representations. Note that invalid dates with millisecond representations
38237        // of `NaN` are not equivalent.
38238        return +a == +b;
38239      // RegExps are compared by their source patterns and flags.
38240      case '[object RegExp]':
38241        return a.source == b.source &&
38242               a.global == b.global &&
38243               a.multiline == b.multiline &&
38244               a.ignoreCase == b.ignoreCase;
38245    }
38246    if (typeof a != 'object' || typeof b != 'object') return false;
38247    // Assume equality for cyclic structures. The algorithm for detecting cyclic
38248    // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
38249    var length = aStack.length;
38250    while (length--) {
38251      // Linear search. Performance is inversely proportional to the number of
38252      // unique nested structures.
38253      if (aStack[length] == a) return bStack[length] == b;
38254    }
38255    // Add the first object to the stack of traversed objects.
38256    aStack.push(a);
38257    bStack.push(b);
38258    var size = 0, result = true;
38259    // Recursively compare objects and arrays.
38260    if (className == '[object Array]') {
38261      // Compare array lengths to determine if a deep comparison is necessary.
38262      size = a.length;
38263      result = size == b.length;
38264      if (result) {
38265        // Deep compare the contents, ignoring non-numeric properties.
38266        while (size--) {
38267          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
38268        }
38269      }
38270    } else {
38271      // Objects with different constructors are not equivalent, but `Object`s
38272      // from different frames are.
38273      var aCtor = a.constructor, bCtor = b.constructor;
38274      if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
38275                               _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
38276        return false;
38277      }
38278      // Deep compare objects.
38279      for (var key in a) {
38280        if (_.has(a, key)) {
38281          // Count the expected number of properties.
38282          size++;
38283          // Deep compare each member.
38284          if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
38285        }
38286      }
38287      // Ensure that both objects contain the same number of properties.
38288      if (result) {
38289        for (key in b) {
38290          if (_.has(b, key) && !(size--)) break;
38291        }
38292        result = !size;
38293      }
38294    }
38295    // Remove the first object from the stack of traversed objects.
38296    aStack.pop();
38297    bStack.pop();
38298    return result;
38299  };
38300
38301  // Perform a deep comparison to check if two objects are equal.
38302  _.isEqual = function(a, b) {
38303    return eq(a, b, [], []);
38304  };
38305
38306  // Is a given array, string, or object empty?
38307  // An "empty" object has no enumerable own-properties.
38308  _.isEmpty = function(obj) {
38309    if (obj == null) return true;
38310    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
38311    for (var key in obj) if (_.has(obj, key)) return false;
38312    return true;
38313  };
38314
38315  // Is a given value a DOM element?
38316  _.isElement = function(obj) {
38317    return !!(obj && obj.nodeType === 1);
38318  };
38319
38320  // Is a given value an array?
38321  // Delegates to ECMA5's native Array.isArray
38322  _.isArray = nativeIsArray || function(obj) {
38323    return toString.call(obj) == '[object Array]';
38324  };
38325
38326  // Is a given variable an object?
38327  _.isObject = function(obj) {
38328    return obj === Object(obj);
38329  };
38330
38331  // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.
38332  each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
38333    _['is' + name] = function(obj) {
38334      return toString.call(obj) == '[object ' + name + ']';
38335    };
38336  });
38337
38338  // Define a fallback version of the method in browsers (ahem, IE), where
38339  // there isn't any inspectable "Arguments" type.
38340  if (!_.isArguments(arguments)) {
38341    _.isArguments = function(obj) {
38342      return !!(obj && _.has(obj, 'callee'));
38343    };
38344  }
38345
38346  // Optimize `isFunction` if appropriate.
38347  if (typeof (/./) !== 'function') {
38348    _.isFunction = function(obj) {
38349      return typeof obj === 'function';
38350    };
38351  }
38352
38353  // Is a given object a finite number?
38354  _.isFinite = function(obj) {
38355    return isFinite(obj) && !isNaN(parseFloat(obj));
38356  };
38357
38358  // Is the given value `NaN`? (NaN is the only number which does not equal itself).
38359  _.isNaN = function(obj) {
38360    return _.isNumber(obj) && obj != +obj;
38361  };
38362
38363  // Is a given value a boolean?
38364  _.isBoolean = function(obj) {
38365    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
38366  };
38367
38368  // Is a given value equal to null?
38369  _.isNull = function(obj) {
38370    return obj === null;
38371  };
38372
38373  // Is a given variable undefined?
38374  _.isUndefined = function(obj) {
38375    return obj === void 0;
38376  };
38377
38378  // Shortcut function for checking if an object has a given property directly
38379  // on itself (in other words, not on a prototype).
38380  _.has = function(obj, key) {
38381    return hasOwnProperty.call(obj, key);
38382  };
38383
38384  // Utility Functions
38385  // -----------------
38386
38387  // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
38388  // previous owner. Returns a reference to the Underscore object.
38389  _.noConflict = function() {
38390    root._ = previousUnderscore;
38391    return this;
38392  };
38393
38394  // Keep the identity function around for default iterators.
38395  _.identity = function(value) {
38396    return value;
38397  };
38398
38399  // Run a function **n** times.
38400  _.times = function(n, iterator, context) {
38401    var accum = Array(n);
38402    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
38403    return accum;
38404  };
38405
38406  // Return a random integer between min and max (inclusive).
38407  _.random = function(min, max) {
38408    if (max == null) {
38409      max = min;
38410      min = 0;
38411    }
38412    return min + Math.floor(Math.random() * (max - min + 1));
38413  };
38414
38415  // List of HTML entities for escaping.
38416  var entityMap = {
38417    escape: {
38418      '&': '&amp;',
38419      '<': '&lt;',
38420      '>': '&gt;',
38421      '"': '&quot;',
38422      "'": '&#x27;',
38423      '/': '&#x2F;'
38424    }
38425  };
38426  entityMap.unescape = _.invert(entityMap.escape);
38427
38428  // Regexes containing the keys and values listed immediately above.
38429  var entityRegexes = {
38430    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
38431    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
38432  };
38433
38434  // Functions for escaping and unescaping strings to/from HTML interpolation.
38435  _.each(['escape', 'unescape'], function(method) {
38436    _[method] = function(string) {
38437      if (string == null) return '';
38438      return ('' + string).replace(entityRegexes[method], function(match) {
38439        return entityMap[method][match];
38440      });
38441    };
38442  });
38443
38444  // If the value of the named property is a function then invoke it;
38445  // otherwise, return it.
38446  _.result = function(object, property) {
38447    if (object == null) return null;
38448    var value = object[property];
38449    return _.isFunction(value) ? value.call(object) : value;
38450  };
38451
38452  // Add your own custom functions to the Underscore object.
38453  _.mixin = function(obj) {
38454    each(_.functions(obj), function(name){
38455      var func = _[name] = obj[name];
38456      _.prototype[name] = function() {
38457        var args = [this._wrapped];
38458        push.apply(args, arguments);
38459        return result.call(this, func.apply(_, args));
38460      };
38461    });
38462  };
38463
38464  // Generate a unique integer id (unique within the entire client session).
38465  // Useful for temporary DOM ids.
38466  var idCounter = 0;
38467  _.uniqueId = function(prefix) {
38468    var id = ++idCounter + '';
38469    return prefix ? prefix + id : id;
38470  };
38471
38472  // By default, Underscore uses ERB-style template delimiters, change the
38473  // following template settings to use alternative delimiters.
38474  _.templateSettings = {
38475    evaluate    : /<%([\s\S]+?)%>/g,
38476    interpolate : /<%=([\s\S]+?)%>/g,
38477    escape      : /<%-([\s\S]+?)%>/g
38478  };
38479
38480  // When customizing `templateSettings`, if you don't want to define an
38481  // interpolation, evaluation or escaping regex, we need one that is
38482  // guaranteed not to match.
38483  var noMatch = /(.)^/;
38484
38485  // Certain characters need to be escaped so that they can be put into a
38486  // string literal.
38487  var escapes = {
38488    "'":      "'",
38489    '\\':     '\\',
38490    '\r':     'r',
38491    '\n':     'n',
38492    '\t':     't',
38493    '\u2028': 'u2028',
38494    '\u2029': 'u2029'
38495  };
38496
38497  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
38498
38499  // JavaScript micro-templating, similar to John Resig's implementation.
38500  // Underscore templating handles arbitrary delimiters, preserves whitespace,
38501  // and correctly escapes quotes within interpolated code.
38502  _.template = function(text, data, settings) {
38503    var render;
38504    settings = _.defaults({}, settings, _.templateSettings);
38505
38506    // Combine delimiters into one regular expression via alternation.
38507    var matcher = new RegExp([
38508      (settings.escape || noMatch).source,
38509      (settings.interpolate || noMatch).source,
38510      (settings.evaluate || noMatch).source
38511    ].join('|') + '|$', 'g');
38512
38513    // Compile the template source, escaping string literals appropriately.
38514    var index = 0;
38515    var source = "__p+='";
38516    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
38517      source += text.slice(index, offset)
38518        .replace(escaper, function(match) { return '\\' + escapes[match]; });
38519
38520      if (escape) {
38521        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
38522      }
38523      if (interpolate) {
38524        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
38525      }
38526      if (evaluate) {
38527        source += "';\n" + evaluate + "\n__p+='";
38528      }
38529      index = offset + match.length;
38530      return match;
38531    });
38532    source += "';\n";
38533
38534    // If a variable is not specified, place data values in local scope.
38535    if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
38536
38537    source = "var __t,__p='',__j=Array.prototype.join," +
38538      "print=function(){__p+=__j.call(arguments,'');};\n" +
38539      source + "return __p;\n";
38540
38541    try {
38542      render = new Function(settings.variable || 'obj', '_', source);
38543    } catch (e) {
38544      e.source = source;
38545      throw e;
38546    }
38547
38548    if (data) return render(data, _);
38549    var template = function(data) {
38550      return render.call(this, data, _);
38551    };
38552
38553    // Provide the compiled function source as a convenience for precompilation.
38554    template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
38555
38556    return template;
38557  };
38558
38559  // Add a "chain" function, which will delegate to the wrapper.
38560  _.chain = function(obj) {
38561    return _(obj).chain();
38562  };
38563
38564  // OOP
38565  // ---------------
38566  // If Underscore is called as a function, it returns a wrapped object that
38567  // can be used OO-style. This wrapper holds altered versions of all the
38568  // underscore functions. Wrapped objects may be chained.
38569
38570  // Helper function to continue chaining intermediate results.
38571  var result = function(obj) {
38572    return this._chain ? _(obj).chain() : obj;
38573  };
38574
38575  // Add all of the Underscore functions to the wrapper object.
38576  _.mixin(_);
38577
38578  // Add all mutator Array functions to the wrapper.
38579  each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
38580    var method = ArrayProto[name];
38581    _.prototype[name] = function() {
38582      var obj = this._wrapped;
38583      method.apply(obj, arguments);
38584      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
38585      return result.call(this, obj);
38586    };
38587  });
38588
38589  // Add all accessor Array functions to the wrapper.
38590  each(['concat', 'join', 'slice'], function(name) {
38591    var method = ArrayProto[name];
38592    _.prototype[name] = function() {
38593      return result.call(this, method.apply(this._wrapped, arguments));
38594    };
38595  });
38596
38597  _.extend(_.prototype, {
38598
38599    // Start chaining a wrapped Underscore object.
38600    chain: function() {
38601      this._chain = true;
38602      return this;
38603    },
38604
38605    // Extracts the result from a wrapped and chained object.
38606    value: function() {
38607      return this._wrapped;
38608    }
38609
38610  });
38611
38612}).call(this);
38613//     Backbone.js 0.9.9
38614
38615//     (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
38616//     Backbone may be freely distributed under the MIT license.
38617//     For all details and documentation:
38618//     http://backbonejs.org
38619
38620(function(){
38621
38622  // Initial Setup
38623  // -------------
38624
38625  // Save a reference to the global object (`window` in the browser, `exports`
38626  // on the server).
38627  var root = this;
38628
38629  // Save the previous value of the `Backbone` variable, so that it can be
38630  // restored later on, if `noConflict` is used.
38631  var previousBackbone = root.Backbone;
38632
38633  // Create a local reference to array methods.
38634  var array = [];
38635  var push = array.push;
38636  var slice = array.slice;
38637  var splice = array.splice;
38638
38639  // The top-level namespace. All public Backbone classes and modules will
38640  // be attached to this. Exported for both CommonJS and the browser.
38641  var Backbone;
38642  if (typeof exports !== 'undefined') {
38643    Backbone = exports;
38644  } else {
38645    Backbone = root.Backbone = {};
38646  }
38647
38648  // Current version of the library. Keep in sync with `package.json`.
38649  Backbone.VERSION = '0.9.9';
38650
38651  // Require Underscore, if we're on the server, and it's not already present.
38652  var _ = root._;
38653  if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
38654
38655  // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
38656  Backbone.$ = root.jQuery || root.Zepto || root.ender;
38657
38658  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
38659  // to its previous owner. Returns a reference to this Backbone object.
38660  Backbone.noConflict = function() {
38661    root.Backbone = previousBackbone;
38662    return this;
38663  };
38664
38665  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
38666  // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
38667  // set a `X-Http-Method-Override` header.
38668  Backbone.emulateHTTP = false;
38669
38670  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
38671  // `application/json` requests ... will encode the body as
38672  // `application/x-www-form-urlencoded` instead and will send the model in a
38673  // form param named `model`.
38674  Backbone.emulateJSON = false;
38675
38676  // Backbone.Events
38677  // ---------------
38678
38679  // Regular expression used to split event strings.
38680  var eventSplitter = /\s+/;
38681
38682  // Implement fancy features of the Events API such as multiple event
38683  // names `"change blur"` and jQuery-style event maps `{change: action}`
38684  // in terms of the existing API.
38685  var eventsApi = function(obj, action, name, rest) {
38686    if (!name) return true;
38687    if (typeof name === 'object') {
38688      for (var key in name) {
38689        obj[action].apply(obj, [key, name[key]].concat(rest));
38690      }
38691    } else if (eventSplitter.test(name)) {
38692      var names = name.split(eventSplitter);
38693      for (var i = 0, l = names.length; i < l; i++) {
38694        obj[action].apply(obj, [names[i]].concat(rest));
38695      }
38696    } else {
38697      return true;
38698    }
38699  };
38700
38701  // Optimized internal dispatch function for triggering events. Tries to
38702  // keep the usual cases speedy (most Backbone events have 3 arguments).
38703  var triggerEvents = function(obj, events, args) {
38704    var ev, i = -1, l = events.length;
38705    switch (args.length) {
38706    case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx);
38707    return;
38708    case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0]);
38709    return;
38710    case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1]);
38711    return;
38712    case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, args[0], args[1], args[2]);
38713    return;
38714    default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
38715    }
38716  };
38717
38718  // A module that can be mixed in to *any object* in order to provide it with
38719  // custom events. You may bind with `on` or remove with `off` callback
38720  // functions to an event; `trigger`-ing an event fires all callbacks in
38721  // succession.
38722  //
38723  //     var object = {};
38724  //     _.extend(object, Backbone.Events);
38725  //     object.on('expand', function(){ alert('expanded'); });
38726  //     object.trigger('expand');
38727  //
38728  var Events = Backbone.Events = {
38729
38730    // Bind one or more space separated events, or an events map,
38731    // to a `callback` function. Passing `"all"` will bind the callback to
38732    // all events fired.
38733    on: function(name, callback, context) {
38734      if (!(eventsApi(this, 'on', name, [callback, context]) && callback)) return this;
38735      this._events || (this._events = {});
38736      var list = this._events[name] || (this._events[name] = []);
38737      list.push({callback: callback, context: context, ctx: context || this});
38738      return this;
38739    },
38740
38741    // Bind events to only be triggered a single time. After the first time
38742    // the callback is invoked, it will be removed.
38743    once: function(name, callback, context) {
38744      if (!(eventsApi(this, 'once', name, [callback, context]) && callback)) return this;
38745      var self = this;
38746      var once = _.once(function() {
38747        self.off(name, once);
38748        callback.apply(this, arguments);
38749      });
38750      once._callback = callback;
38751      this.on(name, once, context);
38752      return this;
38753    },
38754
38755    // Remove one or many callbacks. If `context` is null, removes all
38756    // callbacks with that function. If `callback` is null, removes all
38757    // callbacks for the event. If `events` is null, removes all bound
38758    // callbacks for all events.
38759    off: function(name, callback, context) {
38760      var list, ev, events, names, i, l, j, k;
38761      if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
38762      if (!name && !callback && !context) {
38763        this._events = {};
38764        return this;
38765      }
38766
38767      names = name ? [name] : _.keys(this._events);
38768      for (i = 0, l = names.length; i < l; i++) {
38769        name = names[i];
38770        if (list = this._events[name]) {
38771          events = [];
38772          if (callback || context) {
38773            for (j = 0, k = list.length; j < k; j++) {
38774              ev = list[j];
38775              if ((callback && callback !== (ev.callback._callback || ev.callback)) ||
38776                  (context && context !== ev.context)) {
38777                events.push(ev);
38778              }
38779            }
38780          }
38781          this._events[name] = events;
38782        }
38783      }
38784
38785      return this;
38786    },
38787
38788    // Trigger one or many events, firing all bound callbacks. Callbacks are
38789    // passed the same arguments as `trigger` is, apart from the event name
38790    // (unless you're listening on `"all"`, which will cause your callback to
38791    // receive the true name of the event as the first argument).
38792    trigger: function(name) {
38793      if (!this._events) return this;
38794      var args = slice.call(arguments, 1);
38795      if (!eventsApi(this, 'trigger', name, args)) return this;
38796      var events = this._events[name];
38797      var allEvents = this._events.all;
38798      if (events) triggerEvents(this, events, args);
38799      if (allEvents) triggerEvents(this, allEvents, arguments);
38800      return this;
38801    },
38802
38803    // An inversion-of-control version of `on`. Tell *this* object to listen to
38804    // an event in another object ... keeping track of what it's listening to.
38805    listenTo: function(object, events, callback) {
38806      var listeners = this._listeners || (this._listeners = {});
38807      var id = object._listenerId || (object._listenerId = _.uniqueId('l'));
38808      listeners[id] = object;
38809      object.on(events, callback || this, this);
38810      return this;
38811    },
38812
38813    // Tell this object to stop listening to either specific events ... or
38814    // to every object it's currently listening to.
38815    stopListening: function(object, events, callback) {
38816      var listeners = this._listeners;
38817      if (!listeners) return;
38818      if (object) {
38819        object.off(events, callback, this);
38820        if (!events && !callback) delete listeners[object._listenerId];
38821      } else {
38822        for (var id in listeners) {
38823          listeners[id].off(null, null, this);
38824        }
38825        this._listeners = {};
38826      }
38827      return this;
38828    }
38829  };
38830
38831  // Aliases for backwards compatibility.
38832  Events.bind   = Events.on;
38833  Events.unbind = Events.off;
38834
38835  // Allow the `Backbone` object to serve as a global event bus, for folks who
38836  // want global "pubsub" in a convenient place.
38837  _.extend(Backbone, Events);
38838
38839  // Backbone.Model
38840  // --------------
38841
38842  // Create a new model, with defined attributes. A client id (`cid`)
38843  // is automatically generated and assigned for you.
38844  var Model = Backbone.Model = function(attributes, options) {
38845    var defaults;
38846    var attrs = attributes || {};
38847    this.cid = _.uniqueId('c');
38848    this.changed = {};
38849    this.attributes = {};
38850    this._changes = [];
38851    if (options && options.collection) this.collection = options.collection;
38852    if (options && options.parse) attrs = this.parse(attrs);
38853    if (defaults = _.result(this, 'defaults')) _.defaults(attrs, defaults);
38854    this.set(attrs, {silent: true});
38855    this._currentAttributes = _.clone(this.attributes);
38856    this._previousAttributes = _.clone(this.attributes);
38857    this.initialize.apply(this, arguments);
38858  };
38859
38860  // Attach all inheritable methods to the Model prototype.
38861  _.extend(Model.prototype, Events, {
38862
38863    // A hash of attributes whose current and previous value differ.
38864    changed: null,
38865
38866    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
38867    // CouchDB users may want to set this to `"_id"`.
38868    idAttribute: 'id',
38869
38870    // Initialize is an empty function by default. Override it with your own
38871    // initialization logic.
38872    initialize: function(){},
38873
38874    // Return a copy of the model's `attributes` object.
38875    toJSON: function(options) {
38876      return _.clone(this.attributes);
38877    },
38878
38879    // Proxy `Backbone.sync` by default.
38880    sync: function() {
38881      return Backbone.sync.apply(this, arguments);
38882    },
38883
38884    // Get the value of an attribute.
38885    get: function(attr) {
38886      return this.attributes[attr];
38887    },
38888
38889    // Get the HTML-escaped value of an attribute.
38890    escape: function(attr) {
38891      return _.escape(this.get(attr));
38892    },
38893
38894    // Returns `true` if the attribute contains a value that is not null
38895    // or undefined.
38896    has: function(attr) {
38897      return this.get(attr) != null;
38898    },
38899
38900    // Set a hash of model attributes on the object, firing `"change"` unless
38901    // you choose to silence it.
38902    set: function(key, val, options) {
38903      var attr, attrs;
38904      if (key == null) return this;
38905
38906      // Handle both `"key", value` and `{key: value}` -style arguments.
38907      if (_.isObject(key)) {
38908        attrs = key;
38909        options = val;
38910      } else {
38911        (attrs = {})[key] = val;
38912      }
38913
38914      // Extract attributes and options.
38915      var silent = options && options.silent;
38916      var unset = options && options.unset;
38917
38918      // Run validation.
38919      if (!this._validate(attrs, options)) return false;
38920
38921      // Check for changes of `id`.
38922      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
38923
38924      var now = this.attributes;
38925
38926      // For each `set` attribute...
38927      for (attr in attrs) {
38928        val = attrs[attr];
38929
38930        // Update or delete the current value, and track the change.
38931        unset ? delete now[attr] : now[attr] = val;
38932        this._changes.push(attr, val);
38933      }
38934
38935      // Signal that the model's state has potentially changed, and we need
38936      // to recompute the actual changes.
38937      this._hasComputed = false;
38938
38939      // Fire the `"change"` events.
38940      if (!silent) this.change(options);
38941      return this;
38942    },
38943
38944    // Remove an attribute from the model, firing `"change"` unless you choose
38945    // to silence it. `unset` is a noop if the attribute doesn't exist.
38946    unset: function(attr, options) {
38947      return this.set(attr, void 0, _.extend({}, options, {unset: true}));
38948    },
38949
38950    // Clear all attributes on the model, firing `"change"` unless you choose
38951    // to silence it.
38952    clear: function(options) {
38953      var attrs = {};
38954      for (var key in this.attributes) attrs[key] = void 0;
38955      return this.set(attrs, _.extend({}, options, {unset: true}));
38956    },
38957
38958    // Fetch the model from the server. If the server's representation of the
38959    // model differs from its current attributes, they will be overriden,
38960    // triggering a `"change"` event.
38961    fetch: function(options) {
38962      options = options ? _.clone(options) : {};
38963      if (options.parse === void 0) options.parse = true;
38964      var model = this;
38965      var success = options.success;
38966      options.success = function(resp, status, xhr) {
38967        if (!model.set(model.parse(resp), options)) return false;
38968        if (success) success(model, resp, options);
38969      };
38970      return this.sync('read', this, options);
38971    },
38972
38973    // Set a hash of model attributes, and sync the model to the server.
38974    // If the server returns an attributes hash that differs, the model's
38975    // state will be `set` again.
38976    save: function(key, val, options) {
38977      var attrs, current, done;
38978
38979      // Handle both `"key", value` and `{key: value}` -style arguments.
38980      if (key == null || _.isObject(key)) {
38981        attrs = key;
38982        options = val;
38983      } else if (key != null) {
38984        (attrs = {})[key] = val;
38985      }
38986      options = options ? _.clone(options) : {};
38987
38988      // If we're "wait"-ing to set changed attributes, validate early.
38989      if (options.wait) {
38990        if (attrs && !this._validate(attrs, options)) return false;
38991        current = _.clone(this.attributes);
38992      }
38993
38994      // Regular saves `set` attributes before persisting to the server.
38995      var silentOptions = _.extend({}, options, {silent: true});
38996      if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
38997        return false;
38998      }
38999
39000      // Do not persist invalid models.
39001      if (!attrs && !this._validate(null, options)) return false;
39002
39003      // After a successful server-side save, the client is (optionally)
39004      // updated with the server-side state.
39005      var model = this;
39006      var success = options.success;
39007      options.success = function(resp, status, xhr) {
39008        done = true;
39009        var serverAttrs = model.parse(resp);
39010        if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
39011        if (!model.set(serverAttrs, options)) return false;
39012        if (success) success(model, resp, options);
39013      };
39014
39015      // Finish configuring and sending the Ajax request.
39016      var method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
39017      if (method == 'patch') options.attrs = attrs;
39018      var xhr = this.sync(method, this, options);
39019
39020      // When using `wait`, reset attributes to original values unless
39021      // `success` has been called already.
39022      if (!done && options.wait) {
39023        this.clear(silentOptions);
39024        this.set(current, silentOptions);
39025      }
39026
39027      return xhr;
39028    },
39029
39030    // Destroy this model on the server if it was already persisted.
39031    // Optimistically removes the model from its collection, if it has one.
39032    // If `wait: true` is passed, waits for the server to respond before removal.
39033    destroy: function(options) {
39034      options = options ? _.clone(options) : {};
39035      var model = this;
39036      var success = options.success;
39037
39038      var destroy = function() {
39039        model.trigger('destroy', model, model.collection, options);
39040      };
39041
39042      options.success = function(resp) {
39043        if (options.wait || model.isNew()) destroy();
39044        if (success) success(model, resp, options);
39045      };
39046
39047      if (this.isNew()) {
39048        options.success();
39049        return false;
39050      }
39051
39052      var xhr = this.sync('delete', this, options);
39053      if (!options.wait) destroy();
39054      return xhr;
39055    },
39056
39057    // Default URL for the model's representation on the server -- if you're
39058    // using Backbone's restful methods, override this to change the endpoint
39059    // that will be called.
39060    url: function() {
39061      var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
39062      if (this.isNew()) return base;
39063      return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
39064    },
39065
39066    // **parse** converts a response into the hash of attributes to be `set` on
39067    // the model. The default implementation is just to pass the response along.
39068    parse: function(resp) {
39069      return resp;
39070    },
39071
39072    // Create a new model with identical attributes to this one.
39073    clone: function() {
39074      return new this.constructor(this.attributes);
39075    },
39076
39077    // A model is new if it has never been saved to the server, and lacks an id.
39078    isNew: function() {
39079      return this.id == null;
39080    },
39081
39082    // Call this method to manually fire a `"change"` event for this model and
39083    // a `"change:attribute"` event for each changed attribute.
39084    // Calling this will cause all objects observing the model to update.
39085    change: function(options) {
39086      var changing = this._changing;
39087      this._changing = true;
39088
39089      // Generate the changes to be triggered on the model.
39090      var triggers = this._computeChanges(true);
39091
39092      this._pending = !!triggers.length;
39093
39094      for (var i = triggers.length - 2; i >= 0; i -= 2) {
39095        this.trigger('change:' + triggers[i], this, triggers[i + 1], options);
39096      }
39097
39098      if (changing) return this;
39099
39100      // Trigger a `change` while there have been changes.
39101      while (this._pending) {
39102        this._pending = false;
39103        this.trigger('change', this, options);
39104        this._previousAttributes = _.clone(this.attributes);
39105      }
39106
39107      this._changing = false;
39108      return this;
39109    },
39110
39111    // Determine if the model has changed since the last `"change"` event.
39112    // If you specify an attribute name, determine if that attribute has changed.
39113    hasChanged: function(attr) {
39114      if (!this._hasComputed) this._computeChanges();
39115      if (attr == null) return !_.isEmpty(this.changed);
39116      return _.has(this.changed, attr);
39117    },
39118
39119    // Return an object containing all the attributes that have changed, or
39120    // false if there are no changed attributes. Useful for determining what
39121    // parts of a view need to be updated and/or what attributes need to be
39122    // persisted to the server. Unset attributes will be set to undefined.
39123    // You can also pass an attributes object to diff against the model,
39124    // determining if there *would be* a change.
39125    changedAttributes: function(diff) {
39126      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
39127      var val, changed = false, old = this._previousAttributes;
39128      for (var attr in diff) {
39129        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
39130        (changed || (changed = {}))[attr] = val;
39131      }
39132      return changed;
39133    },
39134
39135    // Looking at the built up list of `set` attribute changes, compute how
39136    // many of the attributes have actually changed. If `loud`, return a
39137    // boiled-down list of only the real changes.
39138    _computeChanges: function(loud) {
39139      this.changed = {};
39140      var already = {};
39141      var triggers = [];
39142      var current = this._currentAttributes;
39143      var changes = this._changes;
39144
39145      // Loop through the current queue of potential model changes.
39146      for (var i = changes.length - 2; i >= 0; i -= 2) {
39147        var key = changes[i], val = changes[i + 1];
39148        if (already[key]) continue;
39149        already[key] = true;
39150
39151        // Check if the attribute has been modified since the last change,
39152        // and update `this.changed` accordingly. If we're inside of a `change`
39153        // call, also add a trigger to the list.
39154        if (current[key] !== val) {
39155          this.changed[key] = val;
39156          if (!loud) continue;
39157          triggers.push(key, val);
39158          current[key] = val;
39159        }
39160      }
39161      if (loud) this._changes = [];
39162
39163      // Signals `this.changed` is current to prevent duplicate calls from `this.hasChanged`.
39164      this._hasComputed = true;
39165      return triggers;
39166    },
39167
39168    // Get the previous value of an attribute, recorded at the time the last
39169    // `"change"` event was fired.
39170    previous: function(attr) {
39171      if (attr == null || !this._previousAttributes) return null;
39172      return this._previousAttributes[attr];
39173    },
39174
39175    // Get all of the attributes of the model at the time of the previous
39176    // `"change"` event.
39177    previousAttributes: function() {
39178      return _.clone(this._previousAttributes);
39179    },
39180
39181    // Run validation against the next complete set of model attributes,
39182    // returning `true` if all is well. If a specific `error` callback has
39183    // been passed, call that instead of firing the general `"error"` event.
39184    _validate: function(attrs, options) {
39185      if (!this.validate) return true;
39186      attrs = _.extend({}, this.attributes, attrs);
39187      var error = this.validate(attrs, options);
39188      if (!error) return true;
39189      if (options && options.error) options.error(this, error, options);
39190      this.trigger('error', this, error, options);
39191      return false;
39192    }
39193
39194  });
39195
39196  // Backbone.Collection
39197  // -------------------
39198
39199  // Provides a standard collection class for our sets of models, ordered
39200  // or unordered. If a `comparator` is specified, the Collection will maintain
39201  // its models in sort order, as they're added and removed.
39202  var Collection = Backbone.Collection = function(models, options) {
39203    options || (options = {});
39204    if (options.model) this.model = options.model;
39205    if (options.comparator !== void 0) this.comparator = options.comparator;
39206    this._reset();
39207    this.initialize.apply(this, arguments);
39208    if (models) this.reset(models, _.extend({silent: true}, options));
39209  };
39210
39211  // Define the Collection's inheritable methods.
39212  _.extend(Collection.prototype, Events, {
39213
39214    // The default model for a collection is just a **Backbone.Model**.
39215    // This should be overridden in most cases.
39216    model: Model,
39217
39218    // Initialize is an empty function by default. Override it with your own
39219    // initialization logic.
39220    initialize: function(){},
39221
39222    // The JSON representation of a Collection is an array of the
39223    // models' attributes.
39224    toJSON: function(options) {
39225      return this.map(function(model){ return model.toJSON(options); });
39226    },
39227
39228    // Proxy `Backbone.sync` by default.
39229    sync: function() {
39230      return Backbone.sync.apply(this, arguments);
39231    },
39232
39233    // Add a model, or list of models to the set. Pass **silent** to avoid
39234    // firing the `add` event for every new model.
39235    add: function(models, options) {
39236      var i, args, length, model, existing, needsSort;
39237      var at = options && options.at;
39238      var sort = ((options && options.sort) == null ? true : options.sort);
39239      models = _.isArray(models) ? models.slice() : [models];
39240
39241      // Turn bare objects into model references, and prevent invalid models
39242      // from being added.
39243      for (i = models.length - 1; i >= 0; i--) {
39244        if(!(model = this._prepareModel(models[i], options))) {
39245          this.trigger("error", this, models[i], options);
39246          models.splice(i, 1);
39247          continue;
39248        }
39249        models[i] = model;
39250
39251        existing = model.id != null && this._byId[model.id];
39252        // If a duplicate is found, prevent it from being added and
39253        // optionally merge it into the existing model.
39254        if (existing || this._byCid[model.cid]) {
39255          if (options && options.merge && existing) {
39256            existing.set(model.attributes, options);
39257            needsSort = sort;
39258          }
39259          models.splice(i, 1);
39260          continue;
39261        }
39262
39263        // Listen to added models' events, and index models for lookup by
39264        // `id` and by `cid`.
39265        model.on('all', this._onModelEvent, this);
39266        this._byCid[model.cid] = model;
39267        if (model.id != null) this._byId[model.id] = model;
39268      }
39269
39270      // See if sorting is needed, update `length` and splice in new models.
39271      if (models.length) needsSort = sort;
39272      this.length += models.length;
39273      args = [at != null ? at : this.models.length, 0];
39274      push.apply(args, models);
39275      splice.apply(this.models, args);
39276
39277      // Sort the collection if appropriate.
39278      if (needsSort && this.comparator && at == null) this.sort({silent: true});
39279
39280      if (options && options.silent) return this;
39281
39282      // Trigger `add` events.
39283      while (model = models.shift()) {
39284        model.trigger('add', model, this, options);
39285      }
39286
39287      return this;
39288    },
39289
39290    // Remove a model, or a list of models from the set. Pass silent to avoid
39291    // firing the `remove` event for every model removed.
39292    remove: function(models, options) {
39293      var i, l, index, model;
39294      options || (options = {});
39295      models = _.isArray(models) ? models.slice() : [models];
39296      for (i = 0, l = models.length; i < l; i++) {
39297        model = this.get(models[i]);
39298        if (!model) continue;
39299        delete this._byId[model.id];
39300        delete this._byCid[model.cid];
39301        index = this.indexOf(model);
39302        this.models.splice(index, 1);
39303        this.length--;
39304        if (!options.silent) {
39305          options.index = index;
39306          model.trigger('remove', model, this, options);
39307        }
39308        this._removeReference(model);
39309      }
39310      return this;
39311    },
39312
39313    // Add a model to the end of the collection.
39314    push: function(model, options) {
39315      model = this._prepareModel(model, options);
39316      this.add(model, _.extend({at: this.length}, options));
39317      return model;
39318    },
39319
39320    // Remove a model from the end of the collection.
39321    pop: function(options) {
39322      var model = this.at(this.length - 1);
39323      this.remove(model, options);
39324      return model;
39325    },
39326
39327    // Add a model to the beginning of the collection.
39328    unshift: function(model, options) {
39329      model = this._prepareModel(model, options);
39330      this.add(model, _.extend({at: 0}, options));
39331      return model;
39332    },
39333
39334    // Remove a model from the beginning of the collection.
39335    shift: function(options) {
39336      var model = this.at(0);
39337      this.remove(model, options);
39338      return model;
39339    },
39340
39341    // Slice out a sub-array of models from the collection.
39342    slice: function(begin, end) {
39343      return this.models.slice(begin, end);
39344    },
39345
39346    // Get a model from the set by id.
39347    get: function(obj) {
39348      if (obj == null) return void 0;
39349      return this._byId[obj.id != null ? obj.id : obj] || this._byCid[obj.cid || obj];
39350    },
39351
39352    // Get the model at the given index.
39353    at: function(index) {
39354      return this.models[index];
39355    },
39356
39357    // Return models with matching attributes. Useful for simple cases of `filter`.
39358    where: function(attrs) {
39359      if (_.isEmpty(attrs)) return [];
39360      return this.filter(function(model) {
39361        for (var key in attrs) {
39362          if (attrs[key] !== model.get(key)) return false;
39363        }
39364        return true;
39365      });
39366    },
39367
39368    // Force the collection to re-sort itself. You don't need to call this under
39369    // normal circumstances, as the set will maintain sort order as each item
39370    // is added.
39371    sort: function(options) {
39372      if (!this.comparator) {
39373        throw new Error('Cannot sort a set without a comparator');
39374      }
39375
39376      if (_.isString(this.comparator) || this.comparator.length === 1) {
39377        this.models = this.sortBy(this.comparator, this);
39378      } else {
39379        this.models.sort(_.bind(this.comparator, this));
39380      }
39381
39382      if (!options || !options.silent) this.trigger('sort', this, options);
39383      return this;
39384    },
39385
39386    // Pluck an attribute from each model in the collection.
39387    pluck: function(attr) {
39388      return _.invoke(this.models, 'get', attr);
39389    },
39390
39391    // Smartly update a collection with a change set of models, adding,
39392    // removing, and merging as necessary.
39393    update: function(models, options) {
39394      var model, i, l, existing;
39395      var add = [], remove = [], modelMap = {};
39396      var idAttr = this.model.prototype.idAttribute;
39397      options = _.extend({add: true, merge: true, remove: true}, options);
39398      if (options.parse) models = this.parse(models);
39399
39400      // Allow a single model (or no argument) to be passed.
39401      if (!_.isArray(models)) models = models ? [models] : [];
39402
39403      // Proxy to `add` for this case, no need to iterate...
39404      if (options.add && !options.remove) return this.add(models, options);
39405
39406      // Determine which models to add and merge, and which to remove.
39407      for (i = 0, l = models.length; i < l; i++) {
39408        model = models[i];
39409        existing = this.get(model.id || model.cid || model[idAttr]);
39410        if (options.remove && existing) modelMap[existing.cid] = true;
39411        if ((options.add && !existing) || (options.merge && existing)) {
39412          add.push(model);
39413        }
39414      }
39415      if (options.remove) {
39416        for (i = 0, l = this.models.length; i < l; i++) {
39417          model = this.models[i];
39418          if (!modelMap[model.cid]) remove.push(model);
39419        }
39420      }
39421
39422      // Remove models (if applicable) before we add and merge the rest.
39423      if (remove.length) this.remove(remove, options);
39424      if (add.length) this.add(add, options);
39425      return this;
39426    },
39427
39428    // When you have more items than you want to add or remove individually,
39429    // you can reset the entire set with a new list of models, without firing
39430    // any `add` or `remove` events. Fires `reset` when finished.
39431    reset: function(models, options) {
39432      options || (options = {});
39433      if (options.parse) models = this.parse(models);
39434      for (var i = 0, l = this.models.length; i < l; i++) {
39435        this._removeReference(this.models[i]);
39436      }
39437      options.previousModels = this.models;
39438      this._reset();
39439      if (models) this.add(models, _.extend({silent: true}, options));
39440      if (!options.silent) this.trigger('reset', this, options);
39441      return this;
39442    },
39443
39444    // Fetch the default set of models for this collection, resetting the
39445    // collection when they arrive. If `add: true` is passed, appends the
39446    // models to the collection instead of resetting.
39447    fetch: function(options) {
39448      options = options ? _.clone(options) : {};
39449      if (options.parse === void 0) options.parse = true;
39450      var collection = this;
39451      var success = options.success;
39452      options.success = function(resp, status, xhr) {
39453        var method = options.update ? 'update' : 'reset';
39454        collection[method](resp, options);
39455        if (success) success(collection, resp, options);
39456      };
39457      return this.sync('read', this, options);
39458    },
39459
39460    // Create a new instance of a model in this collection. Add the model to the
39461    // collection immediately, unless `wait: true` is passed, in which case we
39462    // wait for the server to agree.
39463    create: function(model, options) {
39464      var collection = this;
39465      options = options ? _.clone(options) : {};
39466      model = this._prepareModel(model, options);
39467      if (!model) return false;
39468      if (!options.wait) collection.add(model, options);
39469      var success = options.success;
39470      options.success = function(model, resp, options) {
39471        if (options.wait) collection.add(model, options);
39472        if (success) success(model, resp, options);
39473      };
39474      model.save(null, options);
39475      return model;
39476    },
39477
39478    // **parse** converts a response into a list of models to be added to the
39479    // collection. The default implementation is just to pass it through.
39480    parse: function(resp) {
39481      return resp;
39482    },
39483
39484    // Create a new collection with an identical list of models as this one.
39485    clone: function() {
39486      return new this.constructor(this.models);
39487    },
39488
39489    // Proxy to _'s chain. Can't be proxied the same way the rest of the
39490    // underscore methods are proxied because it relies on the underscore
39491    // constructor.
39492    chain: function() {
39493      return _(this.models).chain();
39494    },
39495
39496    // Reset all internal state. Called when the collection is reset.
39497    _reset: function() {
39498      this.length = 0;
39499      this.models = [];
39500      this._byId  = {};
39501      this._byCid = {};
39502    },
39503
39504    // Prepare a model or hash of attributes to be added to this collection.
39505    _prepareModel: function(attrs, options) {
39506      if (attrs instanceof Model) {
39507        if (!attrs.collection) attrs.collection = this;
39508        return attrs;
39509      }
39510      options || (options = {});
39511      options.collection = this;
39512      var model = new this.model(attrs, options);
39513      if (!model._validate(attrs, options)) return false;
39514      return model;
39515    },
39516
39517    // Internal method to remove a model's ties to a collection.
39518    _removeReference: function(model) {
39519      if (this === model.collection) delete model.collection;
39520      model.off('all', this._onModelEvent, this);
39521    },
39522
39523    // Internal method called every time a model in the set fires an event.
39524    // Sets need to update their indexes when models change ids. All other
39525    // events simply proxy through. "add" and "remove" events that originate
39526    // in other collections are ignored.
39527    _onModelEvent: function(event, model, collection, options) {
39528      if ((event === 'add' || event === 'remove') && collection !== this) return;
39529      if (event === 'destroy') this.remove(model, options);
39530      if (model && event === 'change:' + model.idAttribute) {
39531        delete this._byId[model.previous(model.idAttribute)];
39532        if (model.id != null) this._byId[model.id] = model;
39533      }
39534      this.trigger.apply(this, arguments);
39535    }
39536
39537  });
39538
39539  // Underscore methods that we want to implement on the Collection.
39540  var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
39541    'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
39542    'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
39543    'max', 'min', 'sortedIndex', 'toArray', 'size', 'first', 'head', 'take',
39544    'initial', 'rest', 'tail', 'last', 'without', 'indexOf', 'shuffle',
39545    'lastIndexOf', 'isEmpty'];
39546
39547  // Mix in each Underscore method as a proxy to `Collection#models`.
39548  _.each(methods, function(method) {
39549    Collection.prototype[method] = function() {
39550      var args = slice.call(arguments);
39551      args.unshift(this.models);
39552      return _[method].apply(_, args);
39553    };
39554  });
39555
39556  // Underscore methods that take a property name as an argument.
39557  var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
39558
39559  // Use attributes instead of properties.
39560  _.each(attributeMethods, function(method) {
39561    Collection.prototype[method] = function(value, context) {
39562      var iterator = _.isFunction(value) ? value : function(model) {
39563        return model.get(value);
39564      };
39565      return _[method](this.models, iterator, context);
39566    };
39567  });
39568
39569  // Backbone.Router
39570  // ---------------
39571
39572  // Routers map faux-URLs to actions, and fire events when routes are
39573  // matched. Creating a new one sets its `routes` hash, if not set statically.
39574  var Router = Backbone.Router = function(options) {
39575    options || (options = {});
39576    if (options.routes) this.routes = options.routes;
39577    this._bindRoutes();
39578    this.initialize.apply(this, arguments);
39579  };
39580
39581  // Cached regular expressions for matching named param parts and splatted
39582  // parts of route strings.
39583  var optionalParam = /\((.*?)\)/g;
39584  var namedParam    = /:\w+/g;
39585  var splatParam    = /\*\w+/g;
39586  var escapeRegExp  = /[\-{}\[\]+?.,\\\^$|#\s]/g;
39587
39588  // Set up all inheritable **Backbone.Router** properties and methods.
39589  _.extend(Router.prototype, Events, {
39590
39591    // Initialize is an empty function by default. Override it with your own
39592    // initialization logic.
39593    initialize: function(){},
39594
39595    // Manually bind a single named route to a callback. For example:
39596    //
39597    //     this.route('search/:query/p:num', 'search', function(query, num) {
39598    //       ...
39599    //     });
39600    //
39601    route: function(route, name, callback) {
39602      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
39603      if (!callback) callback = this[name];
39604      Backbone.history.route(route, _.bind(function(fragment) {
39605        var args = this._extractParameters(route, fragment);
39606        callback && callback.apply(this, args);
39607        this.trigger.apply(this, ['route:' + name].concat(args));
39608        Backbone.history.trigger('route', this, name, args);
39609      }, this));
39610      return this;
39611    },
39612
39613    // Simple proxy to `Backbone.history` to save a fragment into the history.
39614    navigate: function(fragment, options) {
39615      Backbone.history.navigate(fragment, options);
39616      return this;
39617    },
39618
39619    // Bind all defined routes to `Backbone.history`. We have to reverse the
39620    // order of the routes here to support behavior where the most general
39621    // routes can be defined at the bottom of the route map.
39622    _bindRoutes: function() {
39623      if (!this.routes) return;
39624      var route, routes = _.keys(this.routes);
39625      while ((route = routes.pop()) != null) {
39626        this.route(route, this.routes[route]);
39627      }
39628    },
39629
39630    // Convert a route string into a regular expression, suitable for matching
39631    // against the current location hash.
39632    _routeToRegExp: function(route) {
39633      route = route.replace(escapeRegExp, '\\$&')
39634                   .replace(optionalParam, '(?:$1)?')
39635                   .replace(namedParam, '([^\/]+)')
39636                   .replace(splatParam, '(.*?)');
39637      return new RegExp('^' + route + '$');
39638    },
39639
39640    // Given a route, and a URL fragment that it matches, return the array of
39641    // extracted parameters.
39642    _extractParameters: function(route, fragment) {
39643      return route.exec(fragment).slice(1);
39644    }
39645
39646  });
39647
39648  // Backbone.History
39649  // ----------------
39650
39651  // Handles cross-browser history management, based on URL fragments. If the
39652  // browser does not support `onhashchange`, falls back to polling.
39653  var History = Backbone.History = function() {
39654    this.handlers = [];
39655    _.bindAll(this, 'checkUrl');
39656
39657    // #1653 - Ensure that `History` can be used outside of the browser.
39658    if (typeof window !== 'undefined') {
39659      this.location = window.location;
39660      this.history = window.history;
39661    }
39662  };
39663
39664  // Cached regex for stripping a leading hash/slash and trailing space.
39665  var routeStripper = /^[#\/]|\s+$/g;
39666
39667  // Cached regex for stripping leading and trailing slashes.
39668  var rootStripper = /^\/+|\/+$/g;
39669
39670  // Cached regex for detecting MSIE.
39671  var isExplorer = /msie [\w.]+/;
39672
39673  // Cached regex for removing a trailing slash.
39674  var trailingSlash = /\/$/;
39675
39676  // Has the history handling already been started?
39677  History.started = false;
39678
39679  // Set up all inheritable **Backbone.History** properties and methods.
39680  _.extend(History.prototype, Events, {
39681
39682    // The default interval to poll for hash changes, if necessary, is
39683    // twenty times a second.
39684    interval: 50,
39685
39686    // Gets the true hash value. Cannot use location.hash directly due to bug
39687    // in Firefox where location.hash will always be decoded.
39688    getHash: function(window) {
39689      var match = (window || this).location.href.match(/#(.*)$/);
39690      return match ? match[1] : '';
39691    },
39692
39693    // Get the cross-browser normalized URL fragment, either from the URL,
39694    // the hash, or the override.
39695    getFragment: function(fragment, forcePushState) {
39696      if (fragment == null) {
39697        if (this._hasPushState || !this._wantsHashChange || forcePushState) {
39698          fragment = this.location.pathname;
39699          var root = this.root.replace(trailingSlash, '');
39700          if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
39701        } else {
39702          fragment = this.getHash();
39703        }
39704      }
39705      return fragment.replace(routeStripper, '');
39706    },
39707
39708    // Start the hash change handling, returning `true` if the current URL matches
39709    // an existing route, and `false` otherwise.
39710    start: function(options) {
39711      if (History.started) throw new Error("Backbone.history has already been started");
39712      History.started = true;
39713
39714      // Figure out the initial configuration. Do we need an iframe?
39715      // Is pushState desired ... is it available?
39716      this.options          = _.extend({}, {root: '/'}, this.options, options);
39717      this.root             = this.options.root;
39718      this._wantsHashChange = this.options.hashChange !== false;
39719      this._wantsPushState  = !!this.options.pushState;
39720      this._hasPushState    = !!(this.options.pushState && this.history && this.history.pushState);
39721      var fragment          = this.getFragment();
39722      var docMode           = document.documentMode;
39723      var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
39724
39725      // Normalize root to always include a leading and trailing slash.
39726      this.root = ('/' + this.root + '/').replace(rootStripper, '/');
39727
39728      if (oldIE && this._wantsHashChange) {
39729        this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
39730        this.navigate(fragment);
39731      }
39732
39733      // Depending on whether we're using pushState or hashes, and whether
39734      // 'onhashchange' is supported, determine how we check the URL state.
39735      if (this._hasPushState) {
39736        Backbone.$(window).bind('popstate', this.checkUrl);
39737      } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
39738        Backbone.$(window).bind('hashchange', this.checkUrl);
39739      } else if (this._wantsHashChange) {
39740        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
39741      }
39742
39743      // Determine if we need to change the base url, for a pushState link
39744      // opened by a non-pushState browser.
39745      this.fragment = fragment;
39746      var loc = this.location;
39747      var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
39748
39749      // If we've started off with a route from a `pushState`-enabled browser,
39750      // but we're currently in a browser that doesn't support it...
39751      if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
39752        this.fragment = this.getFragment(null, true);
39753        this.location.replace(this.root + this.location.search + '#' + this.fragment);
39754        // Return immediately as browser will do redirect to new url
39755        return true;
39756
39757      // Or if we've started out with a hash-based route, but we're currently
39758      // in a browser where it could be `pushState`-based instead...
39759      } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
39760        this.fragment = this.getHash().replace(routeStripper, '');
39761        this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
39762      }
39763
39764      if (!this.options.silent) return this.loadUrl();
39765    },
39766
39767    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
39768    // but possibly useful for unit testing Routers.
39769    stop: function() {
39770      Backbone.$(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
39771      clearInterval(this._checkUrlInterval);
39772      History.started = false;
39773    },
39774
39775    // Add a route to be tested when the fragment changes. Routes added later
39776    // may override previous routes.
39777    route: function(route, callback) {
39778      this.handlers.unshift({route: route, callback: callback});
39779    },
39780
39781    // Checks the current URL to see if it has changed, and if it has,
39782    // calls `loadUrl`, normalizing across the hidden iframe.
39783    checkUrl: function(e) {
39784      var current = this.getFragment();
39785      if (current === this.fragment && this.iframe) {
39786        current = this.getFragment(this.getHash(this.iframe));
39787      }
39788      if (current === this.fragment) return false;
39789      if (this.iframe) this.navigate(current);
39790      this.loadUrl() || this.loadUrl(this.getHash());
39791    },
39792
39793    // Attempt to load the current URL fragment. If a route succeeds with a
39794    // match, returns `true`. If no defined routes matches the fragment,
39795    // returns `false`.
39796    loadUrl: function(fragmentOverride) {
39797      var fragment = this.fragment = this.getFragment(fragmentOverride);
39798      var matched = _.any(this.handlers, function(handler) {
39799        if (handler.route.test(fragment)) {
39800          handler.callback(fragment);
39801          return true;
39802        }
39803      });
39804      return matched;
39805    },
39806
39807    // Save a fragment into the hash history, or replace the URL state if the
39808    // 'replace' option is passed. You are responsible for properly URL-encoding
39809    // the fragment in advance.
39810    //
39811    // The options object can contain `trigger: true` if you wish to have the
39812    // route callback be fired (not usually desirable), or `replace: true`, if
39813    // you wish to modify the current URL without adding an entry to the history.
39814    navigate: function(fragment, options) {
39815      if (!History.started) return false;
39816      if (!options || options === true) options = {trigger: options};
39817      fragment = this.getFragment(fragment || '');
39818      if (this.fragment === fragment) return;
39819      this.fragment = fragment;
39820      var url = this.root + fragment;
39821
39822      // If pushState is available, we use it to set the fragment as a real URL.
39823      if (this._hasPushState) {
39824        this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
39825
39826      // If hash changes haven't been explicitly disabled, update the hash
39827      // fragment to store history.
39828      } else if (this._wantsHashChange) {
39829        this._updateHash(this.location, fragment, options.replace);
39830        if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
39831          // Opening and closing the iframe tricks IE7 and earlier to push a
39832          // history entry on hash-tag change.  When replace is true, we don't
39833          // want this.
39834          if(!options.replace) this.iframe.document.open().close();
39835          this._updateHash(this.iframe.location, fragment, options.replace);
39836        }
39837
39838      // If you've told us that you explicitly don't want fallback hashchange-
39839      // based history, then `navigate` becomes a page refresh.
39840      } else {
39841        return this.location.assign(url);
39842      }
39843      if (options.trigger) this.loadUrl(fragment);
39844    },
39845
39846    // Update the hash location, either replacing the current entry, or adding
39847    // a new one to the browser history.
39848    _updateHash: function(location, fragment, replace) {
39849      if (replace) {
39850        var href = location.href.replace(/(javascript:|#).*$/, '');
39851        location.replace(href + '#' + fragment);
39852      } else {
39853        // #1649 - Some browsers require that `hash` contains a leading #.
39854        location.hash = '#' + fragment;
39855      }
39856    }
39857
39858  });
39859
39860  // Create the default Backbone.history.
39861  Backbone.history = new History;
39862
39863  // Backbone.View
39864  // -------------
39865
39866  // Creating a Backbone.View creates its initial element outside of the DOM,
39867  // if an existing element is not provided...
39868  var View = Backbone.View = function(options) {
39869    this.cid = _.uniqueId('view');
39870    this._configure(options || {});
39871    this._ensureElement();
39872    this.initialize.apply(this, arguments);
39873    this.delegateEvents();
39874  };
39875
39876  // Cached regex to split keys for `delegate`.
39877  var delegateEventSplitter = /^(\S+)\s*(.*)$/;
39878
39879  // List of view options to be merged as properties.
39880  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
39881
39882  // Set up all inheritable **Backbone.View** properties and methods.
39883  _.extend(View.prototype, Events, {
39884
39885    // The default `tagName` of a View's element is `"div"`.
39886    tagName: 'div',
39887
39888    // jQuery delegate for element lookup, scoped to DOM elements within the
39889    // current view. This should be prefered to global lookups where possible.
39890    $: function(selector) {
39891      return this.$el.find(selector);
39892    },
39893
39894    // Initialize is an empty function by default. Override it with your own
39895    // initialization logic.
39896    initialize: function(){},
39897
39898    // **render** is the core function that your view should override, in order
39899    // to populate its element (`this.el`), with the appropriate HTML. The
39900    // convention is for **render** to always return `this`.
39901    render: function() {
39902      return this;
39903    },
39904
39905    // Remove this view by taking the element out of the DOM, and removing any
39906    // applicable Backbone.Events listeners.
39907    remove: function() {
39908      this.$el.remove();
39909      this.stopListening();
39910      return this;
39911    },
39912
39913    // For small amounts of DOM Elements, where a full-blown template isn't
39914    // needed, use **make** to manufacture elements, one at a time.
39915    //
39916    //     var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
39917    //
39918    make: function(tagName, attributes, content) {
39919      var el = document.createElement(tagName);
39920      if (attributes) Backbone.$(el).attr(attributes);
39921      if (content != null) Backbone.$(el).html(content);
39922      return el;
39923    },
39924
39925    // Change the view's element (`this.el` property), including event
39926    // re-delegation.
39927    setElement: function(element, delegate) {
39928      if (this.$el) this.undelegateEvents();
39929      this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
39930      this.el = this.$el[0];
39931      if (delegate !== false) this.delegateEvents();
39932      return this;
39933    },
39934
39935    // Set callbacks, where `this.events` is a hash of
39936    //
39937    // *{"event selector": "callback"}*
39938    //
39939    //     {
39940    //       'mousedown .title':  'edit',
39941    //       'click .button':     'save'
39942    //       'click .open':       function(e) { ... }
39943    //     }
39944    //
39945    // pairs. Callbacks will be bound to the view, with `this` set properly.
39946    // Uses event delegation for efficiency.
39947    // Omitting the selector binds the event to `this.el`.
39948    // This only works for delegate-able events: not `focus`, `blur`, and
39949    // not `change`, `submit`, and `reset` in Internet Explorer.
39950    delegateEvents: function(events) {
39951      if (!(events || (events = _.result(this, 'events')))) return;
39952      this.undelegateEvents();
39953      for (var key in events) {
39954        var method = events[key];
39955        if (!_.isFunction(method)) method = this[events[key]];
39956        if (!method) throw new Error('Method "' + events[key] + '" does not exist');
39957        var match = key.match(delegateEventSplitter);
39958        var eventName = match[1], selector = match[2];
39959        method = _.bind(method, this);
39960        eventName += '.delegateEvents' + this.cid;
39961        if (selector === '') {
39962          this.$el.bind(eventName, method);
39963        } else {
39964          this.$el.delegate(selector, eventName, method);
39965        }
39966      }
39967    },
39968
39969    // Clears all callbacks previously bound to the view with `delegateEvents`.
39970    // You usually don't need to use this, but may wish to if you have multiple
39971    // Backbone views attached to the same DOM element.
39972    undelegateEvents: function() {
39973      this.$el.unbind('.delegateEvents' + this.cid);
39974    },
39975
39976    // Performs the initial configuration of a View with a set of options.
39977    // Keys with special meaning *(model, collection, id, className)*, are
39978    // attached directly to the view.
39979    _configure: function(options) {
39980      if (this.options) options = _.extend({}, _.result(this, 'options'), options);
39981      _.extend(this, _.pick(options, viewOptions));
39982      this.options = options;
39983    },
39984
39985    // Ensure that the View has a DOM element to render into.
39986    // If `this.el` is a string, pass it through `$()`, take the first
39987    // matching element, and re-assign it to `el`. Otherwise, create
39988    // an element from the `id`, `className` and `tagName` properties.
39989    _ensureElement: function() {
39990      if (!this.el) {
39991        var attrs = _.extend({}, _.result(this, 'attributes'));
39992        if (this.id) attrs.id = _.result(this, 'id');
39993        if (this.className) attrs['class'] = _.result(this, 'className');
39994        this.setElement(this.make(_.result(this, 'tagName'), attrs), false);
39995      } else {
39996        this.setElement(_.result(this, 'el'), false);
39997      }
39998    }
39999
40000  });
40001
40002  // Backbone.sync
40003  // -------------
40004
40005  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
40006  var methodMap = {
40007    'create': 'POST',
40008    'update': 'PUT',
40009    'patch':  'PATCH',
40010    'delete': 'DELETE',
40011    'read':   'GET'
40012  };
40013
40014  // Override this function to change the manner in which Backbone persists
40015  // models to the server. You will be passed the type of request, and the
40016  // model in question. By default, makes a RESTful Ajax request
40017  // to the model's `url()`. Some possible customizations could be:
40018  //
40019  // * Use `setTimeout` to batch rapid-fire updates into a single request.
40020  // * Send up the models as XML instead of JSON.
40021  // * Persist models via WebSockets instead of Ajax.
40022  //
40023  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
40024  // as `POST`, with a `_method` parameter containing the true HTTP method,
40025  // as well as all requests with the body as `application/x-www-form-urlencoded`
40026  // instead of `application/json` with the model in a param named `model`.
40027  // Useful when interfacing with server-side languages like **PHP** that make
40028  // it difficult to read the body of `PUT` requests.
40029  Backbone.sync = function(method, model, options) {
40030    var type = methodMap[method];
40031
40032    // Default options, unless specified.
40033    _.defaults(options || (options = {}), {
40034      emulateHTTP: Backbone.emulateHTTP,
40035      emulateJSON: Backbone.emulateJSON
40036    });
40037
40038    // Default JSON-request options.
40039    var params = {type: type, dataType: 'json'};
40040
40041    // Ensure that we have a URL.
40042    if (!options.url) {
40043      params.url = _.result(model, 'url') || urlError();
40044    }
40045
40046    // Ensure that we have the appropriate request data.
40047    if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
40048      params.contentType = 'application/json';
40049      params.data = JSON.stringify(options.attrs || model.toJSON(options));
40050    }
40051
40052    // For older servers, emulate JSON by encoding the request into an HTML-form.
40053    if (options.emulateJSON) {
40054      params.contentType = 'application/x-www-form-urlencoded';
40055      params.data = params.data ? {model: params.data} : {};
40056    }
40057
40058    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
40059    // And an `X-HTTP-Method-Override` header.
40060    if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
40061      params.type = 'POST';
40062      if (options.emulateJSON) params.data._method = type;
40063      var beforeSend = options.beforeSend;
40064      options.beforeSend = function(xhr) {
40065        xhr.setRequestHeader('X-HTTP-Method-Override', type);
40066        if (beforeSend) return beforeSend.apply(this, arguments);
40067      };
40068    }
40069
40070    // Don't process data on a non-GET request.
40071    if (params.type !== 'GET' && !options.emulateJSON) {
40072      params.processData = false;
40073    }
40074
40075    var success = options.success;
40076    options.success = function(resp, status, xhr) {
40077      if (success) success(resp, status, xhr);
40078      model.trigger('sync', model, resp, options);
40079    };
40080
40081    var error = options.error;
40082    options.error = function(xhr, status, thrown) {
40083      if (error) error(model, xhr, options);
40084      model.trigger('error', model, xhr, options);
40085    };
40086
40087    // Make the request, allowing the user to override any Ajax options.
40088    var xhr = Backbone.ajax(_.extend(params, options));
40089    model.trigger('request', model, xhr, options);
40090    return xhr;
40091  };
40092
40093  // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
40094  Backbone.ajax = function() {
40095    return Backbone.$.ajax.apply(Backbone.$, arguments);
40096  };
40097
40098  // Helpers
40099  // -------
40100
40101  // Helper function to correctly set up the prototype chain, for subclasses.
40102  // Similar to `goog.inherits`, but uses a hash of prototype properties and
40103  // class properties to be extended.
40104  var extend = function(protoProps, staticProps) {
40105    var parent = this;
40106    var child;
40107
40108    // The constructor function for the new subclass is either defined by you
40109    // (the "constructor" property in your `extend` definition), or defaulted
40110    // by us to simply call the parent's constructor.
40111    if (protoProps && _.has(protoProps, 'constructor')) {
40112      child = protoProps.constructor;
40113    } else {
40114      child = function(){ parent.apply(this, arguments); };
40115    }
40116
40117    // Add static properties to the constructor function, if supplied.
40118    _.extend(child, parent, staticProps);
40119
40120    // Set the prototype chain to inherit from `parent`, without calling
40121    // `parent`'s constructor function.
40122    var Surrogate = function(){ this.constructor = child; };
40123    Surrogate.prototype = parent.prototype;
40124    child.prototype = new Surrogate;
40125
40126    // Add prototype properties (instance properties) to the subclass,
40127    // if supplied.
40128    if (protoProps) _.extend(child.prototype, protoProps);
40129
40130    // Set a convenience property in case the parent's prototype is needed
40131    // later.
40132    child.__super__ = parent.prototype;
40133
40134    return child;
40135  };
40136
40137  // Set up inheritance for the model, collection, router, view and history.
40138  Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
40139
40140  // Throw an error when a URL is needed, and none is supplied.
40141  var urlError = function() {
40142    throw new Error('A "url" property or function must be specified');
40143  };
40144
40145}).call(this);
40146(function($) {
40147  var methodMap = {
40148    'create': 'POST',
40149    'update': 'PUT',
40150    'delete': 'DELETE',
40151    'read'  : 'GET'
40152  };
40153  
40154  var getUrl = function(object) {
40155    if (!(object && object.url)) return null;
40156    return _.isFunction(object.url) ? object.url() : object.url;
40157  };
40158  
40159  var urlError = function() {
40160    throw new Error("A 'url' property or function must be specified");
40161  };
40162
40163  Backbone.sync = function(method, model, options) {
40164    var type = methodMap[method];
40165
40166    // Default JSON-request options.
40167    var params = _.extend({
40168      type:         type,
40169      dataType:     'json',
40170      beforeSend: function( xhr ) {
40171        var token = $('meta[name="csrf-token"]').attr('content');
40172        if (token) xhr.setRequestHeader('X-CSRF-Token', token);
40173
40174        model.trigger('sync:start');
40175      }
40176    }, options);
40177
40178    if (!params.url) {
40179      params.url = getUrl(model) || urlError();
40180    }
40181
40182    // Ensure that we have the appropriate request data.
40183    if (!params.data && model && (method == 'create' || method == 'update')) {
40184      params.contentType = 'application/json';
40185
40186      var data = {}
40187
40188      if(model.paramRoot) {
40189        data[model.paramRoot] = model.toJSON();
40190      } else {
40191        data = model.toJSON();
40192      }
40193
40194      params.data = JSON.stringify(data)
40195    }
40196
40197    // Don't process data on a non-GET request.
40198    if (params.type !== 'GET') {
40199      params.processData = false;
40200    }
40201
40202    // Trigger the sync end event
40203    var complete = options.complete;
40204    params.complete = function(jqXHR, textStatus) {
40205      model.trigger('sync:end');
40206      if (complete) complete(jqXHR, textStatus);
40207    };
40208    
40209    // Make the request.
40210    return $.ajax(params);
40211  }
40212  
40213})(jQuery);
40214/**
40215 * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
40216 * 
40217 * Dual licensed under the MIT and GPL licenses. 
40218 * This basically means you can use this code however you want for
40219 * free, but don't claim to have written it yourself!
40220 * Donations always accepted: http://www.JavascriptToolbox.com/donate/
40221 * 
40222 * Please do not link to the .js files on javascripttoolbox.com from
40223 * your site. Copy the files locally to your server instead.
40224 * 
40225 */
40226
40227eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('8.$2m=1.2n;8.Q=u(x){e(x<0||x>9?"":"0")+x};8.1g=B R(\'2o\',\'2p\',\'2l\',\'2k\',\'1z\',\'2g\',\'2h\',\'2i\',\'2j\',\'2q\',\'2r\',\'2y\');8.14=B R(\'2z\',\'2A\',\'2x\',\'2w\',\'1z\',\'2s\',\'2t\',\'2u\',\'2v\',\'2f\',\'2b\',\'1R\');8.1d=B R(\'1W\',\'1Z\',\'1Y\',\'1V\',\'1U\',\'1S\',\'1T\');8.1f=B R(\'1X\',\'2e\',\'20\',\'2c\',\'2d\',\'2a\',\'27\');8.1s=1L;3(!8.C.1c){8.C.1c=u(){b S=7.1y();e(S<16?S+16:S)}}8.1q=u(r,t){3(1e(t)=="1a"||t==f||t==""){b 1D=B R(\'y-M-d\',\'G d, y\',\'G d,y\',\'y-G-d\',\'d-G-y\',\'G d\',\'G-d\',\'d-G\');b 1v=B R(\'M/d/y\',\'M-d-y\',\'M.d.y\',\'M/d\',\'M-d\');b 1t=B R(\'d/M/y\',\'d-M-y\',\'d.M.y\',\'d/M\',\'d-M\');b 1u=B R(1D,8.1s?1v:1t,8.1s?1t:1v);Z(b i=0;i<1u.g;i++){b l=1u[i];Z(b j=0;j<l.g;j++){b d=8.1q(r,l[j]);
402273(d!=f){e d}}}e f};7.1I=u(r){Z(b i=0;i<r.g;i++){3("26".2C(r.U(i))==-1){e 13}}e 1L};7.O=u(1E,i,1i,1C){Z(b x=1C;x>=1i;x--){b 5=1E.T(i,i+x);3(5.g<1i){e f}3(7.1I(5)){e 5}}e f};r=r+"";t=t+"";b o=0;b D=0;b c="";b 5="";b 2T="";b x,y;b A=B 8().1c();b v=1;b I=1;b p=0;b J=0;b L=0;b 10="";W(D<t.g){c=t.U(D);5="";W((t.U(D)==c)&&(D<t.g)){5+=t.U(D++)}3(5=="19"||5=="S"||5=="y"){3(5=="19"){x=4;y=4}3(5=="S"){x=2;y=2}3(5=="y"){x=2;y=4}A=7.O(r,o,x,y);3(A==f){e f}o+=A.g;3(A.g==2){3(A>2V){A=16+(A-0)}q{A=2R+(A-0)}}}q 3(5=="G"||5=="1P"){v=0;b Y=(5=="G"?(8.1g.2O(8.14)):8.14);Z(b i=0;i<Y.g;i++){b 1h=Y[i];3(r.T(o,o+1h.g).V()==1h.V()){v=(i%12)+1;o+=1h.g;1A}}3((v<1)||(v>12)){e f}}q 3(5=="1r"||5=="E"){b Y=(5=="1r"?8.1d:8.1f);Z(b i=0;i<Y.g;i++){b 18=Y[i];3(r.T(o,o+18.g).V()==18.V()){o+=18.g;1A}}}q 3(5=="1o"||5=="M"){v=7.O(r,o,5.g,2);3(v==f||(v<1)||(v>12)){e f}o+=v.g}q 3(5=="1m"||5=="d"){I=7.O(r,o,5.g,2);3(I==f||(I<1)||(I>2E)){e f}o+=I.g}q 3(5=="p"||5=="h"){p=7.O(r,o,5.g,2);3(p==f||(p<1)||(p>12)){e f}o+=p.g}q 3(5=="1k"||5=="H"){p=7.O(r,o,5.g,2);3(p==f||(p<0)||(p>23)){e f}o+=p.g}q 3(5=="1l"||5=="K"){p=7.O(r,o,5.g,2);3(p==f||(p<0)||(p>11)){e f}o+=p.g;p++}q 3(5=="1j"||5=="k"){p=7.O(r,o,5.g,2);3(p==f||(p<1)||(p>24)){e f}o+=p.g;p--}q 3(5=="J"||5=="m"){J=7.O(r,o,5.g,2);3(J==f||(J<0)||(J>1K)){e f}o+=J.g}q 3(5=="L"||5=="s"){L=7.O(r,o,5.g,2);3(L==f||(L<0)||(L>1K)){e f}o+=L.g}q 3(5=="a"){3(r.T(o,o+2).V()=="2J"){10="1w"}q 3(r.T(o,o+2).V()=="2N"){10="1x"}q{e f}o+=2}q{3(r.T(o,o+5.g)!=5){e f}q{o+=5.g}}}3(o!=r.g){e f}3(v==2){3(((A%4==0)&&(A%2M!=0))||(A%2L==0)){3(I>29){e f}}q{3(I>28){e f}}}3((v==4)||(v==6)||(v==9)||(v==11)){3(I>2K){e f}}3(p<12&&10=="1x"){p=p-0+12}q 3(p>11&&10=="1w"){p-=12}e B 8(A,v-1,I,p,J,L)};8.2I=u(r,t){e(8.1q(r,t)!=f)};8.C.2D=u(F){3(F==f){e 13}e(7.P()<F.P())};8.C.2F=u(F){3(F==f){e 13}e(7.P()>F.P())};8.C.2G=u(F){3(F==f){e 13}e(7.P()==F.P())};8.C.2W=u(F){3(F==f){e 13}b 1J=B 8(7.P()).1p();b 1F=B 8(F.P()).1p();e(1J.P()==1F.P())};8.C.t=u(t){t=t+"";b X="";b D=0;b c="";b 5="";b y=7.1y()+"";b M=7.1b()+1;b d=7.1Q();b E=7.15();b H=7.1N();b m=7.1G();b s=7.1H();b 19,S,G,1o,1m,p,h,J,L,10,1k,H,1l,K,1j,k;b n=B 2B();3(y.g<4){y=""+(+y+16)}n["y"]=""+y;n["19"]=y;n["S"]=y.T(2,4);n["M"]=M;n["1o"]=8.Q(M);n["G"]=8.1g[M-1];n["1P"]=8.14[M-1];n["d"]=d;n["1m"]=8.Q(d);n["E"]=8.1f[E];n["1r"]=8.1d[E];n["H"]=H;n["1k"]=8.Q(H);3(H==0){n["h"]=12}q 3(H>12){n["h"]=H-12}q{n["h"]=H}n["p"]=8.Q(n["h"]);n["K"]=n["h"]-1;n["k"]=n["H"]+1;n["1l"]=8.Q(n["K"]);n["1j"]=8.Q(n["k"]);3(H>11){n["a"]="1x"}q{n["a"]="1w"}n["m"]=m;n["J"]=8.Q(m);n["s"]=s;n["L"]=8.Q(s);W(D<t.g){c=t.U(D);5="";W((t.U(D)==c)&&(D<t.g)){5+=t.U(D++)}3(1e(n[5])!="1a"){X=X+n[5]}q{X=X+5}}e X};8.C.2P=u(){e 8.1d[7.15()]};8.C.2H=u(){e 8.1f[7.15()]};8.C.2U=u(){e 8.1g[7.1b()]};8.C.2Q=u(){e 8.14[7.1b()]};8.C.1p=u(){7.1O(0);7.1B(0);7.1M(0);7.2S(0);e 7};8.C.1n=u(N,z){3(1e(N)=="1a"||N==f||1e(z)=="1a"||z==f){e 7}z=+z;3(N==\'y\'){7.25(7.1c()+z)}q 3(N==\'M\'){7.22(7.1b()+z)}q 3(N==\'d\'){7.21(7.1Q()+z)}q 3(N==\'w\'){b 17=(z>0)?1:-1;W(z!=0){7.1n(\'d\',17);W(7.15()==0||7.15()==6){7.1n(\'d\',17)}z-=17}}q 3(N==\'h\'){7.1O(7.1N()+z)}q 3(N==\'m\'){7.1B(7.1G()+z)}q 3(N==\'s\'){7.1M(7.1H()+z)}e 7};',62,183,'|||if||token||this|Date|||var|||return|null|length|||||||value|i_val|hh|else|val||format|function|month||||number|year|new|prototype|i_format||date2|MMM||date|mm||ss||interval|getInt|getTime|LZ|Array|yy|substring|charAt|toLowerCase|while|result|names|for|ampm|||false|monthAbbreviations|getDay|1900|step|day_name|yyyy|undefined|getMonth|getFullYear|dayNames|typeof|dayAbbreviations|monthNames|month_name|minlength|kk|HH|KK|dd|add|MM|clearTime|parseString|EE|preferAmericanFormat|dateFirst|checkList|monthFirst|AM|PM|getYear|May|break|setMinutes|maxlength|generalFormats|str|d2|getMinutes|getSeconds|isInteger|d1|59|true|setSeconds|getHours|setHours|NNN|getDate|Dec|Friday|Saturday|Thursday|Wednesday|Sunday|Sun|Tuesday|Monday|Tue|setDate|setMonth|||setFullYear|1234567890|Sat|||Fri|Nov|Wed|Thu|Mon|Oct|June|July|August|September|April|March|VERSION|02|January|February|October|November|Jun|Jul|Aug|Sep|Apr|Mar|December|Jan|Feb|Object|indexOf|isBefore|31|isAfter|equals|getDayAbbreviation|isValid|am|30|400|100|pm|concat|getDayName|getMonthAbbreviation|2000|
40227setMilliseconds|token2|getMonthName|70|equalsIgnoreTime'.split('|'),0,{}))
40228;
40229/*! Image Map Resizer (imageMapResizer.min.js ) - v1.0.10 - 2019-04-10
40230 *  Desc: Resize HTML imageMap to scaled image.
40231 *  Copyright: (c) 2019 David J. Bradshaw - [email protected]
40232 *  License: MIT
40233 */
40234
40235
40236!function(){"use strict";function r(){function e(){var r={width:u.width/u.naturalWidth,height:u.height/u.naturalHeight},a={width:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-left"),10),height:parseInt(window.getComputedStyle(u,null).getPropertyValue("padding-top"),10)};i.forEach(function(e,t){var n=0;o[t].coords=e.split(",").map(function(e){var t=1==(n=1-n)?"width":"height";return a[t]+Math.floor(Number(e)*r[t])}).join(",")})}function t(e){return e.coords.replace(/ *, */g,",").replace(/ +/g,",")}function n(){clearTimeout(d),d=setTimeout(e,250)}function r(e){return document.querySelector('img[usemap="'+e+'"]')}var a=this,o=null,i=null,u=null,d=null;"function"!=typeof a._resize?(o=a.getElementsByTagName("area"),i=Array.prototype.map.call(o,t),u=r("#"+a.name)||r(a.name),a._resize=e,u.addEventListener("load",e,!1),window.addEventListener("focus",e,!1),window.addEventListener("resize",n,!1),window.addEventListener("readystatechange",e,!1),document.addEventListener("fullscreenchange",e,!1),u.width===u.naturalWidth&&u.height===u.naturalHeight||e()):a._resize()}function e(){function t(e){e&&(!function(e){if(!e.tagName)throw new TypeError("Object is not a valid DOM element");if("MAP"!==e.tagName.toUpperCase())throw new TypeError("Expected <MAP> tag, found <"+e.tagName+">.")}(e),r.call(e),n.push(e))}var n;return function(e){switch(n=[],typeof e){case"undefined":case"string":Array.prototype.forEach.call(document.querySelectorAll(e||"map"),t);break;case"object":t(e);break;default:throw new TypeError("Unexpected data type ("+typeof e+").")}return n}}"function"==typeof define&&define.amd?define([],e):"object"==typeof module&&"object"==typeof module.exports?module.exports=e():window.imageMapResize=e(),"jQuery"in window&&(window.jQuery.fn.imageMapResize=function(){return this.filter("map").each(r).end()})}();
40237
40238/*
40239* jQuery timepicker addon
40240* By: Trent Richardson [http://trentrichardson.com]
40241* Version 0.9.3
40242* Last Modified: 02/05/2011
40243* 
40244* Copyright 2010 Trent Richardson
40245* Dual licensed under the MIT and GPL licenses.
40246* http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
40247* http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
40248* 
40249* HERES THE CSS:
40250* .ui-timepicker-div .ui-widget-header{ margin-bottom: 8px; }
40251* .ui-timepicker-div dl{ text-align: left; }
40252* .ui-timepicker-div dl dt{ height: 25px; }
40253* .ui-timepicker-div dl dd{ margin: -25px 0 10px 65px; }
40254* .ui-timepicker-div td { font-size: 90%; }
40255*/
40256
40257
40258(function($) {
40259
40260$.extend($.ui, { timepicker: { version: "0.9.3" } });
40261
40262/* Time picker manager.
40263   Use the singleton instance of this class, $.timepicker, to interact with the time picker.
40264   Settings for (groups of) time pickers are maintained in an instance object,
40265   allowing multiple different settings on the same page. */
40266
40267function Timepicker() {
40268	this.regional = []; // Available regional settings, indexed by language code
40269	this.regional[''] = { // Default regional settings
40270		currentText: 'Now',
40271		closeText: 'Done',
40272		ampm: false,
40273		timeFormat: 'hh:mm tt',
40274		timeOnlyTitle: 'Choose Time',
40275		timeText: 'Time',
40276		hourText: 'Hour',
40277		minuteText: 'Minute',
40278		secondText: 'Second'
40279	};
40280	this._defaults = { // Global defaults for all the datetime picker instances
40281		showButtonPanel: true,
40282		timeOnly: false,
40283		showHour: true,
40284		showMinute: true,
40285		showSecond: false,
40286		showTime: true,
40287		stepHour: 0.05,
40288		stepMinute: 0.05,
40289		stepSecond: 0.05,
40290		hour: 0,
40291		minute: 0,
40292		second: 0,
40293		hourMin: 0,
40294		minuteMin: 0,
40295		secondMin: 0,
40296		hourMax: 23,
40297		minuteMax: 59,
40298		secondMax: 59,
40299		minDateTime: null,
40300		maxDateTime: null,		
40301		hourGrid: 0,
40302		minuteGrid: 0,
40303		secondGrid: 0,
40304		alwaysSetTime: true,
40305		separator: ' ',
40306		altFieldTimeOnly: true,
40307		showTimepicker: true
40308	};
40309	$.extend(this._defaults, this.regional['']);
40310}
40311
40312$.extend(Timepicker.prototype, {
40313	$input: null,
40314	$altInput: null,
40315	$timeObj: null,
40316	inst: null,
40317	hour_slider: null,
40318	minute_slider: null,
40319	second_slider: null,
40320	hour: 0,
40321	minute: 0,
40322	second: 0,
40323	hourMinOriginal: null,
40324	minuteMinOriginal: null,
40325	secondMinOriginal: null,
40326	hourMaxOriginal: null,
40327	minuteMaxOriginal: null,
40328	secondMaxOriginal: null,
40329	ampm: '',
40330	formattedDate: '',
40331	formattedTime: '',
40332	formattedDateTime: '',
40333
40334	/* Override the default settings for all instances of the time picker.
40335	   @param  settings  object - the new settings to use as defaults (anonymous object)
40336	   @return the manager object */
40337	setDefaults: function(settings) {
40338		extendRemove(this._defaults, settings || {});
40339		return this;
40340	},
40341
40342	//########################################################################
40343	// Create a new Timepicker instance
40344	//########################################################################
40345	_newInst: function($input, o) {
40346		var tp_inst = new Timepicker(),
40347			inlineSettings = {};
40348
40349		tp_inst.hour = tp_inst._defaults.hour;
40350		tp_inst.minute = tp_inst._defaults.minute;
40351		tp_inst.second = tp_inst._defaults.second;
40352		tp_inst.ampm = '';
40353		tp_inst.$input = $input;
40354			
40355
40356		for (var attrName in this._defaults) {
40357			var attrValue = $input.attr('time:' + attrName);
40358			if (attrValue) {
40359				try {
40360					inlineSettings[attrName] = eval(attrValue);
40361				} catch (err) {
40362					inlineSettings[attrName] = attrValue;
40363				}
40364			}
40365		}
40366		tp_inst._defaults = $.extend({}, this._defaults, inlineSettings, o, {
40367			beforeShow: function(input, dp_inst) {			
40368				if ($.isFunction(o.beforeShow))
40369					o.beforeShow(input, dp_inst, tp_inst);
40370			},
40371			onChangeMonthYear: function(year, month, dp_inst) {
40372				// Update the time as well : this prevents the time from disappearing from the $input field.
40373				tp_inst._updateDateTime(dp_inst);
40374				if ($.isFunction(o.onChangeMonthYear))
40375					o.onChangeMonthYear(year, month, dp_inst, tp_inst);
40376			},
40377			onClose: function(dateText, dp_inst) {
40378				if (tp_inst.timeDefined === true && $input.val() != '')
40379					tp_inst._updateDateTime(dp_inst);
40380				if ($.isFunction(o.onClose))
40381					o.onClose(dateText, dp_inst, tp_inst);
40382			},
40383			timepicker: tp_inst // add timepicker as a property of datepicker: $.datepicker._get(dp_inst, 'timepicker');
40384		});
40385
40386		if (o.altField)
40387			tp_inst.$altInput = $(o.altField)
40388				.css({ cursor: 'pointer' })
40389				.focus(function(){ $input.trigger("focus"); });
40390						
40391		// datepicker needs minDate/maxDate, timepicker needs minDateTime/maxDateTime..
40392		if(tp_inst._defaults.minDate !== undefined && tp_inst._defaults.minDate instanceof Date)
40393			tp_inst._defaults.minDateTime = new Date(tp_inst._defaults.minDate.getTime());
40394		if(tp_inst._defaults.minDateTime !== undefined && tp_inst._defaults.minDateTime instanceof Date)
40395			tp_inst._defaults.minDate = new Date(tp_inst._defaults.minDateTime.getTime());
40396		if(tp_inst._defaults.maxDate !== undefined && tp_inst._defaults.maxDate instanceof Date)
40397			tp_inst._defaults.maxDateTime = new Date(tp_inst._defaults.maxDate.getTime());
40398		if(tp_inst._defaults.maxDateTime !== undefined && tp_inst._defaults.maxDateTime instanceof Date)
40399			tp_inst._defaults.maxDate = new Date(tp_inst._defaults.maxDateTime.getTime());
40400			
40401		return tp_inst;
40402	},
40403
40404	//########################################################################
40405	// add our sliders to the calendar
40406	//########################################################################
40407	_addTimePicker: function(dp_inst) {
40408		var currDT = (this.$altInput && this._defaults.altFieldTimeOnly) ?
40409				this.$input.val() + ' ' + this.$altInput.val() : 
40410				this.$input.val();
40411
40412		this.timeDefined = this._parseTime(currDT);
40413		this._limitMinMaxDateTime(dp_inst, false);
40414		this._injectTimePicker();
40415	},
40416
40417	//########################################################################
40418	// parse the time string from input value or _setTime
40419	//########################################################################
40420	_parseTime: function(timeString, withDate) {
40421		var regstr = this._defaults.timeFormat.toString()
40422				.replace(/h{1,2}/ig, '(\\d?\\d)')
40423				.replace(/m{1,2}/ig, '(\\d?\\d)')
40424				.replace(/s{1,2}/ig, '(\\d?\\d)')
40425				.replace(/t{1,2}/ig, '(am|pm|a|p)?')
40426				.replace(/\s/g, '\\s?') + '$',
40427			order = this._getFormatPositions(),
40428			treg;
40429
40430		if (!this.inst) this.inst = $.datepicker._getInst(this.$input[0]);
40431
40432		if (withDate || !this._defaults.timeOnly) {
40433			// the time should come after x number of characters and a space.
40434			// x = at least the length of text specified by the date format
40435			var dp_dateFormat = $.datepicker._get(this.inst, 'dateFormat');
40436			regstr = '.{' + dp_dateFormat.length + ',}' + this._defaults.separator + regstr;
40437		}
40438
40439		treg = timeString.match(new RegExp(regstr, 'i'));
40440
40441		if (treg) {
40442			if (order.t !== -1)
40443				this.ampm = ((treg[order.t] === undefined || treg[order.t].length === 0) ?
40444					'' :
40445					(treg[order.t].charAt(0).toUpperCase() == 'A') ? 'AM' : 'PM').toUpperCase();
40446
40447			if (order.h !== -1) {
40448				if (this.ampm == 'AM' && treg[order.h] == '12') 
40449					this.hour = 0; // 12am = 0 hour
40450				else if (this.ampm == 'PM' && treg[order.h] != '12') 
40451					this.hour = (parseFloat(treg[order.h]) + 12).toFixed(0); // 12pm = 12 hour, any other pm = hour + 12
40452				else this.hour = Number(treg[order.h]);
40453			}
40454
40455			if (order.m !== -1) this.minute = Number(treg[order.m]);
40456			if (order.s !== -1) this.second = Number(treg[order.s]);
40457			
40458			return true;
40459
40460		}
40461		return false;
40462	},
40463
40464	//########################################################################
40465	// figure out position of time elements.. cause js cant do named captures
40466	//########################################################################
40467	_getFormatPositions: function() {
40468		var finds = this._defaults.timeFormat.toLowerCase().match(/(h{1,2}|m{1,2}|s{1,2}|t{1,2})/g),
40469			orders = { h: -1, m: -1, s: -1, t: -1 };
40470
40471		if (finds)
40472			for (var i = 0; i < finds.length; i++)
40473				if (orders[finds[i].toString().charAt(0)] == -1)
40474					orders[finds[i].toString().charAt(0)] = i + 1;
40475
40476		return orders;
40477	},
40478
40479	//########################################################################
40480	// generate and inject html for timepicker into ui datepicker
40481	//########################################################################
40482	_injectTimePicker: function() {
40483		var $dp = this.inst.dpDiv,
40484			o = this._defaults,
40485			tp_inst = this,
40486			// Added by Peter Medeiros:
40487			// - Figure out what the hour/minute/second max should be based on the step values.
40488			// - Example: if stepMinute is 15, then minMax is 45.
40489			hourMax = (o.hourMax - (o.hourMax % o.stepHour)).toFixed(0),
40490			minMax  = (o.minuteMax - (o.minuteMax % o.stepMinute)).toFixed(0),
40491			secMax  = (o.secondMax - (o.secondMax % o.stepSecond)).toFixed(0),
40492			dp_id = this.inst.id.toString().replace(/([^A-Za-z0-9_])/g, '');
40493
40494		// Prevent displaying twice
40495		//if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0) {
40496		if ($dp.find("div#ui-timepicker-div-"+ dp_id).length === 0 && o.showTimepicker) {
40497			var noDisplay = ' style="display:none;"',
40498				html =	'<div class="ui-timepicker-div" id="ui-timepicker-div-' + dp_id + '"><dl>' +
40499						'<dt class="ui_tpicker_time_label" id="ui_tpicker_time_label_' + dp_id + '"' +
40500						((o.showTime) ? '' : noDisplay) + '>' + o.timeText + '</dt>' +
40501						'<dd class="ui_tpicker_time" id="ui_tpicker_time_' + dp_id + '"' +
40502						((o.showTime) ? '' : noDisplay) + '></dd>' +
40503						'<dt class="ui_tpicker_hour_label" id="ui_tpicker_hour_label_' + dp_id + '"' +
40504						((o.showHour) ? '' : noDisplay) + '>' + o.hourText + '</dt>',
40505				hourGridSize = 0,
40506				minuteGridSize = 0,
40507				secondGridSize = 0,
40508				size;
40509 
40510			if (o.showHour && o.hourGrid > 0) {
40511				html += '<dd class="ui_tpicker_hour">' +
40512						'<div id="ui_tpicker_hour_' + dp_id + '"' + ((o.showHour)   ? '' : noDisplay) + '></div>' +
40513						'<div style="padding-left: 1px"><table><tr>';
40514
40515				for (var h = o.hourMin; h < hourMax; h += o.hourGrid) {
40516					hourGridSize++;
40517					var tmph = (o.ampm && h > 12) ? h-12 : h;
40518					if (tmph < 10) tmph = '0' + tmph;
40519					if (o.ampm) {
40520						if (h == 0) tmph = 12 +'a';
40521						else if (h < 12) tmph += 'a';
40522						else tmph += 'p';
40523					}
40524					html += '<td>' + tmph + '</td>';
40525				}
40526
40527				html += '</tr></table></div>' +
40528						'</dd>';
40529			} else html += '<dd class="ui_tpicker_hour" id="ui_tpicker_hour_' + dp_id + '"' +
40530							((o.showHour) ? '' : noDisplay) + '></dd>';
40531
40532			html += '<dt class="ui_tpicker_minute_label" id="ui_tpicker_minute_label_' + dp_id + '"' +
40533					((o.showMinute) ? '' : noDisplay) + '>' + o.minuteText + '</dt>';
40534
40535			if (o.showMinute && o.minuteGrid > 0) {
40536				html += '<dd class="ui_tpicker_minute ui_tpicker_minute_' + o.minuteGrid + '">' +
40537						'<div id="ui_tpicker_minute_' + dp_id + '"' +
40538						((o.showMinute) ? '' : noDisplay) + '></div>' +
40539						'<div style="padding-left: 1px"><table><tr>';
40540
40541				for (var m = o.minuteMin; m < minMax; m += o.minuteGrid) {
40542					minuteGridSize++;
40543					html += '<td>' + ((m < 10) ? '0' : '') + m + '</td>';
40544				}
40545
40546				html += '</tr></table></div>' +
40547						'</dd>';
40548			} else html += '<dd class="ui_tpicker_minute" id="ui_tpicker_minute_' + dp_id + '"' +
40549							((o.showMinute) ? '' : noDisplay) + '></dd>';
40550
40551			html += '<dt class="ui_tpicker_second_label" id="ui_tpicker_second_label_' + dp_id + '"' +
40552					((o.showSecond) ? '' : noDisplay) + '>' + o.secondText + '</dt>';
40553
40554			if (o.showSecond && o.secondGrid > 0) {
40555				html += '<dd class="ui_tpicker_second ui_tpicker_second_' + o.secondGrid + '">' +
40556						'<div id="ui_tpicker_second_' + dp_id + '"' +
40557						((o.showSecond) ? '' : noDisplay) + '></div>' +
40558						'<div style="padding-left: 1px"><table><tr>';
40559
40560				for (var s = o.secondMin; s < secMax; s += o.secondGrid) {
40561					secondGridSize++;
40562					html += '<td>' + ((s < 10) ? '0' : '') + s + '</td>';
40563				}
40564
40565				html += '</tr></table></div>' +
40566						'</dd>';
40567			} else html += '<dd class="ui_tpicker_second" id="ui_tpicker_second_' + dp_id + '"'	+
40568							((o.showSecond) ? '' : noDisplay) + '></dd>';
40569
40570			html += '</dl></div>';
40571			$tp = $(html);
40572
40573				// if we only want time picker...
40574			if (o.timeOnly === true) {
40575				$tp.prepend(
40576					'<div class="ui-widget-header ui-helper-clearfix ui-corner-all">' +
40577						'<div class="ui-datepicker-title">' + o.timeOnlyTitle + '</div>' +
40578					'</div>');
40579				$dp.find('.ui-datepicker-header, .ui-datepicker-calendar').hide();
40580			}
40581
40582			this.hour_slider = $tp.find('#ui_tpicker_hour_'+ dp_id).slider({
40583				orientation: "horizontal",
40584				value: this.hour,
40585				min: o.hourMin,
40586				max: hourMax,
40587				step: o.stepHour,
40588				slide: function(event, ui) {
40589					tp_inst.hour_slider.slider( "option", "value", ui.value);
40590					tp_inst._onTimeChange();
40591				}
40592			});
40593
40594			// Updated by Peter Medeiros:
40595			// - Pass in Event and UI instance into slide function
40596			this.minute_slider = $tp.find('#ui_tpicker_minute_'+ dp_id).slider({
40597				orientation: "horizontal",
40598				value: this.minute,
40599				min: o.minuteMin,
40600				max: minMax,
40601				step: o.stepMinute,
40602				slide: function(event, ui) {
40603					// update the global minute slider instance value with the current slider value
40604					tp_inst.minute_slider.slider( "option", "value", ui.value);
40605					tp_inst._onTimeChange();
40606				}
40607			});
40608
40609			this.second_slider = $tp.find('#ui_tpicker_second_'+ dp_id).slider({
40610				orientation: "horizontal",
40611				value: this.second,
40612				min: o.secondMin,
40613				max: secMax,
40614				step: o.stepSecond,
40615				slide: function(event, ui) {
40616					tp_inst.second_slider.slider( "option", "value", ui.value);
40617					tp_inst._onTimeChange();
40618				}
40619			});
40620
40621			// Add grid functionality
40622			if (o.showHour && o.hourGrid > 0) {
40623				size = 100 * hourGridSize * o.hourGrid / (hourMax - o.hourMin);
40624
40625				$tp.find(".ui_tpicker_hour table").css({
40626					width: size + "%",
40627					marginLeft: (size / (-2 * hourGridSize)) + "%",
40628					borderCollapse: 'collapse'
40629				}).find("td").each( function(index) {
40630					$(this).click(function() {
40631						var h = $(this).html();
40632						if(o.ampm)	{
40633							var ap = h.substring(2).toLowerCase(),
40634								aph = parseInt(h.substring(0,2));
40635							if (ap == 'a') {
40636								if (aph == 12) h = 0;
40637								else h = aph;
40638							} else if (aph == 12) h = 12;
40639							else h = aph + 12;
40640						}
40641						tp_inst.hour_slider.slider("option", "value", h);
40642						tp_inst._onTimeChange();
40643					}).css({
40644						cursor: 'pointer',
40645						width: (100 / hourGridSize) + '%',
40646						textAlign: 'center',
40647						overflow: 'hidden'
40648					});
40649				});
40650			}
40651
40652			if (o.showMinute && o.minuteGrid > 0) {
40653				size = 100 * minuteGridSize * o.minuteGrid / (minMax - o.minuteMin);
40654				$tp.find(".ui_tpicker_minute table").css({
40655					width: size + "%",
40656					marginLeft: (size / (-2 * minuteGridSize)) + "%",
40657					borderCollapse: 'collapse'
40658				}).find("td").each(function(index) {
40659					$(this).click(function() {
40660						tp_inst.minute_slider.slider("option", "value", $(this).html());
40661						tp_inst._onTimeChange();
40662					}).css({
40663						cursor: 'pointer',
40664						width: (100 / minuteGridSize) + '%',
40665						textAlign: 'center',
40666						overflow: 'hidden'
40667					});
40668				});
40669			}
40670
40671			if (o.showSecond && o.secondGrid > 0) {
40672				$tp.find(".ui_tpicker_second table").css({
40673					width: size + "%",
40674					marginLeft: (size / (-2 * secondGridSize)) + "%",
40675					borderCollapse: 'collapse'
40676				}).find("td").each(function(index) {
40677					$(this).click(function() {
40678						tp_inst.second_slider.slider("option", "value", $(this).html());
40679						tp_inst._onTimeChange();
40680					}).css({
40681						cursor: 'pointer',
40682						width: (100 / secondGridSize) + '%',
40683						textAlign: 'center',
40684						overflow: 'hidden'
40685					});
40686				});
40687			}
40688
40689			var $buttonPanel = $dp.find('.ui-datepicker-buttonpane');
40690			if ($buttonPanel.length) $buttonPanel.before($tp);
40691			else $dp.append($tp);
40692
40693			this.$timeObj = $('#ui_tpicker_time_'+ dp_id);
40694
40695			if (this.inst !== null) {
40696				var timeDefined = this.timeDefined;
40697				this._onTimeChange();
40698				this.timeDefined = timeDefined;
40699			}
40700
40701			//Emulate datepicker onSelect behavior. Call on slidestop.
40702			var onSelect = tp_inst._defaults['onSelect'];
40703			if (onSelect) {
40704				var inputEl = tp_inst.$input ? tp_inst.$input[0] : null;
40705				var onSelectHandler = function() {
40706					onSelect.apply(inputEl, [tp_inst.formattedDateTime, tp_inst]); // trigger custom callback*/
40707				}
40708				this.hour_slider.bind('slidestop',onSelectHandler);		
40709				this.minute_slider.bind('slidestop',onSelectHandler);		
40710				this.second_slider.bind('slidestop',onSelectHandler);		
40711			}
40712		}
40713	},
40714
40715	//########################################################################
40716	// This function tries to limit the ability to go outside the 
40717	// min/max date range
40718	//########################################################################
40719	_limitMinMaxDateTime: function(dp_inst, adjustSliders){
40720		var o = this._defaults,
40721			dp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay),
40722			tp_date = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay, this.hour, this.minute, this.second, 0);
40723		
40724		if(this._defaults.minDateTime !== null && dp_date){
40725			var minDateTime = this._defaults.minDateTime,
40726				minDateTimeDate = new Date(minDateTime.getFullYear(), minDateTime.getMonth(), minDateTime.getDate(), 0, 0, 0, 0);
40727			
40728			if(this.hourMinOriginal === null || this.minuteMinOriginal === null || this.secondMinOriginal === null){
40729				this.hourMinOriginal = o.hourMin;
40730				this.minuteMinOriginal = o.minuteMin;
40731				this.secondMinOriginal = o.secondMin;
40732			}
40733		
40734			if(minDateTimeDate.getTime() == dp_date.getTime()){
40735				this._defaults.hourMin = minDateTime.getHours();
40736				this._defaults.minuteMin = minDateTime.getMinutes();
40737				this._defaults.secondMin = minDateTime.getSeconds();
40738
40739				if(this.hour < this._defaults.hourMin) this.hour = this._defaults.hourMin;
40740				if(this.minute < this._defaults.minuteMin) this.minute = this._defaults.minuteMin;
40741				if(this.second < this._defaults.secondMin) this.second = this._defaults.secondMin;
40742			}else{
40743				this._defaults.hourMin = this.hourMinOriginal;
40744				this._defaults.minuteMin = this.minuteMinOriginal;
40745				this._defaults.secondMin = this.secondMinOriginal;
40746			}
40747		}
40748
40749		if(this._defaults.maxDateTime !== null && dp_date){
40750			var maxDateTime = this._defaults.maxDateTime,
40751				maxDateTimeDate = new Date(maxDateTime.getFullYear(), maxDateTime.getMonth(), maxDateTime.getDate(), 0, 0, 0, 0);
40752	
40753			if(this.hourMaxOriginal === null || this.minuteMaxOriginal === null || this.secondMaxOriginal === null){
40754				this.hourMaxOriginal = o.hourMax;
40755				this.minuteMaxOriginal = o.minuteMax;
40756				this.secondMaxOriginal = o.secondMax;
40757			}
40758		
40759			if(maxDateTimeDate.getTime() == dp_date.getTime()){
40760				this._defaults.hourMax = maxDateTime.getHours();
40761				this._defaults.minuteMax = maxDateTime.getMinutes();
40762				this._defaults.secondMax = maxDateTime.getSeconds();
40763				
40764				if(this.hour > this._defaults.hourMax){ this.hour = this._defaults.hourMax; }
40765				if(this.minute > this._defaults.minuteMax) this.minute = this._defaults.minuteMax;
40766				if(this.second > this._defaults.secondMax) this.second = this._defaults.secondMax;
40767			}else{
40768				this._defaults.hourMax = this.hourMaxOriginal;
40769				this._defaults.minuteMax = this.minuteMaxOriginal;
40770				this._defaults.secondMax = this.secondMaxOriginal;
40771			}
40772		}
40773				
40774		if(adjustSliders !== undefined && adjustSliders === true){
40775			this.hour_slider.slider("option", { min: this._defaults.hourMin, max: this._defaults.hourMax }).slider('value', this.hour);
40776			this.minute_slider.slider("option", { min: this._defaults.minuteMin, max: this._defaults.minuteMax }).slider('value', this.minute);
40777			this.second_slider.slider("option", { min: this._defaults.secondMin, max: this._defaults.secondMax }).slider('value', this.second);
40778		}
40779
40780	},
40781	
40782	//########################################################################
40783	// when a slider moves, set the internal time...
40784	// on time change is also called when the time is updated in the text field
40785	//########################################################################
40786	_onTimeChange: function() {
40787		var hour   = (this.hour_slider) ? this.hour_slider.slider('value') : false,
40788			minute = (this.minute_slider) ? this.minute_slider.slider('value') : false,
40789			second = (this.second_slider) ? this.second_slider.slider('value') : false;
40790
40791		if (hour !== false) hour = parseInt(hour,10);
40792		if (minute !== false) minute = parseInt(minute,10);
40793		if (second !== false) second = parseInt(second,10);
40794
40795		var ampm = (hour < 12) ? 'AM' : 'PM';
40796			
40797		// If the update was done in the input field, the input field should not be updated.
40798		// If the update was done using the sliders, update the input field.
40799		var hasChanged = (hour != this.hour || minute != this.minute || second != this.second || (this.ampm.length > 0 && this.ampm != ampm));
40800		
40801		if (hasChanged) {
40802
40803			if (hour !== false)this.hour = hour;
40804			if (minute !== false) this.minute = minute;
40805			if (second !== false) this.second = second;
40806		}
40807		if (this._defaults.ampm) this.ampm = ampm;
40808		
40809		this._formatTime();
40810		if (this.$timeObj) this.$timeObj.text(this.formattedTime);
40811		this.timeDefined = true;
40812		if (hasChanged) this._updateDateTime();
40813	},
40814
40815	//########################################################################
40816	// format the time all pretty...
40817	//########################################################################
40818	_formatTime: function(time, format, ampm) {
40819		if (ampm == undefined) ampm = this._defaults.ampm;
40820		time = time || { hour: this.hour, minute: this.minute, second: this.second, ampm: this.ampm };
40821		var tmptime = format || this._defaults.timeFormat.toString();
40822
40823		if (ampm) {
40824			var hour12 = ((time.ampm == 'AM') ? (time.hour) : (time.hour % 12));
40825			hour12 = (Number(hour12) === 0) ? 12 : hour12;
40826			tmptime = tmptime.toString()
40827				.replace(/hh/g, ((hour12 < 10) ? '0' : '') + hour12)
40828				.replace(/h/g, hour12)
40829				.replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)
40830				.replace(/m/g, time.minute)
40831				.replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)
40832				.replace(/s/g, time.second)
40833				.replace(/TT/g, time.ampm.toUpperCase())
40834				.replace(/tt/g, time.ampm.toLowerCase())
40835				.replace(/T/g, time.ampm.charAt(0).toUpperCase())
40836				.replace(/t/g, time.ampm.charAt(0).toLowerCase());
40837		} else {
40838			tmptime = tmptime.toString()
40839				.replace(/hh/g, ((time.hour < 10) ? '0' : '') + time.hour)
40840				.replace(/h/g, time.hour)
40841				.replace(/mm/g, ((time.minute < 10) ? '0' : '') + time.minute)
40842				.replace(/m/g, time.minute)
40843				.replace(/ss/g, ((time.second < 10) ? '0' : '') + time.second)
40844				.replace(/s/g, time.second);
40845			tmptime = $.trim(tmptime.replace(/t/gi, ''));
40846		}
40847
40848		if (arguments.length) return tmptime;
40849		else this.formattedTime = tmptime;
40850	},
40851
40852	//########################################################################
40853	// update our input with the new date time..
40854	//########################################################################
40855	_updateDateTime: function(dp_inst) {
40856		dp_inst = this.inst || dp_inst,
40857			dt = new Date(dp_inst.selectedYear, dp_inst.selectedMonth, dp_inst.selectedDay),
40858			dateFmt = $.datepicker._get(dp_inst, 'dateFormat'),
40859			formatCfg = $.datepicker._getFormatConfig(dp_inst),
40860			timeAvailable = dt !== null && this.timeDefined;
40861		this.formattedDate = $.datepicker.formatDate(dateFmt, (dt === null ? new Date() : dt), formatCfg);
40862		var formattedDateTime = this.formattedDate;
40863		if (dp_inst.lastVal !== undefined && (dp_inst.lastVal.length > 0 && this.$input.val().length === 0))
40864			return;
40865
40866		if (this._defaults.timeOnly === true) {
40867			formattedDateTime = this.formattedTime;
40868		} else if (this._defaults.timeOnly !== true && (this._defaults.alwaysSetTime || timeAvailable)) {			
40869			formattedDateTime += this._defaults.separator + this.formattedTime;
40870		}
40871
40872		this.formattedDateTime = formattedDateTime;
40873
40874		if(!this._defaults.showTimepicker) {
40875			this.$input.val(this.formattedDate);
40876		} else if (this.$altInput && this._defaults.altFieldTimeOnly === true) {
40877			this.$altInput.val(this.formattedTime);
40878			this.$input.val(this.formattedDate);
40879		} else if(this.$altInput) {
40880			this.$altInput.val(formattedDateTime);
40881			this.$input.val(formattedDateTime);
40882		} else {
40883			this.$input.val(formattedDateTime);
40884		}
40885		
40886		this.$input.trigger("change");
40887	}
40888
40889});
40890
40891$.fn.extend({
40892	//########################################################################
40893	// shorthand just to use timepicker..
40894	//########################################################################
40895	timepicker: function(o) {
40896		o = o || {};
40897		var tmp_args = arguments;
40898
40899		if (typeof o == 'object') tmp_args[0] = $.extend(o, { timeOnly: true });
40900
40901		return $(this).each(function() {
40902			$.fn.datetimepicker.apply($(this), tmp_args);
40903		});
40904	},
40905
40906	//########################################################################
40907	// extend timepicker to datepicker
40908	//########################################################################
40909	datetimepicker: function(o) {
40910		o = o || {};
40911		var $input = this,
40912			tmp_args = arguments;
40913
40914		if (typeof(o) == 'string'){
40915			if(o == 'getDate') 
40916				return $.fn.datepicker.apply($(this[0]), tmp_args);
40917			else 
40918				return this.each(function() {
40919					var $t = $(this);
40920					$t.datepicker.apply($t, tmp_args);
40921				});
40922		}
40923		else
40924			return this.each(function() {
40925				var $t = $(this);
40926				$t.datepicker($.timepicker._newInst($t, o)._defaults);
40927			});
40928	}
40929});
40930
40931//########################################################################
40932// the bad hack :/ override datepicker so it doesnt close on select
40933// inspired: http://stackoverflow.com/questions/1252512/jquery-datepicker-prevent-closing-picker-when-clicking-a-date/1762378#1762378
40934//########################################################################
40935$.datepicker._base_selectDate = $.datepicker._selectDate;
40936$.datepicker._selectDate = function (id, dateStr) {
40937	var inst = this._getInst($(id)[0]),
40938		tp_inst = this._get(inst, 'timepicker');
40939
40940	if (tp_inst) {
40941		tp_inst._limitMinMaxDateTime(inst, true);
40942		inst.inline = inst.stay_open = true;
40943		//This way the onSelect handler called from calendarpicker get the full dateTime
40944		this._base_selectDate(id, dateStr + tp_inst._defaults.separator + tp_inst.formattedTime);
40945		inst.inline = inst.stay_open = false;
40946		this._notifyChange(inst);
40947		this._updateDatepicker(inst);
40948	}
40949	else this._base_selectDate(id, dateStr);
40950};
40951
40952//#############################################################################################
40953// second bad hack :/ override datepicker so it triggers an event when changing the input field
40954// and does not redraw the datepicker on every selectDate event
40955//#############################################################################################
40956$.datepicker._base_updateDatepicker = $.datepicker._updateDatepicker;
40957$.datepicker._updateDatepicker = function(inst) {
40958	if (typeof(inst.stay_open) !== 'boolean' || inst.stay_open === false) {
40959				
40960		this._base_updateDatepicker(inst);
40961		
40962		// Reload the time control when changing something in the input text field.
40963		var tp_inst = this._get(inst, 'timepicker');
40964		if(tp_inst) tp_inst._addTimePicker(inst);
40965	}
40966};
40967
40968//#######################################################################################
40969// third bad hack :/ override datepicker so it allows spaces and colan in the input field
40970//#######################################################################################
40971$.datepicker._base_doKeyPress = $.datepicker._doKeyPress;
40972$.datepicker._doKeyPress = function(event) {
40973	var inst = $.datepicker._getInst(event.target),
vendor: 1,171 bytes, lines 40974-41001
40974		tp_inst = $.datepicker._get(inst, 'timepicker');
40975
40976	if (tp_inst) {
40977		if ($.datepicker._get(inst, 'constrainInput')) {
40978			var ampm = tp_inst._defaults.ampm,
40979				datetimeChars = tp_inst._defaults.timeFormat.toString()
40980								.replace(/[hms]/g, '')
40981								.replace(/TT/g, ampm ? 'APM' : '')
40982								.replace(/T/g, ampm ? 'AP' : '')
40983								.replace(/tt/g, ampm ? 'apm' : '')
40984								.replace(/t/g, ampm ? 'ap' : '') +
40985								" " +
40986								tp_inst._defaults.separator +
40987								$.datepicker._possibleChars($.datepicker._get(inst, 'dateFormat')),
40988				chr = String.fromCharCode(event.charCode === undefined ? event.keyCode : event.charCode);
40989			return event.ctrlKey || (chr < ' ' || !datetimeChars || datetimeChars.indexOf(chr) > -1);
40990		}
40991	}
40992	
40993	return $.datepicker._base_doKeyPress(event);
40994};
40995
40996//#######################################################################################
40997// Override key up event to sync manual input changes.
40998//#######################################################################################
40999$.datepicker._base_doKeyUp = $.datepicker._doKeyUp;
41000$.datepicker._doKeyUp = function (event) {
41001	var inst = $.datepicker._getInst(event.target),
41002		tp_inst = $.datepicker._get(inst, 'timepicker');
41003
41004	if (tp_inst) {
41005		if (tp_inst._defaults.timeOnly && (inst.input.val() != inst.lastVal)) {
41006			try {
41007				$.datepicker._updateDatepicker(inst);
41008			}
41009			catch (err) {
41010				$.datepicker.log(err);
41011			}
41012		}
41013	}
41014
41015	return $.datepicker._base_doKeyUp(event);
41016};
41017
41018//#######################################################################################
41019// override "Today" button to also grab the time.
41020//#######################################################################################
41021$.datepicker._base_gotoToday = $.datepicker._gotoToday;
41022$.datepicker._gotoToday = function(id) {
41023	this._base_gotoToday(id);
41024	this._setTime(this._getInst($(id)[0]), new Date());
41025};
41026
41027//#######################################################################################
41028// Disable & enable the Time in the datetimepicker
41029//#######################################################################################
41030$.datepicker._disableTimepickerDatepicker = function(target, date, withDate) {
41031	var inst = this._getInst(target),
41032	tp_inst = this._get(inst, 'timepicker');
41033	if (tp_inst) {
41034		tp_inst._defaults.showTimepicker = false;
41035		tp_inst._onTimeChange();
41036		tp_inst._updateDateTime(inst);
41037	}
41038};
41039
41040$.datepicker._enableTimepickerDatepicker = function(target, date, withDate) {
41041	var inst = this._getInst(target),
41042	tp_inst = this._get(inst, 'timepicker');
41043	if (tp_inst) {
41044		tp_inst._defaults.showTimepicker = true;
41045		tp_inst._onTimeChange();
41046		tp_inst._updateDateTime(inst);
41047	}
41048};
41049
41050//#######################################################################################
41051// Create our own set time function
41052//#######################################################################################
41053$.datepicker._setTime = function(inst, date) {
41054	var tp_inst = this._get(inst, 'timepicker');
41055	if (tp_inst) {
41056		var defaults = tp_inst._defaults,
41057			// calling _setTime with no date sets time to defaults
41058			hour = date ? date.getHours() : defaults.hour,
41059			minute = date ? date.getMinutes() : defaults.minute,
41060			second = date ? date.getSeconds() : defaults.second;
41061
41062		//check if within min/max times..
41063		if ((hour < defaults.hourMin || hour > defaults.hourMax) || (minute < defaults.minuteMin || minute > defaults.minuteMax) || (second < defaults.secondMin || second > defaults.secondMax)) {
41064			hour = defaults.hourMin;
41065			minute = defaults.minuteMin;
41066			second = defaults.secondMin;
41067		}
41068
41069		if (tp_inst.hour_slider) tp_inst.hour_slider.slider('value', hour);
41070		else tp_inst.hour = hour;
41071		if (tp_inst.minute_slider) tp_inst.minute_slider.slider('value', minute);
41072		else tp_inst.minute = minute;
41073		if (tp_inst.second_slider) tp_inst.second_slider.slider('value', second);
41074		else tp_inst.second = second;
41075
41076		tp_inst._onTimeChange();
41077		tp_inst._updateDateTime(inst);
41078	}
41079};
41080
41081//#######################################################################################
41082// Create new public method to set only time, callable as $().datepicker('setTime', date)
41083//#######################################################################################
41084$.datepicker._setTimeDatepicker = function(target, date, withDate) {
41085	var inst = this._getInst(target),
41086		tp_inst = this._get(inst, 'timepicker');
41087
41088	if (tp_inst) {
41089		this._setDateFromField(inst);
41090		var tp_date;
41091		if (date) {
41092			if (typeof date == "string") {
41093				tp_inst._parseTime(date, withDate);
41094				tp_date = new Date();
41095				tp_date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second);
41096			}
41097			else tp_date = new Date(date.getTime());
41098			if (tp_date.toString() == 'Invalid Date') tp_date = undefined;
41099		}
41100		this._setTime(inst, tp_date);
41101	}
41102
41103};
41104
41105//#######################################################################################
41106// override setDate() to allow setting time too within Date object
41107//#######################################################################################
41108$.datepicker._base_setDateDatepicker = $.datepicker._setDateDatepicker;
41109$.datepicker._setDateDatepicker = function(target, date) {
41110	var inst = this._getInst(target),
41111	tp_date = (date instanceof Date) ? new Date(date.getTime()) : date;
41112
41113	this._updateDatepicker(inst);
41114	this._base_setDateDatepicker.apply(this, arguments);
41115	this._setTimeDatepicker(target, tp_date, true);
41116};
41117
41118//#######################################################################################
41119// override getDate() to allow getting time too within Date object
41120//#######################################################################################
41121$.datepicker._base_getDateDatepicker = $.datepicker._getDateDatepicker;
41122$.datepicker._getDateDatepicker = function(target, noDefault) {
41123	var inst = this._getInst(target),
41124		tp_inst = this._get(inst, 'timepicker');
41125
41126	if (tp_inst) {
41127		this._setDateFromField(inst, noDefault);
41128		var date = this._getDate(inst);
41129		if (date && tp_inst._parseTime($(target).val(), true)) date.setHours(tp_inst.hour, tp_inst.minute, tp_inst.second);
41130		return date;
41131	}
41132	return this._base_getDateDatepicker(target, noDefault);
41133};
41134
41135//#######################################################################################
41136// jQuery extend now ignores nulls!
41137//#######################################################################################
41138function extendRemove(target, props) {
41139	$.extend(target, props);
41140	for (var name in props)
41141		if (props[name] === null || props[name] === undefined)
41142			target[name] = props[name];
41143	return target;
41144}
41145
41146$.timepicker = new Timepicker(); // singleton instance
41147$.timepicker.version = "0.9.3";
41148
41149})(jQuery);
41150/**
41151 * jQuery Cookie plugin
41152 *
41153 * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
41154 * Dual licensed under the MIT and GPL licenses:
41155 * http://www.opensource.org/licenses/mit-license.php
41156 * http://www.gnu.org/licenses/gpl.html
41157 *
41158 */
41159
41160jQuery.cookie = function (key, value, options) {
41161
41162    // key and at least value given, set cookie...
41163    if (arguments.length > 1 && String(value) !== "[object Object]") {
41164        options = jQuery.extend({}, options);
41165
41166        if (value === null || value === undefined) {
41167            options.expires = -1;
41168        }
41169
41170        if (typeof options.expires === 'number') {
41171            var days = options.expires, t = options.expires = new Date();
41172            t.setDate(t.getDate() + days);
41173        }
41174
41175        value = String(value);
41176
41177        return (document.cookie = [
41178            encodeURIComponent(key), '=',
41179            options.raw ? value : encodeURIComponent(value),
41180            options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
41181            options.path ? '; path=' + options.path : '',
41182            options.domain ? '; domain=' + options.domain : '',
41183            options.secure ? '; secure' : ''
41184        ].join(''));
41185    }
41186
41187    // key and possibly options given, get cookie...
41188    options = value || {};
41189    var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
41190    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
41191};
41192/*!
41193 * jQuery Cycle Plugin (with Transition Definitions)
41194 * Examples and documentation at: http://jquery.malsup.com/cycle/
41195 * Copyright (c) 2007-2012 M. Alsup
41196 * Version: 2.9999.81 (15-JAN-2013)
41197 * Dual licensed under the MIT and GPL licenses.
41198 * http://jquery.malsup.com/license.html
41199 * Requires: jQuery v1.7.1 or later
41200 */
41201
41202;(function($, undefined) {
41203"use strict";
41204
41205var ver = '2.9999.81';
41206
41207function debug(s) {
41208	if ($.fn.cycle.debug)
41209		log(s);
41210}		
41211function log() {
41212	if (window.console && console.log)
41213		console.log('[cycle] ' + Array.prototype.join.call(arguments,' '));
41214}
41215$.expr[':'].paused = function(el) {
41216	return el.cyclePause;
41217};
41218
41219
41220// the options arg can be...
41221//   a number  - indicates an immediate transition should occur to the given slide index
41222//   a string  - 'pause', 'resume', 'toggle', 'next', 'prev', 'stop', 'destroy' or the name of a transition effect (ie, 'fade', 'zoom', etc)
41223//   an object - properties to control the slideshow
41224//
41225// the arg2 arg can be...
41226//   the name of an fx (only used in conjunction with a numeric value for 'options')
41227//   the value true (only used in first arg == 'resume') and indicates
41228//	 that the resume should occur immediately (not wait for next timeout)
41229
41230$.fn.cycle = function(options, arg2) {
41231	var o = { s: this.selector, c: this.context };
41232
41233	// in 1.3+ we can fix mistakes with the ready state
41234	if (this.length === 0 && options != 'stop') {
41235		if (!$.isReady && o.s) {
41236			log('DOM not ready, queuing slideshow');
41237			$(function() {
41238				$(o.s,o.c).cycle(options,arg2);
41239			});
41240			return this;
41241		}
41242		// is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
41243		log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
41244		return this;
41245	}
41246
41247	// iterate the matched nodeset
41248	return this.each(function() {
41249		var opts = handleArguments(this, options, arg2);
41250		if (opts === false)
41251			return;
41252
41253		opts.updateActivePagerLink = opts.updateActivePagerLink || $.fn.cycle.updateActivePagerLink;
41254		
41255		// stop existing slideshow for this container (if there is one)
41256		if (this.cycleTimeout)
41257			clearTimeout(this.cycleTimeout);
41258		this.cycleTimeout = this.cyclePause = 0;
41259		this.cycleStop = 0; // issue #108
41260
41261		var $cont = $(this);
41262		var $slides = opts.slideExpr ? $(opts.slideExpr, this) : $cont.children();
41263		var els = $slides.get();
41264
41265		if (els.length < 2) {
41266			log('terminating; too few slides: ' + els.length);
41267			return;
41268		}
41269
41270		var opts2 = buildOptions($cont, $slides, els, opts, o);
41271		if (opts2 === false)
41272			return;
41273
41274		var startTime = opts2.continuous ? 10 : getTimeout(els[opts2.currSlide], els[opts2.nextSlide], opts2, !opts2.backwards);
41275
41276		// if it's an auto slideshow, kick it off
41277		if (startTime) {
41278			startTime += (opts2.delay || 0);
41279			if (startTime < 10)
41280				startTime = 10;
41281			debug('first timeout: ' + startTime);
41282			this.cycleTimeout = setTimeout(function(){go(els,opts2,0,!opts.backwards);}, startTime);
41283		}
41284	});
41285};
41286
41287function triggerPause(cont, byHover, onPager) {
41288	var opts = $(cont).data('cycle.opts');
41289	if (!opts)
41290		return;
41291	var paused = !!cont.cyclePause;
41292	if (paused && opts.paused)
41293		opts.paused(cont, opts, byHover, onPager);
41294	else if (!paused && opts.resumed)
41295		opts.resumed(cont, opts, byHover, onPager);
41296}
41297
41298// process the args that were passed to the plugin fn
41299function handleArguments(cont, options, arg2) {
41300	if (cont.cycleStop === undefined)
41301		cont.cycleStop = 0;
41302	if (options === undefined || options === null)
41303		options = {};
41304	if (options.constructor == String) {
41305		switch(options) {
41306		case 'destroy':
41307		case 'stop':
41308			var opts = $(cont).data('cycle.opts');
41309			if (!opts)
41310				return false;
41311			cont.cycleStop++; // callbacks look for change
41312			if (cont.cycleTimeout)
41313				clearTimeout(cont.cycleTimeout);
41314			cont.cycleTimeout = 0;
41315			if (opts.elements)
41316				$(opts.elements).stop();
41317			$(cont).removeData('cycle.opts');
41318			if (options == 'destroy')
41319				destroy(cont, opts);
41320			return false;
41321		case 'toggle':
41322			cont.cyclePause = (cont.cyclePause === 1) ? 0 : 1;
41323			checkInstantResume(cont.cyclePause, arg2, cont);
41324			triggerPause(cont);
41325			return false;
41326		case 'pause':
41327			cont.cyclePause = 1;
41328			triggerPause(cont);
41329			return false;
41330		case 'resume':
41331			cont.cyclePause = 0;
41332			checkInstantResume(false, arg2, cont);
41333			triggerPause(cont);
41334			return false;
41335		case 'prev':
41336		case 'next':
41337			opts = $(cont).data('cycle.opts');
41338			if (!opts) {
41339				log('options not found, "prev/next" ignored');
41340				return false;
41341			}
41342			$.fn.cycle[options](opts);
41343			return false;
41344		default:
41345			options = { fx: options };
41346		}
41347		return options;
41348	}
41349	else if (options.constructor == Number) {
41350		// go to the requested slide
41351		var num = options;
41352		options = $(cont).data('cycle.opts');
41353		if (!options) {
41354			log('options not found, can not advance slide');
41355			return false;
41356		}
41357		if (num < 0 || num >= options.elements.length) {
41358			log('invalid slide index: ' + num);
41359			return false;
41360		}
41361		options.nextSlide = num;
41362		if (cont.cycleTimeout) {
41363			clearTimeout(cont.cycleTimeout);
41364			cont.cycleTimeout = 0;
41365		}
41366		if (typeof arg2 == 'string')
41367			options.oneTimeFx = arg2;
41368		go(options.elements, options, 1, num >= options.currSlide);
41369		return false;
41370	}
41371	return options;
41372	
41373	function checkInstantResume(isPaused, arg2, cont) {
41374		if (!isPaused && arg2 === true) { // resume now!
41375			var options = $(cont).data('cycle.opts');
41376			if (!options) {
41377				log('options not found, can not resume');
41378				return false;
41379			}
41380			if (cont.cycleTimeout) {
41381				clearTimeout(cont.cycleTimeout);
41382				cont.cycleTimeout = 0;
41383			}
41384			go(options.elements, options, 1, !options.backwards);
41385		}
41386	}
41387}
41388
41389function removeFilter(el, opts) {
41390	if (!$.support.opacity && opts.cleartype && el.style.filter) {
41391		try { el.style.removeAttribute('filter'); }
41392		catch(smother) {} // handle old opera versions
41393	}
41394}
41395
41396// unbind event handlers
41397function destroy(cont, opts) {
41398	if (opts.next)
41399		$(opts.next).unbind(opts.prevNextEvent);
41400	if (opts.prev)
41401		$(opts.prev).unbind(opts.prevNextEvent);
41402	
41403	if (opts.pager || opts.pagerAnchorBuilder)
41404		$.each(opts.pagerAnchors || [], function() {
41405			this.unbind().remove();
41406		});
41407	opts.pagerAnchors = null;
41408	$(cont).unbind('mouseenter.cycle mouseleave.cycle');
41409	if (opts.destroy) // callback
41410		opts.destroy(opts);
41411}
41412
41413// one-time initialization
41414function buildOptions($cont, $slides, els, options, o) {
41415	var startingSlideSpecified;
41416	// support metadata plugin (v1.0 and v2.0)
41417	var opts = $.extend({}, $.fn.cycle.defaults, options || {}, $.metadata ? $cont.metadata() : $.meta ? $cont.data() : {});
41418	var meta = $.isFunction($cont.data) ? $cont.data(opts.metaAttr) : null;
41419	if (meta)
41420		opts = $.extend(opts, meta);
41421	if (opts.autostop)
41422		opts.countdown = opts.autostopCount || els.length;
41423
41424	var cont = $cont[0];
41425	$cont.data('cycle.opts', opts);
41426	opts.$cont = $cont;
41427	opts.stopCount = cont.cycleStop;
41428	opts.elements = els;
41429	opts.before = opts.before ? [opts.before] : [];
41430	opts.after = opts.after ? [opts.after] : [];
41431
41432	// push some after callbacks
41433	if (!$.support.opacity && opts.cleartype)
41434		opts.after.push(function() { removeFilter(this, opts); });
41435	if (opts.continuous)
41436		opts.after.push(function() { go(els,opts,0,!opts.backwards); });
41437
41438	saveOriginalOpts(opts);
41439
41440	// clearType corrections
41441	if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
41442		clearTypeFix($slides);
41443
41444	// container requires non-static position so that slides can be position within
41445	if ($cont.css('position') == 'static')
41446		$cont.css('position', 'relative');
41447	if (opts.width)
41448		$cont.width(opts.width);
41449	if (opts.height && opts.height != 'auto')
41450		$cont.height(opts.height);
41451
41452	if (opts.startingSlide !== undefined) {
41453		opts.startingSlide = parseInt(opts.startingSlide,10);
41454		if (opts.startingSlide >= els.length || opts.startSlide < 0)
41455			opts.startingSlide = 0; // catch bogus input
41456		else 
41457			startingSlideSpecified = true;
41458	}
41459	else if (opts.backwards)
41460		opts.startingSlide = els.length - 1;
41461	else
41462		opts.startingSlide = 0;
41463
41464	// if random, mix up the slide array
41465	if (opts.random) {
41466		opts.randomMap = [];
41467		for (var i = 0; i < els.length; i++)
41468			opts.randomMap.push(i);
41469		opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
41470		if (startingSlideSpecified) {
41471			// try to find the specified starting slide and if found set start slide index in the map accordingly
41472			for ( var cnt = 0; cnt < els.length; cnt++ ) {
41473				if ( opts.startingSlide == opts.randomMap[cnt] ) {
41474					opts.randomIndex = cnt;
41475				}
41476			}
41477		}
41478		else {
41479			opts.randomIndex = 1;
41480			opts.startingSlide = opts.randomMap[1];
41481		}
41482	}
41483	else if (opts.startingSlide >= els.length)
41484		opts.startingSlide = 0; // catch bogus input
41485	opts.currSlide = opts.startingSlide || 0;
41486	var first = opts.startingSlide;
41487
41488	// set position and zIndex on all the slides
41489	$slides.css({position: 'absolute', top:0, left:0}).hide().each(function(i) {
41490		var z;
41491		if (opts.backwards)
41492			z = first ? i <= first ? els.length + (i-first) : first-i : els.length-i;
41493		else
41494			z = first ? i >= first ? els.length - (i-first) : first-i : els.length-i;
41495		$(this).css('z-index', z);
41496	});
41497
41498	// make sure first slide is visible
41499	$(els[first]).css('opacity',1).show(); // opacity bit needed to handle restart use case
41500	removeFilter(els[first], opts);
41501
41502	// stretch slides
41503	if (opts.fit) {
41504		if (!opts.aspect) {
41505	        if (opts.width)
41506	            $slides.width(opts.width);
41507	        if (opts.height && opts.height != 'auto')
41508	            $slides.height(opts.height);
41509		} else {
41510			$slides.each(function(){
41511				var $slide = $(this);
41512				var ratio = (opts.aspect === true) ? $slide.width()/$slide.height() : opts.aspect;
41513				if( opts.width && $slide.width() != opts.width ) {
41514					$slide.width( opts.width );
41515					$slide.height( opts.width / ratio );
41516				}
41517
41518				if( opts.height && $slide.height() < opts.height ) {
41519					$slide.height( opts.height );
41520					$slide.width( opts.height * ratio );
41521				}
41522			});
41523		}
41524	}
41525
41526	if (opts.center && ((!opts.fit) || opts.aspect)) {
41527		$slides.each(function(){
41528			var $slide = $(this);
41529			$slide.css({
41530				"margin-left": opts.width ?
41531					((opts.width - $slide.width()) / 2) + "px" :
41532					0,
41533				"margin-top": opts.height ?
41534					((opts.height - $slide.height()) / 2) + "px" :
41535					0
41536			});
41537		});
41538	}
41539
41540	if (opts.center && !opts.fit && !opts.slideResize) {
41541		$slides.each(function(){
41542			var $slide = $(this);
41543			$slide.css({
41544				"margin-left": opts.width ? ((opts.width - $slide.width()) / 2) + "px" : 0,
41545				"margin-top": opts.height ? ((opts.height - $slide.height()) / 2) + "px" : 0
41546			});
41547		});
41548	}
41549		
41550	// stretch container
41551	var reshape = (opts.containerResize || opts.containerResizeHeight) && !$cont.innerHeight();
41552	if (reshape) { // do this only if container has no size http://tinyurl.com/da2oa9
41553		var maxw = 0, maxh = 0;
41554		for(var j=0; j < els.length; j++) {
41555			var $e = $(els[j]), e = $e[0], w = $e.outerWidth(), h = $e.outerHeight();
41556			if (!w) w = e.offsetWidth || e.width || $e.attr('width');
41557			if (!h) h = e.offsetHeight || e.height || $e.attr('height');
41558			maxw = w > maxw ? w : maxw;
41559			maxh = h > maxh ? h : maxh;
41560		}
41561		if (opts.containerResize && maxw > 0 && maxh > 0)
41562			$cont.css({width:maxw+'px',height:maxh+'px'});
41563		if (opts.containerResizeHeight && maxh > 0)
41564			$cont.css({height:maxh+'px'});
41565	}
41566
41567	var pauseFlag = false;  // https://github.com/malsup/cycle/issues/44
41568	if (opts.pause)
41569		$cont.bind('mouseenter.cycle', function(){
41570			pauseFlag = true;
41571			this.cyclePause++;
41572			triggerPause(cont, true);
41573		}).bind('mouseleave.cycle', function(){
41574				if (pauseFlag)
41575					this.cyclePause--;
41576				triggerPause(cont, true);
41577		});
41578
41579	if (supportMultiTransitions(opts) === false)
41580		return false;
41581
41582	// apparently a lot of people use image slideshows without height/width attributes on the images.
41583	// Cycle 2.50+ requires the sizing info for every slide; this block tries to deal with that.
41584	var requeue = false;
41585	options.requeueAttempts = options.requeueAttempts || 0;
41586	$slides.each(function() {
41587		// try to get height/width of each slide
41588		var $el = $(this);
41589		this.cycleH = (opts.fit && opts.height) ? opts.height : ($el.height() || this.offsetHeight || this.height || $el.attr('height') || 0);
41590		this.cycleW = (opts.fit && opts.width) ? opts.width : ($el.width() || this.offsetWidth || this.width || $el.attr('width') || 0);
41591
41592		if ( $el.is('img') ) {
41593			var loading = (this.cycleH === 0 && this.cycleW === 0 && !this.complete);
41594			// don't requeue for images that are still loading but have a valid size
41595			if (loading) {
41596				if (o.s && opts.requeueOnImageNotLoaded && ++options.requeueAttempts < 100) { // track retry count so we don't loop forever
41597					log(options.requeueAttempts,' - img slide not loaded, requeuing slideshow: ', this.src, this.cycleW, this.cycleH);
41598					setTimeout(function() {$(o.s,o.c).cycle(options);}, opts.requeueTimeout);
41599					requeue = true;
41600					return false; // break each loop
41601				}
41602				else {
41603					log('could not determine size of image: '+this.src, this.cycleW, this.cycleH);
41604				}
41605			}
41606		}
41607		return true;
41608	});
41609
41610	if (requeue)
41611		return false;
41612
41613	opts.cssBefore = opts.cssBefore || {};
41614	opts.cssAfter = opts.cssAfter || {};
41615	opts.cssFirst = opts.cssFirst || {};
41616	opts.animIn = opts.animIn || {};
41617	opts.animOut = opts.animOut || {};
41618
41619	$slides.not(':eq('+first+')').css(opts.cssBefore);
41620	$($slides[first]).css(opts.cssFirst);
41621
41622	if (opts.timeout) {
41623		opts.timeout = parseInt(opts.timeout,10);
41624		// ensure that timeout and speed settings are sane
41625		if (opts.speed.constructor == String)
41626			opts.speed = $.fx.speeds[opts.speed] || parseInt(opts.speed,10);
41627		if (!opts.sync)
41628			opts.speed = opts.speed / 2;
41629		
41630		var buffer = opts.fx == 'none' ? 0 : opts.fx == 'shuffle' ? 500 : 250;
41631		while((opts.timeout - opts.speed) < buffer) // sanitize timeout
41632			opts.timeout += opts.speed;
41633	}
41634	if (opts.easing)
41635		opts.easeIn = opts.easeOut = opts.easing;
41636	if (!opts.speedIn)
41637		opts.speedIn = opts.speed;
41638	if (!opts.speedOut)
41639		opts.speedOut = opts.speed;
41640
41641	opts.slideCount = els.length;
41642	opts.currSlide = opts.lastSlide = first;
41643	if (opts.random) {
41644		if (++opts.randomIndex == els.length)
41645			opts.randomIndex = 0;
41646		opts.nextSlide = opts.randomMap[opts.randomIndex];
41647	}
41648	else if (opts.backwards)
41649		opts.nextSlide = opts.startingSlide === 0 ? (els.length-1) : opts.startingSlide-1;
41650	else
41651		opts.nextSlide = opts.startingSlide >= (els.length-1) ? 0 : opts.startingSlide+1;
41652
41653	// run transition init fn
41654	if (!opts.multiFx) {
41655		var init = $.fn.cycle.transitions[opts.fx];
41656		if ($.isFunction(init))
41657			init($cont, $slides, opts);
41658		else if (opts.fx != 'custom' && !opts.multiFx) {
41659			log('unknown transition: ' + opts.fx,'; slideshow terminating');
41660			return false;
41661		}
41662	}
41663
41664	// fire artificial events
41665	var e0 = $slides[first];
41666	if (!opts.skipInitializationCallbacks) {
41667		if (opts.before.length)
41668			opts.before[0].apply(e0, [e0, e0, opts, true]);
41669		if (opts.after.length)
41670			opts.after[0].apply(e0, [e0, e0, opts, true]);
41671	}
41672	if (opts.next)
41673		$(opts.next).bind(opts.prevNextEvent,function(){return advance(opts,1);});
41674	if (opts.prev)
41675		$(opts.prev).bind(opts.prevNextEvent,function(){return advance(opts,0);});
41676	if (opts.pager || opts.pagerAnchorBuilder)
41677		buildPager(els,opts);
41678
41679	exposeAddSlide(opts, els);
41680
41681	return opts;
41682}
41683
41684// save off original opts so we can restore after clearing state
41685function saveOriginalOpts(opts) {
41686	opts.original = { before: [], after: [] };
41687	opts.original.cssBefore = $.extend({}, opts.cssBefore);
41688	opts.original.cssAfter  = $.extend({}, opts.cssAfter);
41689	opts.original.animIn	= $.extend({}, opts.animIn);
41690	opts.original.animOut   = $.extend({}, opts.animOut);
41691	$.each(opts.before, function() { opts.original.before.push(this); });
41692	$.each(opts.after,  function() { opts.original.after.push(this); });
41693}
41694
41695function supportMultiTransitions(opts) {
41696	var i, tx, txs = $.fn.cycle.transitions;
41697	// look for multiple effects
41698	if (opts.fx.indexOf(',') > 0) {
41699		opts.multiFx = true;
41700		opts.fxs = opts.fx.replace(/\s*/g,'').split(',');
41701		// discard any bogus effect names
41702		for (i=0; i < opts.fxs.length; i++) {
41703			var fx = opts.fxs[i];
41704			tx = txs[fx];
41705			if (!tx || !txs.hasOwnProperty(fx) || !$.isFunction(tx)) {
41706				log('discarding unknown transition: ',fx);
41707				opts.fxs.splice(i,1);
41708				i--;
41709			}
41710		}
41711		// if we have an empty list then we threw everything away!
41712		if (!opts.fxs.length) {
41713			log('No valid transitions named; slideshow terminating.');
41714			return false;
41715		}
41716	}
41717	else if (opts.fx == 'all') {  // auto-gen the list of transitions
41718		opts.multiFx = true;
41719		opts.fxs = [];
41720		for (var p in txs) {
41721			if (txs.hasOwnProperty(p)) {
41722				tx = txs[p];
41723				if (txs.hasOwnProperty(p) && $.isFunction(tx))
41724					opts.fxs.push(p);
41725			}
41726		}
41727	}
41728	if (opts.multiFx && opts.randomizeEffects) {
41729		// munge the fxs array to make effect selection random
41730		var r1 = Math.floor(Math.random() * 20) + 30;
41731		for (i = 0; i < r1; i++) {
41732			var r2 = Math.floor(Math.random() * opts.fxs.length);
41733			opts.fxs.push(opts.fxs.splice(r2,1)[0]);
41734		}
41735		debug('randomized fx sequence: ',opts.fxs);
41736	}
41737	return true;
41738}
41739
41740// provide a mechanism for adding slides after the slideshow has started
41741function exposeAddSlide(opts, els) {
41742	opts.addSlide = function(newSlide, prepend) {
41743		var $s = $(newSlide), s = $s[0];
41744		if (!opts.autostopCount)
41745			opts.countdown++;
41746		els[prepend?'unshift':'push'](s);
41747		if (opts.els)
41748			opts.els[prepend?'unshift':'push'](s); // shuffle needs this
41749		opts.slideCount = els.length;
41750
41751		// add the slide to the random map and resort
41752		if (opts.random) {
41753			opts.randomMap.push(opts.slideCount-1);
41754			opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
41755		}
41756
41757		$s.css('position','absolute');
41758		$s[prepend?'prependTo':'appendTo'](opts.$cont);
41759
41760		if (prepend) {
41761			opts.currSlide++;
41762			opts.nextSlide++;
41763		}
41764
41765		if (!$.support.opacity && opts.cleartype && !opts.cleartypeNoBg)
41766			clearTypeFix($s);
41767
41768		if (opts.fit && opts.width)
41769			$s.width(opts.width);
41770		if (opts.fit && opts.height && opts.height != 'auto')
41771			$s.height(opts.height);
41772		s.cycleH = (opts.fit && opts.height) ? opts.height : $s.height();
41773		s.cycleW = (opts.fit && opts.width) ? opts.width : $s.width();
41774
41775		$s.css(opts.cssBefore);
41776
41777		if (opts.pager || opts.pagerAnchorBuilder)
41778			$.fn.cycle.createPagerAnchor(els.length-1, s, $(opts.pager), els, opts);
41779
41780		if ($.isFunction(opts.onAddSlide))
41781			opts.onAddSlide($s);
41782		else
41783			$s.hide(); // default behavior
41784	};
41785}
41786
41787// reset internal state; we do this on every pass in order to support multiple effects
41788$.fn.cycle.resetState = function(opts, fx) {
41789	fx = fx || opts.fx;
41790	opts.before = []; opts.after = [];
41791	opts.cssBefore = $.extend({}, opts.original.cssBefore);
41792	opts.cssAfter  = $.extend({}, opts.original.cssAfter);
41793	opts.animIn	= $.extend({}, opts.original.animIn);
41794	opts.animOut   = $.extend({}, opts.original.animOut);
41795	opts.fxFn = null;
41796	$.each(opts.original.before, function() { opts.before.push(this); });
41797	$.each(opts.original.after,  function() { opts.after.push(this); });
41798
41799	// re-init
41800	var init = $.fn.cycle.transitions[fx];
41801	if ($.isFunction(init))
41802		init(opts.$cont, $(opts.elements), opts);
41803};
41804
41805// this is the main engine fn, it handles the timeouts, callbacks and slide index mgmt
41806function go(els, opts, manual, fwd) {
41807	var p = opts.$cont[0], curr = els[opts.currSlide], next = els[opts.nextSlide];
41808
41809	// opts.busy is true if we're in the middle of an animation
41810	if (manual && opts.busy && opts.manualTrump) {
41811		// let manual transitions requests trump active ones
41812		debug('manualTrump in go(), stopping active transition');
41813		$(els).stop(true,true);
41814		opts.busy = 0;
41815		clearTimeout(p.cycleTimeout);
41816	}
41817
41818	// don't begin another timeout-based transition if there is one active
41819	if (opts.busy) {
41820		debug('transition active, ignoring new tx request');
41821		return;
41822	}
41823
41824
41825	// stop cycling if we have an outstanding stop request
41826	if (p.cycleStop != opts.stopCount || p.cycleTimeout === 0 && !manual)
41827		return;
41828
41829	// check to see if we should stop cycling based on autostop options
41830	if (!manual && !p.cyclePause && !opts.bounce &&
41831		((opts.autostop && (--opts.countdown <= 0)) ||
41832		(opts.nowrap && !opts.random && opts.nextSlide < opts.currSlide))) {
41833		if (opts.end)
41834			opts.end(opts);
41835		return;
41836	}
41837
41838	// if slideshow is paused, only transition on a manual trigger
41839	var changed = false;
41840	if ((manual || !p.cyclePause) && (opts.nextSlide != opts.currSlide)) {
41841		changed = true;
41842		var fx = opts.fx;
41843		// keep trying to get the slide size if we don't have it yet
41844		curr.cycleH = curr.cycleH || $(curr).height();
41845		curr.cycleW = curr.cycleW || $(curr).width();
41846		next.cycleH = next.cycleH || $(next).height();
41847		next.cycleW = next.cycleW || $(next).width();
41848
41849		// support multiple transition types
41850		if (opts.multiFx) {
41851			if (fwd && (opts.lastFx === undefined || ++opts.lastFx >= opts.fxs.length))
41852				opts.lastFx = 0;
41853			else if (!fwd && (opts.lastFx === undefined || --opts.lastFx < 0))
41854				opts.lastFx = opts.fxs.length - 1;
41855			fx = opts.fxs[opts.lastFx];
41856		}
41857
41858		// one-time fx overrides apply to:  $('div').cycle(3,'zoom');
41859		if (opts.oneTimeFx) {
41860			fx = opts.oneTimeFx;
41861			opts.oneTimeFx = null;
41862		}
41863
41864		$.fn.cycle.resetState(opts, fx);
41865
41866		// run the before callbacks
41867		if (opts.before.length)
41868			$.each(opts.before, function(i,o) {
41869				if (p.cycleStop != opts.stopCount) return;
41870				o.apply(next, [curr, next, opts, fwd]);
41871			});
41872
41873		// stage the after callacks
41874		var after = function() {
41875			opts.busy = 0;
41876			$.each(opts.after, function(i,o) {
41877				if (p.cycleStop != opts.stopCount) return;
41878				o.apply(next, [curr, next, opts, fwd]);
41879			});
41880			if (!p.cycleStop) {
41881				// queue next transition
41882				queueNext();
41883			}
41884		};
41885
41886		debug('tx firing('+fx+'); currSlide: ' + opts.currSlide + '; nextSlide: ' + opts.nextSlide);
41887		
41888		// get ready to perform the transition
41889		opts.busy = 1;
41890		if (opts.fxFn) // fx function provided?
41891			opts.fxFn(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
41892		else if ($.isFunction($.fn.cycle[opts.fx])) // fx plugin ?
41893			$.fn.cycle[opts.fx](curr, next, opts, after, fwd, manual && opts.fastOnEvent);
41894		else
41895			$.fn.cycle.custom(curr, next, opts, after, fwd, manual && opts.fastOnEvent);
41896	}
41897	else {
41898		queueNext();
41899	}
41900
41901	if (changed || opts.nextSlide == opts.currSlide) {
41902		// calculate the next slide
41903		var roll;
41904		opts.lastSlide = opts.currSlide;
41905		if (opts.random) {
41906			opts.currSlide = opts.nextSlide;
41907			if (++opts.randomIndex == els.length) {
41908				opts.randomIndex = 0;
41909				opts.randomMap.sort(function(a,b) {return Math.random() - 0.5;});
41910			}
41911			opts.nextSlide = opts.randomMap[opts.randomIndex];
41912			if (opts.nextSlide == opts.currSlide)
41913				opts.nextSlide = (opts.currSlide == opts.slideCount - 1) ? 0 : opts.currSlide + 1;
41914		}
41915		else if (opts.backwards) {
41916			roll = (opts.nextSlide - 1) < 0;
41917			if (roll && opts.bounce) {
41918				opts.backwards = !opts.backwards;
41919				opts.nextSlide = 1;
41920				opts.currSlide = 0;
41921			}
41922			else {
41923				opts.nextSlide = roll ? (els.length-1) : opts.nextSlide-1;
41924				opts.currSlide = roll ? 0 : opts.nextSlide+1;
41925			}
41926		}
41927		else { // sequence
41928			roll = (opts.nextSlide + 1) == els.length;
41929			if (roll && opts.bounce) {
41930				opts.backwards = !opts.backwards;
41931				opts.nextSlide = els.length-2;
41932				opts.currSlide = els.length-1;
41933			}
41934			else {
41935				opts.nextSlide = roll ? 0 : opts.nextSlide+1;
41936				opts.currSlide = roll ? els.length-1 : opts.nextSlide-1;
41937			}
41938		}
41939	}
41940	if (changed && opts.pager)
41941		opts.updateActivePagerLink(opts.pager, opts.currSlide, opts.activePagerClass);
41942	
41943	function queueNext() {
41944		// stage the next transition
41945		var ms = 0, timeout = opts.timeout;
41946		if (opts.timeout && !opts.continuous) {
41947			ms = getTimeout(els[opts.currSlide], els[opts.nextSlide], opts, fwd);
41948         if (opts.fx == 'shuffle')
41949            ms -= opts.speedOut;
41950      }
41951		else if (opts.continuous && p.cyclePause) // continuous shows work off an after callback, not this timer logic
41952			ms = 10;
41953		if (ms > 0)
41954			p.cycleTimeout = setTimeout(function(){ go(els, opts, 0, !opts.backwards); }, ms);
41955	}
41956}
41957
41958// invoked after transition
41959$.fn.cycle.updateActivePagerLink = function(pager, currSlide, clsName) {
41960   $(pager).each(function() {
41961       $(this).children().removeClass(clsName).eq(currSlide).addClass(clsName);
41962   });
41963};
41964
41965// calculate timeout value for current transition
41966function getTimeout(curr, next, opts, fwd) {
41967	if (opts.timeoutFn) {
41968		// call user provided calc fn
41969		var t = opts.timeoutFn.call(curr,curr,next,opts,fwd);
41970		while (opts.fx != 'none' && (t - opts.speed) < 250) // sanitize timeout
41971			t += opts.speed;
41972		debug('calculated timeout: ' + t + '; speed: ' + opts.speed);
41973		if (t !== false)
41974			return t;
41975	}
41976	return opts.timeout;
41977}
41978
41979// expose next/prev function, caller must pass in state
41980$.fn.cycle.next = function(opts) { advance(opts,1); };
41981$.fn.cycle.prev = function(opts) { advance(opts,0);};
41982
41983// advance slide forward or back
41984function advance(opts, moveForward) {
41985	var val = moveForward ? 1 : -1;
41986	var els = opts.elements;
41987	var p = opts.$cont[0], timeout = p.cycleTimeout;
41988	if (timeout) {
41989		clearTimeout(timeout);
41990		p.cycleTimeout = 0;
41991	}
41992	if (opts.random && val < 0) {
41993		// move back to the previously display slide
41994		opts.randomIndex--;
41995		if (--opts.randomIndex == -2)
41996			opts.randomIndex = els.length-2;
41997		else if (opts.randomIndex == -1)
41998			opts.randomIndex = els.length-1;
41999		opts.nextSlide = opts.randomMap[opts.randomIndex];
42000	}
42001	else if (opts.random) {
42002		opts.nextSlide = opts.randomMap[opts.randomIndex];
42003	}
42004	else {
42005		opts.nextSlide = opts.currSlide + val;
42006		if (opts.nextSlide < 0) {
42007			if (opts.nowrap) return false;
42008			opts.nextSlide = els.length - 1;
42009		}
42010		else if (opts.nextSlide >= els.length) {
42011			if (opts.nowrap) return false;
42012			opts.nextSlide = 0;
42013		}
42014	}
42015
42016	var cb = opts.onPrevNextEvent || opts.prevNextClick; // prevNextClick is deprecated
42017	if ($.isFunction(cb))
42018		cb(val > 0, opts.nextSlide, els[opts.nextSlide]);
42019	go(els, opts, 1, moveForward);
42020	return false;
42021}
42022
42023function buildPager(els, opts) {
42024	var $p = $(opts.pager);
42025	$.each(els, function(i,o) {
42026		$.fn.cycle.createPagerAnchor(i,o,$p,els,opts);
42027	});
42028	opts.updateActivePagerLink(opts.pager, opts.startingSlide, opts.activePagerClass);
42029}
42030
42031$.fn.cycle.createPagerAnchor = function(i, el, $p, els, opts) {
42032	var a;
42033	if ($.isFunction(opts.pagerAnchorBuilder)) {
42034		a = opts.pagerAnchorBuilder(i,el);
42035		debug('pagerAnchorBuilder('+i+', el) returned: ' + a);
42036	}
42037	else
42038		a = '<a href="#">'+(i+1)+'</a>';
42039		
42040	if (!a)
42041		return;
42042	var $a = $(a);
42043	// don't reparent if anchor is in the dom
42044	if ($a.parents('body').length === 0) {
42045		var arr = [];
42046		if ($p.length > 1) {
42047			$p.each(function() {
42048				var $clone = $a.clone(true);
42049				$(this).append($clone);
42050				arr.push($clone[0]);
42051			});
42052			$a = $(arr);
42053		}
42054		else {
42055			$a.appendTo($p);
42056		}
42057	}
42058
42059	opts.pagerAnchors =  opts.pagerAnchors || [];
42060	opts.pagerAnchors.push($a);
42061	
42062	var pagerFn = function(e) {
42063		e.preventDefault();
42064		opts.nextSlide = i;
42065		var p = opts.$cont[0], timeout = p.cycleTimeout;
42066		if (timeout) {
42067			clearTimeout(timeout);
42068			p.cycleTimeout = 0;
42069		}
42070		var cb = opts.onPagerEvent || opts.pagerClick; // pagerClick is deprecated
42071		if ($.isFunction(cb))
42072			cb(opts.nextSlide, els[opts.nextSlide]);
42073		go(els,opts,1,opts.currSlide < i); // trigger the trans
42074//		return false; // <== allow bubble
42075	};
42076	
42077	if ( /mouseenter|mouseover/i.test(opts.pagerEvent) ) {
42078		$a.hover(pagerFn, function(){/* no-op */} );
42079	}
42080	else {
42081		$a.bind(opts.pagerEvent, pagerFn);
42082	}
42083	
42084	if ( ! /^click/.test(opts.pagerEvent) && !opts.allowPagerClickBubble)
42085		$a.bind('click.cycle', function(){return false;}); // suppress click
42086	
42087	var cont = opts.$cont[0];
42088	var pauseFlag = false; // https://github.com/malsup/cycle/issues/44
42089	if (opts.pauseOnPagerHover) {
42090		$a.hover(
42091			function() { 
42092				pauseFlag = true;
42093				cont.cyclePause++; 
42094				triggerPause(cont,true,true);
42095			}, function() { 
42096				if (pauseFlag)
42097					cont.cyclePause--; 
42098				triggerPause(cont,true,true);
42099			} 
42100		);
42101	}
42102};
42103
42104// helper fn to calculate the number of slides between the current and the next
42105$.fn.cycle.hopsFromLast = function(opts, fwd) {
42106	var hops, l = opts.lastSlide, c = opts.currSlide;
42107	if (fwd)
42108		hops = c > l ? c - l : opts.slideCount - l;
42109	else
42110		hops = c < l ? l - c : l + opts.slideCount - c;
42111	return hops;
42112};
42113
42114// fix clearType problems in ie6 by setting an explicit bg color
42115// (otherwise text slides look horrible during a fade transition)
42116function clearTypeFix($slides) {
42117	debug('applying clearType background-color hack');
42118	function hex(s) {
42119		s = parseInt(s,10).toString(16);
42120		return s.length < 2 ? '0'+s : s;
42121	}
42122	function getBg(e) {
42123		for ( ; e && e.nodeName.toLowerCase() != 'html'; e = e.parentNode) {
42124			var v = $.css(e,'background-color');
42125			if (v && v.indexOf('rgb') >= 0 ) {
42126				var rgb = v.match(/\d+/g);
42127				return '#'+ hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);
42128			}
42129			if (v && v != 'transparent')
42130				return v;
42131		}
42132		return '#ffffff';
42133	}
42134	$slides.each(function() { $(this).css('background-color', getBg(this)); });
42135}
42136
42137// reset common props before the next transition
42138$.fn.cycle.commonReset = function(curr,next,opts,w,h,rev) {
42139	$(opts.elements).not(curr).hide();
42140	if (typeof opts.cssBefore.opacity == 'undefined')
42141		opts.cssBefore.opacity = 1;
42142	opts.cssBefore.display = 'block';
42143	if (opts.slideResize && w !== false && next.cycleW > 0)
42144		opts.cssBefore.width = next.cycleW;
42145	if (opts.slideResize && h !== false && next.cycleH > 0)
42146		opts.cssBefore.height = next.cycleH;
42147	opts.cssAfter = opts.cssAfter || {};
42148	opts.cssAfter.display = 'none';
42149	$(curr).css('zIndex',opts.slideCount + (rev === true ? 1 : 0));
42150	$(next).css('zIndex',opts.slideCount + (rev === true ? 0 : 1));
42151};
42152
42153// the actual fn for effecting a transition
42154$.fn.cycle.custom = function(curr, next, opts, cb, fwd, speedOverride) {
42155	var $l = $(curr), $n = $(next);
42156	var speedIn = opts.speedIn, speedOut = opts.speedOut, easeIn = opts.easeIn, easeOut = opts.easeOut;
42157	$n.css(opts.cssBefore);
42158	if (speedOverride) {
42159		if (typeof speedOverride == 'number')
42160			speedIn = speedOut = speedOverride;
42161		else
42162			speedIn = speedOut = 1;
42163		easeIn = easeOut = null;
42164	}
42165	var fn = function() {
42166		$n.animate(opts.animIn, speedIn, easeIn, function() {
42167			cb();
42168		});
42169	};
42170	$l.animate(opts.animOut, speedOut, easeOut, function() {
42171		$l.css(opts.cssAfter);
42172		if (!opts.sync) 
42173			fn();
42174	});
42175	if (opts.sync) fn();
42176};
42177
42178// transition definitions - only fade is defined here, transition pack defines the rest
42179$.fn.cycle.transitions = {
42180	fade: function($cont, $slides, opts) {
42181		$slides.not(':eq('+opts.currSlide+')').css('opacity',0);
42182		opts.before.push(function(curr,next,opts) {
42183			$.fn.cycle.commonReset(curr,next,opts);
42184			opts.cssBefore.opacity = 0;
42185		});
42186		opts.animIn	   = { opacity: 1 };
42187		opts.animOut   = { opacity: 0 };
42188		opts.cssBefore = { top: 0, left: 0 };
42189	}
42190};
42191
42192$.fn.cycle.ver = function() { return ver; };
42193
42194// override these globally if you like (they are all optional)
42195$.fn.cycle.defaults = {
42196    activePagerClass: 'activeSlide', // class name used for the active pager link
42197    after:            null,     // transition callback (scope set to element that was shown):  function(currSlideElement, nextSlideElement, options, forwardFlag)
42198    allowPagerClickBubble: false, // allows or prevents click event on pager anchors from bubbling
42199    animIn:           null,     // properties that define how the slide animates in
42200    animOut:          null,     // properties that define how the slide animates out
42201    aspect:           false,    // preserve aspect ratio during fit resizing, cropping if necessary (must be used with fit option)
42202    autostop:         0,        // true to end slideshow after X transitions (where X == slide count)
42203    autostopCount:    0,        // number of transitions (optionally used with autostop to define X)
42204    backwards:        false,    // true to start slideshow at last slide and move backwards through the stack
42205    before:           null,     // transition callback (scope set to element to be shown):     function(currSlideElement, nextSlideElement, options, forwardFlag)
42206    center:           null,     // set to true to have cycle add top/left margin to each slide (use with width and height options)
42207    cleartype:        !$.support.opacity,  // true if clearType corrections should be applied (for IE)
42208    cleartypeNoBg:    false,    // set to true to disable extra cleartype fixing (leave false to force background color setting on slides)
42209    containerResize:  1,        // resize container to fit largest slide
42210    containerResizeHeight:  0,  // resize containers height to fit the largest slide but leave the width dynamic
42211    continuous:       0,        // true to start next transition immediately after current one completes
42212    cssAfter:         null,     // properties that defined the state of the slide after transitioning out
42213    cssBefore:        null,     // properties that define the initial state of the slide before transitioning in
42214    delay:            0,        // additional delay (in ms) for first transition (hint: can be negative)
42215    easeIn:           null,     // easing for "in" transition
42216    easeOut:          null,     // easing for "out" transition
42217    easing:           null,     // easing method for both in and out transitions
42218    end:              null,     // callback invoked when the slideshow terminates (use with autostop or nowrap options): function(options)
42219    fastOnEvent:      0,        // force fast transitions when triggered manually (via pager or prev/next); value == time in ms
42220    fit:              0,        // force slides to fit container
42221    fx:               'fade',   // name of transition effect (or comma separated names, ex: 'fade,scrollUp,shuffle')
42222    fxFn:             null,     // function used to control the transition: function(currSlideElement, nextSlideElement, options, afterCalback, forwardFlag)
42223    height:           'auto',   // container height (if the 'fit' option is true, the slides will be set to this height as well)
42224    manualTrump:      true,     // causes manual transition to stop an active transition instead of being ignored
42225    metaAttr:         'cycle',  // data- attribute that holds the option data for the slideshow
42226    next:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for next slide
42227    nowrap:           0,        // true to prevent slideshow from wrapping
42228    onPagerEvent:     null,     // callback fn for pager events: function(zeroBasedSlideIndex, slideElement)
42229    onPrevNextEvent:  null,     // callback fn for prev/next events: function(isNext, zeroBasedSlideIndex, slideElement)
42230    pager:            null,     // element, jQuery object, or jQuery selector string for the element to use as pager container
42231    pagerAnchorBuilder: null,   // callback fn for building anchor links:  function(index, DOMelement)
42232    pagerEvent:       'click.cycle', // name of event which drives the pager navigation
42233    pause:            0,        // true to enable "pause on hover"
42234    pauseOnPagerHover: 0,       // true to pause when hovering over pager link
42235    prev:             null,     // element, jQuery object, or jQuery selector string for the element to use as event trigger for previous slide
42236    prevNextEvent:    'click.cycle',// event which drives the manual transition to the previous or next slide
42237    random:           0,        // true for random, false for sequence (not applicable to shuffle fx)
42238    randomizeEffects: 1,        // valid when multiple effects are used; true to make the effect sequence random
42239    requeueOnImageNotLoaded: true, // requeue the slideshow if any image slides are not yet loaded
42240    requeueTimeout:   250,      // ms delay for requeue
42241    rev:              0,        // causes animations to transition in reverse (for effects that support it such as scrollHorz/scrollVert/shuffle)
42242    shuffle:          null,     // coords for shuffle animation, ex: { top:15, left: 200 }
42243    skipInitializationCallbacks: false, // set to true to disable the first before/after callback that occurs prior to any transition
42244    slideExpr:        null,     // expression for selecting slides (if something other than all children is required)
42245    slideResize:      1,        // force slide width/height to fixed size before every transition
42246    speed:            1000,     // speed of the transition (any valid fx speed value)
42247    speedIn:          null,     // speed of the 'in' transition
42248    speedOut:         null,     // speed of the 'out' transition
42249    startingSlide:    undefined,// zero-based index of the first slide to be displayed
42250    sync:             1,        // true if in/out transitions should occur simultaneously
42251    timeout:          4000,     // milliseconds between slide transitions (0 to disable auto advance)
42252    timeoutFn:        null,     // callback for determining per-slide timeout value:  function(currSlideElement, nextSlideElement, options, forwardFlag)
42253    updateActivePagerLink: null,// callback fn invoked to update the active pager link (adds/removes activePagerClass style)
42254    width:            null      // container width (if the 'fit' option is true, the slides will be set to this width as well)
42255};
42256
42257}
42257)(jQuery);
42258
42259
42260/*!
42261 * jQuery Cycle Plugin Transition Definitions
42262 * This script is a plugin for the jQuery Cycle Plugin
42263 * Examples and documentation at: http://malsup.com/jquery/cycle/
42264 * Copyright (c) 2007-2010 M. Alsup
42265 * Version:	 2.73
42266 * Dual licensed under the MIT and GPL licenses:
42267 * http://www.opensource.org/licenses/mit-license.php
42268 * http://www.gnu.org/licenses/gpl.html
42269 */
42270(function($) {
42271"use strict";
42272
42273//
42274// These functions define slide initialization and properties for the named
42275// transitions. To save file size feel free to remove any of these that you
42276// don't need.
42277//
42278$.fn.cycle.transitions.none = function($cont, $slides, opts) {
42279	opts.fxFn = function(curr,next,opts,after){
42280		$(next).show();
42281		$(curr).hide();
42282		after();
42283	};
42284};
42285
42286// not a cross-fade, fadeout only fades out the top slide
42287$.fn.cycle.transitions.fadeout = function($cont, $slides, opts) {
42288	$slides.not(':eq('+opts.currSlide+')').css({ display: 'block', 'opacity': 1 });
42289	opts.before.push(function(curr,next,opts,w,h,rev) {
42290		$(curr).css('zIndex',opts.slideCount + (rev !== true ? 1 : 0));
42291		$(next).css('zIndex',opts.slideCount + (rev !== true ? 0 : 1));
42292	});
42293	opts.animIn.opacity = 1;
42294	opts.animOut.opacity = 0;
42295	opts.cssBefore.opacity = 1;
42296	opts.cssBefore.display = 'block';
42297	opts.cssAfter.zIndex = 0;
42298};
42299
42300// scrollUp/Down/Left/Right
42301$.fn.cycle.transitions.scrollUp = function($cont, $slides, opts) {
42302	$cont.css('overflow','hidden');
42303	opts.before.push($.fn.cycle.commonReset);
42304	var h = $cont.height();
42305	opts.cssBefore.top = h;
42306	opts.cssBefore.left = 0;
42307	opts.cssFirst.top = 0;
42308	opts.animIn.top = 0;
42309	opts.animOut.top = -h;
42310};
42311$.fn.cycle.transitions.scrollDown = function($cont, $slides, opts) {
42312	$cont.css('overflow','hidden');
42313	opts.before.push($.fn.cycle.commonReset);
42314	var h = $cont.height();
42315	opts.cssFirst.top = 0;
42316	opts.cssBefore.top = -h;
42317	opts.cssBefore.left = 0;
42318	opts.animIn.top = 0;
42319	opts.animOut.top = h;
42320};
42321$.fn.cycle.transitions.scrollLeft = function($cont, $slides, opts) {
42322	$cont.css('overflow','hidden');
42323	opts.before.push($.fn.cycle.commonReset);
42324	var w = $cont.width();
42325	opts.cssFirst.left = 0;
42326	opts.cssBefore.left = w;
42327	opts.cssBefore.top = 0;
42328	opts.animIn.left = 0;
42329	opts.animOut.left = 0-w;
42330};
42331$.fn.cycle.transitions.scrollRight = function($cont, $slides, opts) {
42332	$cont.css('overflow','hidden');
42333	opts.before.push($.fn.cycle.commonReset);
42334	var w = $cont.width();
42335	opts.cssFirst.left = 0;
42336	opts.cssBefore.left = -w;
42337	opts.cssBefore.top = 0;
42338	opts.animIn.left = 0;
42339	opts.animOut.left = w;
42340};
42341$.fn.cycle.transitions.scrollHorz = function($cont, $slides, opts) {
42342	$cont.css('overflow','hidden').width();
42343	opts.before.push(function(curr, next, opts, fwd) {
42344		if (opts.rev)
42345			fwd = !fwd;
42346		$.fn.cycle.commonReset(curr,next,opts);
42347		opts.cssBefore.left = fwd ? (next.cycleW-1) : (1-next.cycleW);
42348		opts.animOut.left = fwd ? -curr.cycleW : curr.cycleW;
42349	});
42350	opts.cssFirst.left = 0;
42351	opts.cssBefore.top = 0;
42352	opts.animIn.left = 0;
42353	opts.animOut.top = 0;
42354};
42355$.fn.cycle.transitions.scrollVert = function($cont, $slides, opts) {
42356	$cont.css('overflow','hidden');
42357	opts.before.push(function(curr, next, opts, fwd) {
42358		if (opts.rev)
42359			fwd = !fwd;
42360		$.fn.cycle.commonReset(curr,next,opts);
42361		opts.cssBefore.top = fwd ? (1-next.cycleH) : (next.cycleH-1);
42362		opts.animOut.top = fwd ? curr.cycleH : -curr.cycleH;
42363	});
42364	opts.cssFirst.top = 0;
42365	opts.cssBefore.left = 0;
42366	opts.animIn.top = 0;
42367	opts.animOut.left = 0;
42368};
42369
42370// slideX/slideY
42371$.fn.cycle.transitions.slideX = function($cont, $slides, opts) {
42372	opts.before.push(function(curr, next, opts) {
42373		$(opts.elements).not(curr).hide();
42374		$.fn.cycle.commonReset(curr,next,opts,false,true);
42375		opts.animIn.width = next.cycleW;
42376	});
42377	opts.cssBefore.left = 0;
42378	opts.cssBefore.top = 0;
42379	opts.cssBefore.width = 0;
42380	opts.animIn.width = 'show';
42381	opts.animOut.width = 0;
42382};
42383$.fn.cycle.transitions.slideY = function($cont, $slides, opts) {
42384	opts.before.push(function(curr, next, opts) {
42385		$(opts.elements).not(curr).hide();
42386		$.fn.cycle.commonReset(curr,next,opts,true,false);
42387		opts.animIn.height = next.cycleH;
42388	});
42389	opts.cssBefore.left = 0;
42390	opts.cssBefore.top = 0;
42391	opts.cssBefore.height = 0;
42392	opts.animIn.height = 'show';
42393	opts.animOut.height = 0;
42394};
42395
42396// shuffle
42397$.fn.cycle.transitions.shuffle = function($cont, $slides, opts) {
42398	var i, w = $cont.css('overflow', 'visible').width();
42399	$slides.css({left: 0, top: 0});
42400	opts.before.push(function(curr,next,opts) {
42401		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
42402	});
42403	// only adjust speed once!
42404	if (!opts.speedAdjusted) {
42405		opts.speed = opts.speed / 2; // shuffle has 2 transitions
42406		opts.speedAdjusted = true;
42407	}
42408	opts.random = 0;
42409	opts.shuffle = opts.shuffle || {left:-w, top:15};
42410	opts.els = [];
42411	for (i=0; i < $slides.length; i++)
42412		opts.els.push($slides[i]);
42413
42414	for (i=0; i < opts.currSlide; i++)
42415		opts.els.push(opts.els.shift());
42416
42417	// custom transition fn (hat tip to Benjamin Sterling for this bit of sweetness!)
42418	opts.fxFn = function(curr, next, opts, cb, fwd) {
42419		if (opts.rev)
42420			fwd = !fwd;
42421		var $el = fwd ? $(curr) : $(next);
42422		$(next).css(opts.cssBefore);
42423		var count = opts.slideCount;
42424		$el.animate(opts.shuffle, opts.speedIn, opts.easeIn, function() {
42425			var hops = $.fn.cycle.hopsFromLast(opts, fwd);
42426			for (var k=0; k < hops; k++) {
42427				if (fwd)
42428					opts.els.push(opts.els.shift());
42429				else
42430					opts.els.unshift(opts.els.pop());
42431			}
42432			if (fwd) {
42433				for (var i=0, len=opts.els.length; i < len; i++)
42434					$(opts.els[i]).css('z-index', len-i+count);
42435			}
42436			else {
42437				var z = $(curr).css('z-index');
42438				$el.css('z-index', parseInt(z,10)+1+count);
42439			}
42440			$el.animate({left:0, top:0}, opts.speedOut, opts.easeOut, function() {
42441				$(fwd ? this : curr).hide();
42442				if (cb) cb();
42443			});
42444		});
42445	};
42446	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
42447};
42448
42449// turnUp/Down/Left/Right
42450$.fn.cycle.transitions.turnUp = function($cont, $slides, opts) {
42451	opts.before.push(function(curr, next, opts) {
42452		$.fn.cycle.commonReset(curr,next,opts,true,false);
42453		opts.cssBefore.top = next.cycleH;
42454		opts.animIn.height = next.cycleH;
42455		opts.animOut.width = next.cycleW;
42456	});
42457	opts.cssFirst.top = 0;
42458	opts.cssBefore.left = 0;
42459	opts.cssBefore.height = 0;
42460	opts.animIn.top = 0;
42461	opts.animOut.height = 0;
42462};
42463$.fn.cycle.transitions.turnDown = function($cont, $slides, opts) {
42464	opts.before.push(function(curr, next, opts) {
42465		$.fn.cycle.commonReset(curr,next,opts,true,false);
42466		opts.animIn.height = next.cycleH;
42467		opts.animOut.top   = curr.cycleH;
42468	});
42469	opts.cssFirst.top = 0;
42470	opts.cssBefore.left = 0;
42471	opts.cssBefore.top = 0;
42472	opts.cssBefore.height = 0;
42473	opts.animOut.height = 0;
42474};
42475$.fn.cycle.transitions.turnLeft = function($cont, $slides, opts) {
42476	opts.before.push(function(curr, next, opts) {
42477		$.fn.cycle.commonReset(curr,next,opts,false,true);
42478		opts.cssBefore.left = next.cycleW;
42479		opts.animIn.width = next.cycleW;
42480	});
42481	opts.cssBefore.top = 0;
42482	opts.cssBefore.width = 0;
42483	opts.animIn.left = 0;
42484	opts.animOut.width = 0;
42485};
42486$.fn.cycle.transitions.turnRight = function($cont, $slides, opts) {
42487	opts.before.push(function(curr, next, opts) {
42488		$.fn.cycle.commonReset(curr,next,opts,false,true);
42489		opts.animIn.width = next.cycleW;
42490		opts.animOut.left = curr.cycleW;
42491	});
42492	$.extend(opts.cssBefore, { top: 0, left: 0, width: 0 });
42493	opts.animIn.left = 0;
42494	opts.animOut.width = 0;
42495};
42496
42497// zoom
42498$.fn.cycle.transitions.zoom = function($cont, $slides, opts) {
42499	opts.before.push(function(curr, next, opts) {
42500		$.fn.cycle.commonReset(curr,next,opts,false,false,true);
42501		opts.cssBefore.top = next.cycleH/2;
42502		opts.cssBefore.left = next.cycleW/2;
42503		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
42504		$.extend(opts.animOut, { width: 0, height: 0, top: curr.cycleH/2, left: curr.cycleW/2 });
42505	});
42506	opts.cssFirst.top = 0;
42507	opts.cssFirst.left = 0;
42508	opts.cssBefore.width = 0;
42509	opts.cssBefore.height = 0;
42510};
42511
42512// fadeZoom
42513$.fn.cycle.transitions.fadeZoom = function($cont, $slides, opts) {
42514	opts.before.push(function(curr, next, opts) {
42515		$.fn.cycle.commonReset(curr,next,opts,false,false);
42516		opts.cssBefore.left = next.cycleW/2;
42517		opts.cssBefore.top = next.cycleH/2;
42518		$.extend(opts.animIn, { top: 0, left: 0, width: next.cycleW, height: next.cycleH });
42519	});
42520	opts.cssBefore.width = 0;
42521	opts.cssBefore.height = 0;
42522	opts.animOut.opacity = 0;
42523};
42524
42525// blindX
42526$.fn.cycle.transitions.blindX = function($cont, $slides, opts) {
42527	var w = $cont.css('overflow','hidden').width();
42528	opts.before.push(function(curr, next, opts) {
42529		$.fn.cycle.commonReset(curr,next,opts);
42530		opts.animIn.width = next.cycleW;
42531		opts.animOut.left   = curr.cycleW;
42532	});
42533	opts.cssBefore.left = w;
42534	opts.cssBefore.top = 0;
42535	opts.animIn.left = 0;
42536	opts.animOut.left = w;
42537};
42538// blindY
42539$.fn.cycle.transitions.blindY = function($cont, $slides, opts) {
42540	var h = $cont.css('overflow','hidden').height();
42541	opts.before.push(function(curr, next, opts) {
42542		$.fn.cycle.commonReset(curr,next,opts);
42543		opts.animIn.height = next.cycleH;
42544		opts.animOut.top   = curr.cycleH;
42545	});
42546	opts.cssBefore.top = h;
42547	opts.cssBefore.left = 0;
42548	opts.animIn.top = 0;
42549	opts.animOut.top = h;
42550};
42551// blindZ
42552$.fn.cycle.transitions.blindZ = function($cont, $slides, opts) {
42553	var h = $cont.css('overflow','hidden').height();
42554	var w = $cont.width();
42555	opts.before.push(function(curr, next, opts) {
42556		$.fn.cycle.commonReset(curr,next,opts);
42557		opts.animIn.height = next.cycleH;
42558		opts.animOut.top   = curr.cycleH;
42559	});
42560	opts.cssBefore.top = h;
42561	opts.cssBefore.left = w;
42562	opts.animIn.top = 0;
42563	opts.animIn.left = 0;
42564	opts.animOut.top = h;
42565	opts.animOut.left = w;
42566};
42567
42568// growX - grow horizontally from centered 0 width
42569$.fn.cycle.transitions.growX = function($cont, $slides, opts) {
42570	opts.before.push(function(curr, next, opts) {
42571		$.fn.cycle.commonReset(curr,next,opts,false,true);
42572		opts.cssBefore.left = this.cycleW/2;
42573		opts.animIn.left = 0;
42574		opts.animIn.width = this.cycleW;
42575		opts.animOut.left = 0;
42576	});
42577	opts.cssBefore.top = 0;
42578	opts.cssBefore.width = 0;
42579};
42580// growY - grow vertically from centered 0 height
42581$.fn.cycle.transitions.growY = function($cont, $slides, opts) {
42582	opts.before.push(function(curr, next, opts) {
42583		$.fn.cycle.commonReset(curr,next,opts,true,false);
42584		opts.cssBefore.top = this.cycleH/2;
42585		opts.animIn.top = 0;
42586		opts.animIn.height = this.cycleH;
42587		opts.animOut.top = 0;
42588	});
42589	opts.cssBefore.height = 0;
42590	opts.cssBefore.left = 0;
42591};
42592
42593// curtainX - squeeze in both edges horizontally
42594$.fn.cycle.transitions.curtainX = function($cont, $slides, opts) {
42595	opts.before.push(function(curr, next, opts) {
42596		$.fn.cycle.commonReset(curr,next,opts,false,true,true);
42597		opts.cssBefore.left = next.cycleW/2;
42598		opts.animIn.left = 0;
42599		opts.animIn.width = this.cycleW;
42600		opts.animOut.left = curr.cycleW/2;
42601		opts.animOut.width = 0;
42602	});
42603	opts.cssBefore.top = 0;
42604	opts.cssBefore.width = 0;
42605};
42606// curtainY - squeeze in both edges vertically
42607$.fn.cycle.transitions.curtainY = function($cont, $slides, opts) {
42608	opts.before.push(function(curr, next, opts) {
42609		$.fn.cycle.commonReset(curr,next,opts,true,false,true);
42610		opts.cssBefore.top = next.cycleH/2;
42611		opts.animIn.top = 0;
42612		opts.animIn.height = next.cycleH;
42613		opts.animOut.top = curr.cycleH/2;
42614		opts.animOut.height = 0;
42615	});
42616	opts.cssBefore.height = 0;
42617	opts.cssBefore.left = 0;
42618};
42619
42620// cover - curr slide covered by next slide
42621$.fn.cycle.transitions.cover = function($cont, $slides, opts) {
42622	var d = opts.direction || 'left';
42623	var w = $cont.css('overflow','hidden').width();
42624	var h = $cont.height();
42625	opts.before.push(function(curr, next, opts) {
42626		$.fn.cycle.commonReset(curr,next,opts);
42627		opts.cssAfter.display = '';
42628		if (d == 'right')
42629			opts.cssBefore.left = -w;
42630		else if (d == 'up')
42631			opts.cssBefore.top = h;
42632		else if (d == 'down')
42633			opts.cssBefore.top = -h;
42634		else
42635			opts.cssBefore.left = w;
42636	});
42637	opts.animIn.left = 0;
42638	opts.animIn.top = 0;
42639	opts.cssBefore.top = 0;
42640	opts.cssBefore.left = 0;
42641};
42642
42643// uncover - curr slide moves off next slide
42644$.fn.cycle.transitions.uncover = function($cont, $slides, opts) {
42645	var d = opts.direction || 'left';
42646	var w = $cont.css('overflow','hidden').width();
42647	var h = $cont.height();
42648	opts.before.push(function(curr, next, opts) {
42649		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
42650		if (d == 'right')
42651			opts.animOut.left = w;
42652		else if (d == 'up')
42653			opts.animOut.top = -h;
42654		else if (d == 'down')
42655			opts.animOut.top = h;
42656		else
42657			opts.animOut.left = -w;
42658	});
42659	opts.animIn.left = 0;
42660	opts.animIn.top = 0;
42661	opts.cssBefore.top = 0;
42662	opts.cssBefore.left = 0;
42663};
42664
42665// toss - move top slide and fade away
42666$.fn.cycle.transitions.toss = function($cont, $slides, opts) {
42667	var w = $cont.css('overflow','visible').width();
42668	var h = $cont.height();
42669	opts.before.push(function(curr, next, opts) {
42670		$.fn.cycle.commonReset(curr,next,opts,true,true,true);
42671		// provide default toss settings if animOut not provided
42672		if (!opts.animOut.left && !opts.animOut.top)
42673			$.extend(opts.animOut, { left: w*2, top: -h/2, opacity: 0 });
42674		else
42675			opts.animOut.opacity = 0;
42676	});
42677	opts.cssBefore.left = 0;
42678	opts.cssBefore.top = 0;
42679	opts.animIn.left = 0;
42680};
42681
42682// wipe - clip animation
42683$.fn.cycle.transitions.wipe = function($cont, $slides, opts) {
42684	var w = $cont.css('overflow','hidden').width();
42685	var h = $cont.height();
42686	opts.cssBefore = opts.cssBefore || {};
42687	var clip;
42688	if (opts.clip) {
42689		if (/l2r/.test(opts.clip))
42690			clip = 'rect(0px 0px '+h+'px 0px)';
42691		else if (/r2l/.test(opts.clip))
42692			clip = 'rect(0px '+w+'px '+h+'px '+w+'px)';
42693		else if (/t2b/.test(opts.clip))
42694			clip = 'rect(0px '+w+'px 0px 0px)';
42695		else if (/b2t/.test(opts.clip))
42696			clip = 'rect('+h+'px '+w+'px '+h+'px 0px)';
42697		else if (/zoom/.test(opts.clip)) {
42698			var top = parseInt(h/2,10);
42699			var left = parseInt(w/2,10);
42700			clip = 'rect('+top+'px '+left+'px '+top+'px '+left+'px)';
42701		}
42702	}
42703
42704	opts.cssBefore.clip = opts.cssBefore.clip || clip || 'rect(0px 0px 0px 0px)';
42705
42706	var d = opts.cssBefore.clip.match(/(\d+)/g);
42707	var t = parseInt(d[0],10), r = parseInt(d[1],10), b = parseInt(d[2],10), l = parseInt(d[3],10);
42708
42709	opts.before.push(function(curr, next, opts) {
42710		if (curr == next) return;
42711		var $curr = $(curr), $next = $(next);
42712		$.fn.cycle.commonReset(curr,next,opts,true,true,false);
42713		opts.cssAfter.display = 'block';
42714
42715		var step = 1, count = parseInt((opts.speedIn / 13),10) - 1;
42716		(function f() {
42717			var tt = t ? t - parseInt(step * (t/count),10) : 0;
42718			var ll = l ? l - parseInt(step * (l/count),10) : 0;
42719			var bb = b < h ? b + parseInt(step * ((h-b)/count || 1),10) : h;
42720			var rr = r < w ? r + parseInt(step * ((w-r)/count || 1),10) : w;
42721			$next.css({ clip: 'rect('+tt+'px '+rr+'px '+bb+'px '+ll+'px)' });
42722			(step++ <= count) ? setTimeout(f, 13) : $curr.css('display', 'none');
42723		})();
42724	});
42725	$.extend(opts.cssBefore, { display: 'block', opacity: 1, top: 0, left: 0 });
42726	opts.animIn	   = { left: 0 };
42727	opts.animOut   = { left: 0 };
42728};
42729
42730})(jQuery);
42731/*
42732 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
42733 *
42734 * Uses the built in easing capabilities added In jQuery 1.1
42735 * to offer multiple easing options
42736 *
42737 * TERMS OF USE - jQuery Easing
42738 * 
42739 * Open source under the BSD License. 
42740 * 
42741 * Copyright © 2008 George McGinley Smith
42742 * All rights reserved.
42743 * 
42744 * Redistribution and use in source and binary forms, with or without modification, 
42745 * are permitted provided that the following conditions are met:
42746 * 
42747 * Redistributions of source code must retain the above copyright notice, this list of 
42748 * conditions and the following disclaimer.
42749 * Redistributions in binary form must reproduce the above copyright notice, this list 
42750 * of conditions and the following disclaimer in the documentation and/or other materials 
42751 * provided with the distribution.
42752 * 
42753 * Neither the name of the author nor the names of contributors may be used to endorse 
42754 * or promote products derived from this software without specific prior written permission.
42755 * 
42756 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
42757 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42758 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
42759 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,091 bytes, lines 42760-42905
42760 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42761 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
42762 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42763 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
42764 * OF THE POSSIBILITY OF SUCH DAMAGE. 
42765 *
42766*/
42767
42768// t: current time, b: begInnIng value, c: change In value, d: duration
42769jQuery.easing['jswing'] = jQuery.easing['swing'];
42770
42771jQuery.extend( jQuery.easing,
42772{
42773	def: 'easeOutQuad',
42774	swing: function (x, t, b, c, d) {
42775		//alert(jQuery.easing.default);
42776		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
42777	},
42778	easeInQuad: function (x, t, b, c, d) {
42779		return c*(t/=d)*t + b;
42780	},
42781	easeOutQuad: function (x, t, b, c, d) {
42782		return -c *(t/=d)*(t-2) + b;
42783	},
42784	easeInOutQuad: function (x, t, b, c, d) {
42785		if ((t/=d/2) < 1) return c/2*t*t + b;
42786		return -c/2 * ((--t)*(t-2) - 1) + b;
42787	},
42788	easeInCubic: function (x, t, b, c, d) {
42789		return c*(t/=d)*t*t + b;
42790	},
42791	easeOutCubic: function (x, t, b, c, d) {
42792		return c*((t=t/d-1)*t*t + 1) + b;
42793	},
42794	easeInOutCubic: function (x, t, b, c, d) {
42795		if ((t/=d/2) < 1) return c/2*t*t*t + b;
42796		return c/2*((t-=2)*t*t + 2) + b;
42797	},
42798	easeInQuart: function (x, t, b, c, d) {
42799		return c*(t/=d)*t*t*t + b;
42800	},
42801	easeOutQuart: function (x, t, b, c, d) {
42802		return -c * ((t=t/d-1)*t*t*t - 1) + b;
42803	},
42804	easeInOutQuart: function (x, t, b, c, d) {
42805		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
42806		return -c/2 * ((t-=2)*t*t*t - 2) + b;
42807	},
42808	easeInQuint: function (x, t, b, c, d) {
42809		return c*(t/=d)*t*t*t*t + b;
42810	},
42811	easeOutQuint: function (x, t, b, c, d) {
42812		return c*((t=t/d-1)*t*t*t*t + 1) + b;
42813	},
42814	easeInOutQuint: function (x, t, b, c, d) {
42815		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
42816		return c/2*((t-=2)*t*t*t*t + 2) + b;
42817	},
42818	easeInSine: function (x, t, b, c, d) {
42819		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
42820	},
42821	easeOutSine: function (x, t, b, c, d) {
42822		return c * Math.sin(t/d * (Math.PI/2)) + b;
42823	},
42824	easeInOutSine: function (x, t, b, c, d) {
42825		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
42826	},
42827	easeInExpo: function (x, t, b, c, d) {
42828		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
42829	},
42830	easeOutExpo: function (x, t, b, c, d) {
42831		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
42832	},
42833	easeInOutExpo: function (x, t, b, c, d) {
42834		if (t==0) return b;
42835		if (t==d) return b+c;
42836		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
42837		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
42838	},
42839	easeInCirc: function (x, t, b, c, d) {
42840		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
42841	},
42842	easeOutCirc: function (x, t, b, c, d) {
42843		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
42844	},
42845	easeInOutCirc: function (x, t, b, c, d) {
42846		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
42847		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
42848	},
42849	easeInElastic: function (x, t, b, c, d) {
42850		var s=1.70158;var p=0;var a=c;
42851		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
42852		if (a < Math.abs(c)) { a=c; var s=p/4; }
42853		else var s = p/(2*Math.PI) * Math.asin (c/a);
42854		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
42855	},
42856	easeOutElastic: function (x, t, b, c, d) {
42857		var s=1.70158;var p=0;var a=c;
42858		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
42859		if (a < Math.abs(c)) { a=c; var s=p/4; }
42860		else var s = p/(2*Math.PI) * Math.asin (c/a);
42861		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
42862	},
42863	easeInOutElastic: function (x, t, b, c, d) {
42864		var s=1.70158;var p=0;var a=c;
42865		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
42866		if (a < Math.abs(c)) { a=c; var s=p/4; }
42867		else var s = p/(2*Math.PI) * Math.asin (c/a);
42868		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
42869		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
42870	},
42871	easeInBack: function (x, t, b, c, d, s) {
42872		if (s == undefined) s = 1.70158;
42873		return c*(t/=d)*t*((s+1)*t - s) + b;
42874	},
42875	easeOutBack: function (x, t, b, c, d, s) {
42876		if (s == undefined) s = 1.70158;
42877		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
42878	},
42879	easeInOutBack: function (x, t, b, c, d, s) {
42880		if (s == undefined) s = 1.70158; 
42881		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
42882		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
42883	},
42884	easeInBounce: function (x, t, b, c, d) {
42885		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
42886	},
42887	easeOutBounce: function (x, t, b, c, d) {
42888		if ((t/=d) < (1/2.75)) {
42889			return c*(7.5625*t*t) + b;
42890		} else if (t < (2/2.75)) {
42891			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
42892		} else if (t < (2.5/2.75)) {
42893			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
42894		} else {
42895			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
42896		}
42897	},
42898	easeInOutBounce: function (x, t, b, c, d) {
42899		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
42900		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
42901	}
42902});
42903
42904/*
42905 *
42906 * TERMS OF USE - EASING EQUATIONS
42907 * 
42908 * Open source under the BSD License. 
42909 * 
42910 * Copyright © 2001 Robert Penner
42911 * All rights reserved.
42912 * 
42913 * Redistribution and use in source and binary forms, with or without modification, 
42914 * are permitted provided that the following conditions are met:
42915 * 
42916 * Redistributions of source code must retain the above copyright notice, this list of 
42917 * conditions and the following disclaimer.
42918 * Redistributions in binary form must reproduce the above copyright notice, this list 
42919 * of conditions and the following disclaimer in the documentation and/or other materials 
42920 * provided with the distribution.
42921 * 
42922 * Neither the name of the author nor the names of contributors may be used to endorse 
42923 * or promote products derived from this software without specific prior written permission.
42924 * 
42925 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
42926 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42927 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
42928 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42929 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42930 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
42931 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42932 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
42933 * OF THE POSSIBILITY OF SUCH DAMAGE. 
42934 *
42935 */
42936;
42937(function(d){d.formatCurrency={};d.formatCurrency.regions=[];d.formatCurrency.regions[""]={symbol:"$",positiveFormat:"%s%n",negativeFormat:"(%s%n)",decimalSymbol
42937:".",digitGroupSymbol:",",groupDigits:true};
42938d.fn.formatCurrency=function(e,f){if(arguments.length==1&&typeof e!=="string"){f=e;e=false}var g={name:"formatCurrency",colorize:false,region:"",global:true,roundToDecimalPlace:2,eventOnDecimalsEntered:false};
42939g=d.extend(g,d.formatCurrency.regions[""]);f=d.extend(g,f);if(f.region.length>0){f=d.extend(f,b(f.region))}f.regex=a(f);return this.each(function(){$this=d(this);
42940var o="0";o=$this[$this.is("input, select, textarea")?"val":"html"]();if(o.search("\\(")>=0){o="-"+o}if(o===""||(o==="-"&&f.roundToDecimalPlace===-1)){return
42941}if(isNaN(o)){o=o.replace(f.regex,"");if(o===""||(o==="-"&&f.roundToDecimalPlace===-1)){return}if(f.decimalSymbol!="."){o=o.replace(f.decimalSymbol,".")
42942}if(isNaN(o)){o="0"}}var m=String(o).split(".");var r=(o==Math.abs(o));var l=(m.length>1);var k=(l?m[1].toString():"0");var j=k;o=Math.abs(m[0]);
42943o=isNaN(o)?0:o;if(f.roundToDecimalPlace>=0){k=parseFloat("1."+k);k=k.toFixed(f.roundToDecimalPlace);if(k.substring(0,1)=="2"){o=Number(o)+1}k=k.substring(2)
42944}o=String(o);if(f.groupDigits){for(var n=0;n<Math.floor((o.length-(1+n))/3);n++){o=o.substring(0,o.length-(4*n+3))+f.digitGroupSymbol+o.substring(o.length-(4*n+3))
42945}}if((l&&f.roundToDecimalPlace==-1)||f.roundToDecimalPlace>0){o+=f.decimalSymbol+k}var q=r?f.positiveFormat:f.negativeFormat;var h=q.replace(/%s/g,f.symbol);
42946h=h.replace(/%n/g,o);var p=d([]);if(!e){p=$this}else{p=d(e)}p[p.is("input, select, textarea")?"val":"html"](h);if(l&&f.eventOnDecimalsEntered&&j.length>f.roundToDecimalPlace){p.trigger("decimalsEntered",j)
42947}if(f.colorize){p.css("color",r?"black":"red")}})};d.fn.toNumber=function(e){var f=d.extend({name:"toNumber",region:"",global:true},d.formatCurrency.regions[""]);
42948e=jQuery.extend(f,e);if(e.region.length>0){e=d.extend(e,b(e.region))}e.regex=a(e);return this.each(function(){var g=d(this).is("input, select, textarea")?"val":"html";
42949d(this)[g](d(this)[g]().replace("(","(-").replace(e.regex,""))})};d.fn.asNumber=function(f){var g=d.extend({name:"asNumber",region:"",parse:true,parseType:"Float",global:true},d.formatCurrency.regions[""]);
42950f=jQuery.extend(g,f);if(f.region.length>0){f=d.extend(f,b(f.region))}f.regex=a(f);f.parseType=c(f.parseType);var h=d(this).is("input, select, textarea")?"val":"html";
42951var e=d(this)[h]();e=e?e:"";e=e.replace("(","(-");e=e.replace(f.regex,"");if(!f.parse){return e}if(e.length==0){e="0"}if(f.decimalSymbol!="."){e=e.replace(f.decimalSymbol,".")
42952}return window["parse"+f.parseType](e)};function b(g){var f=d.formatCurrency.regions[g];if(f){return f}else{if(/(\w+)-(\w+)/g.test(g)){var e=g.replace(/(\w+)-(\w+)/g,"$1");
42953return d.formatCurrency.regions[e]}}return null}function c(e){switch(e.toLowerCase()){case"int":return"Int";case"float":return"Float";default:throw"invalid parseType"
42954}}function a(e){if(e.symbol===""){return new RegExp("[^\\d"+e.decimalSymbol+"-]","g")}else{var f=e.symbol.replace("$","\\$").replace(".","\\.");
42955return new RegExp(f+"|[^\\d"+e.decimalSymbol+"-]","g")}}})(jQuery);
42956/*! Copyright (c) 2008 Brandon Aaron (http://brandonaaron.net)
42957 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
42958 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
42959 *
42960 * Version: 1.0.3
42961 * Requires jQuery 1.1.3+
42962 * Docs: http://docs.jquery.com/Plugins/livequery
42963 */
42964
42965
42966(function($) {
42967	
42968$.extend($.fn, {
42969	livequery: function(type, fn, fn2) {
42970		var self = this, q;
42971		
42972		// Handle different call patterns
42973		if ($.isFunction(type))
42974			fn2 = fn, fn = type, type = undefined;
42975			
42976		// See if Live Query already exists
42977		$.each( $.livequery.queries, function(i, query) {
42978			if ( self.selector == query.selector && self.context == query.context &&
42979				type == query.type && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) )
42980					// Found the query, exit the each loop
42981					return (q = query) && false;
42982		});
42983		
42984		// Create new Live Query if it wasn't found
42985		q = q || new $.livequery(this.selector, this.context, type, fn, fn2);
42986		
42987		// Make sure it is running
42988		q.stopped = false;
42989		
42990		// Run it immediately for the first time
42991		q.run();
42992		
42993		// Contnue the chain
42994		return this;
42995	},
42996	
42997	expire: function(type, fn, fn2) {
42998		var self = this;
42999		
43000		// Handle different call patterns
43001		if ($.isFunction(type))
43002			fn2 = fn, fn = type, type = undefined;
43003			
43004		// Find the Live Query based on arguments and stop it
43005		$.each( $.livequery.queries, function(i, query) {
43006			if ( self.selector == query.selector && self.context == query.context && 
43007				(!type || type == query.type) && (!fn || fn.$lqguid == query.fn.$lqguid) && (!fn2 || fn2.$lqguid == query.fn2.$lqguid) && !this.stopped )
43008					$.livequery.stop(query.id);
43009		});
43010		
43011		// Continue the chain
43012		return this;
43013	}
43014});
43015
43016$.livequery = function(selector, context, type, fn, fn2) {
43017	this.selector = selector;
43018	this.context  = context || document;
43019	this.type     = type;
43020	this.fn       = fn;
43021	this.fn2      = fn2;
43022	this.elements = [];
43023	this.stopped  = false;
43024	
43025	// The id is the index of the Live Query in $.livequery.queries
43026	this.id = $.livequery.queries.push(this)-1;
43027	
43028	// Mark the functions for matching later on
43029	fn.$lqguid = fn.$lqguid || $.livequery.guid++;
43030	if (fn2) fn2.$lqguid = fn2.$lqguid || $.livequery.guid++;
43031	
43032	// Return the Live Query
43033	return this;
43034};
43035
43036$.livequery.prototype = {
43037	stop: function() {
43038		var query = this;
43039		
43040		if ( this.type )
43041			// Unbind all bound events
43042			this.elements.unbind(this.type, this.fn);
43043		else if (this.fn2)
43044			// Call the second function for all matched elements
43045			this.elements.each(function(i, el) {
43046				query.fn2.apply(el);
43047			});
43048			
43049		// Clear out matched elements
43050		this.elements = [];
43051		
43052		// Stop the Live Query from running until restarted
43053		this.stopped = true;
43054	},
43055	
43056	run: function() {
43057		// Short-circuit if stopped
43058		if ( this.stopped ) return;
43059		var query = this;
43060		
43061		var oEls = this.elements,
43062			els  = $(this.selector, this.context),
43063			nEls = els.not(oEls);
43064		
43065		// Set elements to the latest set of matched elements
43066		this.elements = els;
43067		
43068		if (this.type) {
43069			// Bind events to newly matched elements
43070			nEls.bind(this.type, this.fn);
43071			
43072			// Unbind events to elements no longer matched
43073			if (oEls.length > 0)
43074				$.each(oEls, function(i, el) {
43075					if ( $.inArray(el, els) < 0 )
43076						$.event.remove(el, query.type, query.fn);
43077				});
43078		}
43079		else {
43080			// Call the first function for newly matched elements
43081			nEls.each(function() {
43082				query.fn.apply(this);
43083			});
43084			
43085			// Call the second function for elements no longer matched
43086			if ( this.fn2 && oEls.length > 0 )
43087				$.each(oEls, function(i, el) {
43088					if ( $.inArray(el, els) < 0 )
43089						query.fn2.apply(el);
43090				});
43091		}
43092	}
43093};
43094
43095$.extend($.livequery, {
43096	guid: 0,
43097	queries: [],
43098	queue: [],
43099	running: false,
43100	timeout: null,
43101	
43102	checkQueue: function() {
43103		if ( $.livequery.running && $.livequery.queue.length ) {
43104			var length = $.livequery.queue.length;
43105			// Run each Live Query currently in the queue
43106			while ( length-- )
43107				$.livequery.queries[ $.livequery.queue.shift() ].run();
43108		}
43109	},
43110	
43111	pause: function() {
43112		// Don't run anymore Live Queries until restarted
43113		$.livequery.running = false;
43114	},
43115	
43116	play: function() {
43117		// Restart Live Queries
43118		$.livequery.running = true;
43119		// Request a run of the Live Queries
43120		$.livequery.run();
43121	},
43122	
43123	registerPlugin: function() {
43124		$.each( arguments, function(i,n) {
43125			// Short-circuit if the method doesn't exist
43126			if (!$.fn[n]) return;
43127			
43128			// Save a reference to the original method
43129			var old = $.fn[n];
43130			
43131			// Create a new method
43132			$.fn[n] = function() {
43133				// Call the original method
43134				var r = old.apply(this, arguments);
43135				
43136				// Request a run of the Live Queries
43137				$.livequery.run();
43138				
43139				// Return the original methods result
43140				return r;
43141			}
43142		});
43143	},
43144	
43145	run: function(id) {
43146		if (id != undefined) {
43147			// Put the particular Live Query in the queue if it doesn't already exist
43148			if ( $.inArray(id, $.livequery.queue) < 0 )
43149				$.livequery.queue.push( id );
43150		}
43151		else
43152			// Put each Live Query in the queue if it doesn't already exist
43153			$.each( $.livequery.queries, function(id) {
43154				if ( $.inArray(id, $.livequery.queue) < 0 )
43155					$.livequery.queue.push( id );
43156			});
43157		
43158		// Clear timeout if it already exists
43159		if ($.livequery.timeout) clearTimeout($.livequery.timeout);
43160		// Create a timeout to check the queue and actually run the Live Queries
43161		$.livequery.timeout = setTimeout($.livequery.checkQueue, 20);
43162	},
43163	
43164	stop: function(id) {
43165		if (id != undefined)
43166			// Stop are particular Live Query
43167			$.livequery.queries[ id ].stop();
43168		else
43169			// Stop all Live Queries
43170			$.each( $.livequery.queries, function(id) {
43171				$.livequery.queries[ id ].stop();
43172			});
43173	}
43174});
43175
43176// Register core DOM manipulation methods
43177$.livequery.registerPlugin('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove');
43178
43179// Run Live Queries when the Document is ready
43180$(function() { $.livequery.play(); });
43181
43182
43183// Save a reference to the original init method
43184var init = $.prototype.init;
43185
43186// Create a new init method that exposes two new properties: selector and context
43187$.prototype.init = function(a,c) {
43188	// Call the original init and save the result
43189	var r = init.apply(this, arguments);
43190	
43191	// Copy over properties if they exist already
43192	if (a && a.selector)
43193		r.context = a.context, r.selector = a.selector;
43194		
43195	// Set properties
43196	if ( typeof a == 'string' )
43197		r.context = c || document, r.selector = a;
43198	
43199	// Return the result
43200	return r;
43201};
43202
43203// Give the init function the jQuery prototype for later instantiation (needed after Rev 4091)
43204$.prototype.init.prototype = $.prototype;
43205	
43206})(jQuery);
43207/**
43208 * jQuery.LocalScroll - Animated scrolling navigation, using anchors.
43209 * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
43210 * Dual licensed under MIT and GPL.
43211 * Date: 3/11/2009
43212 * @author Ariel Flesler
43213 * @version 1.2.7
43214 **/
43215
43216;(function($){var l=location.href.replace(/#.*/,'');var g=$.localScroll=function(a){$('body').localScroll(a)};g.defaults={duration:1e3,axis:'y',event:'click',stop:true,target:window,reset:true};
43216g.hash=function(a){if(location.hash){a=$.extend({},g.defaults,a);a.hash=false;if(a.reset){var e=a.duration;delete a.duration;$(a.target).scrollTo(0,a);a.duration=e}i(0,location,a)}};$.fn.localScroll=function(b){b=$.extend({},g.defaults,b);return b.lazy?this.bind(b.event,function(a){var e=$([a.target,a.target.parentNode]).filter(d)[0];if(e)i(a,e,b)}):this.find('a,area').filter(d).bind(b.event,function(a){i(a,this,b)}).end().end();function d(){return!!this.href&&!!this.hash&&this.href.replace(this.hash,'')==l&&(!b.filter||$(this).is(b.filter))}};function i(a,e,b){var d=e.hash.slice(1),f=document.getElementById(d)||document.getElementsByName(d)[0];if(!f)return;if(a)a.preventDefault();var h=$(b.target);if(b.lock&&h.is(':animated')||b.onBefore&&b.onBefore.call(b,a,f,h)===false)return;if(b.stop)h.stop(true);if(b.hash){var j=f.id==d?'id':'name',k=$('<a> </a>').attr(j,d).css({position:'absolute',top:$(window).scrollTop(),left:$(window).scrollLeft()});f[j]='';$('body').prepend(k);location=e.hash;k.remove();f[j]=d}h.scrollTo(f,b).trigger('notify.serialScroll',[f])}})(jQuery);
43217/*
43218	Masked Input plugin for jQuery
43219	Copyright (c) 2007-2013 Josh Bush (digitalbush.com)
43220	Licensed under the MIT license (http://digitalbush.com/projects/masked-input-plugin/#license)
43221	Version: 1.3.1
43222*/
43223
43224(function($) {
43225	function getPasteEvent() {
43226    var el = document.createElement('input'),
43227        name = 'onpaste';
43228    el.setAttribute(name, '');
43229    return (typeof el[name] === 'function')?'paste':'input';             
43230}
43231
43232var pasteEventName = getPasteEvent() + ".mask",
43233	ua = navigator.userAgent,
43234	iPhone = /iphone/i.test(ua),
43235	android=/android/i.test(ua),
43236	caretTimeoutId;
43237
43238$.mask = {
43239	//Predefined character definitions
43240	definitions: {
43241		'9': "[0-9]",
43242		'a': "[A-Za-z]",
43243		'*': "[A-Za-z0-9]"
43244	},
43245	dataName: "rawMaskFn",
43246	placeholder: '_'
43247};
43248
43249$.fn.extend({
43250	//Helper Function for Caret positioning
43251	caret: function(begin, end) {
43252		var range;
43253
43254		if (this.length === 0 || this.is(":hidden")) {
43255			return;
43256		}
43257
43258		if (typeof begin == 'number') {
43259			end = (typeof end === 'number') ? end : begin;
43260			return this.each(function() {
43261				if (this.setSelectionRange) {
43262					this.setSelectionRange(begin, end);
43263				} else if (this.createTextRange) {
43264					range = this.createTextRange();
43265					range.collapse(true);
43266					range.moveEnd('character', end);
43267					range.moveStart('character', begin);
43268					range.select();
43269				}
43270			});
43271		} else {
43272			if (this[0].setSelectionRange) {
43273				begin = this[0].selectionStart;
43274				end = this[0].selectionEnd;
43275			} else if (document.selection && document.selection.createRange) {
43276				range = document.selection.createRange();
43277				begin = 0 - range.duplicate().moveStart('character', -100000);
43278				end = begin + range.text.length;
43279			}
43280			return { begin: begin, end: end };
43281		}
43282	},
43283	unmask: function() {
43284		return this.trigger("unmask");
43285	},
43286	mask: function(mask, settings) {
43287		var input,
43288			defs,
43289			tests,
43290			partialPosition,
43291			firstNonMaskPos,
43292			len;
43293
43294		if (!mask && this.length > 0) {
43295			input = $(this[0]);
43296			return input.data($.mask.dataName)();
43297		}
43298		settings = $.extend({
43299			placeholder: $.mask.placeholder, // Load default placeholder
43300			completed: null
43301		}, settings);
43302
43303
43304		defs = $.mask.definitions;
43305		tests = [];
43306		partialPosition = len = mask.length;
43307		firstNonMaskPos = null;
43308
43309		$.each(mask.split(""), function(i, c) {
43310			if (c == '?') {
43311				len--;
43312				partialPosition = i;
43313			} else if (defs[c]) {
43314				tests.push(new RegExp(defs[c]));
43315				if (firstNonMaskPos === null) {
43316					firstNonMaskPos = tests.length - 1;
43317				}
43318			} else {
43319				tests.push(null);
43320			}
43321		});
43322
43323		return this.trigger("unmask").each(function() {
43324			var input = $(this),
43325				buffer = $.map(
43326				mask.split(""),
43327				function(c, i) {
43328					if (c != '?') {
43329						return defs[c] ? settings.placeholder : c;
43330					}
43331				}),
43332				focusText = input.val();
43333
43334			function seekNext(pos) {
43335				while (++pos < len && !tests[pos]);
43336				return pos;
43337			}
43338
43339			function seekPrev(pos) {
43340				while (--pos >= 0 && !tests[pos]);
43341				return pos;
43342			}
43343
43344			function shiftL(begin,end) {
43345				var i,
43346					j;
43347
43348				if (begin<0) {
43349					return;
43350				}
43351
43352				for (i = begin, j = seekNext(end); i < len; i++) {
43353					if (tests[i]) {
43354						if (j < len && tests[i].test(buffer[j])) {
43355							buffer[i] = buffer[j];
43356							buffer[j] = settings.placeholder;
43357						} else {
43358							break;
43359						}
43360
43361						j = seekNext(j);
43362					}
43363				}
43364				writeBuffer();
43365				input.caret(Math.max(firstNonMaskPos, begin));
43366			}
43367
43368			function shiftR(pos) {
43369				var i,
43370					c,
43371					j,
43372					t;
43373
43374				for (i = pos, c = settings.placeholder; i < len; i++) {
43375					if (tests[i]) {
43376						j = seekNext(i);
43377						t = buffer[i];
43378						buffer[i] = c;
43379						if (j < len && tests[j].test(t)) {
43380							c = t;
43381						} else {
43382							break;
43383						}
43384					}
43385				}
43386			}
43387
43388			function keydownEvent(e) {
43389				var k = e.which,
43390					pos,
43391					begin,
43392					end;
43393
43394				//backspace, delete, and escape get special treatment
43395				if (k === 8 || k === 46 || (iPhone && k === 127)) {
43396					pos = input.caret();
43397					begin = pos.begin;
43398					end = pos.end;
43399
43400					if (end - begin === 0) {
43401						begin=k!==46?seekPrev(begin):(end=seekNext(begin-1));
43402						end=k===46?seekNext(end):end;
43403					}
43404					clearBuffer(begin, end);
43405					shiftL(begin, end - 1);
43406
43407					e.preventDefault();
43408				} else if (k == 27) {//escape
43409					input.val(focusText);
43410					input.caret(0, checkVal());
43411					e.preventDefault();
43412				}
43413			}
43414
43415			function keypressEvent(e) {
43416				var k = e.which,
43417					pos = input.caret(),
43418					p,
43419					c,
43420					next;
43421
43422				if (e.ctrlKey || e.altKey || e.metaKey || k < 32) {//Ignore
43423					return;
43424				} else if (k) {
43425					if (pos.end - pos.begin !== 0){
43426						clearBuffer(pos.begin, pos.end);
43427						shiftL(pos.begin, pos.end-1);
43428					}
43429
43430					p = seekNext(pos.begin - 1);
43431					if (p < len) {
43432						c = String.fromCharCode(k);
43433						if (tests[p].test(c)) {
43434							shiftR(p);
43435
43436							buffer[p] = c;
43437							writeBuffer();
43438							next = seekNext(p);
43439
43440							if(android){
43441								setTimeout($.proxy($.fn.caret,input,next),0);
43442							}else{
43443								input.caret(next);
43444							}
43445
43446							if (settings.completed && next >= len) {
43447								settings.completed.call(input);
43448							}
43449						}
43450					}
43451					e.preventDefault();
43452				}
43453			}
43454
43455			function clearBuffer(start, end) {
43456				var i;
43457				for (i = start; i < end && i < len; i++) {
43458					if (tests[i]) {
43459						buffer[i] = settings.placeholder;
43460					}
43461				}
43462			}
43463
43464			function writeBuffer() { input.val(buffer.join('')); }
43465
43466			function checkVal(allow) {
43467				//try to place characters where they belong
43468				var test = input.val(),
43469					lastMatch = -1,
43470					i,
43471					c;
43472
43473				for (i = 0, pos = 0; i < len; i++) {
43474					if (tests[i]) {
43475						buffer[i] = settings.placeholder;
43476						while (pos++ < test.length) {
43477							c = test.charAt(pos - 1);
43478							if (tests[i].test(c)) {
43479								buffer[i] = c;
43480								lastMatch = i;
43481								break;
43482							}
43483						}
43484						if (pos > test.length) {
43485							break;
43486						}
43487					} else if (buffer[i] === test.charAt(pos) && i !== partialPosition) {
43488						pos++;
43489						lastMatch = i;
43490					}
43491				}
43492				if (allow) {
43493					writeBuffer();
43494				} else if (lastMatch + 1 < partialPosition) {
43495					input.val("");
43496					clearBuffer(0, len);
43497				} else {
43498					writeBuffer();
43499					input.val(input.val().substring(0, lastMatch + 1));
43500				}
43501				return (partialPosition ? i : firstNonMaskPos);
43502			}
43503
43504			input.data($.mask.dataName,function(){
43505				return $.map(buffer, function(c, i) {
43506					return tests[i]&&c!=settings.placeholder ? c : null;
43507				}).join('');
43508			});
43509
43510			if (!input.attr("readonly"))
43511				input
43512				.one("unmask", function() {
43513					input
43514						.unbind(".mask")
43515						.removeData($.mask.dataName);
43516				})
43517				.bind("focus.mask", function() {
43518					clearTimeout(caretTimeoutId);
43519					var pos,
43520						moveCaret;
43521
43522					focusText = input.val();
43523					pos = checkVal();
43524					
43525					caretTimeoutId = setTimeout(function(){
43526						writeBuffer();
43527						if (pos == mask.length) {
43528							input.caret(0, pos);
43529						} else {
43530							input.caret(pos);
43531						}
43532					}, 10);
43533				})
43534				.bind("blur.mask", function() {
43535					checkVal();
43536					if (input.val() != focusText)
43537						input.change();
43538				})
43539				.bind("keydown.mask", keydownEvent)
43540				.bind("keypress.mask", keypressEvent)
43541				.bind(pasteEventName, function() {
43542					setTimeout(function() { 
43543						var pos=checkVal(true);
43544						input.caret(pos); 
43545						if (settings.completed && pos == input.val().length)
43546							settings.completed.call(input);
43547					}, 0);
43548				});
43549			checkVal(); //Perform initial check for existing values
43550		});
43551	}
43552});
43553
43554
43555})(jQuery);
43556/**
43557 * Copyright (c) 2007-2012 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
43558 * Dual licensed under MIT and GPL.
43559 * @author Ariel Flesler
43560 * @version 1.4.3.1
43561 */
43562
43563;(function($){var h=$.scrollTo=function(a,b,c){$(window).scrollTo(a,b,c)};h.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1,limit:true};h.window=function(a){return $(window)._scrollable()};$.fn._scrollable=function(){return this.map(function(){var a=this,isWin=!a.nodeName||$.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!isWin)return a;var b=(a.contentWindow||a).document||a.ownerDocument||a;return/webkit/i.test(navigator.userAgent)||b.compatMode=='BackCompat'?b.body:b.documentElement})};$.fn.scrollTo=function(e,f,g){if(typeof f=='object'){g=f;f=0}if(typeof g=='function')g={onAfter:g};if(e=='max')e=9e9;g=$.extend({},h.defaults,g);f=f||g.duration;g.queue=g.queue&&g.axis.length>1;if(g.queue)f/=2;g.offset=both(g.offset);g.over=both(g.over);return this._scrollable().each(function(){if(e==null)return;var d=this,$elem=$(d),targ=e,toff,attr={},win=$elem.is('html,body');switch(typeof targ){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ)){targ=both(targ);break}targ=$(targ,this);if(!targ.length)return;case'object':if(targ.is||targ.style)toff=(targ=$(targ)).offset()}$.each(g.axis.split(''),function(i,a){var b=a=='x'?'Left':'Top',pos=b.toLowerCase(),key='scroll'+b,old=d[key],max=h.max(d,a);if(toff){attr[key]=toff[pos]+(win?0:old-$elem.offset()[pos]);if(g.margin){attr[key]-=parseInt(targ.css('margin'+b))||0;attr[key]-=parseInt(targ.css('border'+b+'Width'))||0}attr[key]+=g.offset[pos]||0;if(g.over[pos])attr[key]+=targ[a=='x'?'width':'height']()*g.over[pos]}else{var c=targ[pos];attr[key]=c.slice&&c.slice(-1)=='%'?parseFloat(c)/100*max:c}if(g.limit&&/^\d+$/.test(attr[key]))attr[key]=attr[key]<=0?0:Math.min(attr[key],max);if(!i&&g.queue){if(old!=attr[key])animate(g.onAfterFirst);delete attr[key]}});animate(g.onAfter);function animate(a){$elem.animate(attr,f,g.easing,a&&function(){a.call(this,e,g)})}}).end()};h.max=function(a,b){var c=b=='x'?'Width':'Height',scroll='scroll'+c;if(!$(a).is('html,body'))return a[scroll]-$(a)[c.toLowerCase()]();var d='client'+c,html=a.ownerDocument.documentElement,body=a.ownerDocument.body;return Math.max(html[scroll],body[scroll])-Math.min(html[d],body[d])};function both(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
43564/*!
43565 * jQuery Transit - CSS3 transitions and transformations
43566 * (c) 2011-2012 Rico Sta. Cruz <[email protected]>
43567 * MIT Licensed.
43568 *
43569 * http://ricostacruz.com/jquery.transit
43570 * http://github.com/rstacruz/jquery.transit
43571 */
43572
43573(function(k){k.transit={version:"0.9.9",propertyMap:{marginLeft:"margin",marginRight:"margin",marginBottom:"margin",marginTop:"margin",paddingLeft:"padding",paddingRight:"padding",paddingBottom:"padding",paddingTop:"padding"},enabled:true,useTransitionEnd:false};var d=document.createElement("div");var q={};function b(v){if(v in d.style){return v}var u=["Moz","Webkit","O","ms"];var r=v.charAt(0).toUpperCase()+v.substr(1);if(v in d.style){return v}for(var t=0;t<u.length;++t){var s=u[t]+r;if(s in d.style){return s}}}function e(){d.style[q.transform]="";d.style[q.transform]="rotateY(90deg)";return d.style[q.transform]!==""}var a=navigator.userAgent.toLowerCase().indexOf("chrome")>-1;q.transition=b("transition");q.transitionDelay=b("transitionDelay");q.transform=b("transform");q.transformOrigin=b("transformOrigin");q.transform3d=e();var i={transition:"transitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",WebkitTransition:"webkitTransitionEnd",msTransition:"MSTransitionEnd"};var f=q.transitionEnd=i[q.transition]||null;for(var p in q){if(q.hasOwnProperty(p)&&typeof k.support[p]==="undefined"){k.support[p]=q[p]}}d=null;k.cssEase={_default:"ease","in":"ease-in",out:"ease-out","in-out":"ease-in-out",snap:"cubic-bezier(0,1,.5,1)",easeOutCubic:"cubic-bezier(.215,.61,.355,1)",easeInOutCubic:"cubic-bezier(.645,.045,.355,1)",easeInCirc:"cubic-bezier(.6,.04,.98,.335)",easeOutCirc:"cubic-bezier(.075,.82,.165,1)",easeInOutCirc:"cubic-bezier(.785,.135,.15,.86)",easeInExpo:"cubic-bezier(.95,.05,.795,.035)",easeOutExpo:"cubic-bezier(.19,1,.22,1)",easeInOutExpo:"cubic-bezier(1,0,0,1)",easeInQuad:"cubic-bezier(.55,.085,.68,.53)",easeOutQuad:"cubic-bezier(.25,.46,.45,.94)",easeInOutQuad:"cubic-bezier(.455,.03,.515,.955)",easeInQuart:"cubic-bezier(.895,.03,.685,.22)",easeOutQuart:"cubic-bezier(.165,.84,.44,1)",easeInOutQuart:"cubic-bezier(.77,0,.175,1
43573)",easeInQuint:"cubic-bezier(.755,.05,.855,.06)",easeOutQuint:"cubic-bezier(.23,1,.32,1)",easeInOutQuint:"cubic-bezier(.86,0,.07,1)",easeInSine:"cubic-bezier(.47,0,.745,.715)",easeOutSine:"cubic-bezier(.39,.575,.565,1)",easeInOutSine:"cubic-bezier(.445,.05,.55,.95)",easeInBack:"cubic-bezier(.6,-.28,.735,.045)",easeOutBack:"cubic-bezier(.175, .885,.32,1.275)",easeInOutBack:"cubic-bezier(.68,-.55,.265,1.55)"};k.cssHooks["transit:transform"]={get:function(r){return k(r).data("transform")||new j()},set:function(s,r){var t=r;if(!(t instanceof j)){t=new j(t)}if(q.transform==="WebkitTransform"&&!a){s.style[q.transform]=t.toString(true)}else{s.style[q.transform]=t.toString()}k(s).data("transform",t)}};k.cssHooks.transform={set:k.cssHooks["transit:transform"].set};if(k.fn.jquery<"1.8"){k.cssHooks.transformOrigin={get:function(r){return r.style[q.transformOrigin]},set:function(r,s){r.style[q.transformOrigin]=s}};k.cssHooks.transition={get:function(r){return r.style[q.transition]},set:function(r,s){r.style[q.transition]=s}}}n("scale");n("translate");n("rotate");n("rotateX");n("rotateY");n("rotate3d");n("perspective");n("skewX");n("skewY");n("x",true);n("y",true);function j(r){if(typeof r==="string"){this.parse(r)}return this}j.prototype={setFromString:function(t,s){var r=(typeof s==="string")?s.split(","):(s.constructor===Array)?s:[s];r.unshift(t);j.prototype.set.apply(this,r)},set:function(s){var r=Array.prototype.slice.apply(arguments,[1]);if(this.setter[s]){this.setter[s].apply(this,r)}else{this[s]=r.join(",")}},get:function(r){if(this.getter[r]){return this.getter[r].apply(this)}else{return this[r]||0}},setter:{rotate:function(r){this.rotate=o(r,"deg")},rotateX:function(r){this.rotateX=o(r,"deg")},rotateY:function(r){this.rotateY=o(r,"deg")},scale:function(r,s){if(s===undefined){s=r}this.scale=r+","+s},skewX:function(r){this.skewX=o(r,"deg")},skewY:function(r){this.skewY=o(r,"deg")},perspective:function(r){this.perspective=o(r,"px")},x:function(r){this.set("translate",r,null)},y:function(r){this.set("translate",null,r)},translate:function(r,s){if(this._translateX===undefined){this._translateX=0}if(this._translateY===undefined){this._translateY=0}if(r!==null&&r!==undefined){this._translateX=o(r,"px")}if(s!==null&&s!==undefined){this._translateY=o(s,"px")}
43573this.translate=this._translateX+","+this._translateY}},getter:{x:function(){return this._translateX||0},y:function(){return this._translateY||0},scale:function(){var r=(this.scale||"1,1").split(",");if(r[0]){r[0]=parseFloat(r[0])}if(r[1]){r[1]=parseFloat(r[1])}return(r[0]===r[1])?r[0]:r},rotate3d:function(){var t=(this.rotate3d||"0,0,0,0deg").split(",");for(var r=0;r<=3;++r){if(t[r]){t[r]=parseFloat(t[r])}}if(t[3]){t[3]=o(t[3],"deg")}return t}},parse:function(s){var r=this;s.replace(/([a-zA-Z0-9]+)\((.*?)\)/g,function(t,v,u){r.setFromString(v,u)})},toString:function(t){var s=[];for(var r in this){if(this.hasOwnProperty(r)){if((!q.transform3d)&&((r==="rotateX")||(r==="rotateY")||(r==="perspective")||(r==="transformOrigin"))){continue}if(r[0]!=="_"){if(t&&(r==="scale")){s.push(r+"3d("+this[r]+",1)")}else{if(t&&(r==="translate")){s.push(r+"3d("+this[r]+",0)")}else{s.push(r+"("+this[r]+")")}}}}}return s.join(" ")}};function m(s,r,t){if(r===true){s.queue(t)}else{if(r){s.queue(r,t)}else{t()}}}function h(s){var r=[];k.each(s,function(t){t=k.camelCase(t);t=k.transit.propertyMap[t]||k.cssProps[t]||t;t=c(t);if(k.inArray(t,r)===-1){r.push(t)}});return r}function g(s,v,x,r){var t=h(s);if(k.cssEase[x]){x=k.cssEase[x]}var w=""+l(v)+" "+x;if(parseInt(r,10)>0){w+=" "+l(r)}var u=[];k.each(t,function(z,y){u.push(y+" "+w)});return u.join(", ")}k.fn.transition=k.fn.transit=function(z,s,y,C){var D=this;var u=0;var w=true;if(typeof s==="function"){C=s;s=undefined}if(typeof y==="function"){C=y;y=undefined}if(typeof z.easing!=="undefined"){y=z.easing;delete z.easing}if(typeof z.duration!=="undefined"){s=z.duration;delete z.duration}if(typeof z.complete!=="undefined"){C=z.complete;delete z.complete}if(typeof z.queue!=="undefined"){w=z.queue;delete z.queue}if(typeof z.delay!=="undefined"){u=z.delay;delete z.delay}if(typeof s==="undefined"){s=k.fx.speeds._default}if(typeof y==="undefined"){y=k.cssEase._default}s=l(s);var E=g(z,s,y,u);var B=k.transit.enabled&&q.transition;var t=B?(parseInt(s,10)+parseInt(u,10)):0;if(t===0){var A=function(F){D.css(z);if(C){C.apply(D)}if(F){F()}};m(D,w,A);return D}var x={};var r=function(H){var G=false;var F=function(){if(G){D.unbind(f,F)}if(t>0){D.each(function(){this.style[q.transition]=(x[this]||null)})}if(typeof C==="function"){C.apply(D)}if(typeof H==="function"){H()}};if((t>0)&&(f)&&(k.transit.useTransitionEnd)){G=true;D.bind(f,F)}else{window.setTimeout(F,t)}D.each(function(){if(t>0){this.style[q.transition]=E}k(this).css(z)})};var v=function(F){this.offsetWidth;r(F)};m(D,w,v);return this};function n(s,r){if(!r){k.cssNumber[s]=true}k.transit.propertyMap[s]=q.transform;k.cssHooks[s]={get:function(v){var u=k(v).css("transit:transform");return u.get(s)},set:function(v,w){var u=k(v).css("transit:transform");u.setFromString(s,w);k(v).css({"transit:transform":u})}}}function c(r){return r.replace(/([A-Z])/g,function(s){return"-"+s.toLowerCase()})}function o(s,r){if((typeof s==="string")&&(!s.match(/^[\-0-9\.]+$/))){return s}else{return""+s+r}}function l(s){var r=s;if(k.fx.speeds[r]){r=k.fx.speeds[r]}return o(r,"ms")}k.transit.getTransitionValue=g})(jQuery);
43574// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
43575// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
43576// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
43577jQuery.validator.addMethod("creditcardtypes", function(value, element, param) {
43578  if (/[^0-9\-]+/.test(value)) {
43579    return false;
43580  }
43581
43582  value = value.replace(/\D/g, "");
43583
43584  var validTypes = 0x0000;
43585
43586  if (param.mastercard) {
43587    validTypes |= 0x0001;
43588  }
43589  if (param.visa) {
43590    validTypes |= 0x0002;
43591  }
43592  if (param.amex) {
43593    validTypes |= 0x0004;
43594  }
43595  if (param.dinersclub) {
43596    validTypes |= 0x0008;
43597  }
43598  if (param.enroute) {
43599    validTypes |= 0x0010;
43600  }
43601  if (param.discover) {
43602    validTypes |= 0x0020;
43603  }
43604  if (param.jcb) {
43605    validTypes |= 0x0040;
43606  }
43607  if (param.unknown) {
43608    validTypes |= 0x0080;
43609  }
43610  if (param.all) {
43611    validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
43612  }
43613  if (validTypes & 0x0001 && /^(5[12345])/.test(value)) { //mastercard
43614    return value.length === 16;
43615  }
43616  if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa
43617    return value.length === 16;
43618  }
43619  if (validTypes & 0x0004 && /^(3[47])/.test(value)) { //amex
43620    return value.length === 15;
43621  }
43622  if (validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test(value)) { //dinersclub
43623    return value.length === 14;
43624  }
43625  if (validTypes & 0x0010 && /^(2(014|149))/.test(value)) { //enroute
43626    return value.length === 15;
43627  }
43628  if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover
43629    return value.length === 16;
43630  }
43631  if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb
43632    return value.length === 16;
43633  }
43634  if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb
43635    return value.length === 15;
43636  }
43637  if (validTypes & 0x0080) { //unknown
43638    return true;
43639  }
43640  return false;
43641}, "Please enter a valid credit card number.");
43642
43643jQuery.validator.addMethod("creditcardexpirymonth", function(value, element, param) {
43644  var today = new Date();
43645  var month = today.getMonth() + 1;
43646  var year = today.getFullYear() - 2000;
43647  
43648  var input_month = parseInt( $("#cc_expiry_month").val(), 10);
43649  var input_year = parseInt( $("#cc_expiry_year").val(), 10);
43650
43651  return (input_month >= month && input_year >= year) || input_year > year;
43652
43653}, "Please enter a valid expiry month.");
43654
43655jQuery.validator.addMethod("creditcardexpiryyear", function(value, element, param) {
43656  var today = new Date();
43657  var year = today.getFullYear() - 2000;
43658  
43659  var input_year = parseInt( $("#cc_expiry_year").val(), 10);
43660  
43661  // trigger evaluation of the month field so we can check if 
43662  // combination of month and year is valid. this has to run assync so it doesn't 
43663  // crashes the validator ability to check all fields
43664  setTimeout(function(){ $(".complete_checkout").validate().element('#cc_expiry_month'); }, 1000);
43665  
43666  return input_year >= year;
43667
43668}, "Please enter a valid expiry year.");
43669/*
43670    The MIT License (MIT)
43671    Copyright (c) 2014 Dirk Groenen
43672    Permission is hereby granted, free of charge, to any person obtaining a copy of
43673    this software and associated documentation files (the "Software"), to deal in
43674    the Software without restriction, including without limitation the rights to
43675    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
43676    the Software, and to permit persons to whom the Software is furnished to do so,
43677    subject to the following conditions:
43678    The above copyright notice and this permission notice shall be included in all
43679    copies or substantial portions of the Software.
43680*/
43681
43682
43683(function($){
43684    $.fn.viewportChecker = function(useroptions){
43685        // Define options and extend with user
43686        var options = {
43687            classToAdd: 'visible',
43688            classToRemove : 'invisible',
43689            classToAddForFullView : 'full-visible',
43690            removeClassAfterAnimation: false,
43691            offset: 100,
43692            repeat: false,
43693            invertBottomOffset: true,
43694            callbackFunction: function(elem, action){},
43695            scrollHorizontal: false,
43696            scrollBox: window
43697        };
43698        $.extend(options, useroptions);
43699
43700        // Cache the given element and height of the browser
43701        var $elem = this,
43702            boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()};
43703
43704        /*
43705         * Main method that checks the elements and adds or removes the class(es)
43706         */
43707        this.checkElements = function(){
43708            var viewportStart, viewportEnd;
43709
43710            // Set some vars to check with
43711            if (!options.scrollHorizontal){
43712                viewportStart = Math.max(
43713                    $('html').scrollTop(),
43714                    $('body').scrollTop(),
43715                    $(window).scrollTop()
43716                );
43717                viewportEnd = (viewportStart + boxSize.height);
43718            }
43719            else{
43720                viewportStart = Math.max(
43721                    $('html').scrollLeft(),
43722                    $('body').scrollLeft(),
43723                    $(window).scrollLeft()
43724                );
43725                viewportEnd = (viewportStart + boxSize.width);
43726            }
43727
43728            // Loop through all given dom elements
43729            $elem.each(function(){
43730                var $obj = $(this),
43731                    objOptions = {},
43732                    attrOptions = {};
43733
43734                //  Get any individual attribution data
43735                if ($obj.data('vp-add-class'))
43736                    attrOptions.classToAdd = $obj.data('vp-add-class');
43737                if ($obj.data('vp-remove-class'))
43738                    attrOptions.classToRemove = $obj.data('vp-remove-class');
43739                if ($obj.data('vp-add-class-full-view'))
43740                    attrOptions.classToAddForFullView = $obj.data('vp-add-class-full-view');
43741                if ($obj.data('vp-keep-add-class'))
43742                    attrOptions.removeClassAfterAnimation = $obj.data('vp-remove-after-animation');
43743                if ($obj.data('vp-offset'))
43744                    attrOptions.offset = $obj.data('vp-offset');
43745                if ($obj.data('vp-repeat'))
43746                    attrOptions.repeat = $obj.data('vp-repeat');
43747                if ($obj.data('vp-scrollHorizontal'))
43748                    attrOptions.scrollHorizontal = $obj.data('vp-scrollHorizontal');
43749                if ($obj.data('vp-invertBottomOffset'))
43750                    attrOptions.scrollHorizontal = $obj.data('vp-invertBottomOffset');
43751
43752                // Extend objOptions with data attributes and default options
43753                $.extend(objOptions, options);
43754                $.extend(objOptions, attrOptions);
43755
43756                // If class already exists; quit
43757                if ($obj.data('vp-animated') && !objOptions.repeat){
43758                    return;
43759                }
43760
43761                // Check if the offset is percentage based
43762                if (String(objOptions.offset).indexOf("%") > 0)
43763                    objOptions.offset = (parseInt(objOptions.offset) / 100) * boxSize.height;
43764
43765                // Get the raw start and end positions
43766                var rawStart = (!objOptions.scrollHorizontal) ? $obj.offset().top : $obj.offset().left,
43767                    rawEnd = (!objOptions.scrollHorizontal) ? rawStart + $obj.height() : rawStart + $obj.width();
43768
43769                // Add the defined offset
43770                var elemStart = Math.round( rawStart ) + objOptions.offset,
43771                    elemEnd = (!objOptions.scrollHorizontal) ? elemStart + $obj.height() : elemStart + $obj.width();
43772
43773                if (objOptions.invertBottomOffset)
43774                    elemEnd -= (objOptions.offset * 2);
43775
43776                // Add class if in viewport
43777                if ((elemStart < viewportEnd) && (elemEnd > viewportStart)){
43778
43779                    // Remove class
43780                    $obj.removeClass(objOptions.classToRemove);
43781                    $obj.addClass(objOptions.classToAdd);
43782
43783                    // Do the callback function. Callback wil send the jQuery object as parameter
43784                    objOptions.callbackFunction($obj, "add");
43785
43786                    // Check if full element is in view
43787                    if (rawEnd <= viewportEnd && rawStart >= viewportStart)
43788                        $obj.addClass(objOptions.classToAddForFullView);
43789                    else
43790                        $obj.removeClass(objOptions.classToAddForFullView);
43791
43792                    // Set element as already animated
43793                    $obj.data('vp-animated', true);
43794
43795                    if (objOptions.removeClassAfterAnimation) {
43796                        $obj.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){
43797                            $obj.removeClass(objOptions.classToAdd);
43798                        });
43799                    }
43800
43801                // Remove class if not in viewport and repeat is true
43802                } else if ($obj.hasClass(objOptions.classToAdd) && (objOptions.repeat)){
43803                    $obj.removeClass(objOptions.classToAdd + " " + objOptions.classToAddForFullView);
43804
43805                    // Do the callback function.
43806                    objOptions.callbackFunction($obj, "remove");
43807
43808                    // Remove already-animated-flag
43809                    $obj.data('vp-animated', false);
43810                }
43811            });
43812
43813        };
43814
43815        /**
43816         * Binding the correct event listener is still a tricky thing.
43817         * People have expierenced sloppy scrolling when both scroll and touch
43818         * events are added, but to make sure devices with both scroll and touch
43819         * are handles too we always have to add the window.scroll event
43820         *
43821         * @see  https://github.com/dirkgroenen/jQuery-viewport-checker/issues/25
43822         * @see  https://github.com/dirkgroenen/jQuery-viewport-checker/issues/27
43823         */
43824
43825        // Select the correct events
43826        if( 'ontouchstart' in window || 'onmsgesturechange' in window ){
43827            // Device with touchscreen
43828            $(document).bind("touchmove MSPointerMove pointermove", this.checkElements);
43829        }
43830
43831        // Always load on window load
43832        $(options.scrollBox).bind("load scroll", this.checkElements);
43833
43834        // On resize change the height var
43835        $(window).resize(function(e){
43836            boxSize = {height: $(options.scrollBox).height(), width: $(options.scrollBox).width()};
43837            $elem.checkElements();
43838        });
43839
43840        // trigger inital check if elements already visible
43841        this.checkElements();
43842
43843        // Default jquery plugin behaviour
43844        return this;
43845    };
43846})(jQuery);
43847/*
43848    json2.js
43849    2011-10-19
43850
43851    Public Domain.
43852
43853    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
43854
43855    See http://www.JSON.org/js.html
43856
43857
43858    This code should be minified before deployment.
43859    See http://javascript.crockford.com/jsmin.html
43860
43861    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
43862    NOT CONTROL.
43863
43864
43865    This file creates a global JSON object containing two methods: stringify
43866    and parse.
43867
43868        JSON.stringify(value, replacer, space)
43869            value       any JavaScript value, usually an object or array.
43870
43871            replacer    an optional parameter that determines how object
43872                        values are stringified for objects. It can be a
43873                        function or an array of strings.
43874
43875            space       an optional parameter that specifies the indentation
43876                        of nested structures. If it is omitted, the text will
43877                        be packed without extra whitespace. If it is a number,
43878                        it will specify the number of spaces to indent at each
43879                        level. If it is a string (such as '\t' or '&nbsp;'),
43880                        it contains the characters used to indent at each level.
43881
43882            This method produces a JSON text from a JavaScript value.
43883
43884            When an object value is found, if the object contains a toJSON
43885            method, its toJSON method will be called and the result will be
43886            stringified. A toJSON method does not serialize: it returns the
43887            value represented by the name/value pair that should be serialized,
43888            or undefined if nothing should be serialized. The toJSON method
43889            will be passed the key associated with the value, and this will be
43890            bound to the value
43891
43892            For example, this would serialize Dates as ISO strings.
43893
43894                Date.prototype.toJSON = function (key) {
43895                    function f(n) {
43896                        // Format integers to have at least two digits.
43897                        return n < 10 ? '0' + n : n;
43898                    }
43899
43900                    return this.getUTCFullYear()   + '-' +
43901                         f(this.getUTCMonth() + 1) + '-' +
43902                         f(this.getUTCDate())      + 'T' +
43903                         f(this.getUTCHours())     + ':' +
43904                         f(this.getUTCMinutes())   + ':' +
43905                         f(this.getUTCSeconds())   + 'Z';
43906                };
43907
43908            You can provide an optional replacer method. It will be passed the
43909            key and value of each member, with this bound to the containing
43910            object. The value that is returned from your method will be
43911            serialized. If your method returns undefined, then the member will
43912            be excluded from the serialization.
43913
43914            If the replacer parameter is an array of strings, then it will be
43915            used to select the members to be serialized. It filters the results
43916            such that only members with keys listed in the replacer array are
43917            stringified.
43918
43919            Values that do not have JSON representations, such as undefined or
43920            functions, will not be serialized. Such values in objects will be
43921            dropped;
43921 in arrays they will be replaced with null. You can use
43922            a replacer function to replace those with JSON values.
43923            JSON.stringify(undefined) returns undefined.
43924
43925            The optional space parameter produces a stringification of the
43926            value that is filled with line breaks and indentation to make it
43927            easier to read.
43928
43929            If the space parameter is a non-empty string, then that string will
43930            be used for indentation. If the space parameter is a number, then
43931            the indentation will be that many spaces.
43932
43933            Example:
43934
43935            text = JSON.stringify(['e', {pluribus: 'unum'}]);
43936            // text is '["e",{"pluribus":"unum"}]'
43937
43938
43939            text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
43940            // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
43941
43942            text = JSON.stringify([new Date()], function (key, value) {
43943                return this[key] instanceof Date ?
43944                    'Date(' + this[key] + ')' : value;
43945            });
43946            // text is '["Date(---current time---)"]'
43947
43948
43949        JSON.parse(text, reviver)
43950            This method parses a JSON text to produce an object or array.
43951            It can throw a SyntaxError exception.
43952
43953            The optional reviver parameter is a function that can filter and
43954            transform the results. It receives each of the keys and values,
43955            and its return value is used instead of the original value.
43956            If it returns what it received, then the structure is not modified.
43957            If it returns undefined then the member is deleted.
43958
43959            Example:
43960
43961            // Parse the text. Values that look like ISO date strings will
43962            // be converted to Date objects.
43963
43964            myData = JSON.parse(text, function (key, value) {
43965                var a;
43966                if (typeof value === 'string') {
43967                    a =
43968/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
43969                    if (a) {
43970                        return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
43971                            +a[5], +a[6]));
43972                    }
43973                }
43974                return value;
43975            });
43976
43977            myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
43978                var d;
43979                if (typeof value === 'string' &&
43980                        value.slice(0, 5) === 'Date(' &&
43981                        value.slice(-1) === ')') {
43982                    d = new Date(value.slice(5, -1));
43983                    if (d) {
43984                        return d;
43985                    }
43986                }
43987                return value;
43988            });
43989
43990
43991    This is a reference implementation. You are free to copy, modify, or
43992    redistribute.
43993*/
43994
43995/*jslint evil: true, regexp: true */
43996
43997/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
43998    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
43999    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
44000    lastIndex, length, parse, prototype, push, replace, slice, stringify,
44001    test, toJSON, toString, valueOf
44002*/
44003
44004
44005// Create a JSON object only if one does not already exist. We create the
44006// methods in a closure to avoid creating global variables.
44007
44008var JSON;
44009if (!JSON) {
44010    JSON = {};
44011}
44012
44013(function () {
44014    'use strict';
44015
44016    function f(n) {
44017        // Format integers to have at least two digits.
44018        return n < 10 ? '0' + n : n;
44019    }
44020
44021    if (typeof Date.prototype.toJSON !== 'function') {
44022
44023        Date.prototype.toJSON = function (key) {
44024
44025            return isFinite(this.valueOf())
44026                ? this.getUTCFullYear()     + '-' +
44027                    f(this.getUTCMonth() + 1) + '-' +
44028                    f(this.getUTCDate())      + 'T' +
44029                    f(this.getUTCHours())     + ':' +
44030                    f(this.getUTCMinutes())   + ':' +
44031                    f(this.getUTCSeconds())   + 'Z'
44032                : null;
44033        };
44034
44035        String.prototype.toJSON      =
44036            Number.prototype.toJSON  =
44037            Boolean.prototype.toJSON = function (key
vendor: 10,100 bytes, lines 44037-44333
44037) {
44038                return this.valueOf();
44039            };
44040    }
44041
44042    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
44043        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
44044        gap,
44045        indent,
44046        meta = {    // table of character substitutions
44047            '\b': '\\b',
44048            '\t': '\\t',
44049            '\n': '\\n',
44050            '\f': '\\f',
44051            '\r': '\\r',
44052            '"' : '\\"',
44053            '\\': '\\\\'
44054        },
44055        rep;
44056
44057
44058    function quote(string) {
44059
44060// If the string contains no control characters, no quote characters, and no
44061// backslash characters, then we can safely slap some quotes around it.
44062// Otherwise we must also replace the offending characters with safe escape
44063// sequences.
44064
44065        escapable.lastIndex = 0;
44066        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
44067            var c = meta[a];
44068            return typeof c === 'string'
44069                ? c
44070                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
44071        }) + '"' : '"' + string + '"';
44072    }
44073
44074
44075    function str(key, holder) {
44076
44077// Produce a string from holder[key].
44078
44079        var i,          // The loop counter.
44080            k,          // The member key.
44081            v,          // The member value.
44082            length,
44083            mind = gap,
44084            partial,
44085            value = holder[key];
44086
44087// If the value has a toJSON method, call it to obtain a replacement value.
44088
44089        if (value && typeof value === 'object' &&
44090                typeof value.toJSON === 'function') {
44091            value = value.toJSON(key);
44092        }
44093
44094// If we were called with a replacer function, then call the replacer to
44095// obtain a replacement value.
44096
44097        if (typeof rep === 'function') {
44098            value = rep.call(holder, key, value);
44099        }
44100
44101// What happens next depends on the value's type.
44102
44103        switch (typeof value) {
44104        case 'string':
44105            return quote(value);
44106
44107        case 'number':
44108
44109// JSON numbers must be finite. Encode non-finite numbers as null.
44110
44111            return isFinite(value) ? String(value) : 'null';
44112
44113        case 'boolean':
44114        case 'null':
44115
44116// If the value is a boolean or null, convert it to a string. Note:
44117// typeof null does not produce 'null'. The case is included here in
44118// the remote chance that this gets fixed someday.
44119
44120            return String(value);
44121
44122// If the type is 'object', we might be dealing with an object or an array or
44123// null.
44124
44125        case 'object':
44126
44127// Due to a specification blunder in ECMAScript, typeof null is 'object',
44128// so watch out for that case.
44129
44130            if (!value) {
44131                return 'null';
44132            }
44133
44134// Make an array to hold the partial results of stringifying this object value.
44135
44136            gap += indent;
44137            partial = [];
44138
44139// Is the value an array?
44140
44141            if (Object.prototype.toString.apply(value) === '[object Array]') {
44142
44143// The value is an array. Stringify every element. Use null as a placeholder
44144// for non-JSON values.
44145
44146                length = value.length;
44147                for (i = 0; i < length; i += 1) {
44148                    partial[i] = str(i, value) || 'null';
44149                }
44150
44151// Join all of the elements together, separated with commas, and wrap them in
44152// brackets.
44153
44154                v = partial.length === 0
44155                    ? '[]'
44156                    : gap
44157                    ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
44158                    : '[' + partial.join(',') + ']';
44159                gap = mind;
44160                return v;
44161            }
44162
44163// If the replacer is an array, use it to select the members to be stringified.
44164
44165            if (rep && typeof rep === 'object') {
44166                length = rep.length;
44167                for (i = 0; i < length; i += 1) {
44168                    if (typeof rep[i] === 'string') {
44169                        k = rep[i];
44170                        v = str(k, value);
44171                        if (v) {
44172                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
44173                        }
44174                    }
44175                }
44176            } else {
44177
44178// Otherwise, iterate through all of the keys in the object.
44179
44180                for (k in value) {
44181                    if (Object.prototype.hasOwnProperty.call(value, k)) {
44182                        v = str(k, value);
44183                        if (v) {
44184                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
44185                        }
44186                    }
44187                }
44188            }
44189
44190// Join all of the member texts together, separated with commas,
44191// and wrap them in braces.
44192
44193            v = partial.length === 0
44194                ? '{}'
44195                : gap
44196                ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
44197                : '{' + partial.join(',') + '}';
44198            gap = mind;
44199            return v;
44200        }
44201    }
44202
44203// If the JSON object does not yet have a stringify method, give it one.
44204
44205    if (typeof JSON.stringify !== 'function') {
44206        JSON.stringify = function (value, replacer, space) {
44207
44208// The stringify method takes a value and an optional replacer, and an optional
44209// space parameter, and returns a JSON text. The replacer can be a function
44210// that can replace values, or an array of strings that will select the keys.
44211// A default replacer method can be provided. Use of the space parameter can
44212// produce text that is more easily readable.
44213
44214            var i;
44215            gap = '';
44216            indent = '';
44217
44218// If the space parameter is a number, make an indent string containing that
44219// many spaces.
44220
44221            if (typeof space === 'number') {
44222                for (i = 0; i < space; i += 1) {
44223                    indent += ' ';
44224                }
44225
44226// If the space parameter is a string, it will be used as the indent string.
44227
44228            } else if (typeof space === 'string') {
44229                indent = space;
44230            }
44231
44232// If there is a replacer, it must be a function or an array.
44233// Otherwise, throw an error.
44234
44235            rep = replacer;
44236            if (replacer && typeof replacer !== 'function' &&
44237                    (typeof replacer !== 'object' ||
44238                    typeof replacer.length !== 'number')) {
44239                throw new Error('JSON.stringify');
44240            }
44241
44242// Make a fake root object containing our value under the key of ''.
44243// Return the result of stringifying the value.
44244
44245            return str('', {'': value});
44246        };
44247    }
44248
44249
44250// If the JSON object does not yet have a parse method, give it one.
44251
44252    if (typeof JSON.parse !== 'function') {
44253        JSON.parse = function (text, reviver) {
44254
44255// The parse method takes a text and an optional reviver function, and returns
44256// a JavaScript value if the text is a valid JSON text.
44257
44258            var j;
44259
44260            function walk(holder, key) {
44261
44262// The walk method is used to recursively walk the resulting structure so
44263// that modifications can be made.
44264
44265                var k, v, value = holder[key];
44266                if (value && typeof value === 'object') {
44267                    for (k in value) {
44268                        if (Object.prototype.hasOwnProperty.call(value, k)) {
44269                            v = walk(value, k);
44270                            if (v !== undefined) {
44271                                value[k] = v;
44272                            } else {
44273                                delete value[k];
44274                            }
44275                        }
44276                    }
44277                }
44278                return reviver.call(holder, key, value);
44279            }
44280
44281
44282// Parsing happens in four stages. In the first stage, we replace certain
44283// Unicode characters with escape sequences. JavaScript handles many characters
44284// incorrectly, either silently deleting them, or treating them as line endings.
44285
44286            text = String(text);
44287            cx.lastIndex = 0;
44288            if (cx.test(text)) {
44289                text = text.replace(cx, function (a) {
44290                    return '\\u' +
44291                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
44292                });
44293            }
44294
44295// In the second stage, we run the text against regular expressions that look
44296// for non-JSON patterns. We are especially concerned with '()' and 'new'
44297// because they can cause invocation, and '=' because it can cause mutation.
44298// But just to be safe, we want to reject all unexpected forms.
44299
44300// We split the second stage into 4 regexp operations in order to work around
44301// crippling inefficiencies in IE's and Safari's regexp engines. First we
44302// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
44303// replace all simple value tokens with ']' characters. Third, we delete all
44304// open brackets that follow a colon or comma or that begin the text. Finally,
44305// we look to see that the remaining characters are only whitespace or ']' or
44306// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
44307
44308            if (/^[\],:{}\s]*$/
44309                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
44310                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
44311                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
44312
44313// In the third stage we use the eval function to compile the text into a
44314// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
44315// in JavaScript: it can begin a block or an object literal. We wrap the text
44316// in parens to eliminate the ambiguity.
44317
44318                j = eval('(' + text + ')');
44319
44320// In the optional fourth stage, we recursively walk the new structure, passing
44321// each name/value pair to a reviver function for possible transformation.
44322
44323                return typeof reviver === 'function'
44324                    ? walk({'': j}, '')
44325                    : j;
44326            }
44327
44328// If the text is not JSON parseable, then a SyntaxError is thrown.
44329
44330            throw new SyntaxError('JSON.parse');
44331        };
44332    }
44333}());
vendor: 5,235 bytes, lines 44334-44337
44334/*! modernizr 3.3.1 (Custom Build) | MIT *
44335 * https://modernizr.com/download/?-applicationcache-backgroundsize-borderimage-boxshadow-canvas-canvastext-cssanimations-csscalc-csscolumns-cssreflections-csstransforms-csstransforms3d-csstransitions-flexbox-flexboxlegacy-fontface-generatedcontent-geolocation-hashchange-history-hsla-indexeddb-inlinesvg-input-inputtypes-localstorage-multiplebgs-objectfit-opacity-postmessage-rgba-sessionstorage-smil-svg-svgclippaths-textshadow-touchevents-video-webgl-websockets-websqldatabase-webworkers-domprefixes-hasevent-mq-prefixes-setclasses-shiv-testallprops-testprop-teststyles !*/
44336
44337 !function(e,t,n){function r(e,t){return typeof e===t}function a(){var e,t,n,a,o,i,s;for(var c in b)if(b.hasOwnProperty(c)){if(e=[],t=b[c],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n<t.options.aliases.length;n++)e.push(t.options.aliases[n].toLowerCase());for(a=r(t.fn,"function")?t.fn():t.fn,o=0;o<e.length;o++)i=e[o],s=i.split("."),1===s.length?Modernizr[s[0]]=a:(!Modernizr[s[0]]||Modernizr[s[0]]instanceof Boolean||(Modernizr[s[0]]=new Boolean(Modernizr[s[0]])),Modernizr[s[0]][s[1]]=a),y.push((a?"":"no-")+s.join("-"))}}function o(e){var t=C.className,n=Modernizr._config.classPrefix||"";if(E&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(t+=" "+n+e.join(" "+n),E?C.className.baseVal=t:C.className=t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):E?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function s(e,t){return!!~(""+e).indexOf(t)}function c(){var e=t.body;return e||(e=i(E?"svg":"body"),e.fake=!0),e}function l(e,n,r,a){var o,s,l,d,u="modernizr",f=i("div"),p=c();if(parseInt(r,10))for(;r--;)l=i("div"),l.id=a?a[r]:u+(r+1),f.appendChild(l);return o=i("style"),o.type="text/css",o.id="s"+u,(p.fake?p:f).appendChild(o),p.appendChild(f),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(t.createTextNode(e)),f.id=u,p.fake&&(p.style.background="",p.style.overflow="hidden",d=C.style.overflow,C.style.overflow="hidden",C.appendChild(p)),s=n(f,e),p.fake?(p.parentNode.removeChild(p),C.style.overflow=d,C.offsetHeight):f.parentNode.removeChild(f),!!s}function d(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function u(e,t){return function(){return e.apply(t,arguments)}}function f(e,t,n){var a;for(var o in e)if(e[o]in t)return n===!1?e[o]:(a=t[e[o]],r(a,"function")?u(a,n||t):a);return!1}function p(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function m(t,r){var a=t.length;if("CSS"in e&&"supports"in e.CSS){for(;a--;)if(e.CSS.supports(p(t[a]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var o=[];a--;)o.push("("+p(t[a])+":"+r+")");return o=o.join(" or "),l("@supports ("+o+") { #modernizr { position: absolute; } }",function(e){return"absolute"==getComputedStyle(e,null).position})}return n}function h(e,t,a,o){function c(){u&&(delete V.style,delete V.modElem)}if(o=r(o,"undefined")?!1:o,!r(a,"undefined")){var l=m(e,a);if(!r(l,"undefined"))return l}for(var u,f,p,h,g,v=["modernizr","tspan","samp"];!V.style&&v.length;)u=!0,V.modElem=i(v.shift()),V.style=V.modElem.style;for(p=e.length,f=0;p>f;f++)if(h=e[f],g=V.style[h],s(h,"-")&&(h=d(h)),V.style[h]!==n){if(o||r(a,"undefined"))return c(),"pfx"==t?h:!0;try{V.style[h]=a}catch(y){}if(V.style[h]!=g)return c(),"pfx"==t?h:!0}return c(),!1}function g(e,t,n,a,o){var i=e.charAt(0).toUpperCase()+e.slice(1),s=(e+" "+B.join(i+" ")+i).split(" ");return r(t,"string")||r(t,"undefined")?h(s,t,a,o):(s=(e+" "+_.join(i+" ")+i).split(" "),f(s,t,n))}function v(e,t,r){return g(e,n,n,t,r)}var y=[],b=[],x={_version:"3.3.1",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){b.push({name:e,fn:t,options:n})},addAsyncTest:function(e){b.push({name:null,fn:e})}},Modernizr=function(){};Modernizr.prototype=x,Modernizr=new Modernizr,Modernizr.addTest("applicationcache","applicationCache"in e),Modernizr.addTest("geolocation","geolocation"in navigator),Modernizr.addTest("history",function(){var t=navigator.userAgent;return-1===t.indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone")?e.history&&"pushState"in e.history:!1}),Modernizr.addTest("postmessage","postMessage"in e),Modernizr.addTest("svg",!!t.createElementNS&&!!t.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect);var T=!1;try{T="WebSocket"in e&&2===e.WebSocket.CLOSING}catch(w){}Modernizr.addTest("websockets",T),Modernizr.addTest("localstorage",function(){var e="modernizr";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(t){return!1}}),Modernizr.addTest("sessionstorage",function(){var e="modernizr";try{return sessionStorage.setItem(e,e),sessionStorage.removeItem(e),!0}catch(t){return!1}}),Modernizr.addTest("websqldatabase","openDatabase"in e),Modernizr.addTest("webworkers","Worker"
44337in e);var S=x._config.usePrefixes?" -webkit- -moz- -o- -ms- ".split(" "):["",""];x._prefixes=S;var C=t.documentElement,E="svg"===C.nodeName.toLowerCase();E||!function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x<style>"+t+"</style>",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=b.elements;return"string"==typeof e?e.split(" "):e}function a(e,t){var n=b.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),b.elements=n+" "+e,l(t)}function o(e){var t=y[e[g]];return t||(t={},v++,e[g]=v,y[v]=t),t}function i(e,n,r){if(n||(n=t),u)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():h.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function s(e,n){if(e||(e=t),u)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,s=r(),c=s.length;c>i;i++)a.createElement(s[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return b.shivMethods?i(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-:]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(b,t.frag)}function l(e){e||(e=t);var r=o(e);return!b.shivCSS||d||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),u||c(e,r),e}var d,u,f="3.7.3",p=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,h=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g="_html5shiv",v=0,y={};!function(){try{var e=t.createElement("a");e.innerHTML="<xyz></xyz>",d="hidden"in e,u=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){d=!0,u=!0}}();var b={elements:p.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:f,shivCSS:p.shivCSS!==!1,supportsUnknownElements:u,shivMethods:p.shivMethods!==!1,type:"default",shivDocument:l,createElement:i,createDocumentFragment:s,addElements:a};e.html5=b,l(t),"object"==typeof module&&module.exports&&(module.exports=b)}("undefined"!=typeof e?e:this,t);var k="Moz O ms Webkit",_=x._config.usePrefixes?k.toLowerCase().split(" "):[];x._domPrefixes=_;var z=function(){function e(e,t){var a;return e?(t&&"string"!=typeof t||(t=i(t||"div")),e="on"+e,a=e in t,!a&&r&&(t.setAttribute||(t=i("div")),t.setAttribute(e,""),a="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),a):!1}var r=!("onblur"in t.documentElement);return e}();x.hasEvent=z,Modernizr.addTest("hashchange",function(){return z("hashchange",e)===!1?!1:t.documentMode===n||t.documentMode>7}),Modernizr.addTest("canvas",function(){var e=i("canvas");return!(!e.getContext||!e.getContext("2d"))}),Modernizr.addTest("canvastext",function(){return Modernizr.canvas===!1?!1:"function"==typeof i("canvas").getContext("2d").fillText}),Modernizr.addTest("video",function(){var e=i("video"),t=!1;try{(t=!!e.canPlayType)&&(t=new Boolean(t),t.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),t.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),t.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""),t.vp9=e.canPlayType('video/webm; codecs="vp9"').replace(/^no$/,""),t.hls=e.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(/^no$/,""))}catch(n){}return t}),Modernizr.addTest("webgl",function(){var t=i("canvas"),n="probablySupportsContext"in t?"probablySupportsContext":"supportsContext";return n in t?t[n]("webgl")||t[n]("experimental-webgl"):"WebGLRenderingContext"in e}),Modernizr.addTest("csscalc",function(){var e="width:",t="calc(10px);",n=i("a");return n.style.cssText=e+S.join(t+e),!!n.style.length}),Modernizr.addTest("multiplebgs",function(){var e=i("a").style;return e.cssText="background:url(https://),url(https://),red url(https://)",/(url\s*\(.*?){3}/.test(e.background)}),Modernizr.addTest("opacity",function(){var e=i("a").style;return e.cssText=S.join("opacity:.55;"),/^0.55$/.test(e.opacity)}),Modernizr.addTest("rgba",function(){var e=i("a").style;return e.cssText="background-color:rgba(150,255,150,.5)",(""+e.backgroundColor).indexOf("rgba")>-1}),Modernizr.addTest("inlinesvg",function(){var e=i("div");return e.innerHTML="<svg/>
vendor: 7,488 bytes, lines 44337-44355
44337","http://www.w3.org/2000/svg"==("undefined"!=typeof SVGRect&&e.firstChild&&e.firstChild.namespaceURI)});var N=i("input"),P="autocomplete autofocus list placeholder max min multiple pattern required step".split(" "),R={};Modernizr.input=function(t){for(var n=0,r=t.length;r>n;n++)R[t[n]]=!!(t[n]in N);return R.list&&(R.list=!(!i("datalist")||!e.HTMLDataListElement)),R}(P);var A="search tel url email datetime date month week time datetime-local number range color".split(" "),j={};Modernizr.inputtypes=function(e){for(var r,a,o,i=e.length,s="1)",c=0;i>c;c++)N.setAttribute("type",r=e[c]),o="text"!==N.type&&"style"in N,o&&(N.value=s,N.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(r)&&N.style.WebkitAppearance!==n?(C.appendChild(N),a=t.defaultView,o=a.getComputedStyle&&"textfield"!==a.getComputedStyle(N,null).WebkitAppearance&&0!==N.offsetHeight,C.removeChild(N)):/^(search|tel)$/.test(r)||(o=/^(url|email)$/.test(r)?N.checkValidity&&N.checkValidity()===!1:N.value!=s)),j[e[c]]=!!o;return j}(A),Modernizr.addTest("hsla",function(){var e=i("a").style;return e.cssText="background-color:hsla(120,40%,100%,.5)",s(e.backgroundColor,"rgba")||s(e.backgroundColor,"hsla")});var M="CSS"in e&&"supports"in e.CSS,L="supportsCSS"in e;Modernizr.addTest("supports",M||L);var $={}.toString;Modernizr.addTest("svgclippaths",function(){return!!t.createElementNS&&/SVGClipPath/.test($.call(t.createElementNS("http://www.w3.org/2000/svg","clipPath")))}),Modernizr.addTest("smil",function(){return!!t.createElementNS&&/SVGAnimate/.test($.call(t.createElementNS("http://www.w3.org/2000/svg","animate")))});var F=function(){var t=e.matchMedia||e.msMatchMedia;return t?function(e){var n=t(e);return n&&n.matches||!1}:function(t){var n=!1;return l("@media "+t+" { #modernizr { position: absolute; } }",function(t){n="absolute"==(e.getComputedStyle?e.getComputedStyle(t,null):t.currentStyle).position}),n}}();x.mq=F;var O=x.testStyles=l;Modernizr.addTest("touchevents",function(){var n;if("ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch)n=!0;else{var r=["@media (",S.join("touch-enabled),("),"heartz",")","{#modernizr{top:9px;position:absolute}}"].join("");O(r,function(e){n=9===e.offsetTop})}return n});var D=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,a=533>t&&e.match(/android/gi);return n||a||r}();D?Modernizr.addTest("fontface",!1):O('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),a=r.sheet||r.styleSheet,o=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"",i=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);Modernizr.addTest("fontface",i)}),O('#modernizr{font:0/0 a}#modernizr:after{content:":)";visibility:hidden;font:7px/1 a}',function(e){Modernizr.addTest("generatedcontent",e.offsetHeight>=7)});var B=x._config.usePrefixes?k.split(" "):[];x._cssomPrefixes=B;var I=function(t){var r,a=S.length,o=e.CSSRule;if("undefined"==typeof o)return n;if(!t)return!1;if(t=t.replace(/^@/,""),r=t.replace(/-/g,"_").toUpperCase()+"_RULE",r in o)return"@"+t;for(var i=0;a>i;i++){var s=S[i],c=s.toUpperCase()+"_"+r;if(c in o)return"@-"+s.toLowerCase()+"-"+t}return!1};x.atRule=I;var W={elem:i("modernizr")};Modernizr._q.push(function(){delete W.elem});var V={style:W.elem.style};Modernizr._q.unshift(function(){delete V.style});var q=x.testProp=function(e,t,r){return h([e],n,t,r)};Modernizr.addTest("textshadow",q("textShadow","1px 1px")),x.testAllProps=g,x.testAllProps=v,Modernizr.addTest("cssanimations",v("animationName","a",!0)),Modernizr.addTest("backgroundsize",v("backgroundSize","100%",!0)),Modernizr.addTest("borderimage",v("borderImage","url() 1",!0)),Modernizr.addTest("boxshadow",v("boxShadow","1px 1px",!0)),function(){Modernizr.addTest("csscolumns",function(){var e=!1,t=v("columnCount");try{(e=!!t)&&(e=new Boolean(e))}catch(n){}return e});for(var e,t,n=["Width","Span","Fill","Gap","Rule","RuleColor","RuleStyle","RuleWidth","BreakBefore","BreakAfter","BreakInside"],r=0;r<n.length;r++)e=n[r].toLowerCase(),t=v("column"+n[r]),("breakbefore"===e||"breakafter"===e||"breakinside"==e)&&(t=t||v(n[r])),Modernizr.addTest("csscolumns."+e,t)}(),Modernizr.addTest("flexbox",v("flexBasis","1px",!0)),Modernizr.addTest("flexboxlegacy",v("boxDirection","reverse",!0)),Modernizr.addTest("cssreflections",v("boxReflect","above",!0)),Modernizr.addTest("csstransforms",function(){return-1===navigator.userAgent.indexOf("Android 2.")&&v("transform","scale(1)",!0)}),Modernizr.addTest("csstransforms3d",function(){var e=!!v("perspective","1px",!0),t=Modernizr._config.usePrefixes;if(e&&(!t||"webkitPerspective"in C.style)){var n,r="#modernizr{width:0;height:0}";Modernizr.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",O(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),Modernizr.addTest("csstransitions",v("transition","all",!0));var H,U=x.prefixed=function(e,t,n){return 0===e.indexOf("@")?I(e):(-1!=e.indexOf("-")&&(e=d(e)),t?g(e,t,n):g(e,"pfx"))};try{H=U("indexedDB",e)}catch(w){}Modernizr.addTest("indexeddb",!!H),H&&Modernizr.addTest("indexeddb.deletedatabase","deleteDatabase"in H),Modernizr.addTest("objectfit",!!U("objectFit"),{aliases:["object-fit"]}),a(),o(y),delete x.addTest,delete x.addAsyncTest;for(var G=0;G<Modernizr._q.length;G++)Modernizr._q[G]();e.Modernizr=Modernizr}(window,document);
44338/*
44339     _ _      _       _
44340 ___| (_) ___| | __  (_)___
44341/ __| | |/ __| |/ /  | / __|
44342\__ \ | | (__|   < _ | \__ \
44343|___/_|_|\___|_|\_(_)/ |___/
44344                   |__/
44345
44346 Version: 1.8.1
44347  Author: Ken Wheeler
44348 Website: http://kenwheeler.github.io
44349    Docs: http://kenwheeler.github.io/slick
44350    Repo: http://github.com/kenwheeler/slick
44351  Issues: http://github.com/kenwheeler/slick/issues
44352
44353 */
44354
44355!function(i){"use strict";"function"==typeof define&&define.amd?define(["jquery"],i):"undefined"!=typeof exports?module.exports=i(require("jquery")):i(jQuery)}(function(i){"use strict";var e=window.Slick||{};(e=function(){var e=0;return function(t,o){var s,n=this;n.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:i(t),appendDots:i(t),arrows:!0,asNavFor:null,prevArrow:'<button class="slick-prev" aria-label="Previous" type="button">Previous</button>',nextArrow:'<button class="slick-next" aria-label="Next" type="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(e,t){return i('<button type="button" />').text(t+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,focusOnChange:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},n.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,scrolling:!1,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,
vendor: 6,594 bytes, line 44355
44355sliding:!1,slideOffset:0,swipeLeft:null,swiping:!1,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},i.extend(n,n.initials),n.activeBreakpoint=null,n.animType=null,n.animProp=null,n.breakpoints=[],n.breakpointSettings=[],n.cssTransitions=!1,n.focussed=!1,n.interrupted=!1,n.hidden="hidden",n.paused=!0,n.positionProp=null,n.respondTo=null,n.rowCount=1,n.shouldClick=!0,n.$slider=i(t),n.$slidesCache=null,n.transformType=null,n.transitionType=null,n.visibilityChange="visibilitychange",n.windowWidth=0,n.windowTimer=null,s=i(t).data("slick")||{},n.options=i.extend({},n.defaults,o,s),n.currentSlide=n.options.initialSlide,n.originalSettings=n.options,void 0!==document.mozHidden?(n.hidden="mozHidden",n.visibilityChange="mozvisibilitychange"):void 0!==document.webkitHidden&&(n.hidden="webkitHidden",n.visibilityChange="webkitvisibilitychange"),n.autoPlay=i.proxy(n.autoPlay,n),n.autoPlayClear=i.proxy(n.autoPlayClear,n),n.autoPlayIterator=i.proxy(n.autoPlayIterator,n),n.changeSlide=i.proxy(n.changeSlide,n),n.clickHandler=i.proxy(n.clickHandler,n),n.selectHandler=i.proxy(n.selectHandler,n),n.setPosition=i.proxy(n.setPosition,n),n.swipeHandler=i.proxy(n.swipeHandler,n),n.dragHandler=i.proxy(n.dragHandler,n),n.keyHandler=i.proxy(n.keyHandler,n),n.instanceUid=e++,n.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,n.registerBreakpoints(),n.init(!0)}}()).prototype.activateADA=function(){this.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},e.prototype.addSlide=e.prototype.slickAdd=function(e,t,o){var s=this;if("boolean"==typeof t)o=t,t=null;else if(t<0||t>=s.slideCount)return!1;s.unload(),"number"==typeof t?0===t&&0===s.$slides.length?i(e).appendTo(s.$slideTrack):o?i(e).insertBefore(s.$slides.eq(t)):i(e).insertAfter(s.$slides.eq(t)):!0===o?i(e).prependTo(s.$slideTrack):i(e).appendTo(s.$slideTrack),s.$slides=s.$slideTrack.children(this.options.slide),s.$slideTrack.children(this.options.slide).detach(),s.$slideTrack.append(s.$slides),s.$slides.each(function(e,t){i(t).attr("data-slick-index",e)}),s.$slidesCache=s.$slides,s.reinit()},e.prototype.animateHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.animate({height:e},i.options.speed)}},e.prototype.animateSlide=function(e,t){var o={},s=this;s.animateHeight(),!0===s.options.rtl&&!1===s.options.vertical&&(e=-e),!1===s.transformsEnabled?!1===s.options.vertical?s.$slideTrack.animate({left:e},s.options.speed,s.options.easing,t):s.$slideTrack.animate({top:e},s.options.speed,s.options.easing,t):!1===s.cssTransitions?(!0===s.options.rtl&&(s.currentLeft=-s.currentLeft),i({animStart:s.currentLeft}).animate({animStart:e},{duration:s.options.speed,easing:s.options.easing,step:function(i){i=Math.ceil(i),!1===s.options.vertical?(o[s.animType]="translate("+i+"px, 0px)",s.$slideTrack.css(o)):(o[s.animType]="translate(0px,"+i+"px)",s.$slideTrack.css(o))},complete:function(){t&&t.call()}})):(s.applyTransition(),e=Math.ceil(e),!1===s.options.vertical?o[s.animType]="translate3d("+e+"px, 0px, 0px)":o[s.animType]="translate3d(0px,"+e+"px, 0px)",s.$slideTrack.css(o),t&&setTimeout(function(){s.disableTransition(),t.call()},s.options.speed))},e.prototype.getNavTarget=function(){var e=this,t=e.options.asNavFor;return t&&null!==t&&(t=i(t).not(e.$slider)),t},e.prototype.asNavFor=function(e){var t=this.getNavTarget();null!==t&&"object"==typeof t&&t.each(function(){var t=i(this).slick("getSlick");t.unslicked||t.slideHandler(e,!0)})},e.prototype.applyTransition=function(i){var e=this,t={};!1===e.options.fade?t[e.transitionType]=e.transformType+" "+e.options.speed+"ms "+e.options.cssEase:t[e.transitionType]="opacity "+e.options.speed+"ms "+e.options.cssEase,!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.autoPlay=function(){var i=this;i.autoPlayClear(),i.slideCount>i.options.slidesToShow&&(i.autoPlayTimer=setInterval(i.autoPlayIterator,i.options.autoplaySpeed))},e.prototype.autoPlayClear=function(){var i=this;i.autoPlayTimer&&clearInterval(i.autoPlayTimer)},e.prototype.autoPlayIterator=function(){var i=this,e=i.currentSlide+i.options.slidesToScroll;i.paused||i.interrupted||i.focussed||(!1===i.options.infinite&&(1===i.direction&&i.currentSlide+1===i.slideCount-1?i.direction=0:0===i.direction&&(e=i.currentSlide-i.options.slidesToScroll,i.currentSlide-1==0&&(i.direction=1))),i.slideHandler(e))},e.prototype.buildArrows=function(){var e=this;!0===e.options.arrows&&(e.$prevArrow=i(e.options.prevArrow).addClass("slick-arrow"),e.$nextArrow=i(e.options.nextArrow).addClass("slick-arrow"),e.slideCount>e.options.slidesToShow?(e.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.prependTo(e.options.appendArrows),e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.appendTo(e.options.appendArrows),!0!==e.options.infinite&&e.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):e.$prevArrow.add(e.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},e.prototype.buildDots=function(){var e,t,o=this;if(!0===o.options.dots){for(o.$slider.addClass("slick-dotted"),t=i("<ul />").addClass(o.options.dotsClass),e=0;e<=o.getDotCount();e+=1)t.append(i("<li />").append(o.options.customPaging.call(this,o,e)));o.$dots=t.appendTo(o.options.appendDots),o.$dots.find("li").first().addClass("slick-active")}},e.prototype.buildOut=function(){var e=this;e.$slides=e.$slider.children(e.options.slide+":not(.slick-cloned)").addClass("slick-slide"),e.slideCount=e.$slides.length,e.$slides.each(function(e,t){i(t).attr("data-slick-index",e).data("originalStyling",i(t).attr("style")||"")}),e.$slider.addClass("slick-slider"),e.$slideTrack=0===e.slideCount?i('<div class="slick-track"/>').appendTo(e.$slider):e.$slides.wrapAll('<div class="slick-track"/>').parent(),e.$list=e.$slideTrack.wrap('<div class="slick-list"/>').parent(),e.$slideTrack.css("opacity",0),!0!==e.options.centerMode&&!0!==e.options.swipeToSlide||(e.options.slidesToScroll=1),i("img[data-lazy]",e.$slider).not("[src]").addClass("slick-loading"),e.setupInfinite(),e.buildArrows(),e.buildDots(),e.updateDots(),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),!0===e.options.draggable&&e.$list.addClass("draggable")},e.prototype.buildRows=function(){var i,e,t,o,s,n,r,l=this;if(o=document.createDocumentFragment(),n=l.$slider.children(),l.o
vendor: 3,442 bytes, line 44355
44355ptions.rows>1){for(r=l.options.slidesPerRow*l.options.rows,s=Math.ceil(n.length/r),i=0;i<s;i++){var d=document.createElement("div");for(e=0;e<l.options.rows;e++){var a=document.createElement("div");for(t=0;t<l.options.slidesPerRow;t++){var c=i*r+(e*l.options.slidesPerRow+t);n.get(c)&&a.appendChild(n.get(c))}d.appendChild(a)}o.appendChild(d)}l.$slider.empty().append(o),l.$slider.children().children().children().css({width:100/l.options.slidesPerRow+"%",display:"inline-block"})}},e.prototype.checkResponsive=function(e,t){var o,s,n,r=this,l=!1,d=r.$slider.width(),a=window.innerWidth||i(window).width();if("window"===r.respondTo?n=a:"slider"===r.respondTo?n=d:"min"===r.respondTo&&(n=Math.min(a,d)),r.options.responsive&&r.options.responsive.length&&null!==r.options.responsive){s=null;for(o in r.breakpoints)r.breakpoints.hasOwnProperty(o)&&(!1===r.originalSettings.mobileFirst?n<r.breakpoints[o]&&(s=r.breakpoints[o]):n>r.breakpoints[o]&&(s=r.breakpoints[o]));null!==s?null!==r.activeBreakpoint?(s!==r.activeBreakpoint||t)&&(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):(r.activeBreakpoint=s,"unslick"===r.breakpointSettings[s]?r.unslick(s):(r.options=i.extend({},r.originalSettings,r.breakpointSettings[s]),!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e)),l=s):null!==r.activeBreakpoint&&(r.activeBreakpoint=null,r.options=r.originalSettings,!0===e&&(r.currentSlide=r.options.initialSlide),r.refresh(e),l=s),e||!1===l||r.$slider.trigger("breakpoint",[r,l])}},e.prototype.changeSlide=function(e,t){var o,s,n,r=this,l=i(e.currentTarget);switch(l.is("a")&&e.preventDefault(),l.is("li")||(l=l.closest("li")),n=r.slideCount%r.options.slidesToScroll!=0,o=n?0:(r.slideCount-r.currentSlide)%r.options.slidesToScroll,e.data.message){case"previous":s=0===o?r.options.slidesToScroll:r.options.slidesToShow-o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide-s,!1,t);break;case"next":s=0===o?r.options.slidesToScroll:o,r.slideCount>r.options.slidesToShow&&r.slideHandler(r.currentSlide+s,!1,t);break;case"index":var d=0===e.data.index?0:e.data.index||l.index()*r.options.slidesToScroll;r.slideHandler(r.checkNavigable(d),!1,t),l.children().trigger("focus");break;default:return}},e.prototype.checkNavigable=function(i){var e,t;if(e=this.getNavigableIndexes(),t=0,i>e[e.length-1])i=e[e.length-1];else for(var o in e){if(i<e[o]){i=t;break}t=e[o]}return i},e.prototype.cleanUpEvents=function(){var e=this;e.options.dots&&null!==e.$dots&&(i("li",e.$dots).off("click.slick",e.changeSlide).off("mouseenter.slick",i.proxy(e.interrupt,e,!0)).off("mouseleave.slick",i.proxy(e.interrupt,e,!1)),!0===e.options.accessibility&&e.$dots.off("keydown.slick",e.keyHandler)),e.$slider.off("focus.slick blur.slick"),!0===e.options.arrows&&e.slideCount>e.options.slidesToShow&&(e.$prevArrow&&e.$prevArrow.off("click.slick",e.changeSlide),e.$nextArrow&&e.$nextArrow.off("click.slick",e.changeSlide),!0===e.options.accessibility&&(e.$prevArrow&&e.$prevArrow.off("keydown.slick",e.keyHandler),e.$nextArrow&&e.$nextArrow.off("keydown.slick",e.keyHandler))),e.$list.off("touchstart.slick mousedown.slick",e.swipeHandler),e.$list.off("touchmove.slick mousemove.slick",e.swipeHandler),e.$list.off("touchend.slick mouseup.slick",e.swipeHandler),e.$list.off("touchcancel.slick mouseleave.
44355slick",e.swipeHandler),e.$list.off("click.slick",e.clickHandler),i(document).off(e.visibilityChange,e.visibility),e.cleanUpSlideEvents(),!0===e.options.accessibility&&e.$list.off("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().off("click.slick",e.selectHandler),i(window).off("orientationchange.slick.slick-"+e.instanceUid,e.orientationChange),i(window).off("resize.slick.slick-"+e.instanceUid,e.resize),i("[draggable!=true]",e.$slideTrack).off("dragstart",e.preventDefault),i(window).off("load.slick.slick-"+e.instanceUid,e.setPosition)},e.prototype.cleanUpSlideEvents=function(){var e=this;e.$list.off("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.off("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.cleanUpRows=function(){var i,e=this;e.options.rows>1&&((i=e.$slides.children().children()).removeAttr("style"),e.$slider.empty().append(i))},e.prototype.clickHandler=function(i){!1===this.shouldClick&&(i.stopImmediatePropagation(),i.stopPropagation(),i.preventDefault())},e.prototype.destroy=function(e){var t=this;t.autoPlayClear(),t.touchObject={},t.cleanUpEvents(),i(".slick-cloned",t.$slider).detach(),t.$dots&&t.$dots.remove(),t.$prevArrow&&t.$prevArrow.length&&(t.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.prevArrow)&&t.$prevArrow.remove()),t.$nextArrow&&t.$nextArrow.length&&(t.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),t.htmlExpr.test(t.options.nextArrow)&&t.$nextArrow.remove()),t.$slides&&(t.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){i(this).attr("style",i(this).data("originalStyling"))}),t.$slideTrack.children(this.options.slide).detach(),t.$slideTrack.detach(),t.$list.detach(),t.$slider.append(t.$slides)),t.cleanUpRows(),t.$slider.removeClass("slick-slider"),t.$slider.removeClass("slick-initialized"),t.$slider.removeClass("slick-dotted"),t.unslicked=!0,e||t.$slider.trigger("destroy",[t])},e.prototype.disableTransition=function(i){var e=this,t={};t[e.transitionType]="",!1===e.options.fade?e.$slideTrack.css(t):e.$slides.eq(i).css(t)},e.prototype.fadeSlide=function(i,e){var t=this;!1===t.cssTransitions?(t.$slides.eq(i).css({zIndex:t.options.zIndex}),t.$slides.eq(i).animate({opacity:1},t.options.speed,t.options.easing,e)):(t.applyTransition(i),t.$slides.eq(i).css({opacity:1,zIndex:t.options.zIndex}),e&&setTimeout(function(){t.disableTransition(i),e.call()},t.options.speed))},e.prototype.fadeSlideOut=function(i){var e=this;!1===e.cssTransitions?e.$slides.eq(i).animate({opacity:0,zIndex:e.options.zIndex-2},e.options.speed,e.options.easing):(e.applyTransition(i),e.$slides.eq(i).css({opacity:0,zIndex:e.options.zIndex-2}))},e.prototype.filterSlides=e.prototype.slickFilter=function(i){var e=this;null!==i&&(e.$slidesCache=e.$slides,e.unload(),e.$slideTrack.children(this.options.slide).detach(),e.$slidesCache.filter(i).appendTo(e.$slideTrack),e.reinit())},e.prototype.focusHandler=function(){var e=this;e.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*",function(t){t.stopImmediatePropagation();var o=i(this);setTimeout(function(){e.options.pauseOnFocus&&(e.focussed=o.is(":focus"),e.autoPlay())},0)})},e.prototype.getCurrent=e.prototype.slickCurrentSlide=function(){return this.currentSlide},e.prototype.getDotCount=function(){var i=this,e=0,t=0,o=0;if(!0===i.options.infinite)if(i.slideCount<=i.options.slidesToShow)++o;else for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else if(!0===i.options.centerMode)o=i.slideCount;else if(i.options.asNavFor)for(;e<i.slideCount;)++o,e=t+i.options.slidesToScroll,t+=i.options.slidesToScroll<=i.options.slidesToShow?i.options.slidesToScroll:i.options.slidesToShow;else o=1+Math.ceil((i.slideCount-i.options.slidesToShow)/i.options.slidesToScroll);return o-1},e.prototype.getLeft=function(i){var e,t,o,s,n=this,r=0;return n.slideOffset=0,t=n.$slides.first().outerHeight(!0),!0===n.options.infinite?(n.slideCount>n.options.slidesToShow&&(n.slideOffset=n.slideWidth*n.options.slidesToShow*-1,s=-1,!0===n.options.vertical&&!0===n.options.centerMode&&(2===n.options.slidesToShow?s=-1.5:1===n.options.slidesToShow&&(s=-2)),r=t*n.options.slidesToShow*s),n.slideCount%n.options.slidesToScroll!=0&&i+n.options.slidesToScroll>n.slideCount&&n.slideCount>n.options.slidesToShow&&(i>n.slideCount?(n.slideOffset=(n.options.slidesToShow-(i-n.slideCount))*n.slideWidth*-1,r=(n.options.slidesToShow-(i-n.slideCount))*t*-1):(n.slideOffset=n.slideCount%n.options.slidesToScroll*n.slideWidth*-1,r=n.slideCount%n.options.slidesToScroll*t*-1))):i+n.options.slidesToShow>n.slideCount&&(n.slideOffset=(i+n.options.slidesToShow-n.slideCount)*n.slideWidth,r=(i+n.options.slidesToShow-n.slideCount)*t),n.slideCount<=n.options.slidesToShow&&(n.slideOffset=0,r=0),!0===n.options.centerMode&&n.slideCount<=n.options.slidesToShow?n.slideOffset=n.slideWidth*Math.floor(n.options.slidesToShow)/2-n.slideWidth*n.slideCount/2:!0===n.options.centerMode&&!0===n.options.infinite?n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)-n.slideWidth:!0===n.options.centerMode&&(n.slideOffset=0,n.slideOffset+=n.slideWidth*Math.floor(n.options.slidesToShow/2)),e=!1===n.options.vertical?i*n.slideWidth*-1+n.slideOffset:i*t*-1+r,!0===n.options.variableWidth&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,!0===n.options.centerMode&&(o=n.slideCount<=n.options.slidesToShow||!1===n.options.infinite?n.$slideTrack.children(".slick-slide").eq(i):n.$slideTrack.children(".slick-slide").eq(i+n.options.slidesToShow+1),e=!0===n.options.rtl?o[0]?-1*(n.$slideTrack.width()-o[0].offsetLeft-o.width()):0:o[0]?-1*o[0].offsetLeft:0,e+=(n.$list.width()-o.outerWidth())/2)),e},e.prototype.getOption=e.prototype.slickGetOption=function(i){return this.options[i]},e.prototype.getNavigableIndexes=function(){var i,e=this,t=0,o=0,s=[];for(!1===e.options.infinite?i=e.slideCount:(t=-1*e.options.slidesToScroll,o=-1*e.options.slidesToScroll,i=2*e.slideCount);t<i;)s.push(t),t=o+e.options.slidesToScroll,o+=e.options.slidesToScroll<=e.options.slidesToShow?e.options.slidesToScroll:e.options.slidesToShow;return s},e.prototype.getSlick=function(){return this},e.prototype.getSlideCount=function(){var e,t,o=this;return t=!0===o.options.centerMode?o.slideWidth*Math.floor(o.options.slidesToShow/2):0,!0===o.options.swipeToSlide?(o.$slideTrack.find(".slick-slide").each(function(s,n){if(n.offsetLeft-t+i(n).outerWidth()/2>-1*o.swipeLeft)return e=n,!1}),Math.abs(i(e).attr("data-slick-index")-o.currentSlide)||1):o.options.slidesToScroll},e.prototype.goTo=e.prototype.slickGoTo=function(i,e){this.changeSlide({data:{message:"index",index:
44355parseInt(i)}},e)},e.prototype.init=function(e){var t=this;i(t.$slider).hasClass("slick-initialized")||(i(t.$slider).addClass("slick-initialized"),t.buildRows(),t.buildOut(),t.setProps(),t.startLoad(),t.loadSlider(),t.initializeEvents(),t.updateArrows(),t.updateDots(),t.checkResponsive(!0),t.focusHandler()),e&&t.$slider.trigger("init",[t]),!0===t.options.accessibility&&t.initADA(),t.options.autoplay&&(t.paused=!1,t.autoPlay())},e.prototype.initADA=function(){var e=this,t=Math.ceil(e.slideCount/e.options.slidesToShow),o=e.getNavigableIndexes().filter(function(i){return i>=0&&i<e.slideCount});e.$slides.add(e.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),null!==e.$dots&&(e.$slides.not(e.$slideTrack.find(".slick-cloned")).each(function(t){var s=o.indexOf(t);i(this).attr({role:"tabpanel",id:"slick-slide"+e.instanceUid+t,tabindex:-1}),-1!==s&&i(this).attr({"aria-describedby":"slick-slide-control"+e.instanceUid+s})}),e.$dots.attr("role","tablist").find("li").each(function(s){var n=o[s];i(this).attr({role:"presentation"}),i(this).find("button").first().attr({role:"tab",id:"slick-slide-control"+e.instanceUid+s,"aria-controls":"slick-slide"+e.instanceUid+n,"aria-label":s+1+" of "+t,"aria-selected":null,tabindex:"-1"})}).eq(e.currentSlide).find("button").attr({"aria-selected":"true",tabindex:"0"}).end());for(var s=e.currentSlide,n=s+e.options.slidesToShow;s<n;s++)e.$slides.eq(s).attr("tabindex",0);e.activateADA()},e.prototype.initArrowEvents=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},i.changeSlide),i.$nextArrow.off("click.slick").on("click.slick",{message:"next"},i.changeSlide),!0===i.options.accessibility&&(i.$prevArrow.on("keydown.slick",i.keyHandler),i.$nextArrow.on("keydown.slick",i.keyHandler)))},e.prototype.initDotEvents=function(){var e=this;!0===e.options.dots&&(i("li",e.$dots).on("click.slick",{message:"index"},e.changeSlide),!0===e.options.accessibility&&e.$dots.on("keydown.slick",e.keyHandler)),!0===e.options.dots&&!0===e.options.pauseOnDotsHover&&i("li",e.$dots).on("mouseenter.slick",i.proxy(e.interrupt,e,!0)).on("mouseleave.slick",i.proxy(e.interrupt,e,!1))},e.prototype.initSlideEvents=function(){var e=this;e.options.pauseOnHover&&(e.$list.on("mouseenter.slick",i.proxy(e.interrupt,e,!0)),e.$list.on("mouseleave.slick",i.proxy(e.interrupt,e,!1)))},e.prototype.initializeEvents=function(){var e=this;e.initArrowEvents(),e.initDotEvents(),e.initSlideEvents(),e.$list.on("touchstart.slick mousedown.slick",{action:"start"},e.swipeHandler),e.$list.on("touchmove.slick mousemove.slick",{action:"move"},e.swipeHandler),e.$list.on("touchend.slick mouseup.slick",{action:"end"}
44355,e.swipeHandler),e.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},e.swipeHandler),e.$list.on("click.slick",e.clickHandler),i(document).on(e.visibilityChange,i.proxy(e.visibility,e)),!0===e.options.accessibility&&e.$list.on("keydown.slick",e.keyHandler),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),i(window).on("orientationchange.slick.slick-"+e.instanceUid,i.proxy(e.orientationChange,e)),i(window).on("resize.slick.slick-"+e.instanceUid,i.proxy(e.resize,e)),i("[draggable!=true]",e.$slideTrack).on("dragstart",e.preventDefault),i(window).on("load.slick.slick-"+e.instanceUid,e.setPosition),i(e.setPosition)},e.prototype.initUI=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.show(),i.$nextArrow.show()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.show()},e.prototype.keyHandler=function(i){var e=this;i.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===i.keyCode&&!0===e.options.accessibility?e.changeSlide({data:{message:!0===e.options.rtl?"next":"previous"}}):39===i.keyCode&&!0===e.options.accessibility&&e.changeSlide({data:{message:!0===e.options.rtl?"previous":"next"}}))},e.prototype.lazyLoad=function(){function e(e){i("img[data-lazy]",e).each(function(){var e=i(this),t=i(this).attr("data-lazy"),o=i(this).attr("data-srcset"),s=i(this).attr("data-sizes")||n.$slider.attr("data-sizes"),r=document.createElement("img");r.onload=function(){e.animate({opacity:0}
vendor: 5,619 bytes, line 44355
44355,100,function(){o&&(e.attr("srcset",o),s&&e.attr("sizes",s)),e.attr("src",t).animate({opacity:1},200,function(){e.removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading")}),n.$slider.trigger("lazyLoaded",[n,e,t])})},r.onerror=function(){e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),n.$slider.trigger("lazyLoadError",[n,e,t])},r.src=t})}var t,o,s,n=this;if(!0===n.options.centerMode?!0===n.options.infinite?s=(o=n.currentSlide+(n.options.slidesToShow/2+1))+n.options.slidesToShow+2:(o=Math.max(0,n.currentSlide-(n.options.slidesToShow/2+1)),s=n.options.slidesToShow/2+1+2+n.currentSlide):(o=n.options.infinite?n.options.slidesToShow+n.currentSlide:n.currentSlide,s=Math.ceil(o+n.options.slidesToShow),!0===n.options.fade&&(o>0&&o--,s<=n.slideCount&&s++)),t=n.$slider.find(".slick-slide").slice(o,s),"anticipated"===n.options.lazyLoad)for(var r=o-1,l=s,d=n.$slider.find(".slick-slide"),a=0;a<n.options.slidesToScroll;a++)r<0&&(r=n.slideCount-1),t=(t=t.add(d.eq(r))).add(d.eq(l)),r--,l++;e(t),n.slideCount<=n.options.slidesToShow?e(n.$slider.find(".slick-slide")):n.currentSlide>=n.slideCount-n.options.slidesToShow?e(n.$slider.find(".slick-cloned").slice(0,n.options.slidesToShow)):0===n.currentSlide&&e(n.$slider.find(".slick-cloned").slice(-1*n.options.slidesToShow))},e.prototype.loadSlider=function(){var i=this;i.setPosition(),i.$slideTrack.css({opacity:1}),i.$slider.removeClass("slick-loading"),i.initUI(),"progressive"===i.options.lazyLoad&&i.progressiveLazyLoad()},e.prototype.next=e.prototype.slickNext=function(){this.changeSlide({data:{message:"next"}})},e.prototype.orientationChange=function(){var i=this;i.checkResponsive(),i.setPosition()},e.prototype.pause=e.prototype.slickPause=function(){var i=this;i.autoPlayClear(),i.paused=!0},e.prototype.play=e.prototype.slickPlay=function(){var i=this;i.autoPlay(),i.options.autoplay=!0,i.paused=!1,i.focussed=!1,i.interrupted=!1},e.prototype.postSlide=function(e){var t=this;t.unslicked||(t.$slider.trigger("afterChange",[t,e]),t.animating=!1,t.slideCount>t.options.slidesToShow&&t.setPosition(),t.swipeLeft=null,t.options.autoplay&&t.autoPlay(),!0===t.options.accessibility&&(t.initADA(),t.options.focusOnChange&&i(t.$slides.get(t.currentSlide)).attr("tabindex",0).focus()))},e.prototype.prev=e.prototype.slickPrev=function(){this.changeSlide({data:{message:"previous"}})},e.prototype.preventDefault=function(i){i.preventDefault()},e.prototype.progressiveLazyLoad=function(e){e=e||1;var t,o,s,n,r,l=this,d=i("img[data-lazy]",l.$slider);d.length?(t=d.first(),o=t.attr("data-lazy"),s=t.attr("data-srcset"),n=t.attr("data-sizes")||l.$slider.attr("data-sizes"),(r=document.createElement("img")).onload=function(){s&&(t.attr("srcset",s),n&&t.attr("sizes",n)),t.attr("src",o).removeAttr("data-lazy data-srcset data-sizes").removeClass("slick-loading"),!0===l.options.adaptiveHeight&&l.setPosition(),l.$slider.trigger("lazyLoaded",[l,t,o]),l.progressiveLazyLoad()},r.onerror=function(){e<3?setTimeout(function(){l.progressiveLazyLoad(e+1)},500):(t.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),l.$slider.trigger("lazyLoadError",[l,t,o]),l.progressiveLazyLoad())},r.src=o):l.$slider.trigger("allImagesLoaded",[l])},e.prototype.refresh=function(e){var t,o,s=this;o=s.slideCount-s.options.slidesToShow,!s.options.infinite&&s.currentSlide>o&&(s.currentSlide=o),s.slideCount<=s.options.slidesToShow&&(s.currentSlide=0),t=s.currentSlide,s.destroy(!0),i.extend(s,s.initials,{currentSlide:t}),s.init(),e||s.changeSlide({data:{message:"index",index:t}},!1)},e.prototype.registerBreakpoints=function(){var e,t,o,s=this,n=s.options.responsive||null;if("array"===i.type(n)&&n.length){s.respondTo=s.options.respondTo||"window";for(e in n)if(o=s.breakpoints.length-1,n.hasOwnProperty(e)){for(t=n[e].breakpoint;o>=0;)s.breakpoints[o]&&s.breakpoints[o]===t&&s.breakpoints.splice(o,1),o--;s.breakpoints.push(t),s.breakpointSettings[t]=n[e].settings}s.breakpoints.sort(function(i,e){return s.options.mobileFirst?i-e:e-i})}},e.prototype.reinit=function(){var e=this;e.$slides=e.$slideTrack.children(e.options.slide).addClass("slick-slide"),e.slideCount=e.$slides.length,e.currentSlide>=e.slideCount&&0!==e.currentSlide&&(e.currentSlide=e.currentSlide-e.options.slidesToScroll),e.slideCount<=e.options.slidesToShow&&(e.currentSlide=0),e.registerBreakpoints(),e.setProps(),e.setupInfinite(),e.buildArrows(),e.updateArrows(),e.initArrowEvents(),e.buildDots(),e.updateDots(),e.initDotEvents(),e.cleanUpSlideEvents(),e.initSlideEvents(),e.checkResponsive(!1,!0),!0===e.options.focusOnSelect&&i(e.$slideTrack).children().on("click.slick",e.selectHandler),e.setSlideClasses("number"==typeof e.currentSlide?e.currentSlide:0),e.setPosition(),e.focusHandler(),e.paused=!e.options.autoplay,e.autoPlay(),e.$slider.trigger("reInit",[e])},e.prototype.resize=function(){var e=this;i(window).width()!==e.windowWidth&&(clearTimeout(e.windowDelay),e.windowDelay=window.setTimeout(function(){e.windowWidth=i(window).width(),e.checkResponsive(),e.unslicked||e.setPosition()},50))},e.prototype.removeSlide=e.prototype.slickRemove=function(i,e,t){var o=this;if(i="boolean"==typeof i?!0===(e=i)?0:o.slideCount-1:!0===e?--i:i,o.slideCount<1||i<0||i>o.slideCount-1)return!1;o.unload(),!0===t?o.$slideTrack.children().remove():o.$slideTrack.children(this.options.slide).eq(i).remove(),o.$slides=o.$slideTrack.children(this.options.slide),o.$slideTrack.children(this.options.slide).detach(),o.$slideTrack.append(o.$slides),o.$slidesCache=o.$slides,o.reinit()},e.prototype.setCSS=function(i){var e,t,o=this,s={};
44355!0===o.options.rtl&&(i=-i),e="left"==o.positionProp?Math.ceil(i)+"px":"0px",t="top"==o.positionProp?Math.ceil(i)+"px":"0px",s[o.positionProp]=i,!1===o.transformsEnabled?o.$slideTrack.css(s):(s={},!1===o.cssTransitions?(s[o.animType]="translate("+e+", "+t+")",o.$slideTrack.css(s)):(s[o.animType]="translate3d("+e+", "+t+", 0px)",o.$slideTrack.css(s)))},e.prototype.setDimensions=function(){var i=this;!1===i.options.vertical?!0===i.options.centerMode&&i.$list.css({padding:"0px "+i.options.centerPadding}):(i.$list.height(i.$slides.first().outerHeight(!0)*i.options.slidesToShow),!0===i.options.centerMode&&i.$list.css({padding:i.options.centerPadding+" 0px"})),i.listWidth=i.$list.width(),i.listHeight=i.$list.height(),!1===i.options.vertical&&!1===i.options.variableWidth?(i.slideWidth=Math.ceil(i.listWidth/i.options.slidesToShow),i.$slideTrack.width(Math.ceil(i.slideWidth*i.$slideTrack.children(".slick-slide").length))):!0===i.options.variableWidth?i.$slideTrack.width(5e3*i.slideCount):(i.slideWidth=Math.ceil(i.listWidth),i.$slideTrack.height(Math.ceil(i.$slides.first().outerHeight(!0)*i.$slideTrack.children(".slick-slide").length)));var e=i.$slides.first().outerWidth(!0)-i.$slides.first().width();!1===i.options.variableWidth&&i.$slideTrack.children(".slick-slide").width(i.slideWidth-e)},e.prototype.setFade=function(){var e,t=this;t.$slides.each(function(o,s){e=t.slideWidth*o*-1,!0===t.options.rtl?i(s).css({position:"relative",right:e,top:0,zIndex:t.options.zIndex-2,opacity:0}
44355):i(s).css({position:"relative",left:e,top:0,zIndex:t.options.zIndex-2,opacity:0})}),t.$slides.eq(t.currentSlide).css({zIndex:t.options.zIndex-1,opacity:1})},e.prototype.setHeight=function(){var i=this;if(1===i.options.slidesToShow&&!0===i.options.adaptiveHeight&&!1===i.options.vertical){var e=i.$slides.eq(i.currentSlide).outerHeight(!0);i.$list.css("height",e)}},e.prototype.setOption=e.prototype.slickSetOption=function(){var e,t,o,s,n,r=this,l=!1;if("object"===i.type(arguments[0])?(o=arguments[0],l=arguments[1],n="multiple"):"string"===i.type(arguments[0])&&(o=arguments[0],s=arguments[1],l=arguments[2],"responsive"===arguments[0]&&"array"===i.type(arguments[1])?n="responsive":void 0!==arguments[1]&&(n="single")),"single"===n)r.options[o]=s;else if("multiple"===n)i.each(o,function(i,e){r.options[i]=e});else if("responsive"===n)for(t in s)if("array"!==i.type(r.options.responsive))r.options.responsive=[s[t]];else{for(e=r.options.responsive.length-1;e>=0;)r.options.responsive[e].breakpoint===s[t].breakpoint&&r.options.responsive.splice(e,1),e--;r.options.responsive.push(s[t])}l&&(r.unload(),r.reinit())},e.prototype.setPosition=function(){var i=this;i.setDimensions(),i.setHeight(),!1===i.options.fade?i.setCSS(i.getLeft(i.currentSlide)):i.setFade(),i.$slider.trigger("setPosition",[i])},e.prototype.setProps=function(){var i=this,e=document.body.style;i.positionProp=!0===i.options.vertical?"top":"left","top"===i.positionProp?i.$slider.addClass("slick-vertical"):i.$slider.removeClass("slick-vertical"),void 0===e.WebkitTransition&&void 0===e.MozTransition&&void 0===e.msTransition||!0===i.options.useCSS&&(i.cssTransitions=!0),i.options.fade&&("number"==typeof i.options.zIndex?i.options.zIndex<3&&(i.options.zIndex=3):i.options.zIndex=i.defaults.zIndex),void 0!==e.OTransform&&(i.animType="OTransform",i.transformType="-o-transform",i.transitionType="OTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.MozTransform&&(i.animType="MozTransform",i.transformType="-moz-transform",i.transitionType="MozTransition",void 0===e.perspectiveProperty&&void 0===e.MozPerspective&&(i.animType=!1)),void 0!==e.webkitTransform&&(i.animType="webkitTransform",i.transformType="-webkit-transform",i.transitionType="webkitTransition",void 0===e.perspectiveProperty&&void 0===e.webkitPerspective&&(i.animType=!1)),void 0!==e.msTransform&&(i.animType="msTransform",i.transformType="-ms-transform",i.transitionType="msTransition",void 0===e.msTransform&&(i.animType=!1)),void 0!==e.transform&&!1!==i.animType&&(i.animType="transform",i.transformType="transform",i.transitionType="transition"),i.transformsEnabled=i.options.useTransform&&null!==i.animType&&!1!==i.animType},e.prototype.setSlideClasses=function(i){var e,t,o,s,n=this;if(t=n.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),n.$slides.eq(i).addClass("slick-current"),!0===n.options.centerMode){var r=n.options.slidesToShow%2==0?1:0;e=Math.floor(n.options.slidesToShow/2),!0===n.options.infinite&&(i>=e&&i<=n.slideCount-1-e?n.$slides.slice(i-e+r,i+e+1).addClass("slick-active").attr("aria-hidden","false"):(o=n.options.slidesToShow+i,t.slice(o-e+1+r,o+e+2).addClass("slick-active").attr("aria-hidden","false")),0===i?t.eq(t.length-1-n.options.slidesToShow).addClass("slick-center"):i===n.slideCount-1&&t.eq(n.options.slidesToShow).addClass("slick-center")),n.$slides.eq(i).addClass("slick-center")}else i>=0&&i<=n.slideCount-n.options.slidesToShow?n.$slides.slice(i,i+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):t.length<=n.options.slidesToShow?t.addClass("slick-active").attr("aria-hidden","false"):(s=n.slideCount%n.options.slidesToShow,o=!0===n.options.infinite?n.options.slidesToShow+i:i,n.options.slidesToShow==n.options.slidesToScroll&&n.slideCount-i<n.options.slidesToShow?t.slice(o-(n.options.slidesToShow-s),o+s).addClass("slick-active").attr("aria-hidden","false"):t.slice(o,o+n.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"));"ondemand"!==n.options.lazyLoad&&"anticipated"!==n.options.lazyLoad||n.lazyLoad()},e.prototype.setupInfinite=function(){var e,t,o,s=this;if(!0===s.options.fade&&(s.options.centerMode=!1),!0===s.options.infinite&&!1===s.options.fade&&(t=null,s.slideCount>s.options.slidesToShow)){for(o=!0===s.options.centerMode?s.options.slidesToShow+1:s.options.slidesToShow,e=s.slideCount;e>s.slideCount-o;e-=1)t=e-1,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t-s.slideCount).prependTo(s.$slideTrack).addClass("slick-cloned");for(e=0;e<o+s.slideCount;e+=1)t=e,i(s.$slides[t]).clone(!0).attr("id","").attr("data-slick-index",t+s.slideCount).appendTo(s.$slideTrack).addClass("slick-cloned");s.$slideTrack.find(".slick-cloned").find("[id]").each(function(){i(this).attr("id","")})}},e.prototype.interrupt=function(i){var e=this;i||e.autoPlay(),e.interrupted=i},e.prototype.selectHandler=function(e){var t=this,o=i(e.target).is(".slick-slide")?i(e.target):i(e.target).parents(".slick-slide"),s=parseInt(o.attr("data-slick-index"));s||(s=0),t.slideCount<=t.options.slidesToShow?t.slideHandler(s,!1,!0):t.slideHandler(s)},e.prototype.slideHandler=function(i,e,t){var o,s,n,r,l,d=null,a=this;if(e=e||!1,!(!0===a.animating&&!0===a.options.waitForAnimate||!0===a.options.fade&&a.currentSlide===i))if(!1===e&&a.asNavFor(i),o=i,d=a.getLeft(o),r=a.getLeft(a.currentSlide),a.currentLeft=null===a.swipeLeft?r:a.swipeLeft,!1===a.options.infinite&&!1===a.options.centerMode&&(i<0||i>a.getDotCount()*a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else if(!1===a.options.infinite&&!0===a.options.centerMode&&(i<0||i>a.slideCount-a.options.slidesToScroll))!1===a.options.fade&&(o=a.currentSlide,!0!==t?a.animateSlide(r,function(){a.postSlide(o)}):a.postSlide(o));else{if(a.options.autoplay&&clearInterval(a.autoPlayTimer),s=o<0?a.slideCount%a.options.slidesToScroll!=0?a.slideCount-a.slideCount%a.options.slidesToScroll:a.slideCount+
44355o:o>=a.slideCount?a.slideCount%a.options.slidesToScroll!=0?0:o-a.slideCount:o,a.animating=!0,a.$slider.trigger("beforeChange",[a,a.currentSlide,s]),n=a.currentSlide,a.currentSlide=s,a.setSlideClasses(a.currentSlide),a.options.asNavFor&&(l=(l=a.getNavTarget()).slick("getSlick")).slideCount<=l.options.slidesToShow&&l.setSlideClasses(a.currentSlide),a.updateDots(),a.updateArrows(),!0===a.options.fade)return!0!==t?(a.fadeSlideOut(n),a.fadeSlide(s,function(){a.postSlide(s)})):a.postSlide(s),void a.animateHeight();!0!==t?a.animateSlide(d,function(){a.postSlide(s)}):a.postSlide(s)}},e.prototype.startLoad=function(){var i=this;!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&(i.$prevArrow.hide(),i.$nextArrow.hide()),!0===i.options.dots&&i.slideCount>i.options.slidesToShow&&i.$dots.hide(),i.$slider.addClass("slick-loading")},e.prototype.swipeDirection=function(){var i,e,t,o,s=this;return i=s.touchObject.startX-s.touchObject.curX,e=s.touchObject.startY-s.touchObject.curY,t=Math.atan2(e,i),(o=Math.round(180*t/Math.PI))<0&&(o=360-Math.abs(o)),o<=45&&o>=0?!1===s.options.rtl?"left":"right":o<=360&&o>=315?!1===s.options.rtl?"left":"right":o>=135&&o<=225?!1===s.options.rtl?"right":"left":!0===s.options.verticalSwiping?o>=35&&o<=135?"down":"up":"vertical"},e.prototype.swipeEnd=function(i){var e,t,o=this;if(o.dragging=!1,o.swiping=!1,o.scrolling)return o.scrolling=!1,!1;if(o.interrupted=!1,o.shouldClick=!(o.touchObject.swipeLength>10),void 0===o.touchObject.curX)return!1;if(!0===o.touchObject.edgeHit&&o.$slider.trigger("edge",[o,o.swipeDirection()]),o.touchObject.swipeLength>=o.touchObject.minSwipe){switch(t=o.swipeDirection()){case"left":case"down":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide+o.getSlideCount()):o.currentSlide+o.getSlideCount(),o.currentDirection=0;break;case"right":case"up":e=o.options.swipeToSlide?o.checkNavigable(o.currentSlide-o.getSlideCount()):o.currentSlide-o.getSlideCount(),o.currentDirection=1}"vertical"!=t&&(o.slideHandler(e),o.touchObject={},o.$slider.trigger("swipe",[o,t]))}else o.touchObject.startX!==o.touchObject.curX&&(o.slideHandler(o.currentSlide),o.touchObject={})},e.prototype.swipeHandler=function(i){var e=this;if(!(!1===e.options.swipe||"ontouchend"in document&&!1===e.options.swipe||!1===e.options.draggable&&-1!==i.type.indexOf("mouse")))switch(e.touchObject.fingerCount=i.originalEvent&&void 0!==i.originalEvent.touches?i.originalEvent.touches.length:1,e.touchObject.minSwipe=e.listWidth/e.options.touchThreshold,!0===e.options.verticalSwiping&&(e.touchObject.minSwipe=e.listHeight/e.options.touchThreshold),i.data.action){case"start":e.swipeStart(i);break;case"move":e.swipeMove(i);break;case"end":e.swipeEnd(i)}},e.prototype.swipeMove=function(i){var e,t,o,s,n,r,l=this;return n=void 0!==i.originalEvent?i.originalEvent.touches:null,!(!l.dragging||l.scrolling||n&&1!==n.length)&&(e=l.getLeft(l.currentSlide),l.touchObject.curX=void 0!==n?n[0].pageX:i.clientX,l.touchObject.curY=void 0!==n?n[0].pageY:i.clientY,l.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(l.touchObject.curX-l.touchObject.startX,2))),r=Math.round(Math.sqrt(Math.pow(l.touchObject.curY-l.touchObject.startY,2))),!l.options.verticalSwiping&&!l.swiping&&r>4?(l.scrolling=!0,!1):(!0===l.options.verticalSwiping&&(l.touchObject.swipeLength=r),t=l.swipeDirection(),void 0!==i.originalEvent&&l.touchObject.swipeLength>4&&(l.swiping=!0,i.preventDefault()),s=(!1===l.options.rtl?1:-1)*(l.touchObject.curX>l.touchObject.startX?1:-1),!0===l.options.verticalSwiping&&(s=l.touchObject.curY>l.touchObject.startY?1:-1),o=l.touchObject.swipeLength,l.touchObject.edgeHit=!1,!1===l.options.infinite&&(0===l.currentSlide&&"right"===t||l.currentSlide>=l.getDotCount()&&"left"===t)&&(o=l.touchObject.swipeLength*l.options.edgeFriction,l.touchObject.edgeHit=!0),!1===l.options.vertical?l.swipeLeft=e+o*s:l.swipeLeft=e+o*(l.$list.height()/l.listWidth)*s,!0===l.options.verticalSwiping&&(l.swipeLeft=e+o*s),!0!==l.options.fade&&!1!==l.options.touchMove&&(!0===l.animating?(l.swipeLeft=null,!1):void l.setCSS(l.swipeLeft))))},e.prototype.swipeStart=function(i){var e,t=this;if(t.interrupted=!0,1!==t.touchObject.fingerCount||t.slideCount<=t.options.slidesToShow)return t.touchObject={},!1;void 0!==i.originalEvent&&void 0!==i.originalEvent.touches&&(e=i.originalEvent.touches[0]),t.touchObject.startX=t.touchObject.curX=void 0!==e?e.pageX:i.clientX,t.touchObject.startY=t.touchObject.curY=void 0!==e?e.pageY:i.clientY,t.dragging=!0},e.prototype.unfilterSlides=e.prototype.slickUnfilter=function(){var i=this;null!==i.$slidesCache&&(i.unload(),i.$slideTrack.children(this.options.slide).detach(),i.$slidesCache.appendTo(i.$slideTrack),i.reinit())},e.prototype.unload=function(){var e=this;i(".slick-cloned",e.$slider).remove(),e.$dots&&e.$dots.remove(),e.$prevArrow&&e.htmlExpr.test(e.options.prevArrow)&&e.$prevArrow.remove(),e.$nextArrow&&e.htmlExpr.test(e.options.nextArrow)&&e.$nextArrow.remove(),e.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")}
44355,e.prototype.unslick=function(i){var e=this;e.$slider.trigger("unslick",[e,i]),e.destroy()},e.prototype.updateArrows=function(){var i=this;Math.floor(i.options.slidesToShow/2),!0===i.options.arrows&&i.slideCount>i.options.slidesToShow&&!i.options.infinite&&(i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===i.currentSlide?(i.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-i.options.slidesToShow&&!1===i.options.centerMode?(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):i.currentSlide>=i.slideCount-1&&!0===i.options.centerMode&&(i.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),i.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},e.prototype.updateDots=function(){var i=this;null!==i.$dots&&(i.$dots.find("li").removeClass("slick-active").end(),i.$dots.find("li").eq(Math.floor(i.currentSlide/i.options.slidesToScroll)).addClass("slick-active"))},e.prototype.visibility=function(){var i=this;i.options.autoplay&&(document[i.hidden]?i.interrupted=!0:i.interrupted=!1)},i.fn.slick=function(){var i,t,o=this,s=arguments[0],n=Array.prototype.slice.call(arguments,1),r=o.length;for(i=0;i<r;i++)if("object"==typeof s||void 0===s?o[i].slick=new e(o[i],s):t=o[i].slick[s].apply(o[i].slick,n),void 0!==t)return t;return o}});
44356// WebcamJS v1.0.24
44357// Webcam library for capturing JPEG/PNG images in JavaScript
44358// Attempts getUserMedia, falls back to Flash
44359// Author: Joseph Huckaby: http://github.com/jhuckaby
44360// Based on JPEGCam: http://code.google.com/p/jpegcam/
44361// Copyright (c) 2012 - 2017 Joseph Huckaby
44362// Licensed under the MIT License
44363
44364(function(window) {
44365var _userMedia;
44366
44367// declare error types
44368
44369// inheritance pattern here:
44370// https://stackoverflow.com/questions/783818/how-do-i-create-a-custom-error-in-javascript
44371function FlashError() {
44372	var temp = Error.apply(this, arguments);
44373	temp.name = this.name = "FlashError";
44374	this.stack = temp.stack;
44375	this.message = temp.message;
44376}
44377
44378function WebcamError() {
44379	var temp = Error.apply(this, arguments);
44380	temp.name = this.name = "WebcamError";
44381	this.stack = temp.stack;
44382	this.message = temp.message;
44383}
44384
44385IntermediateInheritor = function() {};
44386IntermediateInheritor.prototype = Error.prototype;
44387
44388FlashError.prototype = new IntermediateInheritor();
44389WebcamError.prototype = new IntermediateInheritor();
44390
44391var Webcam = {
44392	version: '1.0.24',
44393	
44394	// globals
44395	protocol: location.protocol.match(/https/i) ? 'https' : 'http',
44396	loaded: false,   // true when webcam movie finishes loading
44397	live: false,     // true when webcam is initialized and ready to snap
44398	userMedia: true, // true when getUserMedia is supported natively
44399
44400	iOS: /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream,
44401
44402	params: {
44403		width: 0,
44404		height: 0,
44405		dest_width: 0,         // size of captured image
44406		dest_height: 0,        // these default to width/height
44407		image_format: 'jpeg',  // image format (may be jpeg or png)
44408		jpeg_quality: 90,      // jpeg image quality from 0 (worst) to 100 (best)
44409		enable_flash: true,    // enable flash fallback,
44410		force_flash: false,    // force flash mode,
44411		flip_horiz: false,     // flip image horiz (mirror mode)
44412		fps: 30,               // camera frames per second
44413		upload_name: 'webcam', // name of file in upload post data
44414		constraints: null,     // custom user media constraints,
44415		swfURL: '',            // URI to webcam.swf movie (defaults to the js location)
44416		flashNotDetectedText: 'ERROR: No Adobe Flash Player detected.  Webcam.js relies on Flash for browsers that do not support getUserMedia (like yours).',
44417		noInterfaceFoundText: 'No supported webcam interface found.',
44418		unfreeze_snap: true,    // Whether to unfreeze the camera after snap (defaults to true)
44419		iosPlaceholderText: 'Click here to open camera.',
44420		user_callback: null,    // callback function for snapshot (used if no user_callback parameter given to snap function)
44421		user_canvas: null       // user provided canvas for snapshot (used if no user_canvas parameter given to snap function)
44422	},
44423
44424	errors: {
44425		FlashError: FlashError,
44426		WebcamError: WebcamError
44427	},
44428	
44429	hooks: {}, // callback hook functions
44430	
44431	init: function() {
44432		// initialize, check for getUserMedia support
44433		var self = this;
44434		
vendor: 6,990 bytes, lines 44435-44631
44435		// Setup getUserMedia, with polyfill for older browsers
44436		// Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
44437		this.mediaDevices = (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ? 
44438			navigator.mediaDevices : ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
44439				getUserMedia: function(c) {
44440					return new Promise(function(y, n) {
44441						(navigator.mozGetUserMedia ||
44442						navigator.webkitGetUserMedia).call(navigator, c, y, n);
44443					});
44444				}
44445		} : null);
44446		
44447		window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
44448		this.userMedia = this.userMedia && !!this.mediaDevices && !!window.URL;
44449		
44450		if (this.iOS) {
44451			this.userMedia = null;
44452		}
44453		
44454		// Older versions of firefox (< 21) apparently claim support but user media does not actually work
44455		if (navigator.userAgent.match(/Firefox\D+(\d+)/)) {
44456			if (parseInt(RegExp.$1, 10) < 21) this.userMedia = null;
44457		}
44458		
44459		// Make sure media stream is closed when navigating away from page
44460		if (this.userMedia) {
44461			window.addEventListener( 'beforeunload', function(event) {
44462				self.reset();
44463			} );
44464		}
44465	},
44466	
44467	exifOrientation: function(binFile) {
44468		// extract orientation information from the image provided by iOS
44469		// algorithm based on exif-js
44470		var dataView = new DataView(binFile);
44471		if ((dataView.getUint8(0) != 0xFF) || (dataView.getUint8(1) != 0xD8)) {
44472			console.log('Not a valid JPEG file');
44473			return 0;
44474		}
44475		var offset = 2;
44476		var marker = null;
44477		while (offset < binFile.byteLength) {
44478			// find 0xFFE1 (225 marker)
44479			if (dataView.getUint8(offset) != 0xFF) {
44480				console.log('Not a valid marker at offset ' + offset + ', found: ' + dataView.getUint8(offset));
44481				return 0;
44482			}
44483			marker = dataView.getUint8(offset + 1);
44484			if (marker == 225) {
44485				offset += 4;
44486				var str = "";
44487				for (n = 0; n < 4; n++) {
44488					str += String.fromCharCode(dataView.getUint8(offset+n));
44489				}
44490				if (str != 'Exif') {
44491					console.log('Not valid EXIF data found');
44492					return 0;
44493				}
44494				
44495				offset += 6; // tiffOffset
44496				var bigEnd = null;
44497
44498				// test for TIFF validity and endianness
44499				if (dataView.getUint16(offset) == 0x4949) {
44500					bigEnd = false;
44501				} else if (dataView.getUint16(offset) == 0x4D4D) {
44502					bigEnd = true;
44503				} else {
44504					console.log("Not valid TIFF data! (no 0x4949 or 0x4D4D)");
44505					return 0;
44506				}
44507
44508				if (dataView.getUint16(offset+2, !bigEnd) != 0x002A) {
44509					console.log("Not valid TIFF data! (no 0x002A)");
44510					return 0;
44511				}
44512
44513				var firstIFDOffset = dataView.getUint32(offset+4, !bigEnd);
44514				if (firstIFDOffset < 0x00000008) {
44515					console.log("Not valid TIFF data! (First offset less than 8)", dataView.getUint32(offset+4, !bigEnd));
44516					return 0;
44517				}
44518
44519				// extract orientation data
44520				var dataStart = offset + firstIFDOffset;
44521				var entries = dataView.getUint16(dataStart, !bigEnd);
44522				for (var i=0; i<entries; i++) {
44523					var entryOffset = dataStart + i*12 + 2;
44524					if (dataView.getUint16(entryOffset, !bigEnd) == 0x0112) {
44525						var valueType = dataView.getUint16(entryOffset+2, !bigEnd);
44526						var numValues = dataView.getUint32(entryOffset+4, !bigEnd);
44527						if (valueType != 3 && numValues != 1) {
44528							console.log('Invalid EXIF orientation value type ('+valueType+') or count ('+numValues+')');
44529							return 0;
44530						}
44531						var value = dataView.getUint16(entryOffset + 8, !bigEnd);
44532						if (value < 1 || value > 8) {
44533							console.log('Invalid EXIF orientation value ('+value+')');
44534							return 0;
44535						}
44536						return value;
44537					}
44538				}
44539			} else {
44540				offset += 2+dataView.getUint16(offset+2);
44541			}
44542		}
44543		return 0;
44544	},
44545	
44546	fixOrientation: function(origObjURL, orientation, targetImg) {
44547		// fix image orientation based on exif orientation data
44548		// exif orientation information
44549		//    http://www.impulseadventure.com/photo/exif-orientation.html
44550		//    link source wikipedia (https://en.wikipedia.org/wiki/Exif#cite_note-20)
44551		var img = new Image();
44552		img.addEventListener('load', function(event) {
44553			var canvas = document.createElement('canvas');
44554			var ctx = canvas.getContext('2d');
44555			
44556			// switch width height if orientation needed
44557			if (orientation < 5) {
44558				canvas.width = img.width;
44559				canvas.height = img.height;
44560			} else {
44561				canvas.width = img.height;
44562				canvas.height = img.width;
44563			}
44564
44565			// transform (rotate) image - see link at beginning this method
44566			switch (orientation) {
44567				case 2: ctx.transform(-1, 0, 0, 1, img.width, 0); break;
44568				case 3: ctx.transform(-1, 0, 0, -1, img.width, img.height); break;
44569				case 4: ctx.transform(1, 0, 0, -1, 0, img.height); break;
44570				case 5: ctx.transform(0, 1, 1, 0, 0, 0); break;
44571				case 6: ctx.transform(0, 1, -1, 0, img.height , 0); break;
44572				case 7: ctx.transform(0, -1, -1, 0, img.height, img.width); break;
44573				case 8: ctx.transform(0, -1, 1, 0, 0, img.width); break;
44574			}
44575
44576			ctx.drawImage(img, 0, 0);
44577			// pass rotated image data to the target image container
44578			targetImg.src = canvas.toDataURL();
44579		}, false);
44580		// start transformation by load event
44581		img.src = origObjURL;
44582	},
44583	
44584	attach: function(elem) {
44585		// create webcam preview and attach to DOM element
44586		// pass in actual DOM reference, ID, or CSS selector
44587		if (typeof(elem) == 'string') {
44588			elem = document.getElementById(elem) || document.querySelector(elem);
44589		}
44590		if (!elem) {
44591			return this.dispatch('error', new WebcamError("Could not locate DOM element to attach to."));
44592		}
44593		this.container = elem;
44594		elem.innerHTML = ''; // start with empty element
44595		
44596		// insert "peg" so we can insert our preview canvas adjacent to it later on
44597		var peg = document.createElement('div');
44598		elem.appendChild( peg );
44599		this.peg = peg;
44600		
44601		// set width/height if not already set
44602		if (!this.params.width) this.params.width = elem.offsetWidth;
44603		if (!this.params.height) this.params.height = elem.offsetHeight;
44604		
44605		// make sure we have a nonzero width and height at this point
44606		if (!this.params.width || !this.params.height) {
44607			return this.dispatch('error', new WebcamError("No width and/or height for webcam.  Please call set() first, or attach to a visible element."));
44608		}
44609		
44610		// set defaults for dest_width / dest_height if not set
44611		if (!this.params.dest_width) this.params.dest_width = this.params.width;
44612		if (!this.params.dest_height) this.params.dest_height = this.params.height;
44613		
44614		this.userMedia = _userMedia === undefined ? this.userMedia : _userMedia;
44615		// if force_flash is set, disable userMedia
44616		if (this.params.force_flash) {
44617			_userMedia = this.userMedia;
44618			this.userMedia = null;
44619		}
44620		
44621		// check for default fps
44622		if (typeof this.params.fps !== "number") this.params.fps = 30;
44623
44624		// adjust scale if dest_width or dest_height is different
44625		var scaleX = this.params.width / this.params.dest_width;
44626		var scaleY = this.params.height / this.params.dest_height;
44627		
44628		if (this.userMedia) {
44629			// setup webcam video container
44630			var video = document.createElement('video');
44631			video.setAttribute('autoplay', 'autoplay
vendor: 26,369 bytes, lines 44631-45406
44631');
44632			video.style.width = '' + this.params.dest_width + 'px';
44633			video.style.height = '' + this.params.dest_height + 'px';
44634			
44635			if ((scaleX != 1.0) || (scaleY != 1.0)) {
44636				elem.style.overflow = 'hidden';
44637				video.style.webkitTransformOrigin = '0px 0px';
44638				video.style.mozTransformOrigin = '0px 0px';
44639				video.style.msTransformOrigin = '0px 0px';
44640				video.style.oTransformOrigin = '0px 0px';
44641				video.style.transformOrigin = '0px 0px';
44642				video.style.webkitTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
44643				video.style.mozTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
44644				video.style.msTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
44645				video.style.oTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
44646				video.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
44647			}
44648			
44649			// add video element to dom
44650			elem.appendChild( video );
44651			this.video = video;
44652			
44653			// ask user for access to their camera
44654			var self = this;
44655			this.mediaDevices.getUserMedia({
44656				"audio": false,
44657				"video": this.params.constraints || {
44658					mandatory: {
44659						minWidth: this.params.dest_width,
44660						minHeight: this.params.dest_height
44661					}
44662				}
44663			})
44664			.then( function(stream) {
44665				// got access, attach stream to video
44666				video.onloadedmetadata = function(e) {
44667					self.stream = stream;
44668					self.loaded = true;
44669					self.live = true;
44670					self.dispatch('load');
44671					self.dispatch('live');
44672					self.flip();
44673				};
44674				// as window.URL.createObjectURL() is deprecated, adding a check so that it works in Safari.
44675				// older browsers may not have srcObject
44676				if ("srcObject" in video) {
44677				  	video.srcObject = stream;
44678				}
44679				else {
44680				  	// using URL.createObjectURL() as fallback for old browsers
44681				  	video.src = window.URL.createObjectURL(stream);
44682				}
44683			})
44684			.catch( function(err) {
44685				// JH 2016-07-31 Instead of dispatching error, now falling back to Flash if userMedia fails (thx @john2014)
44686				// JH 2016-08-07 But only if flash is actually installed -- if not, dispatch error here and now.
44687				if (self.params.enable_flash && self.detectFlash()) {
44688					setTimeout( function() { self.params.force_flash = 1; self.attach(elem); }, 1 );
44689				}
44690				else {
44691					self.dispatch('error', err);
44692				}
44693			});
44694		}
44695		else if (this.iOS) {
44696			// prepare HTML elements
44697			var div = document.createElement('div');
44698			div.id = this.container.id+'-ios_div';
44699			div.className = 'webcamjs-ios-placeholder';
44700			div.style.width = '' + this.params.width + 'px';
44701			div.style.height = '' + this.params.height + 'px';
44702			div.style.textAlign = 'center';
44703			div.style.display = 'table-cell';
44704			div.style.verticalAlign = 'middle';
44705			div.style.backgroundRepeat = 'no-repeat';
44706			div.style.backgroundSize = 'contain';
44707			div.style.backgroundPosition = 'center';
44708			var span = document.createElement('span');
44709			span.className = 'webcamjs-ios-text';
44710			span.innerHTML = this.params.iosPlaceholderText;
44711			div.appendChild(span);
44712			var img = document.createElement('img');
44713			img.id = this.container.id+'-ios_img';
44714			img.style.width = '' + this.params.dest_width + 'px';
44715			img.style.height = '' + this.params.dest_height + 'px';
44716			img.style.display = 'none';
44717			div.appendChild(img);
44718			var input = document.createElement('input');
44719			input.id = this.container.id+'-ios_input';
44720			input.setAttribute('type', 'file');
44721			input.setAttribute('accept', 'image/*');
44722			input.setAttribute('capture', 'camera');
44723			
44724			var self = this;
44725			var params = this.params;
44726			// add input listener to load the selected image
44727			input.addEventListener('change', function(event) {
44728				if (event.target.files.length > 0 && event.target.files[0].type.indexOf('image/') == 0) {
44729					var objURL = URL.createObjectURL(event.target.files[0]);
44730
44731					// load image with auto scale and crop
44732					var image = new Image();
44733					image.addEventListener('load', function(event) {
44734						var canvas = document.createElement('canvas');
44735						canvas.width = params.dest_width;
44736						canvas.height = params.dest_height;
44737						var ctx = canvas.getContext('2d');
44738
44739						// crop and scale image for final size
44740						ratio = Math.min(image.width / params.dest_width, image.height / params.dest_height);
44741						var sw = params.dest_width * ratio;
44742						var sh = params.dest_height * ratio;
44743						var sx = (image.width - sw) / 2;
44744						var sy = (image.height - sh) / 2;
44745						ctx.drawImage(image, sx, sy, sw, sh, 0, 0, params.dest_width, params.dest_height);
44746
44747						var dataURL = canvas.toDataURL();
44748						img.src = dataURL;
44749						div.style.backgroundImage = "url('"+dataURL+"')";
44750					}, false);
44751					
44752					// read EXIF data
44753					var fileReader = new FileReader();
44754					fileReader.addEventListener('load', function(e) {
44755						var orientation = self.exifOrientation(e.target.result);
44756						if (orientation > 1) {
44757							// image need to rotate (see comments on fixOrientation method for more information)
44758							// transform image and load to image object
44759							self.fixOrientation(objURL, orientation, image);
44760						} else {
44761							// load image data to image object
44762							image.src = objURL;
44763						}
44764					}, false);
44765					
44766					// Convert image data to blob format
44767					var http = new XMLHttpRequest();
44768					http.open("GET", objURL, true);
44769					http.responseType = "blob";
44770					http.onload = function(e) {
44771						if (this.status == 200 || this.status === 0) {
44772							fileReader.readAsArrayBuffer(this.response);
44773						}
44774					};
44775					http.send();
44776
44777				}
44778			}, false);
44779			input.style.display = 'none';
44780			elem.appendChild(input);
44781			// make div clickable for open camera interface
44782			div.addEventListener('click', function(event) {
44783				if (params.user_callback) {
44784					// global user_callback defined - create the snapshot
44785					self.snap(params.user_callback, params.user_canvas);
44786				} else {
44787					// no global callback definied for snapshot, load image and wait for external snap method call
44788					input.style.display = 'block';
44789					input.focus();
44790					input.click();
44791					input.style.display = 'none';
44792				}
44793			}, false);
44794			elem.appendChild(div);
44795			this.loaded = true;
44796			this.live = true;
44797		}
44798		else if (this.params.enable_flash && this.detectFlash()) {
44799			// flash fallback
44800			window.Webcam = Webcam; // needed for flash-to-js interface
44801			var div = document.createElement('div');
44802			div.innerHTML = this.getSWFHTML();
44803			elem.appendChild( div );
44804		}
44805		else {
44806			this.dispatch('error', new WebcamError( this.params.noInterfaceFoundText ));
44807		}
44808		
44809		// setup final crop for live preview
44810		if (this.params.crop_width && this.params.crop_height) {
44811			var scaled_crop_width = Math.floor( this.params.crop_width * scaleX );
44812			var scaled_crop_height = Math.floor( this.params.crop_height * scaleY );
44813			
44814			elem.style.width = '' + scaled_crop_width + 'px';
44815			elem.style.height = '' + scaled_crop_height + 'px';
44816			elem.style.overflow = 'hidden';
44817			
44818			elem.scrollLeft = Math.floor( (this.params.width / 2) - (scaled_crop_width / 2) );
44819			elem.scrollTop = Math.floor( (this.params.height / 2) - (scaled_crop_height / 2) );
44820		}
44821		else {
44822			// no crop, set size to desired
44823			elem.style.width = '' + this.params.width + 'px';
44824			elem.style.height = '' + this.params.height + 'px';
44825		}
44826	},
44827	
44828	reset: function() {
44829		// shutdown camera, reset to potentially attach again
44830		if (this.preview_active) this.unfreeze();
44831		
44832		// attempt to fix issue #64
44833		this.unflip();
44834		
44835		if (this.userMedia) {
44836			if (this.stream) {
44837				if (this.stream.getVideoTracks) {
44838					// get video track to call stop on it
44839					var tracks = this.stream.getVideoTracks();
44840					if (tracks && tracks[0] && tracks[0].stop) tracks[0].stop();
44841				}
44842				else if (this.stream.stop) {
44843					// deprecated, may be removed in future
44844					this.stream.stop();
44845				}
44846			}
44847			delete this.stream;
44848			delete this.video;
44849		}
44850
44851		if ((this.userMedia !== true) && this.loaded && !this.iOS) {
44852			// call for turn off camera in flash
44853			var movie = this.getMovie();
44854			if (movie && movie._releaseCamera) movie._releaseCamera();
44855		}
44856
44857		if (this.container) {
44858			this.container.innerHTML = '';
44859			delete this.container;
44860		}
44861	
44862		this.loaded = false;
44863		this.live = false;
44864	},
44865	
44866	set: function() {
44867		// set one or more params
44868		// variable argument list: 1 param = hash, 2 params = key, value
44869		if (arguments.length == 1) {
44870			for (var key in arguments[0]) {
44871				this.params[key] = arguments[0][key];
44872			}
44873		}
44874		else {
44875			this.params[ arguments[0] ] = arguments[1];
44876		}
44877	},
44878	
44879	on: function(name, callback) {
44880		// set callback hook
44881		name = name.replace(/^on/i, '').toLowerCase();
44882		if (!this.hooks[name]) this.hooks[name] = [];
44883		this.hooks[name].push( callback );
44884	},
44885	
44886	off: function(name, callback) {
44887		// remove callback hook
44888		name = name.replace(/^on/i, '').toLowerCase();
44889		if (this.hooks[name]) {
44890			if (callback) {
44891				// remove one selected callback from list
44892				var idx = this.hooks[name].indexOf(callback);
44893				if (idx > -1) this.hooks[name].splice(idx, 1);
44894			}
44895			else {
44896				// no callback specified, so clear all
44897				this.hooks[name] = [];
44898			}
44899		}
44900	},
44901	
44902	dispatch: function() {
44903		// fire hook callback, passing optional value to it
44904		var name = arguments[0].replace(/^on/i, '').toLowerCase();
44905		var args = Array.prototype.slice.call(arguments, 1);
44906		
44907		if (this.hooks[name] && this.hooks[name].length) {
44908			for (var idx = 0, len = this.hooks[name].length; idx < len; idx++) {
44909				var hook = this.hooks[name][idx];
44910				
44911				if (typeof(hook) == 'function') {
44912					// callback is function reference, call directly
44913					hook.apply(this, args);
44914				}
44915				else if ((typeof(hook) == 'object') && (hook.length == 2)) {
44916					// callback is PHP-style object instance method
44917					hook[0][hook[1]].apply(hook[0], args);
44918				}
44919				else if (window[hook]) {
44920					// callback is global function name
44921					window[ hook ].apply(window, args);
44922				}
44923			} // loop
44924			return true;
44925		}
44926		else if (name == 'error') {
44927			if ((args[0] instanceof FlashError) || (args[0] instanceof WebcamError)) {
44928				message = args[0].message;
44929			} else {
44930				message = "Could not access webcam: " + args[0].name + ": " + 
44931					args[0].message + " " + args[0].toString();
44932			}
44933
44934			// default error handler if no custom one specified
44935			alert("Webcam.js Error: " + message);
44936		}
44937		
44938		return false; // no hook defined
44939	},
44940
44941	setSWFLocation: function(value) {
44942		// for backward compatibility.
44943		this.set('swfURL', value);
44944	},
44945	
44946	detectFlash: function() {
44947		// return true if browser supports flash, false otherwise
44948		// Code snippet borrowed from: https://github.com/swfobject/swfobject
44949		var SHOCKWAVE_FLASH = "Shockwave Flash",
44950			SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
44951        	FLASH_MIME_TYPE = "application/x-shockwave-flash",
44952        	win = window,
44953        	nav = navigator,
44954        	hasFlash = false;
44955        
44956        if (typeof nav.plugins !== "undefined" && typeof nav.plugins[SHOCKWAVE_FLASH] === "object") {
44957        	var desc = nav.plugins[SHOCKWAVE_FLASH].description;
44958        	if (desc && (typeof nav.mimeTypes !== "undefined" && nav.mimeTypes[FLASH_MIME_TYPE] && nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
44959        		hasFlash = true;
44960        	}
44961        }
44962        else if (typeof win.ActiveXObject !== "undefined") {
44963        	try {
44964        		var ax = new ActiveXObject(SHOCKWAVE_FLASH_AX);
44965        		if (ax) {
44966        			var ver = ax.GetVariable("$version");
44967        			if (ver) hasFlash = true;
44968        		}
44969        	}
44970        	catch (e) {;}
44971        }
44972        
44973        return hasFlash;
44974	},
44975	
44976	getSWFHTML: function() {
44977		// Return HTML for embedding flash based webcam capture movie		
44978		var html = '',
44979			swfURL = this.params.swfURL;
44980		
44981		// make sure we aren't running locally (flash doesn't work)
44982		if (location.protocol.match(/file/)) {
44983			this.dispatch('error', new FlashError("Flash does not work from local disk.  Please run from a web server."));
44984			return '<h3 style="color:red">ERROR: the Webcam.js Flash fallback does not work from local disk.  Please run it from a web server.</h3>';
44985		}
44986		
44987		// make sure we have flash
44988		if (!this.detectFlash()) {
44989			this.dispatch('error', new FlashError("Adobe Flash Player not found.  Please install from get.adobe.com/flashplayer and try again."));
44990			return '<h3 style="color:red">' + this.params.flashNotDetectedText + '</h3>';
44991		}
44992		
44993		// set default swfURL if not explicitly set
44994		if (!swfURL) {
44995			// find our script tag, and use that base URL
44996			var base_url = '';
44997			var scpts = document.getElementsByTagName('script');
44998			for (var idx = 0, len = scpts.length; idx < len; idx++) {
44999				var src = scpts[idx].getAttribute('src');
45000				if (src && src.match(/\/webcam(\.min)?\.js/)) {
45001					base_url = src.replace(/\/webcam(\.min)?\.js.*$/, '');
45002					idx = len;
45003				}
45004			}
45005			if (base_url) swfURL = base_url + '/webcam.swf';
45006			else swfURL = 'webcam.swf';
45007		}
45008		
45009		// if this is the user's first visit, set flashvar so flash privacy settings panel is shown first
45010		if (window.localStorage && !localStorage.getItem('visited')) {
45011			this.params.new_user = 1;
45012			localStorage.setItem('visited', 1);
45013		}
45014		
45015		// construct flashvars string
45016		var flashvars = '';
45017		for (var key in this.params) {
45018			if (flashvars) flashvars += '&';
45019			flashvars += key + '=' + escape(this.params[key]);
45020		}
45021		
45022		// construct object/embed tag
45023		html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" type="application/x-shockwave-flash" codebase="'+this.protocol+'://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+this.params.width+'" height="'+this.params.height+'" id="webcam_movie_obj" align="middle"><param name="wmode" value="opaque" /><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+swfURL+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><embed id="webcam_movie_embed" src="'+swfURL+'" wmode="opaque" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+this.params.width+'" height="'+this.params.height+'" name="webcam_movie_embed" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'"></embed></object>';
45024		
45025		return html;
45026	},
45027	
45028	getMovie: function() {
45029		// get reference to movie object/embed in DOM
45030		if (!this.loaded) return this.dispatch('error', new FlashError("Flash Movie is not loaded yet"));
45031		var movie = document.getElementById('webcam_movie_obj');
45032		if (!movie || !movie._snap) movie = document.getElementById('webcam_movie_embed');
45033		if (!movie) this.dispatch('error', new FlashError("Cannot locate Flash movie in DOM"));
45034		return movie;
45035	},
45036	
45037	freeze: function() {
45038		// show preview, freeze camera
45039		var self = this;
45040		var params = this.params;
45041		
45042		// kill preview if already active
45043		if (this.preview_active) this.unfreeze();
45044		
45045		// determine scale factor
45046		var scaleX = this.params.width / this.params.dest_width;
45047		var scaleY = this.params.height / this.params.dest_height;
45048		
45049		// must unflip container as preview canvas will be pre-flipped
45050		this.unflip();
45051		
45052		// calc final size of image
45053		var final_width = params.crop_width || params.dest_width;
45054		var final_height = params.crop_height || params.dest_height;
45055		
45056		// create canvas for holding preview
45057		var preview_canvas = document.createElement('canvas');
45058		preview_canvas.width = final_width;
45059		preview_canvas.height = final_height;
45060		var preview_context = preview_canvas.getContext('2d');
45061		
45062		// save for later use
45063		this.preview_canvas = preview_canvas;
45064		this.preview_context = preview_context;
45065		
45066		// scale for preview size
45067		if ((scaleX != 1.0) || (scaleY != 1.0)) {
45068			preview_canvas.style.webkitTransformOrigin = '0px 0px';
45069			preview_canvas.style.mozTransformOrigin = '0px 0px';
45070			preview_canvas.style.msTransformOrigin = '0px 0px';
45071			preview_canvas.style.oTransformOrigin = '0px 0px';
45072			preview_canvas.style.transformOrigin = '0px 0px';
45073			preview_canvas.style.webkitTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
45074			preview_canvas.style.mozTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
45075			preview_canvas.style.msTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
45076			preview_canvas.style.oTransform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
45077			preview_canvas.style.transform = 'scaleX('+scaleX+') scaleY('+scaleY+')';
45078		}
45079		
45080		// take snapshot, but fire our own callback
45081		this.snap( function() {
45082			// add preview image to dom, adjust for crop
45083			preview_canvas.style.position = 'relative';
45084			preview_canvas.style.left = '' + self.container.scrollLeft + 'px';
45085			preview_canvas.style.top = '' + self.container.scrollTop + 'px';
45086			
45087			self.container.insertBefore( preview_canvas, self.peg );
45088			self.container.style.overflow = 'hidden';
45089			
45090			// set flag for user capture (use preview)
45091			self.preview_active = true;
45092			
45093		}, preview_canvas );
45094	},
45095	
45096	unfreeze: function() {
45097		// cancel preview and resume live video feed
45098		if (this.preview_active) {
45099			// remove preview canvas
45100			this.container.removeChild( this.preview_canvas );
45101			delete this.preview_context;
45102			delete this.preview_canvas;
45103			
45104			// unflag
45105			this.preview_active = false;
45106			
45107			// re-flip if we unflipped before
45108			this.flip();
45109		}
45110	},
45111	
45112	flip: function() {
45113		// flip container horiz (mirror mode) if desired
45114		if (this.params.flip_horiz) {
45115			var sty = this.container.style;
45116			sty.webkitTransform = 'scaleX(-1)';
45117			sty.mozTransform = 'scaleX(-1)';
45118			sty.msTransform = 'scaleX(-1)';
45119			sty.oTransform = 'scaleX(-1)';
45120			sty.transform = 'scaleX(-1)';
45121			sty.filter = 'FlipH';
45122			sty.msFilter = 'FlipH';
45123		}
45124	},
45125	
45126	unflip: function() {
45127		// unflip container horiz (mirror mode) if desired
45128		if (this.params.flip_horiz) {
45129			var sty = this.container.style;
45130			sty.webkitTransform = 'scaleX(1)';
45131			sty.mozTransform = 'scaleX(1)';
45132			sty.msTransform = 'scaleX(1)';
45133			sty.oTransform = 'scaleX(1)';
45134			sty.transform = 'scaleX(1)';
45135			sty.filter = '';
45136			sty.msFilter = '';
45137		}
45138	},
45139	
45140	savePreview: function(user_callback, user_canvas) {
45141		// save preview freeze and fire user callback
45142		var params = this.params;
45143		var canvas = this.preview_canvas;
45144		var context = this.preview_context;
45145		
45146		// render to user canvas if desired
45147		if (user_canvas) {
45148			var user_context = user_canvas.getContext('2d');
45149			user_context.drawImage( canvas, 0, 0 );
45150		}
45151		
45152		// fire user callback if desired
45153		user_callback(
45154			user_canvas ? null : canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100 ),
45155			canvas,
45156			context
45157		);
45158		
45159		// remove preview
45160		if (this.params.unfreeze_snap) this.unfreeze();
45161	},
45162	
45163	snap: function(user_callback, user_canvas) {
45164		// use global callback and canvas if not defined as parameter
45165		if (!user_callback) user_callback = this.params.user_callback;
45166		if (!user_canvas) user_canvas = this.params.user_canvas;
45167		
45168		// take snapshot and return image data uri
45169		var self = this;
45170		var params = this.params;
45171		
45172		if (!this.loaded) return this.dispatch('error', new WebcamError("Webcam is not loaded yet"));
45173		// if (!this.live) return this.dispatch('error', new WebcamError("Webcam is not live yet"));
45174		if (!user_callback) return this.dispatch('error', new WebcamError("Please provide a callback function or canvas to snap()"));
45175		
45176		// if we have an active preview freeze, use that
45177		if (this.preview_active) {
45178			this.savePreview( user_callback, user_canvas );
45179			return null;
45180		}
45181		
45182		// create offscreen canvas element to hold pixels
45183		var canvas = document.createElement('canvas');
45184		canvas.width = this.params.dest_width;
45185		canvas.height = this.params.dest_height;
45186		var context = canvas.getContext('2d');
45187		
45188		// flip canvas horizontally if desired
45189		if (this.params.flip_horiz) {
45190			context.translate( params.dest_width, 0 );
45191			context.scale( -1, 1 );
45192		}
45193		
45194		// create inline function, called after image load (flash) or immediately (native)
45195		var func = function() {
45196			// render image if needed (flash)
45197			if (this.src && this.width && this.height) {
45198				context.drawImage(this, 0, 0, params.dest_width, params.dest_height);
45199			}
45200			
45201			// crop if desired
45202			if (params.crop_width && params.crop_height) {
45203				var crop_canvas = document.createElement('canvas');
45204				crop_canvas.width = params.crop_width;
45205				crop_canvas.height = params.crop_height;
45206				var crop_context = crop_canvas.getContext('2d');
45207				
45208				crop_context.drawImage( canvas, 
45209					Math.floor( (params.dest_width / 2) - (params.crop_width / 2) ),
45210					Math.floor( (params.dest_height / 2) - (params.crop_height / 2) ),
45211					params.crop_width,
45212					params.crop_height,
45213					0,
45214					0,
45215					params.crop_width,
45216					params.crop_height
45217				);
45218				
45219				// swap canvases
45220				context = crop_context;
45221				canvas = crop_canvas;
45222			}
45223			
45224			// render to user canvas if desired
45225			if (user_canvas) {
45226				var user_context = user_canvas.getContext('2d');
45227				user_context.drawImage( canvas, 0, 0 );
45228			}
45229			
45230			// fire user callback if desired
45231			user_callback(
45232				user_canvas ? null : canvas.toDataURL('image/' + params.image_format, params.jpeg_quality / 100 ),
45233				canvas,
45234				context
45235			);
45236		};
45237		
45238		// grab image frame from userMedia or flash movie
45239		if (this.userMedia) {
45240			// native implementation
45241			context.drawImage(this.video, 0, 0, this.params.dest_width, this.params.dest_height);
45242			
45243			// fire callback right away
45244			func();
45245		}
45246		else if (this.iOS) {
45247			var div = document.getElementById(this.container.id+'-ios_div');
45248			var img = document.getElementById(this.container.id+'-ios_img');
45249			var input = document.getElementById(this.container.id+'-ios_input');
45250			// function for handle snapshot event (call user_callback and reset the interface)
45251			iFunc = function(event) {
45252				func.call(img);
45253				img.removeEventListener('load', iFunc);
45254				div.style.backgroundImage = 'none';
45255				img.removeAttribute('src');
45256				input.value = null;
45257			};
45258			if (!input.value) {
45259				// No image selected yet, activate input field
45260				img.addEventListener('load', iFunc);
45261				input.style.display = 'block';
45262				input.focus();
45263				input.click();
45264				input.style.display = 'none';
45265			} else {
45266				// Image already selected
45267				iFunc(null);
45268			}			
45269		}
45270		else {
45271			// flash fallback
45272			var raw_data = this.getMovie()._snap();
45273			
45274			// render to image, fire callback when complete
45275			var img = new Image();
45276			img.onload = func;
45277			img.src = 'data:image/'+this.params.image_format+';base64,' + raw_data;
45278		}
45279		
45280		return null;
45281	},
45282	
45283	configure: function(panel) {
45284		// open flash configuration panel -- specify tab name:
45285		// "camera", "privacy", "default", "localStorage", "microphone", "settingsManager"
45286		if (!panel) panel = "camera";
45287		this.getMovie()._configure(panel);
45288	},
45289	
45290	flashNotify: function(type, msg) {
45291		// receive notification from flash about event
45292		switch (type) {
45293			case 'flashLoadComplete':
45294				// movie loaded successfully
45295				this.loaded = true;
45296				this.dispatch('load');
45297				break;
45298			
45299			case 'cameraLive':
45300				// camera is live and ready to snap
45301				this.live = true;
45302				this.dispatch('live');
45303				break;
45304
45305			case 'error':
45306				// Flash error
45307				this.dispatch('error', new FlashError(msg));
45308				break;
45309
45310			default:
45311				// catch-all event, just in case
45312				// console.log("webcam flash_notify: " + type + ": " + msg);
45313				break;
45314		}
45315	},
45316	
45317	b64ToUint6: function(nChr) {
45318		// convert base64 encoded character to 6-bit integer
45319		// from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
45320		return nChr > 64 && nChr < 91 ? nChr - 65
45321			: nChr > 96 && nChr < 123 ? nChr - 71
45322			: nChr > 47 && nChr < 58 ? nChr + 4
45323			: nChr === 43 ? 62 : nChr === 47 ? 63 : 0;
45324	},
45325
45326	base64DecToArr: function(sBase64, nBlocksSize) {
45327		// convert base64 encoded string to Uintarray
45328		// from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
45329		var sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
45330			nOutLen = nBlocksSize ? Math.ceil((nInLen * 3 + 1 >> 2) / nBlocksSize) * nBlocksSize : nInLen * 3 + 1 >> 2, 
45331			taBytes = new Uint8Array(nOutLen);
45332		
45333		for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
45334			nMod4 = nInIdx & 3;
45335			nUint24 |= this.b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
45336			if (nMod4 === 3 || nInLen - nInIdx === 1) {
45337				for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
45338					taBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
45339				}
45340				nUint24 = 0;
45341			}
45342		}
45343		return taBytes;
45344	},
45345	
45346	upload: function(image_data_uri, target_url, callback) {
45347		// submit image data to server using binary AJAX
45348		var form_elem_name = this.params.upload_name || 'webcam';
45349		
45350		// detect image format from within image_data_uri
45351		var image_fmt = '';
45352		if (image_data_uri.match(/^data\:image\/(\w+)/))
45353			image_fmt = RegExp.$1;
45354		else
45355			throw "Cannot locate image format in Data URI";
45356		
45357		// extract raw base64 data from Data URI
45358		var raw_image_data = image_data_uri.replace(/^data\:image\/\w+\;base64\,/, '');
45359		
45360		// contruct use AJAX object
45361		var http = new XMLHttpRequest();
45362		http.open("POST", target_url, true);
45363		
45364		// setup progress events
45365		if (http.upload && http.upload.addEventListener) {
45366			http.upload.addEventListener( 'progress', function(e) {
45367				if (e.lengthComputable) {
45368					var progress = e.loaded / e.total;
45369					Webcam.dispatch('uploadProgress', progress, e);
45370				}
45371			}, false );
45372		}
45373		
45374		// completion handler
45375		var self = this;
45376		http.onload = function() {
45377			if (callback) callback.apply( self, [http.status, http.responseText, http.statusText] );
45378			Webcam.dispatch('uploadComplete', http.status, http.responseText, http.statusText);
45379		};
45380		
45381		// create a blob and decode our base64 to binary
45382		var blob = new Blob( [ this.base64DecToArr(raw_image_data) ], {type: 'image/'+image_fmt} );
45383		
45384		// stuff into a form, so servers can easily receive it as a standard file upload
45385		var form = new FormData();
45386		form.append( form_elem_name, blob, form_elem_name+"."+image_fmt.replace(/e/, '') );
45387		
45388		// send data to server
45389		http.send(form);
45390	}
45391	
45392};
45393
45394Webcam.init();
45395
45396if (typeof define === 'function' && define.amd) {
45397	define( function() { return Webcam; } );
45398} 
45399else if (typeof module === 'object' && module.exports) {
45400	module.exports = Webcam;
45401} 
45402else {
45403	window.Webcam = Webcam;
45404}
45405
45406}(window));
45407// =========
45408// = Alert =
45409// =========
45410
45411$(document).ready(function() {
45412
45413  if ($('.conditions-alert--sticky').length > 0) {
45414    if($.cookie('conditions-alert') === null || $.cookie('conditions-alert') < $('.conditions-alert').data('updated')) {      
45415      $('.conditions-alert--sticky').addClass('conditions-alert--active');
45416    }
45417    
45418    $('.js-conditions-alert-close').on('click', function() {
45419      $('#site_wide_alert').slideUp(300);
45420      $.cookie('conditions-alert', $('.conditions-alert').data('updated'), { expires: 1 });
45421    });
45422  }
45423});
45424$(document).ready(function () {
45425
45426  // Check if function exists before calling.
45427  if (typeof $.fn.viewportChecker !== 'undefined' && $.isFunction($.fn.viewportChecker)) {
45428    $('.ac:not(.ac-once)').viewportChecker({
45429      offset: 0,
45430      repeat: false,
45431    });
45432  };
45433
45434});
45435function set_pass_balance(element){
45436  pass_no = element.data('pass-no')
45437  $.ajax({
45438    url: '/gift_cards/' + pass_no,
45439    type: 'get',
45440    dataType: 'json',
45441    success: function(data) {
45442      //processResponse(data);
45443      if (data.status == "success") {
45444        element.text("$" + data.balance)
45445        element.parents('.pass_info').find('.account_reload_link').show()
45446        if (data.voided)
45447          element.parents('.pass_info').find('.pass_info-voided').removeClass('hide');
45448      }else{
45449        element.text("$0.00")
45450      }
45451    },
45452    error: function(data) {
45453      return ""
45454    }
45455  });
45456}
45457
45458// $(document).ready(function(){
45459
45460//   $('span.pass-balance').each(function() {
45461//     set_pass_balance($(this));
45462//   });
45463
45464// });
45465
45466$(document).ready(function(){
45467    function add_cc_requirement() {
45468      $('#cc_number').rules("add",{required: true});
45469      $('#cc_expiry_month').rules("add",{creditcardexpirymonth: true});
45470      $('#cc_expiry_year').rules("add",{creditcardexpiryyear: true});
45471      $('#cc_cvv').rules("add",{required: true});
45472    }
45473
45474    function remove_cc_requirement() {
45475      $('#cc_number').rules("remove","required");
45476      $('#cc_expiry_month').rules("remove","creditcardexpirymonth");
45477      $('#cc_expiry_year').rules("remove","creditcardexpiryyear");
45478      $('#cc_cvv').rules("remove","required");
45479    }
45480
45481    function checkGiftCard() {
45482      if ($('#cart_giftcard').length > 0 && $('#cart_giftcard').val() !== '') {
45483        $('.giftcard.collapsible-form-item, #apply-giftcard').click();
45484      } else {
45485        // Open Credit Card form if collapsed
45486        if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-plus')) {
45487          $('.creditcard.collapsible-form-item').click(); 
45488        }       
45489      }
45490    }
45491
45492    $('#apply-promocode').click(function(event) {
45493      event.preventDefault();
45494      $('#apply-promocode').text('Validating..').addClass('disabled');
45495      $.post('/cart/promocode', $('#cart_promocode').serialize(), function(result) {
45496        $('#apply-promocode').text('Apply').removeClass('disabled');
45497        if (result.cart_totals) {
45498          $('.cart__totals').replaceWith(result.cart_totals);
45499        }
45500        if (result.cart_items && $('.cart__items').length > 0) {
45501          $('.cart__items').replaceWith(result.cart_items);
45502        }
45503        if (result.status == 'ok') {
45504          // yay, let's tell the user all is good!
45505          alert('Promo code has been successfully applied!');
45506          checkGiftCard();
45507        }
45508        else {
45509          // failed to apply promocode, let the user know
45510          alert("Sorry, couldn't find this promocode, please check your spelling.");
45511        }
45512        if (result.status) {
45513          $('input[name="cart[promocode]"]').val(result.promocode);
45514          $("p.promocode-message").text(result.message);    
45515        }
45516      });
45517    });
45518
45519    $('#validate-bin').click(function(event) {
45520      event.preventDefault();
45521      $('#validate-bin').text('Validating..').addClass('disabled');
45522      $.post('/cart/validate_bin', {bin: $('#cc_number').val().slice(0,6)}, function(result) {
45523        
45524        if (result.cart_totals) {
45525          $('.cart__totals').replaceWith(result.cart_totals);
45526        }
45527        if (result.cart_items && $('.cart__items').length > 0) {
45528          $('.cart__items').replaceWith(result.cart_items);
45529        }
45530        if (result.status == 'ok') {
45531          $("#validation-return-message").html('Your RBC Avion® Visa® has been verified.<br>Your Friday Friend Pass offer has been applied below.');
45532          $("#cc_number").prop("readonly", true)
45533        }
45534        else {
45535          $("#validation-return-message").html('Error: Card not eligible for the BOGO promotion.');
45536          $("#cc_number").removeProp("readonly")
45537        }
45538        if (result.status) {
45539          $('input[name="cart[promocode]"]').val(result.promocode);
45540          $('#validate-bin').text('Validate card').removeClass('disabled');
45541        }
45542      });
45543    });
45544
45545    $('#apply-giftcard').click(function(event) {
45546      event.preventDefault();
45547      $('.form-item--giftcard .form-item-message').hide();
45548      $('.form-item--giftcard #giftcard-current-balance').hide();
45549      $('#apply-giftcard').text('Validating..').addClass('disabled');
45550      $.post('/cart/giftcard', $('#cart_giftcard').serialize(), function(result) {
45551        $('#apply-giftcard').text('Apply').removeClass('disabled');
45552        if (result.status == "ok") {
45553          // Collapse Credit Card form if open
45554          if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-minus')) {
45555            $('.creditcard.collapsible-form-item').click();
45556          }
45557          remove_cc_requirement();
45558        } else {
45559          // Open Credit Card form if collapsed
45560          if ($('.creditcard.collapsible-form-item').find('i').hasClass('icon-plus')) {
45561            $('.creditcard.collapsible-form-item').click();
45562          }
45563          add_cc_requirement();
45564        }
45565        if (result.cart_totals) {
45566          $('.cart__totals').replaceWith(result.cart_totals);
45567        }
45568        $('.form-item--giftcard .form-item-message').text(result.message).css('display', 'block');
45569        if (result.current_balance !== null) {
45570          $('.form-item--giftcard #giftcard-current-balance').text("Current Balance: $"+result.current_balance).css('display', 'block');
45571        }
45572      });
45573    });
45574
45575    // Init
45576    checkGiftCard();
45577});
45578function calc_subtotal(with_activities) {
45579  with_activities = with_activities || false;
45580  var t=0.00;
45581  $('.buy_area select.price-select').each(function(){
45582    var itm_price = $(this).find('option[value='+$(this).val()+']').attr('data-price')
45583    $(this).closest('tr.item_info').attr('data-price', itm_price);
45584  });
45585  $('.buy_area tr.item_info, .buy_area .item_info').each(function(){
45586    qty = parseInt($(this).find('.qty').val());
45587    t = t + ( $(this).attr('data-price') * qty );
45588    // Global activities
45589    $('.product_activities').find('.activities option[value!=""]:selected').each(function() {
45590      t = t + parseFloat($(this).attr('data-price') * qty );
45591    });
45592  });
45593  // Activities by item
45594  $('.activities:not(.single-activity) option[value!=""]:selected, .admission_mods .form-item[data-item-index] input:checked').each(function() {
45595    var act_price = parseFloat($(this).attr('data-price'));
45596    if (!isNaN(act_price))
45597      t = t + act_price;
45598  });
45599
45600  return t;
45601}
45602
45603function item_quantity(item) {
45604  q = $('.item_info[data-item-id="'+item+'"]').find('.qty');
45605  return (parseInt(q.val()) * q.closest('.item_info').data('for-n-users'));
45606}
45607
45608function total_quantity() {
45609	var q=0;
45610	$('.buy_area .qty').each(function(){
45611		q = q + (parseInt($(this).val()) * $(this).closest('.item_info').data('for-n-users'));
45612	});
45613	return q;
45614}
45615
45616function activity_claimed_quantity(activity_dci) {
45617  selected_activities = $('[data-dci="'+activity_dci+'"]:selected'); 
45618  var q = 0
45619  selected_activities.each(function(){
45620    q = q + $(this).data('for-n-users');
45621  });
45622
45623  return q;
45624}
45625
45626function activity_claimed_quantities() {
45627  selected_activities = {};
45628  $('option[data-dci][value!=""]:selected').each(function(){
45629    if (selected_activities[$(this).attr('data-dci')] === undefined) selected_activities[$(this).attr('data-dci')] = 0;
45630    selected_activities[$(this).attr('data-dci')] += $(this).data('for-n-users');
45631  });
45632  return selected_activities;
45633}
45634
45635function lock_buy_area() {
45636  $(".buy_area").addClass('muted');
45637  $('.buy_area .tally').addClass('muted');
45638	$('ul.times').addClass("loading");
45639	// $('.buy_area select, .buy_area input, .buy_area button[type="submit"]').not("#local_postal_code").prop('disabled', true);
45640}
45641
45642function unlock_buy_area(item) {
45643  $(".buy_area").removeClass('muted');
45644  $('ul.times').removeClass("loading");
45645  if (!is_single_activity() || (is_single_activity() && $('.product__step-last').is(":visible"))) {
45646    $('.buy_area .tally').removeClass('muted');
45647  }
45648
45649
45650  if ($('#product_buy_area').data('product-type') == 'scheduled_activity') {
45651    // $('.buy_area select, .buy_area input').removeAttr('disabled');
45652    $('.buy_area tr.item_info td').removeClass('text-muted muted');
45653
45654    if ( $('#product_buy_area').data('item-level-availability') == true && item != false && total_quantity() != 0 ) {
45655      selected_row = $('[data-item-id="'+item+'"]');
45656      var siblings = selected_row.siblings('.item_info');
45657      var siblings_qty_selects = siblings.find('.qty');
45658      // siblings_qty_selects.attr('disabled','disabled')
45659      siblings.find('td').addClass('text-muted muted');
45660    }
45661  }
45662}
45663
45664function hide_activities(activities) {
45665  activities.find('li[class!="item_benefit"], .savings_info').removeClass('visible').slideUp();
45666  activities.find('.modifier_group').each(function(){
45667    hide_modifier_group($(this));
45668  });
45669  activities.removeClass('open');
45670}
45671
45672function hide_modifier_group(modifier_group) {
45673  group_activities = modifier_group.next('.modifier_group__list');
45674  group_activities.find('select').val("");
45675  if (group_activities.is(":visible")) {
45676    modifier_group.click();
45677  }
45678  modifier_group.removeClass('visible').slideUp();
45679}
45680
45681var currentPriceRequest = null;
45682
45683function get_sw_subtotal() {
45684  form = $('#edit_cart, #new_cart').first().serializeArray();
45685  currentPriceRequest = $.ajax({
45686    url: "/cart_items/get_items_price",
45687    type: 'POST',
45688    dataType: 'json',
45689    cache: true,
45690    data: form,
45691    beforeSend : function() {           
45692      if(currentPriceRequest != null) {
45693        currentPriceRequest.abort();
45694      }
45695    },
45696    success: function(data) {
45697      var subtotal = calc_subtotal(true);
45698      if (data.price < subtotal)
45699        $('.running_total_without_discount').text(subtotal).formatCurrency().removeClass('hide');
45700      $('.running_total').text("$"+data.price);
45701    },
45702    error: function(data) {
45703      console.log('Failed to get items price');
45704    },
45705    complete: function() {
45706      $('.running_total').removeClass('loading');
45707    }
45708  });
45709}
45710
45711
45712function is_single_activity() {
45713  return ($('.single-activity').length > 0);
45714}
45715
45716function tram_times_present() {
45717  return ($(".tram-times").length > 0);
45718}
45719
45720function tram_times_required(date) {
45721  if (typeof date === 'string')
45722    date = Date.parseString(date);
45723  var start = $(".tram-times").data('activity-start-date')
45724  var end = $(".tram-times").data('activity-end-date')
45725  var days = $(".tram-times").data('activity-days');
45726  var blackouts = $(".tram-times").data('blackouts');
45727
45728  return activityDateAvailable(date, start, end, days, blackouts)
45729}
45730
45731function tram_times_required_highlight_datepicker() {
45732  return $(".tram-times").data('highlight-required-days');
45733}
45734
45735function tram_times_required_highlight_datepicker_reference() {
45736  if (tram_times_required_highlight_datepicker()) {
45737    setTimeout(function() {
45738      var wrapper = $('.ui-datepicker-tram-times-required-reference-wrapper');
45739      if (wrapper.length == 0) {
45740        wrapper = $('<div class="ui-datepicker-tram-times-required-reference-wrapper"><span class="ui-datepicker-tram-times-required-reference"></span> Requires Skyride booking.</div>');
45741      }
45742      $('#ui-datepicker-div').append(wrapper);    
45743    }, 0);
45744  }
45745}
45746
45747
45748function toggle_tram_times(date) {
45749  var req = tram_times_required(date);
45750  $(".tram-times").closest('.product__step').toggleClass('hide', !req);
45751  $('.product__step.tram-times__not-required').toggleClass('hide', req);
45752  $('.button.book-now').toggleClass('hide', !req);
45753
45754}
45755
45756function is_passholders_load_times() {
45757  return ($('.passholders-load-times').length > 0);
45758}
45759
45760function should_get_sw_subtotal() {
45761  // Always calculate price if product type is Bundled
45762  return $('#product_buy_area').data('product-type') == "scheduled_activity" || ($('#product_buy_area').data('product-type') == "bundled" && !is_passholders_load_times());
45763
45764  // TEMPORARILY DEPRECATED
45765  //-----------------------
45766  // The logic below used to check if there's any selected activity
45767  // to then trigger a price calculation. Since items pricing rules can
45768  // now affect the price of the parent item, priciung must always be calculated
45769  //-----------------------
45770
45771  // checked_items_activities = false; 
45772  // $('.item_activities').each(function(){
45773  //   item = $(this).data('item-id');
45774  //   if (item_quantity(item) > 0 && $(this).find('input:checked').length > 0) {
45775  //     checked_items_activities = true;
45776  //   }
45777  // })
45778
45779  // checked_product_activities = ($('.product_activities input:checked').length > 0 && total_quantity() > 0);
45780
45781  // return checked_items_activities || checked_product_activities;
45782}
45783
45784function loading_running_totals() {
45785  if (should_get_sw_subtotal()) $('#product_buy_area .running_total').text('').addClass('loading');
45786  $('#product_buy_area .running_total_without_discount').text('').addClass('hide');
45787}
45788
45789function quick_checkout_check() {
45790  var activities_check = $('.activities [data-item-id][data-item-index] option[data-personal-info-required=1]:selected').length == 0;
45791  var trams_check = $('.tram-time:not(.tram-time--template) option[data-personal-info-required=1]:selected').length == 0;
45792  var items_check = true;
45793  $('#product_buy_area .item_info[data-personal-info-required=1] .qty').each(function() {
45794    if ($(this).val() > 0) {
45795      items_check = false;
45796    }
45797  });
45798
45799  if (is_single_activity()) {
45800
45801  }
45802
45803  if (activities_check && items_check && trams_check) {
45804    toggle_quick_checkout_button('show');
45805  } else {
45806    toggle_quick_checkout_button('hide');
45807  }
45808}
45809
45810function toggle_quick_checkout_button(action) {
45811  if (action == 'show') {
45812    $('.quick-checkout-divider').removeClass('hidden');
45813    $('#cart_submit_quick_checkout').removeClass('hidden');
45814  } else {
45815    $('.quick-checkout-divider').addClass('hidden');
45816    $('#cart_submit_quick_checkout').addClass('hidden');
45817  }
45818
45819}
45820
45821function set_items_prices(date) {
45822  var product_id = $('#product_buy_area').data('product-id');
45823  lock_buy_area();
45824  $('.item_info .price').addClass('loading');
45825
45826  var url = '/products/'+product_id+'/items_prices?date='+date;
45827
45828  if (is_single_activity()) {
45829    // If single activity, send the current mod group in order to get a bundled price 
45830    // and get admission ticket prices as a separate item,
45831    // in order to handle activity bookings with or without ticket
45832    var item_modifier_group_id = $('#product_buy_area').data('item-modifier-group-id');
45833    if (item_modifier_group_id) url = url+'&item_modifier_group_id='+item_modifier_group_id;
45834    url = url+'&include_admission_mods_as_items=true';
45835  } else {
45836    // ...otherwise, bundle the admission ticket price with the parent items
45837    url = url+'&bundle_admission_mods=true';
45838  }
45839
45840  $.ajax({
45841    url: url,
45842    type: 'GET',
45843    dataType: 'json',
45844    data: '',
45845    success: function(data) {
45846      $.each(data, function(k, v){
45847        var item = $('.item_info[data-item-id="'+v.item_id+'"]');
45848        if (item.length > 0) {
45849          // It's an item price
45850          item.attr('data-price', v.price);
45851          item.find('td.price').text(v.price);          
45852        } else {
45853          // It's an admission mod item price
45854          $('.admission_mods .form-item input[value="'+v.item_id+'"]').attr('data-price', v.price);
45855        }
45856      });
45857      unlock_buy_area(false)
45858      $('.item_info .price').removeClass('loading');
45859    },
45860    error: function(data) {
45861    },
45862    complete: function() {
45863
45864      unlock_buy_area(false);
45865      $('.item_info .price').removeClass('loading');
45866    }
45867  });
45868}
45869
45870function get_item(item_id) {
45871  return $('tr.item_info[data-item-id="'+item_id+'"]');
45872}
45873
45874function get_item_quantity(item_id) {
45875  return get_item(item_id).find('.qty').val();
45876}
45877
45878function get_item_activities(item_id) {
45879  return $('tr.item_activities[data-item-id="'+item_id+'"]');
45880}
45881
45882function get_item_activities_list(item_id) {
45883  return get_item_activities(item_id).find('.activities');
45884}
45885
45886
45887function toggle_single_activity_list(item_id, action) {
45888  var item_activities = get_item_activities(item_id) || $(document);
45889  var list = item_activities.find('.single-activity .modifier_group__list');
45890  list.toggleClass('hide', (action !== 'show'));
45891}
45892
45893
45894var availability_cache = {};
45895var availability_cache_expires_at = {};
45896function show_available_activities(date, item_id, dci_codes) {
45897
45898  item_id = item_id || false;
45899  dci_codes = dci_codes || false;
45900  
45901  lock_buy_area();
45902  loading_running_totals();
45903
45904  $(".loading_activities_error, .loading_activities_not_available, .checking_availability_error").addClass('hide');
45905
45906
45907  if ( total_quantity() == 0 ) {
45908    toggle_single_activity_list(null, 'hide');
45909    hide_activities($('.activities'));
45910    $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency();
45911    if ($('#activity_date').val() != "") {
45912      unlock_buy_area(false);
45913    }
45914
45915  } else {
45916
45917    var product_id = $('#product_buy_area').data('product-id');
45918
45919    var url = '/products/'+product_id+'/max_available?date='+date;
45920  
45921    if (item_id) {
45922      var item_activities = get_item_activities_list(item_id);
45923      if (item_quantity(item_id) == 0 ) {
45924        toggle_single_activity_list(item_id, 'hide')
45925        hide_activities(item_activities);
45926      } else {
45927        if (!item_activities.hasClass('open')) {
45928          item_activities.siblings('.loading_activities').removeClass('hide');
45929        }
45930      }
45931      url += '&item_id=' + item_id;
45932    } else { 
45933      $('.activities.open').each(function(){
45934         $(this).siblings('.loading_activities').removeClass('hide');
45935      });
45936    }
45937
45938    if (tram_times_present())
45939      $(".tram-times").siblings('.loading_activities').removeClass('hide');
45940
45941
45942    if (dci_codes.length > 0) url += '&dci_codes=' + dci_codes.join(',');
45943
45944    if (availability_cache[url]!==undefined && $.now() < availability_cache_expires_at[url]) {
45945      apply_availability_changes(availability_cache[url], item_id);
45946    } else {
45947      if (date) {
45948        $.ajax({
45949          url: url,
45950          type: 'GET',
45951          dataType: 'json',
45952          data: '',
45953          success: function(data) {
45954            availability_cache[url] = data;
45955            availability_cache_expires_at[url] = $.now() + 60000; // 1 minute cache life
45956            apply_availability_changes(data, item_id);
45957          },
45958          error: function(data) {
45959            if (item_id && item_activities.length > 0)
45960              if (dci_codes.length > 0) {
45961                for (var i = 0; i < dci_codes.length; i++) {
45962                  item_activities.find('option[data-dci="'+dci_codes[i]+'"]').closest('select').val('');
45963                  item_activities.find('option[data-dci="'+dci_codes[i]+'"]').closest('select').siblings('.checking_availability_error').removeClass('hide');
45964                }
45965              } else {
45966                item_activities.siblings(".loading_activities_error").removeClass('hide');
45967              }
45968            after_show_available_activities(item_id);
45969            console.log('Failed to check availability');
45970          
45971          }
45972        });
45973      }
45974    }
45975  } // end if quanity 0
45976}
45977
45978function apply_availability_changes(data, item_id) {
45979  unlock_buy_area(false)
45980  var activities = null;
45981  var claimed_qties = activity_claimed_quantities();
45982  var rem_qties = {};
45983  if (data !== null) {
45984    $.each(data, function(dci, entry) {
45985      // Keep track of remaining qties by DCI for further adjustments
45986      if (rem_qties[dci]===undefined) rem_qties[dci] = 0;
45987      rem_qties[dci] += parseInt(entry.qty_rem);
45988
45989      activity = $('.activities .form-item--template option[data-dci="'+dci+'"]');
45990      if (activity.length > 0) {
45991        for (var j = 0; j < activity.length; j++) {
45992          this_activity = $(activity[j]); 
45993          claimed_qty = claimed_qties[dci] || 0;
45994          this_activity.toggleClass('visible', (entry.qty_rem - claimed_qty >= this_activity.data('for-n-users')));
45995        }            
45996      }
45997
45998      tram_time = $('.tram-times .form-item option[data-dci="'+dci+'"]');
45999      if (tram_time.length > 0) {
46000        for (var j = 0; j < tram_time.length; j++) {
46001          this_tram_time = $(tram_time[j]); 
46002          this_tram_time.toggleClass('visible', entry.qty_rem >= total_quantity());
46003        }            
46004      }  
46005    });
46006
46007    $('.activities .form-item--template').each(function(){
46008      template = $(this);
46009      is_single_activity = ($(this).closest('.single-activity').length > 0);
46010      template.siblings('.form-item[data-item-id="'+template.attr('data-item-id')+'"][data-item-index]').find('select').each(function(i, el){
46011        select = $(el);
46012        selected_value = select.val();
46013        options_selector = 'select option[value=""], select option.visible';
46014        // if (item_id) {
46015        options_selector = options_selector + ', select option[value="'+selected_value+'"]';
46016        // }
46017        options = template.find(options_selector).clone();
46018        select.empty().append(options);
46019        if (select.find('option[value="'+selected_value+'"]').length > 0) {
46020          select.val(selected_value);
46021        } else {
46022          select.val("");
46023          populate_modifier_ids();
46024        }
46025        // For single activities, if only one value available, select it
46026        if (is_single_activity) {
46027          // Find if there's only one option available
46028          only_option = template.find('select option.visible[value!=""]');
46029          if (selected_value == "" && only_option.length == 1) {
46030            only_option_dci = only_option.data('dci');
46031            // Make sure claimed_qties object has a value for this DCI
46032            if (claimed_qties[only_option_dci]===undefined) claimed_qties[only_option_dci] = 0;
46033            // Check if there's availability left before selecting the only option
46034            if (rem_qties[only_option_dci] - claimed_qties[only_option_dci] >= only_option.data('for-n-users')) {
46035              // Select only option and increase claimed qty
46036              select.val(only_option.val());          
46037              claimed_qties[only_option_dci] += parseInt(only_option.data('for-n-users'));
46038              populate_modifier_ids();
46039              set_step_2_select_state();
46040            } else {
46041              // Remove option if no longer available
46042              select.find('option[value="'+only_option.val()+'"]').remove();
46043            }
46044          }
46045        }
46046      });
46047    });
46048    activities = $('.activities');
46049
46050
46051    $('.tram-times .tram-time--template').each(function(){
46052      template = $(this);
46053      template.siblings('.tram-time').find('select').each(function(i, el){
46054        select = $(el);
46055        selected_value = select.val();
46056        options_selector = 'select option[value=""], select option';
46057        options = template.find(options_selector).clone();
46058        select.empty().append(options);
46059        // For tram times, sold out items show up disabled
46060        select.find('option:not(.visible)[value!=""]').attr("disabled", "disabled").append($("<span> (SOLD OUT)</span>"));
46061        if (select.find('option[value="'+selected_value+'"]').length > 0) {
46062          select.val(selected_value);
46063        } else {
46064          select.val("");
46065          // populate_modifier_ids();
46066        }
46067      });
46068    });
46069  }
46070
46071  if (activities.length > 0) {
46072    var this_item_id, is_single_activity, open_activities;
46073    activities.each(function(i, activity) {
46074      this_item_id = $(activity).closest('tr.item_activities').attr('data-item-id');
46075      is_single_activity = $(activity).hasClass('single-activity');
46076      open_activities = false
46077      $(activity).find('.modifier_group').each(function() {
46078        group_name = $(this).attr('data-group');
46079        list = $(this).next('.modifier_group__list').first();
46080        if (list.find('.form-item[data-item-index] option[data-group="'+group_name+'"]').length > 0) {
46081          if (is_single_activity && (!item_id || item_id == this_item_id)) {
46082            toggle_single_activity_list(this_item_id, 'show');
46083          }
46084          $(this).slideDown();
46085          open_activities = true
46086        } else {
46087          if (is_single_activity && (!item_id || item_id == this_item_id)) {
46088            toggle_single_activity_list(this_item_id, 'hide');
46089            if (get_item_quantity(this_item_id) > 0)
46090              get_item_activities_list(this_item_id).siblings(".loading_activities_not_available").removeClass('hide');
46091          }
46092          hide_modifier_group($(this));
46093        }
46094      });
46095
46096      if (open_activities) {
46097        $(this).find('.savings_info').slideDown();
46098        $(this).addClass('open');
46099      } else {
46100        $(this).find('.savings_info').slideUp();
46101        $(this).removeClass('open');
46102      }
46103    });
46104  }
46105
46106  after_show_available_activities(item_id);
46107
46108  if (should_get_sw_subtotal()) {
46109    get_sw_subtotal();
46110  } else {
46111    $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency();
46112  }
46113
46114  quick_checkout_check();
46115}
46116
46117function after_show_available_activities(item_id) {
46118  unlock_buy_area(false);
46119  item_activities = get_item_activities(item_id);
46120  // Remove activities loader
46121  if (item_activities.length > 0)
46122    item_activities.find('.loading_activities').addClass('hide');
46123  else
46124    $('.loading_activities').addClass('hide');
46125
46126  // Remove availability loader
46127  $('.activities select').removeClass('loading');
46128  $('.tram-time select').removeClass('loading');
46129  $('.checking_availability').addClass('hide');
46130}
46131
46132function show_available_times(date, item) {
46133
46134  default_message = "Please select a quantity above.";
46135  if ($('.option.time').data('user-selectable-date') == true) {
46136    default_message = "Please select a date and a quantity above.";
46137  }
46138
46139  item = item || false;
46140  
46141  if ( total_quantity() == 0 ) {
46142    $('ul.times li').slideUp();
46143    $('ul.times input').prop('checked',false);
46144    $('#message').text(default_message).slideDown();
46145    $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency();
46146    unlock_buy_area(item)
46147  } else {
46148
46149    var product_id = $('#product_buy_area').data('product-id');
46150    lock_buy_area();
46151    loading_running_totals();
46152    $('#message').slideUp();
46153
46154    var url = '/products/'+product_id+'/max_available?date='+date;
46155	
46156    if (item) {
46157      url += '&item_id=' + item;
46158    }
46159
46160  	$.ajax({
46161  		url: url,
46162  		type: 'GET',
46163  		dataType: 'json',
46164  		data: '',
46165  		success: function(data) {
46166  			unlock_buy_area(item);
46167  			var most_avail = 0;
46168        $.each(data, function(dci, entry) {
46169          if (entry.qty_rem >= total_quantity() && entry.qty_rem != 0) {
46170            $('li[data-dci="'+dci+'"]').slideDown()
46171          } else {
46172            $('li[data-dci="'+dci+'"] input').prop('checked',false);
46173            $('li[data-dci="'+dci+'"]').slideUp();
46174          }
46175          if (entry.qty_rem > most_avail) {
46176            most_avail = entry.qty_rem;
46177          }
46178  			});
46179  			most_avail == 0 ? $('#message').text("Please try another date. We have no available times for this date.").show() : $('#none_available').hide();
46180  			most_avail < total_quantity() ? $('#message').text("Please try another date. There are no remaining times with "+total_quantity()+" available spaces for this day.").show() : $('#none_available').hide();
46181        if (should_get_sw_subtotal()) {
46182          get_sw_subtotal();
46183        } else {
46184          $('.running_total').removeClass('loading').text(calc_subtotal()).formatCurrency();
46185        }
46186  		},
46187  		error: function(data) {
46188  			console.log('Failed to check availability');
46189			
46190  		}
46191  	});
46192  } // end if quanity 0
46193}
46194
46195var benefits_quantities_cache = {};
46196function show_available_benefits(date) {
46197
46198  if (!$('#product_buy_area').data('load-benefits')) return true;
46199
46200  var product_id = $('#product_buy_area').data('product-id');
46201  var url = "/users/benefits?date="+date+"&product_id="+product_id;
46202  if (is_single_activity()) {
46203    var item_modifier_group_id = $('#product_buy_area').data('item-modifier-group-id');
46204    url += "&item_modifier_group_id="+item_modifier_group_id
46205  }
46206  $.ajax({
46207    url: url,
46208    type: 'GET',
46209    dataType: 'json',
46210    data: '',
46211    success: function(data) {
46212      if (data.items_partials) {
46213        $("tr.item_benefits").each(function(i, b) {
46214          var item_benefits = $(b);
46215          var item_id = item_benefits.data("itemId");
46216          if (data.items_partials[item_id])
46217            item_benefits.find("td").html(data.items_partials[item_id]);
46218        }); 
46219      }
46220
46221      if (data.admission_partial) {
46222        $(".item_benefits.admission_mods-benefits").html(data.admission_partial)
46223      }
46224
46225      if (data.add_and_save_partial) {
46226        $(".activities .item_benefits").html(data.add_and_save_partial)
46227      }
46228
46229      benefits_quantities_cache = {};
46230      $.each(data.data, function(i, b) {
46231        if (!benefits_quantities_cache[b.benefitid]) benefits_quantities_cache[b.benefitid] = {
46232          pass_nos: {}
46233        };
46234
46235        benefits_quantities_cache[b.benefitid].pass_nos[b.pass_no] = {
46236          remaining_qty: b.remainingquantity,
46237          redeemed_qty: 0
46238        }
46239      });
46240
46241      $(".item_benefits").each(function(i, b) {
46242        if ($(b).find('.item_benefit:not(.hide)').length == 0) {
46243          $(b).hide();
46244        } else {
46245          $(b).show();
46246        }
46247      });
46248    }
46249  });
46250}
46251
46252
46253function validate_product_form( $form ) {
46254  
46255  $('#buy_area_messages li').remove();
46256  $('#product_buy_area .error').removeClass('error');
46257  
46258  if ( total_quantity() == 0 ) {
46259    $('<li/>', {
46260      text: "Please select a least one item quantity."
46261    }).appendTo('#buy_area_messages');
46262    $('select.qty').effect('shake', { distance: 4, times: 2 }, 100 );
46263  }
46264
46265  if (tram_times_present()) {
46266    if (validate_tram_times_required()) {
46267      validate_tram_times_sequence();
46268    }
46269  }
46270  
46271  // scheduled activites
46272  if ( $('.dates').length > 0 ) {
46273    if ( $('.dates input').val() == '' ) {
46274      $('<li/>', {
46275        text: "Please select a date."
46276      }).appendTo('#buy_area_messages');
46277      $('.dates').effect('shake', { distance: 4, times: 2 }, 100 );
46278    }
46279  }
46280
46281  if ( $('ul.times').length > 0 ) {
46282    if ( $('ul.times input:checked').length == 0 ) {
46283      $('<li/>', {
46284        text: "Please select a time."
46285      }).appendTo('#buy_area_messages');
46286      $('ul.times').effect('shake', { distance: 4, times: 2 }, 100 );
46287    }
46288  }
46289  
46290  // gift cards
46291  if ( $('ul.designs').length > 0 ) {
46292    if ( $('ul.designs input:checked').length == 0 ) {
46293      $('<li/>', {
46294        text: "Please select a design."
46295      }).appendTo('#buy_area_messages');
46296      $('ul.designs').effect('shake', { distance: 4, times: 2 }, 100 );
46297    }
46298  }
46299
46300  // gift card refill
46301  if ( $('.option.pass_no input').length > 0 ) {
46302    if ( $('.option.pass_no input').val() == "" ) {
46303      $('<li/>', {
46304        text: "Please enter a gift card or pass number."
46305      }).appendTo('#buy_area_messages');
46306      $('.option.pass_no').effect('shake', { distance: 4, times: 2 }, 100 );
46307    }
46308  }
46309  
46310  // retail items
46311  if ( $('#item_option_id').length > 0 ) {
46312    if ( $('#item_option_id').val() == "" ) {
46313      $('<li/>', {
46314        text: "Please select a colour and size."
46315      }).appendTo('#buy_area_messages');
46316      $('.option.size, .option.colour').effect('shake', { distance: 4, times: 2 }, 100 );
46317    }
46318  }
46319  
46320  if (toggle_buy_area_messages() === false) {
46321    return false;
46322  }
46323
46324  return true;
46325}
46326
46327function validate_activity_form( $form ) {
46328  
46329  var messages_area = $form.find('.product__step-form__messages');
46330  messages_area.find('li').remove();
46331  
46332  var empty_select = $form.find('.form-item[data-item-id][data-item-index] option[value=""]:selected').closest('select');
46333  if ( empty_select.length > 0 ) {
46334    $('<li/>', {
46335      text: "Please select a least one option per Guest."
46336    }).appendTo(messages_area);
46337     empty_select.effect('shake', { distance: 4, times: 2 }, 100 );
46338  }
46339
46340  if ( messages_area.find('li').length > 0) {
46341    messages_area.slideDown();
46342    return false;
46343  } else {
46344    messages_area.slideUp();
46345  }
46346
46347  return true;
46348}
46349
46350function validate_tram_times_required() {
46351  
46352  if (!tram_times_required($("#activity_date").val())) return true;
46353
46354  var error = false;
46355  if (is_staff_pass()) {
46356    if (get_unselected_tram_times().length > 1) {
46357      error = true;
46358      message = "Please select a minimum of one boarding time.";
46359    }
46360  } else {
46361    if (get_unselected_tram_times().length > 0) {
46362      error = true;
46363      is_upload = $('.tram-time:not(.tram-time--template)[data-type=Upload]').length > 0
46364      is_download = $('.tram-time:not(.tram-time--template)[data-type=Download]').length > 0
46365      details = (is_upload && is_download) ? "upload and download boarding times." : (is_upload ? "upload boarding time." : "download boarding time.");
46366      message = "Please select "+details;
46367      if ($("#download_only").is(":checked"))
46368        message = "Please select download boarding time.";
46369    }
46370  }
46371
46372  if (error) {
46373    $('<li/>', {
46374      text: message
46375    }).appendTo('#buy_area_messages');
46376    $('.tram-time select[name=mods]').effect('shake', { distance: 4, times: 2 }, 100);
46377    $('.tram-time:not(.tram-time--template)').addClass('error');
46378
46379    return false;
46380  } else {
46381    return true;
46382  }
46383}
46384
46385function validate_tram_times_sequence() {
46386
46387  if (is_staff_pass()) return true;
46388
46389  if ($('.tram-time:not(.tram-time--template)[data-type=Upload]').length > 0
46390                && $('.tram-time:not(.tram-time--template)[data-type=Download]').length > 0) {
46391    var upload_time = $('.tram-time:not(.tram-time--template)[data-type=Upload] option:selected').data('starttime');
46392    var download_time = $('.tram-time:not(.tram-time--template)[data-type=Download] option:selected').data('starttime');
46393    if (upload_time >= download_time) {
46394      message = "Selected download time must later than selected upload time. Please revise your selections to proceed.";
46395      $('<li/>', {
46396        text: message
46397      }).appendTo('#buy_area_messages');
46398      $('.tram-time select').effect('shake', { distance: 4, times: 2 }, 100 );
46399      $('.tram-time:not(.tram-time--template)').addClass('error'); 
46400      return false;       
46401    }
46402  }
46403  return true;
46404}
46405
46406function is_staff_pass() {
46407  return $('.staff-pass').length > 0;
46408}
46409
46410function toggle_buy_area_messages() {
46411  if ( $('#buy_area_messages li').length > 0) {
46412    $('#buy_area_messages').slideDown();
46413    return false;
46414  } else {
46415    $('#buy_area_messages').slideUp();
46416  }
46417}
46418
46419/*
46420  Create all fields for a hidden cart item form
46421*/
46422function create_cart_item_attributes_item(item_id, item_modifier_group_id, date) {
46423  var block = $('<div></div>');
46424  var cart_form = $("#edit_cart, #new_cart").first();
46425  var index = cart_form.find("[data-item-id="+item_id+"]").length;
46426  var global_index = -1;
46427  cart_form.find("[data-item-id]").each(function(){
46428    this_index = parseInt($(this).attr('data-item-global-index'));
46429    if (this_index > global_index)
46430      global_index = this_index;
46431  });
46432
46433  global_index++;
46434
46435  block.attr("data-item-id", item_id);
46436  block.attr("data-item-index", index);
46437  block.attr("data-item-global-index", global_index);
46438
46439  block.append(create_cart_item_attributes_input_field('hidden', 'item_id', item_id, global_index, false, {}));
46440  if (item_modifier_group_id !== undefined && item_modifier_group_id > 0)
46441    block.append(create_cart_item_attributes_input_field('hidden', 'item_modifier_group_id', item_modifier_group_id, global_index, false, {}));
46442  block.append(create_cart_item_attributes_input_field('hidden', 'date', date, global_index, false, {}));
46443  block.append(create_cart_item_attributes_input_field('hidden', 'add_to_quantity', "1", global_index, false, {}));
46444  block.append(create_cart_item_attributes_input_field('hidden', 'benefits', $("input[data-item-id="+item_id+"][type=checkbox][name*=benefit]:checked").val(), global_index, false, {}));
46445  cart_form.append(block);
46446}
46447
46448/*
46449  Create a hidden cart item form field
46450*/
46451function create_cart_item_attributes_input_field(type, name, value, index, is_array, attributes) {
46452  var input = $('<input/>');
46453  input.attr("type", type);
46454  input.attr("id", "cart_cart_items_attributes_"+index+"_"+name);
46455  input.attr("name", "cart[cart_items_attributes]["+index+"]["+name+"]"+(is_array ? "[]" : ""));
46456  input.attr("value", value);
46457  $.each(attributes, function(key, value){
46458    input.attr(key, value);
46459  });
46460  return input;
46461}
46462
46463
46464/*
46465  Look at the visible modifiers/guests fields values and populate
46466  the hidden cart items form values
46467*/
46468function populate_modifier_ids() {
46469  var cart_form = $("#edit_cart, #new_cart").first();
46470  cart_form.find('[data-item-id][data-item-index] [name$="[item_modifier_ids][]"]').remove();
46471  $('.form-item[data-item-id][data-item-index]').each(function(){
46472    cart_item = cart_form.find('[data-item-id="'+$(this).attr('data-item-id')+'"][data-item-index="'+$(this).attr('data-item-index')+'"]');
46473    value = $(this).find('select, input:checked').val();
46474    if (value !== undefined && cart_item.find('[name$="[item_modifier_ids][]"][value="'+value+'"]').length == 0) {
46475      cart_item.append(create_cart_item_attributes_input_field('hidden', 'item_modifier_ids', $(this).find('select, input:checked').val(), cart_item.attr('data-item-global-index'), true,  {}));
46476    }    
46477  });
46478
46479  tram_time_form_field = cart_form.find('[name$="[tram_times]"]');
46480  tram_time_form_field.val($('.tram-time:not(.tram-time--template) option:selected').map(function(){return $(this).data('dci')}).get().join());
46481}
46482
46483/*
46484  Keep consistency on the hidden cart items form fields indexing
46485  and reflect the order across all modifiers/guests fields
46486*/
46487function set_items_global_index_and_sort_guests(){
46488  var cart_form = $("#edit_cart, #new_cart").first();
46489  // Set global indexes to all items
46490  var new_index = 0;
46491  $('tr.item_info').each(function() {
46492    // For those items with quantity grater than zero...
46493    if ($(this).find('.qty').val() > 0) {
46494      item_id = $(this).attr('data-item-id');
46495      // ...and all corresponding hidden cart items form fields...
46496      cart_form.find('[data-item-id="'+item_id+'"][data-item-global-index]').each(function(){
46497        // Grab current local and global index
46498        var current_global_index = $(this).attr('data-item-global-index');
46499        var current_local_index = $(this).attr('data-item-index');
46500        // Set the new global index to form items and replace all form fields names indexes
46501        $(this).attr('data-item-global-index', new_index);
46502        $(this).find('input').each(function(i, el){
46503          $(el).attr('id', $(el).attr('id').replace("_"+current_global_index+"_", "_"+new_index+"_"));
46504          $(el).attr('name', $(el).attr('name').replace("["+current_global_index+"]", "["+new_index+"]"));
46505        });
46506        // Set the new global index to all modifiers/guests fields
46507        $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+current_local_index+'"]').attr('data-item-global-index', new_index);
46508        $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+current_local_index+'"] label .guest-index').text(parseInt(current_local_index)+1);
46509        // Increment new index for next iteration
46510        new_index++;
46511      });
46512    }
46513  });
46514
46515  // Sort guests
46516  $('.activities .modifier_group__list').each(function(){
46517    var items = $(this).find('.form-item[data-item-id][data-item-index]');
46518    items.sort(function(a,b) {
46519     return +$(a).data('itemGlobalIndex') - +$(b).data('itemGlobalIndex');
46520    });
46521    $(this).find('.form-item[data-item-id][data-item-index]').remove();
46522    $(this).append(items);
46523  });
46524}
46525
46526/*
46527  Generate item summary for a set quantity of guests and a price
46528*/
46529function item_guests_summary(item, qty, price) {
46530  item_name = $(item).attr('data-item-name');
46531  return $('<div>'+item_name+' X '+qty+'<div class="right item-price">$'+((price || 0) * qty).toFixed(2)+'</div></div>')
46532}
46533
46534/*
46535  Generate tram times summary
46536*/
46537function tram_times_summary() {
46538  var summary = "<p>";
46539  $('.tram-time:not(.tram-time--template)').each(function(){
46540    summary += $(this).data("type") + ": " + $(this).find('option:selected').text() + "<br>";
46541  });
46542  summary += "</p>";
46543  return summary;
46544}
46545
46546/*
46547  Toggle tram times step for non-single activities
46548*/
46549function toggle_tram_times_step() {
46550  if (!is_single_activity()) {
46551    populate_modifier_ids();
46552    if (total_quantity() > 0) {
46553      $('.product__step-step3 .buy-label h6').removeClass('disabled');
46554      $('.product__step-step3 .product__step-form').slideDown();
46555    } else {
46556      $('.product__step-step3 .buy-label h6').addClass('disabled');
46557      $('.product__step-step3 .product__step-form').slideUp();
46558    }
46559
46560  }
46561}
46562
46563/*
46564  Reset single activity form
46565*/
46566function reset_form(date) {
46567
46568  if (is_single_activity()) {
46569    $('.product__step').not('.product__step-step2').find('.product__step-form').slideUp();
46570    $('[data-item-id][data-item-index][data-item-global-index]').remove();
46571    $('.product__step-summary').html('');
46572    $('.product__step:not(.product__step-last) .buy-label a').addClass('hide');
46573    $('.product__step-last').addClass('hide');
46574    $('.product__step-last .buy-label a .right').text('Hide');
46575    scroll_to_step('.product__step-step1');    
46576  }
46577  $('.product__step-step2 .product__step-form').slideDown();
46578  $('.product__step-step2 .buy-label h6').removeClass('disabled');
46579  $('tr.item_info').each(function(){
46580    item_id = $(this).attr('data-item-id');
46581    if (get_item_quantity(item_id) > 0)
46582      set_form_fields_for_item(item_id, true);
46583  });
46584  set_tram_times_fields();
46585
46586  show_available_activities(date, null);
46587}
46588
46589function scroll_to_step(step) {
46590  $('html, body').animate({
46591    scrollTop: $(step).offset().top - 200
46592  }, 500);
46593}
46594
46595function set_step_2_select_state() {
46596  var activities_selects = $('.product__step-step2 .form-item[data-item-id][data-item-index] select');
46597  var empty_activities_selects = activities_selects.find('option[value=""]:selected').closest('select');
46598  if (activities_selects.length == 0 || empty_activities_selects.length > 0) {
46599    $('.product__step-step2 .product__step-form__select, .product__step .buy-label a').attr('disabled', 'disabled');
46600  } else {
46601    $('.product__step-step2 .product__step-form__select, .product__step .buy-label a').removeAttr('disabled');
46602  }
46603}
46604
46605function set_form_fields_for_item(item_id, without_availability_check) {
46606  without_availability_check = without_availability_check || false;
46607  var item = get_item(item_id);
46608  var cart_form = $("#edit_cart, #new_cart").first();
46609  var item_modifier_group_id = item.attr('data-item-modifier-group-id');
46610  var item_name = item.attr('data-item-name');
46611  var qty = get_item_quantity(item_id);
46612  var existingQty = cart_form.find("[data-item-id="+item_id+"]").length;
46613
46614  // Update existing fields date
46615  cart_form.find('[data-item-id="'+item_id+'"] input[name$="[date]"]').val($('#activity_date').val());
46616
46617  // Add necessary number of fields to match current total quantity
46618  if (qty >= existingQty) {
46619    for(i=existingQty; i < qty; i++) {
46620      create_cart_item_attributes_item(item_id, item_modifier_group_id, $('#activity_date').val());
46621    }
46622    $('.form-item--template[data-item-id="'+item_id+'"]').each(function(){
46623      var item_activity = $(this).clone();
46624      item_activity.removeClass('form-item--template').show();
46625      for(i=existingQty; i < qty; i++) {
46626        item_activity.attr("data-item-index", i);
46627        item_activity.find('label .item-name').html(item_name);
46628        $(this).parent().append(item_activity.clone());
46629      }
46630    });  
46631  // Remove necessary number of fields to match current total quantity
46632  } else {
46633    for(i=existingQty - 1; i >= qty; i--) {
46634      cart_form.find('[data-item-id="'+item_id+'"][data-item-index="'+i+'"]').remove();
46635      $('.form-item[data-item-id="'+item_id+'"][data-item-index="'+i+'"]').remove();
46636    }
46637  }
46638  // Set global indexes and populate hidden cart items form fields values
46639  set_items_global_index_and_sort_guests();
46640  populate_modifier_ids();
46641  set_benefits();
46642  set_step_2_select_state();
46643  if (!without_availability_check) show_available_activities( $('#activity_date').val(), item_id );
46644}
46645
46646function set_tram_times_fields() {
46647  $('.tram-time:not(.tram-time--template)').remove();
46648  $('.tram-time--template').each(function(){
46649    var tram_time = $(this).clone();
46650    tram_time.removeClass('tram-time--template').show();
46651    $(this).parent().append(tram_time.clone());
46652  });
46653}
46654
46655
46656function get_unselected_tram_times() {
46657  var selector = ".tram-time:not(.tram-time--template) select";
46658  if ($("#download_only").is(":checked")) {
46659    selector = ".tram-time[data-type=Download]:not(.tram-time--template) select";
46660  }
46661  return $(selector).filter(function(){
46662    return $(this).val() == "";
46663  });
46664}
46665
46666function set_benefits() {
46667  var cart_form = $("#edit_cart, #new_cart").first();
46668  $('.form-item[data-item-id][data-item-index]').each(function(){
46669    cart_item = cart_form.find('[data-item-id="'+$(this).attr('data-item-id')+'"][data-item-index="'+$(this).attr('data-item-index')+'"]');
46670    let items_benefits = $("tr.item_benefits input[data-item-id="+$(this).attr('data-item-id')+"][type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get();
46671    let admission_items_benefits = $(".admission_mods-benefits input[type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get();
46672    let add_and_save_activities_benefits = $(".activities .item_benefits input[type=checkbox][name*=benefit]:checked").map((i, b) => $(b).val()).get();
46673    cart_item.find('input[name$="[benefits]"]').val(
46674      items_benefits
46675        .concat(admission_items_benefits)
46676        .concat(add_and_save_activities_benefits)
46677        .join(',')
46678    )
46679  });
46680}
46681
46682function update_benefits_quantities(e) {
46683
46684  if (e) {
46685    // If context item is provided, show/hide item benefits depending on item qty 
46686    let current_item_qty = $(e).val();
46687    let item_benefits = $(e).closest("tr.item_info").next('.item_benefits');
46688    if (item_benefits)
46689      item_benefits.toggleClass('hide', (current_item_qty == 0));  
46690  }
46691
46692  // Collect current state of items quantities
46693  var items_qties = {};
46694  let items = $('tr.item_info');
46695  for (var i = 0; i < items.length; i++) {
46696    let item = $(items[i]);
46697    let qty = parseInt(item.find('select.qty').val());
46698    items_qties[item.data("itemId")] = qty
46699  }
46700  // For each benefit quantities...
46701  Object.entries(benefits_quantities_cache).forEach(function([b_id, b]) {
46702    // Assigned current item quantities
46703    benefits_quantities_cache[b_id]["items_qties"] = JSON.parse(JSON.stringify(items_qties
46703));
46704    // For each benefit pass no
46705    Object.entries(b.pass_nos).forEach(function([p_no, qties]) {
46706      // Reset benefit/pass no redeemed qty
46707      benefits_quantities_cache[b_id].pass_nos[p_no]["redeemed_qty"] = 0;
46708      // For each benefit/pass no/item qty... 
46709      Object.entries(items_qties).forEach(function([item_id, qty]) {
46710        qty = benefits_quantities_cache[b_id]["items_qties"][item_id];
46711        if (qty > 0) {
46712          // Find the benefits checkbox that handles this benefit, for this pass no and this item: 
46713          // Benefits checkboxes can be located within...
46714          // 1- items
46715          let is_item_benefit = true
46716          let benefit_box = $('.item_benefits[data-item-id='+item_id+']').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]");
46717          // 2- or admission ticket step
46718          if (benefit_box.length == 0) {
46719            is_item_benefit = false
46720            benefit_box = $('.admission_mods-benefits').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]");
46721          }
46722          // 3- or add and save step
46723          if (benefit_box.length == 0) {
46724            is_item_benefit = false
46725            benefit_box = $('.activities .item_benefits').find("input[data-benefit-id="+b_id+"][data-pass-no="+p_no+"]");
46726          }
46727
46728          let benefit_quantities_cache = benefits_quantities_cache[b_id].pass_nos[p_no]
46729          let remaining_qty = benefit_quantities_cache["remaining_qty"] - benefit_quantities_cache["redeemed_qty"];
46730
46731          if (remaining_qty > 0) {
46732            benefit_box.prop("disabled", false);
46733            if (benefit_box.is(":checked")) {
46734              let redeemable_qty = qty > remaining_qty ? remaining_qty : qty;
46735              benefits_quantities_cache[b_id].pass_nos[p_no]["redeemed_qty"] += redeemable_qty;
46736              benefits_quantities_cache[b_id]["items_qties"][item_id] = qty - redeemable_qty;              
46737            }
46738          } else {
46739            if (is_item_benefit)
46740              benefit_box.prop("checked", false);
46741          }
46742        }
46743      });
46744    });
46745  });
46746
46747  Object.entries(benefits_quantities_cache).forEach(function([b_id, b]) {
46748    Object.entries(b.pass_nos).forEach(function([p_no, qties]) {
46749      let final_remaining_qty = qties["remaining_qty"] - qties["redeemed_qty"];
46750      let benefit_boxes = $('.item_benefits input[data-benefit-id="'+b_id+'"][data-pass-no="'+p_no+'"]');
46751
46752      benefit_boxes.toggleClass("hide", (b.remainingquantity == 0));
46753      benefit_boxes.each(function(i, b){
46754        if (final_remaining_qty == 0 && !$(b).is(":checked")) {
46755          $(b).prop("disabled", true)
46756        } else {
46757          $(b).prop("disabled", false)
46758        }
46759      });
46760      benefit_boxes.next('label').find('span.item_benefit-qty_available').text("("+final_remaining_qty+" available)");
46761    });
46762  });
46763
46764  set_benefits();
46765  loading_running_totals();
46766  get_sw_subtotal();
46767}
46768
46769/*
46770  Populate form modifier ids on any activity selection change
46771  Enable Step 2 Select button and any edit button, only if all activity selects have value
46772*/
46773$(document).on("change", '#product_buy_area[data-product-type="bundled"] .form-item[data-item-index] select, .tram-time:not(.tram-time--template) select, #product_buy_area[data-product-type="bundled"] .form-item[data-item-index] input', function(){
46774  populate_modifier_ids();
46775  set_step_2_select_state();
46776});
46777
46778/*
46779  Select/Unselect all guests admission tickets with one click 
46780*/
46781$(document).on("change", '#product_buy_area[data-product-type="bundled"] input[name="add_admission_mods"]', function(){
46782  var add_admission_mods = $('input[name="add_admission_mods"]:checked').val();
46783  var checked = (add_admission_mods == "1");
46784  $('.admission_mods').attr('data-add-tickets', add_admission_mods);
46785  $('.admission_mods [data-item-id][data-item-index] input').prop('checked', checked).change();
46786  loading_running_totals();
46787  get_sw_subtotal();
46788});
46789
46790/*
46791  Submit/Select activity step 2 form (Activity/Guest quantities) 
46792*/
46793$(document).on("click", '.product__step-step2 button.product__step-form__select', function(){
46794  // Validate form to be sure there aren't empty dropboxes
46795  if (!validate_activity_form($(this).closest('.product__step-form'))) return true;
46796  // Clear Step 2 form summary and Step 3 form details to later populate them
46797  var step2_summary = $('.product__step-step2 .product__step-summary');
46798  var step3_add_details = $('.product__step-step3 .product__step-form .form-item.add .details');
46799  step2_summary.html('');
46800  step3_add_details.html('');
46801  // Fill out Step 2 form summary and Step 3 form details 
46802  $('tr.item_info').each(function() {
46803    qty = $(this).find('.qty').val();
46804    if (qty > 0) {
46805      item_id = $(this).attr('data-item-id');
46806      activity_price = $('.product__step-step2 .product__step-form [data-item-index][data-item-id="'+item_id+'"] option:selected').attr('data-price');
46807      ticket_price = $('.product__step-step3 .product__step-form [data-item-index][data-item-id="'+item_id+'"] input').attr('data-price');
46808      step2_summary.append(item_guests_summary($(this), qty, activity_price));
46809      step3_add_details.append(item_guests_summary($(this), qty, ticket_price));
46810    }
46811  });
46812  // Populate step 3 pricing details based on step 2 quantities
46813  $('[name="add_admission_mods"][value="'+$('.admission_mods').attr('data-add-tickets')+'"]').prop('checked', true).change();
46814  // Go to step 3
46815  $('.product__step-step2 .product__step-form').slideUp();
46816  $('.product__step-step2 .buy-label a').removeClass('hide');
46817  $('.product__step-step2 .product__step-summary').slideDown();
46818  $('.product__step-step3 .product__step-summary').slideUp();
46819  $('.product__step-step3 .buy-label a').addClass('hide');
46820  $('.product__step-step3 .buy-label h6').removeClass('disabled');
46821  $('.product__step-step3 .product__step-form').slideDown();
46822  scroll_to_step($('.product__step-step2'));
46823});
46824
46825/*
46826  Select activity step 3 form (Admission ticket selection) 
46827*/
46828$(document).on("click", '.product__step-step3 button.product__step-form__select', function(){
46829  // Clear form summary
46830  var step3_summary = $('.product__step-step3 .product__step-summary');
46831  step3_summary.html('');
46832  // If tickets were added, fill out summary with details about pricing and quantities
46833  // and switch add and save content
46834  if ($('input[name="add_admission_mods"]:checked').val() == '1') {
46835    $('tr.item_info').each(function() {
46836      qty = $(this).find('.qty').val();
46837      if (qty > 0) {
46838        item_id = $(this).attr('data-item-id');
46839        ticket_price = $('.product__step-step3 .product__step-form [data-item-index][data-item-id="'+item_id+'"] input').attr('data-price');
46840        step3_summary.append(item_guests_summary($(this), qty, ticket_price));
46841      }
46842    }); 
46843    $('.product__step-last .add-and-save').removeClass('hide');
46844    $('.product__step-last .not-add-and-save').addClass('hide');   
46845  // Else, fill out summary with message and $0.00 price
46846  // and switch add and save content
46847  } else {
46848    step3_summary.html('<div>I already have a Ticket or Pass<div class="right item-price">$0.00</div></div>');
46849    $('.product__step-last .add-and-save').addClass('hide');
46850    $('.product__step-last .not-add-and-save').removeClass('hide');
46851  }
46852  // Go to tram times step
46853  $('.product__step-step3 .product__step-form').slideUp();
46854  $('.product__step-step3 .buy-label a').removeClass('hide');
46855  $('.product__step-step3 .product__step-summary').slideDown();
46856  if (tram_times_present() && tram_times_required($("#activity_date").val())) {
46857    $('.product__step-tram-times .buy-label a .right').text('Hide');
46858    $('.product__step-tram-times .product__step-summary').slideUp();
46859    $('.product__step-tram-times .buy-label a').addClass('hide');
46860    $('.product__step-tram-times .buy-label h6').removeClass('disabled');
46861    $('.product__step-tram-times .product__step-form').slideDown();
46862  } else {
46863    toggle_last_step();
46864  }
46865
46866  scroll_to_step($('.product__step-step3'));
46867});
46868
46869/*
46870  Select activity step 4 form (Tram times selection) 
46871*/
46872$(document).on("click", '.product__step-tram-times button.product__step-form__select', function(){
46873  // Clear form errors
46874  $('.tram-time').removeClass('error');
46875  $('#buy_area_messages li').remove();
46876  if (validate_tram_times_sequence()) {
46877    // Set form summary
46878    $('.product__step-tram-times .product__step-summary').html(tram_times_summary());
46879    // Go to last step
46880    $('.product__step-tram-times .product__step-form').slideUp();
46881    $('.product__step-tram-times .buy-label a').removeClass('hide');
46882    $('.product__step-tram-times .product__step-summary').slideDown();
46883    toggle_last_step();
46884    scroll_to_step($('.product__step-tram-times'));
46885  }
46886  toggle_buy_area_messages();
46887});
46888
46889/*
46890  Toggle last step
46891*/
46892function toggle_last_step() {
46893  setTimeout(function(){
46894    $('.buy_area .tally').removeClass('muted');
46895  },0);
46896  $('.product__step-last .buy-label a .right').text('Hide');
46897  if ($('.product__step-last .form-item[data-item-index] option[data-dci]').length > 0) {
46898    $('.product__step-last').removeClass('hide');
46899    $('.product__step-last .product__step-form').slideDown();
46900  } else {
46901    $('.product__step-last').addClass('hide');
46902    $('.product__step-last .product__step-form').slideUp();
46903    $('.product__step-last .product__step-form .form-item[data-item-index] select').val("").change();
46904  }
46905}
46906
46907/*
46908  Handle click on Edit activity step form  
46909*/
46910$(document).on("click", '.product__step:not(.product__step-last) .buy-label a', function(e){
46911  e.preventDefault();
46912  $('.buy_area .tally').addClass('muted');
46913  // Get current step wrapper
46914  var current_step = $(this).closest('.product__step');
46915  // Hide all forms
46916  $('.product__step .product__step-form').slideUp();
46917  // Show all edit buttons and summaries, except for current step
46918  $('.product__step').not(current_step).find('.buy-label a').removeClass('hide');
46919  $('.product__step').not(current_step).find('.product__step-summary').slideDown();
46920  // Reset step 5 form
46921  $('.product__step-last .buy-label a .right').text('Hide');
46922  $('.product__step-last').addClass('hide');
46923  // Show current step form
46924  current_step.find('.product__step-summary').slideUp();
46925  current_step.find('.product__step-form').slideDown();
46926  $(this).addClass('hide');
46927  setTimeout(function(){
46928    scroll_to_step(current_step);
46929  }, 300);
46930});
46931
46932/*
46933  Handle click on Hide activity step form 
46934*/
46935$(document).on("click", '.product__step-last .buy-label a', function(e){
46936  e.preventDefault();
46937  var current_step = $(this).closest('.product__step');
46938  var handle = $(this).find('.right');
46939  if (handle.text() == 'Hide') {
46940    current_step.find('.product__step-form').slideUp();
46941    handle.text('Show');
46942  } else {
46943    current_step.find('.product__step-form').slideDown();
46944    handle.text('Hide');
46945  }
46946  scroll_to_step(current_step);
46947});
46948
46949/*
46950  Set activity/option prices if not unique-price is false
46951*/
46952$(document).on("change", 'select[data-unique-price=false]', function(e){
46953  e.preventDefault();
46954  var selected_option = $(this).find('option:selected');
46955  var label = $(this).siblings('label');
46956
46957  if (selected_option.data('price') === undefined) 
46958    price = ""
46959  else
46960    price = '$'+selected_option.data('price');
46961
46962  label.find('.item-price').text(price);
46963});
46964
46965$(document).on("change", ".tram-time select", function(e){
46966  var unselected = get_unselected_tram_times();
46967  var next_button = $(this).closest(".product__step-form").find(".product__step-form__select");
46968  if (unselected.length == 0) {
46969    next_button.removeAttr('disabled');    
46970  }
46971  else {
46972    next_button.attr('disabled', 'disabled');
46973  }
46974});
46975
46976$(document).on("change", ".item_benefits input[type=checkbox][name*=benefit_]", function(e){
46977  update_benefits_quantities();
46978});
46979
46980$(document).ready(function(){
46981
46982  $('a.what_is_btn').click(function(){
46983    $('.what_is').slideToggle();
46984    return false;	
46985  });
46986
46987  //Cart - Checkout Now - Alert any workflow hooks or unselected modifiers
46988  $('#ecomm_cart a.checkout_now').click(function(){
46989    if ($('#ecomm_cart .product__modifiers fieldset.select_one input[type!=hidden]').length > 0 ) {
46990      var mod_selected = false;
46991      $('#ecomm_cart .product__modifiers fieldset.select_one').each(function(){
46992        if ( $(this).find('input:checked').length > 0 ) { 
46993          mod_selected = true 
46994        } else { 
46995          mod_selected = false; 
46996          $(this).effect('shake', { distance: 4, times: 2 }, 100 ); 
46997        }
46998      });
46999      if (!mod_selected) {
47000        notify("Please review each item in your cart and select any additional options");
47001        $(this).text("Checkout Now");
47002        return false;
47003      }
47004    }
47005    if ($('#ecomm_cart .cart__items li.show_alert').length > 0  ) {
47006      var alerts = [];
47007      $('#ecomm_cart .cart__items li.show_alert').each(function(){
47008        alerts.push( $(this).data('alert-text') );
47009      });
47010      alerts = alerts.unique();
47011      if (confirm(alerts.join(". ")+"\n\nClick OK to Continue Checkout.")) {
47012        return true;
47013      } else {
47014        $(this).text("Checkout Now");
47015        return false;
47016      }
47017    }
47018
47019  });
47020
47021  // update totals
47022  $('body').bind('content_replaced', function(){
47023    $('span.grand_total').text( $('#ecomm_cart').data('grand-total') );
47024  });
47025
47026  // make checkboxes behave like radios for grouped select one mods
47027  $("#ecomm_cart .product__modifiers .select_one input").on("click", function(e) {
47028    var submit = true
47029    if ($(this).prop('checked') == true) {
47030      $(this).closest('.mod-group').find('input').not(this).prop('checked', false);
47031    } else {
47032      $(this).prop('checked', true);
47033      submit = false
47034    }
47035    if (submit) {
47036      $(this).closest('form').submit().addClass("loading");
47037      $(this).closest('mod-group').addClass("loading");      
47038    }
47039  });
47040
47041});
47042$(document).ready(function(){
47043
47044// =====================
47045// = Waiver Navigation =
47046// =====================
47047  
47048
47049  $('.waiver--intro > a').click(function(event) {
47050    $(this).closest('.waiver--intro').hide();
47051    $(this).closest('.waiver--intro').next('.waiver-other-steps').removeClass('hidden');
47052    refresh_scrolling();
47053  });
47054
47055  refresh_scrolling = function() {
47056    info_div = document.getElementById("additional_info");
47057    if (info_div)
47058      info_div.appendChild(document.createElement("span"));
47059  }
47060  
47061  refresh_scrolling();
47062
47063  $('.btn-next').click(function(){
47064    tab = $(this).closest('.tab-content').prev().find('> .active').next('li').find('a');
47065    tab.trigger('click')
47066    $('html, body').animate({
47067        scrollTop: tab.offset().top - 160
47068    }, 500);
47069    refresh_scrolling();
47070  });
47071
47072  $('.btn-previous').click(function(){
47073    tab = $(this).closest('.tab-content').prev().find('> .active').prev('li').find('a');
47074    tab.trigger('click');
47075    $('html, body').animate({
47076        scrollTop: tab.offset().top - 160
47077    }, 500);
47078    refresh_scrolling();
47079  });
47080
47081  $('a.disabled').click(function(e) {
47082    e.preventDefault();
47083  });
47084
47085  $(".waiver-form ul.nav").on('show', "li.disabled a", function(event) {
47086    event.stopImmediatePropagation();
47087          return false;
47088      });
47089  $(".waiver-form ul.nav").off('show', "li:not(.disabled) a")
47090
47091  $(".waiver-form ul.nav").off();
47092
47093  $(".agreed_to_waiver").change(function(){
47094    var current_section = $(this).closest('.tab-pane').index() + 2;
47095
47096    if ( $(this).is(':checked') ) {
47097      $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+') a').attr('data-toggle', 'tab').removeClass('disabled');
47098      $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+')').removeClass('disabled');
47099      $(this).closest('.tab-pane').find('.btn-agree').removeClass('disabled');
47100    }
47101    else {
47102      $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+') a').addClass('disabled').removeAttr('data-toggle');
47103      $(this).closest('.waiver-form').find('ul.nav-tabs li:nth-child('+current_section+')').addClass('disabled');
47104      $(this).closest('.tab-pane').find('.btn-agree').addClass('disabled');
47105      $(this).closest('.tab-pane').nextAll().find(".agreed_to_waiver").prop('checked', false).trigger("change")
47106    }
47107    
47108
47109  });
47110
47111  $('.item.waiver-header').click(function(){
47112    var current = $(this).next('.additional_info.form-details')
47113    if (current.hasClass('hide')){
47114      current.toggleClass('hide');
47115      $('.additional_info.form-details').not(current).addClass('hide');
47116    }
47117  })
47118
47119  toggleWaiverContinueBtn = function(){
47120    if ($(".waiver-form-details[data-completed=false]").length){
47121      $('.button.waiver-continue').addClass('hidden');
47122    }
47123    else {
47124      $('.button.waiver-continue').removeClass('hidden');
47125    }    
47126  }
47127  toggleWaiverContinueBtn();
47128
47129  showNextWaiver = function(){
47130    current = $('.additional_info.form-details').first();
47131    current.removeClass('hide');
47132    $('.additional_info.form-details').not(current).addClass('hide');
47133    //if ($(".waiver-form-details[data-completed=false][data-type=3rd_party]").length == 0) {
47134      $("#onerisk_waivers__iframe-modal").modal('show');
47135    //}
47136
47137  }
47138  showNextWaiver();
47139
47140  $(window).on("message", function(e) {
47141    try {
47142        var data = JSON.parse(e.originalEvent.data);
47143        if (data.messageType == "waiverCompleted") {
47144          $('.waiver-form').each(function(i, f){
47145            if ($(f).find('input[name="waiver_signoff[liability_form_attributes][siriusware_liability_form]"]').val() == data.posFormId
47146                && $(f).find('input[name="waiver_signoff[liability_form_attributes][siriusware_guest_no]"]').val() == data.posGuestId) {
47147               $(f).find('form').submit();
47148               console.log('waiver form submitted');
47149               return false;
47150            } else {
47151              console.log('no matching waiver form found');
47152            }
47153          });
47154        } else if (data.messageType == "allCompleted" || data.messageType == "allWaiversCompleted") {
47155          $('.waiver-form').each(function(i, f){
47156            $(f).find('form').submit();
47157          })
47158          
47159          setTimeout(function(){ $('#onerisk_waivers__iframe-modal').modal("hide"); }, 1000);
47160        }
47161        console.log(data);
47162    } catch(e) {
47163    }
47164  });
47165
47166  $(document).ajaxSuccess(function() {
47167    toggleWaiverContinueBtn();
47168    showNextWaiver();
47169  });
47170
47171  $.validator.addMethod("iagreerule", function(value, element, param) { 
47172        return this.optional(element) || value === param; 
47173    }, "You must enter {0}");
47174
47175  jQuery.validator.messages.required = "";
47176
47177  $('.waiver-update-button').each(function() {
47178    $(this).validate({
47179      invalidHandler: function(e, validator) {
47180        var errors = validator.numberOfInvalids();
47181        if (errors) {
47182          var message = errors == 1
47183            ? 'There is 1 error in the form. It has been highlighted in red.'
47184            : 'There are ' + errors + ' errors in the form.  They have been highlighted in red.';
47185          $("div.errors").html(message);
47186          $("div.errors").show();
47187        } else {
47188          $("div.errors").hide();
47189        }
47190      },
47191      errorElement: "span",
47192      errorLabelContainer: ".error",
47193      highlight: function(element) {
47194        $(element).closest('.field').removeClass('success').addClass('error');
47195      },
47196      unhighlight: function(element) {
47197        $(element).closest('.field').removeClass('error').addClass('success');
47198      },
47199      success: function(element) {
47200        $(element).closest('.field').removeClass('error').addClass('success');
47201        if ($('#hash_view').val()) {
47202          $('.intro').html('You have successfully signed the eWaiver.');
47203          $('span.required').remove();
47204        }
47205      },
47206      rules: {
47207        // simple rule, converted to {required:true}
47208        "cart_item[waiver_signoff_attributes][waiver_full_name]": {
47209          required: true,
47210          minlength: 3
47211        },
47212        // compound rule
47213        iagree: {
47214          required: true,
47215          iagreerule: 'I AGREE' 
47216        }
47217      },
47218      messages: {
47219        iagree: "Please type 'I AGREE'",
47220        "cart_item[waiver_signoff_attributes][waiver_full_name]": "Please enter your full name"
47221      }
47222      
47223    });
47224  });
47225
47226  $(".onerisk_waivers__iframe iframe").load(function(){
47227    $(this).siblings(".loader-wrapper").addClass("hide");
47228    $(this).removeClass("hide");
47229  })
47230});
47231$(document).ready(function(){
47232
47233
47234  // Payment & Shipping checkout#index
47235  $('a#same_as_billing').click(function(){
47236    $('#billing_address input[type="text"]').each(function(){
47237      var target_id = $(this).attr('id').replace(/billing/g,"shipping");
47238      var val = $(this).val();
47239      $("#"+target_id).val(val);
47240    });
47241    $(this).closest('form').valid();
47242    return false;
47243  });
47244
47245
47246  $('form#complete_checkout, form.complete_checkout').submit(function(e){
47247    if (!$(this).valid()){
47248      e.preventDefault();
47249      notify("Form invalid, please fix issues before submitting.", "1");
47250      return;
47251    }
47252
47253    show_order_status_dialog();
47254
47255    if ($(this).data('remote') == true){
47256      e.preventDefault();
47257
47258      $(window).bind("beforeunload",function(event) {
47259        return "Your order is processing. Are you sure?";
47260      });
47261
47262      var data = $(this).serialize();
47263      $.ajax({
47264          type: "POST",
47265          url: $(this).attr('action'),
47266          data: data,
47267          headers: { 'Cache-Control': 'no-cache'}
47268      }).success(function(data){
47269
47270        $(window).unbind("beforeunload");
47271        
47272        if ( data.status == "ok" && data.siriusware_wwsale_id ) {
47273          window.location = "/orders/"+data.siriusware_wwsale_id+"/thanks";
47274        } else if ( data.status == "error" ) {
47275          if (data.error_type == 'dupe_user') {
47276            checkout_login_issue("There was an error submitting your order:<br><strong>"+data.message);
47277          } else if (data.error_type == 'contact_support') {
47278            checkout_processing_message('We apologize as we are unable to complete your request. Please contact Guest Services to complete your purchase at <a "href"="tel:+16049809311">604.980.9311</a> or <a "href"="mailto:[email protected]">[email protected]</a>.', "/checkout", "Close");
47279          } else {
47280            checkout_processing_message("There was an error submitting your order:<br><strong>"+data.message+"</strong> Please edit your order and try again.", "/checkout", "Edit Order");
47281          } 
47282        } else {
47283          checkout_processing_message("There was an error processing your payment. Please try again in a few minutes.", "/checkout", "Close");
47284        }
47285      });
47286      return false;
47287    }
47288  });
47289});
47290
47291function show_order_status_dialog() {
47292  var dialog = $('#checkout_processing');
47293  if (!dialog[0]) {
47294    dialog = $('<div/>', {
47295      id: "checkout_processing"
47296    })
47297  }
47298  dialog.html('<p class="message">Submitting your order...</p>');
47299  dialog.appendTo('body').dialog({
47300    width: 400,
47301    // height: 200,
47302    closeOnEscape: false,
47303    draggable: false,
47304    open: function(event, ui) { $(".ui-dialog-titlebar-close").hide(); },
47305    resizable: false,
47306    modal: true,
47307    title: "Order Status",
47308    close: function(){
47309      dialog.dialog('destroy').remove();
47310    }
47311  });
47312  $('<div/>', {
47313    "class": "progress_bar"
47314  }).appendTo('#checkout_processing');
47315
47316  loadCheckoutSurvey();
47317}
47318
47319var poll_tries=0;
47320function poll_for_checkout_success(sw_id) {
47321  $.ajax({
47322    url: '/checkout/'+sw_id+'/get_status',
47323    type: 'GET',
47324    dataType: 'json',    
47325    success: function(data) {
47326      if (data.status == 'pending') {
47327        if (poll_tries < 60) {
47328          poll_tries++;
47329          setTimeout(function() { poll_for_checkout_success(sw_id); }, 2000);
47330        } else {
47331          if (window.survey) {
47332            checkout_processing_message("There was a delay in processing your payment. We will keep trying and email you when your order has been processed.<br>Order #:"+sw_id, "/account", "Go to My Account page");          
47333          } else {
47334            window.location = "/checkout/"+data.order_number+"/delayed";
47335          }
47336        }
47337      } else if (data.status == 'error') {
47338        checkout_processing_message("There was an error processing your order: "+data.message+". Please correct the error and try again.<br>Order #:"+sw_id, "close_dialog", "Close");
47339      } else if (data.status == 'rejected') {
47340        checkout_processing_message("We're sorry, your order could not be completed. Please try again or contact guest services.<br>Order #:"+sw_id, "close_dialog", "Close");
47341      } else {
47342        if (window.survey) {
47343          checkout_processing_message("Your order was processed successfully", "/orders/"+data.order_number+"/thanks", "View Receipt");
47344        } else {
47345          window.location = "/orders/"+data.order_number+"/thanks";
47346        }
47347      }
47348    },
47349    error: function(data) {
47350      checkout_processing_message("There was an error processing your payment. Please try again in a few minutes.<br>Order #:"+sw_id, "close_dialog", "Close");
47351    }
47352  });
47353}
47354
47355function checkout_processing_message(message, url, link_text) {
47356  if ($("#checkout_processing").length == 0)
47357    show_order_status_dialog()
47358
47359  $(".ui-dialog-titlebar-close").show();
47360  $('#checkout_processing .message').html(message);
47361  $('#checkout_processing .progress_bar').remove();
47362  if (url == "close_dialog") {
47363    $('<a/>', {
47364      "href": "#",
47365      "class": "button",
47366      text: link_text,
47367      click: function(){
47368        $('#checkout_processing').dialog('destroy').remove();
47369      }
47370    }).insertAfter('#checkout_processing .message');
47371  } else {
47372    $('<a/>', {
47373      "href": url,
47374      "class": "button",
47375      text: link_text
47376    }).insertAfter('#checkout_processing .message');
47377  }
47378}
47379
47380function checkout_login_issue(message) { 
47381  $(".ui-dialog-titlebar-close").show();
47382  $('#checkout_processing .message').html(message);
47383  $('#checkout_processing .progress_bar').remove();
47384  $('<a/>', {
47385    "href": '/login',
47386    "class": "button login-btn",
47387    text: 'Login'
47388  }).insertAfter('#checkout_processing .message');
47389  $('<a/>', {
47390    "href": '/forgot',
47391    "class": "small",
47392    text: "Forgot your password?"
47393  }).insertAfter('#checkout_processing .login-btn');
47394  $('.login-btn').after(" ");
47395}
47396
47397function loadCheckoutSurvey() {
47398  $.ajax({
47399    url: "/checkout/survey.html",
47400    dataType: "html",
47401    success: function(data) {
47402      window.survey = true
47403
47404      // resize dialog
47405      $("#checkout_processing").dialog("option", "width", 620)
47406      $("#checkout_processing").dialog("option", "height", 520)
47407      $("#checkout_processing").dialog("option", "position", $("#checkout_processing").dialog("option", "position"));
47408
47409      // append survey
47410      var $survey = $('<div/>', {
47411        "class": "checkout_survey",
47412        "html": data
47413      }).appendTo('#checkout_processing');
47414
47415      $survey.find("form").submit(function(){
47416        var data = $(this).serialize();
47417
47418        $.ajax({
47419          url: $(this).attr('action'),
47420          data: data,
47421          type: 'POST',
47422          dataType: 'json',
47423          success: function(data) {
47424            window.survey = false
47425            $survey.text("Thank you for your response.");
47426            $("#checkout_processing").dialog("option", "width", 400)
47427            $("#checkout_processing").dialog("option", "height", 200)
47428            $("#checkout_processing").dialog("option", "position", $("#checkout_processing").dialog("option", "position"));
47429          }
47430        });
47431
47432        return false;
47433      });
47434
47435    }
47436  });
47437}
47438;
47439$(document).ready(function(){
47440  
47441  jQuery.validator.messages.required = "";
47442
47443  // Add method to validate delivery date
47444  jQuery.validator.addMethod("validdeliverydate", function(value, element, params) {
47445    formItem = $(element).closest('.form-item');
47446    if (formItem.closest('.user_personal_info_fields').find('.user-type').val() == 'self') 
47447      return true;
47448
47449    var today = new Date();
47450    var todaydd = today.getDate();
47451    var todaymm = today.getMonth()+1;
47452    var todayyyyy = today.getFullYear();
47453
47454    if(todaydd < 10){
47455      todaydd='0'+todaydd;
47456    }
47457    
47458    if(todaymm < 10){
47459       todaymm="0"+todaymm;
47460    }   
47461
47462    deliveryyyyy = formItem.find('select[name*="delivery_date(1i)"]').val();  
47463    deliverymm = formItem.find('select[name*="delivery_date(2i)"]').val();  
47464    deliverydd = formItem.find('select[name*="delivery_date(3i)"]').val(); 
47465
47466    if(deliverydd < 10){
47467      deliverydd='0'+deliverydd;
47468    }
47469    if(deliverymm < 10){
47470       deliverymm="0"+deliverymm;
47471    }
47472
47473    if ([deliveryyyyy,deliverymm,deliverydd].join('-') < [todayyyyy,todaymm,todaydd].join('-')) {
47474      formItem.removeClass('success').addClass('error');
47475      return false;
47476    }
47477    formItem.removeClass('error').addClass('success');
47478
47479    return true;
47480
47481  }, "Please make sure delivery dates are greater or equal than today.");
47482
47483  $('#additional_info #edit_cart').validate({
47484    invalidHandler: function(e, validator) {
47485			var errors = validator.numberOfInvalids();
47486			if (errors) {
47487				var message = errors == 1
47488					? 'There is 1 error in the form. It has been highlighted in red.'
47489					: 'There are ' + errors + ' errors in the form.  They have been highlighted in red.';
47490				$("div.errors").html(message);
47491				$("div.errors").show();
47492			} else {
47493				$("div.errors").hide();
47494			}
47495		},
47496		errorElement: "span",
47497		errorLabelContainer: "#errors",
47498    highlight: function(element) {
47499      // Small delay to make sure errors on select_date fields get highlighted
47500      setTimeout(function(){
47501        $(element).closest('.form-item').removeClass('success').addClass('error');
47502      }, 100);
47503    },
47504    unhighlight: function(element) {
47505      $(element).closest('.form-item').removeClass('error').addClass('success');
47506    },
47507    success: function(element) {
47508      $(element).closest('.form-item').removeClass('error').addClass('success');
47509    }
47510    
47511  });
47512
47513  // Ser delivery date rule
47514  $('.form-item--delivery-date').each(function() {
47515      $(this).find('select').first().rules('add', {
47516        validdeliverydate: true,
47517      });
47518  });
47519
47520  $('.form-item--delivery-date select[name*="[delivery_date(2i)]"], .form-item--delivery-date select[name*="[delivery_date(3i)]"]').change(function(){
47521    $(this).siblings('select[name*="[delivery_date(1i)]"]').focus().blur();
47522  })
47523  
47524  $('#continue_to_checkout').click(function(){
47525    if ( $('#additional_info #edit_cart').valid()) {
47526      if ($(".lookup-pass:visible").length > 0) {
47527        $('html, body').animate({
47528          scrollTop: $(".lookup-pass:visible").first().offset().top - 200
47529        }, 500);
47530        
47531        notify("Please fill out missing contact information.");
47532        return false;
47533      }
47534
47535      if ( $('.agreed_to_waiver').length > 0 && $('.agreed_to_waiver').prop('checked') != true) {
47536        notify("Please read each waiver and click the check box to indicate you agree to the terms of the waiver.");
47537        return false;
47538      } 
47539
47540      $(this).val("Please wait...");
47541      return true;
47542    } 
47543    else {
47544      notify("Form invalid, please fix issues before submitting.", "1");
47545      return false;
47546    }
47547  });
47548
47549  var $mapping = {
47550    'new': '3rd_party',
47551    'managed_user': 'managed_user',
47552    'minor': 'kid'
47553  };
47554
47555  updateUserType = function(){
47556    var $mapping = {
47557      'new': '3rd_party',
47558      'managed_user': 'managed_user',
47559      'minor': 'kid'
47560    };
47561
47562    $('.user-type').each(function(index){
47563      var $origin = $(this).prev().find('input.populate_form:checked');
47564      var user_id = $origin.val();
47565      if (!$mapping[user_id])
47566        $mapping[user_id] = 'self';
47567      $(this).val($mapping[user_id]);
47568
47569    })
47570  }
47571  updateUserType();
47572
47573  // Select a Guest Controls
47574  $('#additional_info input.populate_form').change(function(){
47575    var user_id = $(this).val();
47576    var cart_item_id = $(this).data('cartItemId');
47577    var $field_set = $(this).closest('.user_personal_info_fields');
47578
47579    if (user_id == "managed_user") {
47580      user_id = $(this).siblings('.managed_users').val();
47581    }
47582    changeUser( $field_set, user_id, cart_item_id);
47583
47584    $field_set.find('a.change-again').hide();
47585    if (user_id != "managed_user" && user_id != "existing_user") {
47586      $(this).next('a.change-again').removeClass('hide');
47587      $(this).next('a.change-again').show();
47588    } else {
47589      $(this).next('a.change-again').hide();
47590    }
47591
47592    // update user type
47593    var $user_type = $(this).closest('.block.form').find('.user-type');
47594    if (!$mapping[user_id])
47595      $mapping[user_id] = 'self';
47596    $user_type.val($mapping[user_id]);
47597
47598  });
47599
47600
47601  $('#additional_info a.change-again').click(function(){
47602    // if ($(this).hasClass('change-self'))
47603    //   changeUser( $(this).closest('.user_personal_info_fields'), "123" );
47604    // else
47605      changeUser( $(this).closest('.user_personal_info_fields'), "new" );
47606    return false;
47607  });
47608
47609  $('#additional_info select.populate_form').change(function(){
47610    var $field_set = $(this).closest('.user_personal_info_fields');
47611
47612    $(this).siblings('.managed_user_radio').first().attr('checked', true);
47613
47614    var user_id = $(this).val();
47615    var cart_item_id = $(this).data('cartItemId');
47616
47617    changeUser( $field_set, user_id, cart_item_id );
47618
47619    $field_set.find('a.change-again').hide();
47620  });
47621
47622  $('.recipient-fields input[name*=recipient_first_name], .recipient-fields input[name*=recipient_last_name], .recipient-fields input[name*=recipient_email]').change(function() {
47623    var field_set = $(this).closest('.user_personal_info_fields');
47624    var name = $(this).attr('name');
47625    if (name.indexOf("recipient_first_name") > -1) {
47626      field_set.find(".name-fields input[type=hidden][name*=first_name]").val($(this).val());
47627
47628    } else if (name.indexOf("recipient_last_name") > -1) {
47629      field_set.find(".name-fields input[type=hidden][name*=last_name]").val($(this).val());
47630
47631    } else if (name.indexOf("recipient_email") > -1) {
47632      field_set.find(".name-fields input[type=hidden][name*=email]").val($(this).val());
47633    }
47634  });
47635
47636  function changeUser($field_set, user_id, cart_item_id) {
47637    var url = $('.change-user-controls').data('user-data-path');
47638
47639    $.ajax({
47640			url: url,
47641			data: {
47642        user_id: user_id,
47643        cart_item_id: cart_item_id
47644			},
47645			type: 'GET',
47646			dataType: 'json',
47647			success: function(data) {				
47648        populateForm($field_set, data, user_id);
47649
47650			},
47651			error: function() {
47652			}
47653		});
47654  };
47655
47656  function showContactEmailField($field_set) {
47657    $field_set.find('.form-item--contact-email').removeClass('hide');
47658    $field_set.find('.form-item--contact-email input').addClass('required').prop('required', true);
47659  }
47660
47661  function hideContactEmailField($field_set) {
47662    $field_set.find('.form-item--contact-email').addClass('hide').removeClass('error');
47663    $field_set.find('.form-item--contact-email input').removeClass('required').prop('required', false).val('');  
47664  }
47665
47666  function populateForm($field_set, data, user_id) {
47667
47668    var is_current_user = (data.id == user_id);
47669
47670    for ( field in data ) {
47671      if (field == 'siriusware_mugshot_cache_preview_url') {
47672        $field_set.find('.form-item--photo-preview img').attr('src', data[field] );  
47673      } else if (field != "id") {
47674        $field_set.find("input[name*='\["+field+"\]'], select[name*='\["+field+"\]']").val( data[field] );  
47675      }
47676    }
47677
47678    // show/hide mugshot field
47679    if (data["has_siriusware_mug_shot"]) {
47680      $field_set.find("input[name*='siriusware_mugshot_cache']").closest('.form-item').addClass('hide');
47681      $field_set.find(".form-item.form-item--has-a-photo").removeClass('hide');
47682    } else {
47683      $field_set.find("input[name*='siriusware_mugshot_cache']").closest('.form-item').removeClass('hide');
47684      $field_set.find(".form-item.form-item--has-a-photo").addClass('hide');
47685    }
47686
47687    for ( field in data.address ) {
47688      if (field != "id") {
47689        $field_set.find(".address_fields input[name*="+field+"], .address_fields select[name*="+field+"]").val( data.address[field] ).change();
47690        if (field == "country") {
47691          //  If country, repopulate province
47692          $field_set.find(".address_fields input[name*='province'], .address_fields select[name*='province']").val( data.address["province"] );
47693        }
47694      }
47695    }
47696
47697    if (data.cart_item_email !== null) {
47698      for ( field in data.cart_item_email ) {
47699        if (field != "id") {
47700          $field_set.find(".recipient-fields input[name*="+field+"]").val( data.cart_item_email[field] );
47701        }
47702      }
47703    } else {
47704    // set user fields
47705      $field_set.find(".recipient-fields input[name*=recipient_first_name]").val(data['first_name']);
47706      $field_set.find(".recipient-fields input[name*=recipient_last_name]").val(data['last_name']);
47707      $field_set.find(".recipient-fields input[name*=recipient_email]").val(data['email']);
47708      $field_set.find(".recipient-fields input[name*=recipient_email_type]").val(data['email']);
47709
47710    // set disabled fields
47711      $field_set.find(".recipient-disabled .recipient_first_name").text(data['first_name']);
47712      $field_set.find(".recipient-disabled .recipient_last_name").text(data['last_name']);
47713      $field_set.find(".recipient-disabled .recipient_email").text(data['email']);
47714    }
47715
47716    // set name (for disabled state)
47717    $field_set.find(".name-disabled .first_name").text(data['first_name']);
47718    $field_set.find(".name-disabled .last_name").text(data['last_name']);
47719
47720    // set id's
47721    $field_set.find("input[name*='\[address_attributes\]\[id\]']").last().val( data.address.id );
47722    $field_set.find("input[name*='\[id\]']").last().val( data.id );
47723
47724    // show / hide user lookup form AND lock / unlock name fields
47725    if (data.id) {
47726      if (!isNaN(user_id) && data['birth_date(1i)'] == null){
47727        showLookup($field_set, true, user_id)
47728        $field_set.find(".name-disabled").slideUp();
47729        $field_set.find(".recipient-disabled").slideUp();
47730        $field_set.find(".name-fields").slideDown().removeClass('hide'); 
47731        $field_set.find(".recipient-fields").slideDown().removeClass('hide'); 
47732        return;
47733      }
47734      showLookup($field_set, false, user_id)
47735      $field_set.find(".name-disabled").slideDown().removeClass('hide');
47736      $field_set.find(".recipient-disabled").slideDown().removeClass('hide');
47737      $field_set.find(".recipient-disabled").find(".form-item").removeClass('hide');
47738      $field_set.find(".name-fields").slideUp();
47739      $field_set.find(".recipient-fields").slideUp();
47740      hideContactEmailField($field_set);
47741    } else {
47742      showLookup($field_set, true, user_id)
47743      $field_set.find(".name-disabled").slideUp();
47744      $field_set.find(".recipient-disabled").slideUp();
47745      $field_set.find(".recipient-disabled").find(".form-item").removeClass('hide');
47746      $field_set.find(".name-fields").slideDown().removeClass('hide');
47747      $field_set.find(".recipient-fields").slideDown().removeClass('hide');
47748      showContactEmailField($field_set);
47749    }
47750
47751    // Show/Hide Add Pass to My Account
47752    $field_set.find('.form-item--add-pass-to-manager').toggleClass('hide', is_current_user);
47753    $field_set.find('.form-item--add-pass-to-manager').find('input[type=checkbox]').prop('checked', !is_current_user);
47754  }
47755 
47756  $('#additional_info a.skip-lookup').click(function(){
47757    var $field_set = $(this).closest('.user_personal_info_fields');
47758    showLookup($field_set, false);
47759
47760    return false;
47761  });
47762
47763  function showLookup($field_set, state, user_id) {
47764    user_id = user_id || "3rd_party"
47765    if (state == true) {
47766      if (!isNaN(user_id)){
47767        $field_set.find(".self-lookup-pass").removeClass('hide');
47768        $field_set.find(".self-lookup-pass").slideDown();
47769        $field_set.find(".lookup-pass").slideUp();
47770      }
47771      else {
47772        $field_set.find(".lookup-pass").removeClass('hide');
47773        $field_set.find(".lookup-pass").slideDown();
47774        $field_set.find(".self-lookup-pass").slideUp();
47775      }
47776      $field_set.find(".user-form").slideUp();
47777    } else {
47778      if (!isNaN(user_id)) {
47779        $field_set.find(".self-lookup-pass").slideUp();
47780        $field_set.find(".lookup-pass").slideUp();
47781      }
47782      else {
47783        $field_set.find(".lookup-pass").slideUp();
47784        $field_set.find(".self-lookup-pass").slideUp();
47785      }
47786      $field_set.find(".user-form").removeClass('hide');
47787      $field_set.find(".user-form").slideDown();
47788    }
47789  }
47790
47791  $("#additional_info .self-lookup-pass a.submit-self-lookup").click(function(e) {
47792    e.preventDefault();
47793
47794    var $button = $(this);
47795    var prev_text = $(this).text();
47796    $button.text("Please wait...");
47797
47798    var $field_set = $button.closest('.user_personal_info_fields');
47799    var $lookup_form = $button.closest('.self-lookup-pass');
47800
47801    // {"siriusware_pass_no" => "166078036000", "date" => "1980-04-12"}
47802    var date = [
47803      $lookup_form.find("select[name='lookup_birth_date[year]']").val(),
47804      $lookup_form.find("select[name='lookup_birth_date[month]']").val(),
47805      $lookup_form.find("select[name='lookup_birth_date[day]']").val()
47806    ].join("-")
47807
47808    var data = { 
47809      pass: {
47810        siriusware_pass_no: $lookup_form.find("input[name='lookup_pass_no']").val()
47811      }
47812    }
47813
47814    if (date != '--')
47815      data.pass.date = date;
47816
47817    $lookup_form.find(".error").slideUp();
47818    $.ajax({
47819      url: "/users/add_pass_to_self",
47820      data: data,
47821      dataType: "json",
47822      type: 'POST',
47823      success: function(data, status) {
47824        populateForm($field_set, data, 'self');
47825        $button.text(prev_text);
47826      },
47827      error: function() {
47828        $lookup_form.find(".error").slideDown();
47829        $button.text(prev_text);
47830      }
47831    });
47832  });
47833
47834  $("#additional_info .lookup-pass a.submit-lookup").click(function(e) {
47835    e.preventDefault();
47836
47837    var $button = $(this);
47838    var prev_text = $(this).text();
47839    $button.text("Please wait...");
47840
47841    var $field_set = $button.closest('.user_personal_info_fields');
47842    var $lookup_form = $button.closest('.lookup-pass');
47843
47844    // {"siriusware_pass_no" => "100123456", "date" => "1977-11-1"}
47845    var date = [
47846      $lookup_form.find("select[name='lookup_birth_date[year]']").val(),
47847      $lookup_form.find("select[name='lookup_birth_date[month]']").val(),
47848      $lookup_form.find("select[name='lookup_birth_date[day]']").val()
47849    ].join("-")
47850
47851    var data = { 
47852      pass: {
47853        input_no: $lookup_form.find("input[name='lookup_pass_no']").val(),
47854        date: date
47855      }
47856    }
47857    $.ajax({
47858      url: "/user_lookup/pass",
47859      data: data,
47860      dataType: "json",
47861			type: 'GET',
47862      success: function(data, status) {
47863        populateForm($field_set, data, '3rd_party');
47864        $button.text(prev_text);
47865      },
47866      error: function() {
47867        $lookup_form.find(".error-message").slideDown();
47868        $button.text(prev_text);
47869      }
47870    });
47871  });
47872
47873  // same as above
47874  $('#additional_info a.same_as_above').each(function(){
47875    if ($(this).closest('.personal_info_fields').index('.personal_info_fields') > 0 ||
47876        $(this).closest('.user_personal_info_fields').index('.user_personal_info_fields') > 0) {
47877      $(this).parent().removeClass('hide');
47878      $(this).parent().show();
47879    }
47880  });
47881
47882  $('#additional_info a.same_as_above').click(function(){
47883    const parent_class = $(this).data('same-as-above') == 'address' ? 'address_fields' : 'user_personal_info_fields';
47884
47885    var $copy_to = $(this).closest('.'+parent_class);
47886
47887    // multi-person item
47888    var $copy_from = $(this).closest('.personal_info_fields').prev();
47889
47890    if ($copy_from.length == 0) {
47891      $copy_from = $(this).closest('.cart__item').prevAll('.cart__item').first().find('.personal_info_fields').first()
47892    }
47893
47894    var $fields = $copy_from.find('.'+parent_class+' input, .'+parent_class+' select');
47895    $fields.each(function(){
47896      var $field = $(this);
47897      var field_name = $field.attr('name').match(/\[([^\[^\]]*)\]$/);
47898      if (field_name) {
47899        var name = field_name.pop();
47900        name = name.replace("(","_").replace(")","")
47901        $copy_to.find('input[id*='+name+'], select[id*='+name+']').each(function(){
47902          if ( $(this).attr('id').split("_").pop() != "id" ) {
47903            $(this).val( $field.val() );
47904            $(this).change();
47905          }
47906        });  
47907      }
47908    });
47909
47910    return false;
47911  });
47912  
47913});
47914$(document).ready(function(){
47915  
47916  jQuery.validator.messages.required = "";
47917
47918  $('.edit_user_address').validate({
47919    invalidHandler: function(e, validator) {
47920      var errors = validator.numberOfInvalids();
47921      if (errors) {
47922        var message = errors == 1
47923          ? 'There is 1 error in the form. It has been highlighted in red.'
47924          : 'There are ' + errors + ' errors in the form.  They have been highlighted in red.';
47925        $("div.errors").html(message);
47926        $("div.errors").show();
47927      } else {
47928        $("div.errors").hide();
47929      }
47930    },
47931    errorElement: "span",
47932    errorLabelContainer: "#errors",
47933    highlight: function(element) {
47934      $(element).closest('.form-item').removeClass('success').addClass('error');
47935    },
47936    unhighlight: function(element) {
47937      $(element).closest('.form-item').removeClass('error').addClass('success');
47938    }
47939  });
47940
47941  $('.edit_user_address .form-actions button').click(function(){    
47942    if ($('.edit_user_address').valid()) {
47943      $(this).val("Please wait...");
47944      return true;
47945    } 
47946    else {
47947      notify("Form invalid, please fix issues before submitting.", "1");
47948      return false;
47949    }
47950  });
47951});
47952$.widget("ui.tsSlideshow", {
47953
47954  // default options
47955  options: {
47956    rate: 3000,
47957    duration: 1500
47958  },
47959
47960  _create: function() {
47961    var self = this;
47962    self.curIndex = self.element.children().first().index();
47963    self.element.children().eq( self.curIndex ).fadeIn(self.options.duration, function(){
47964      self.timer = setTimeout(function(){self.next();},self.options.rate);
47965    });
47966
47967  },
47968
47969  update: function() {
47970
47971  },
47972
47973  next: function() {		
47974    var self = this;
47975    self.element.children().eq( self.curIndex ).css('z-index','0');
47976    self.element.children().eq( self._nextIndex() ).css('z-index','1').fadeIn( self.options.duration, function(){			
47977      // hide previous
47978      self.element.children().eq( self.curIndex ).css('display','none');
47979
47980      self.curIndex = self._nextIndex();
47981      clearTimeout(self.timer);
47982      self.timer = setTimeout(function(){self.next();},self.options.rate);	
47983
47984    });
47985  },
47986
47987  start: function() {
47988    var self = this;
47989    self.next();
47990  },
47991
47992  stop: function() {
47993    var self = this;
47994    clearTimeout(self.timer);
47995  },
47996
47997  _nextIndex: function() {
47998    var self = this;
47999    var total = self.element.children().length;
48000    if ( self.curIndex == (total - 1)) {
48001      return 0;
48002    }
48003    return this.curIndex + 1;
48004  },
48005
48006  destroy: function() {
48007    $.Widget.prototype.destroy.apply(this, arguments); // default destroy
48008    // now do other stuff particular to this widget
48009  }
48010
48011});
48012/*
48013* On Off Switch Plugin
48014*
48015* Copyright (c) 2011 Thought Shop Creative Inc.
48016*
48017* By Trevor Johnston
48018*
48019* Date: 2011-04-12
48020* Rev: 1.0-2
48021*/
48022
48023(function($){  
48024	
48025	$.widget("ui.tsWidgets", {
48026		// default options
48027		options: {
48028			
48029		},
48030		
48031		active: false,
48032		
48033		_create: function() {
48034			var self = this;
48035			
48036			self._bindTriggerClicks();
48037			
48038			// check external clicks
48039			$(document).mousedown(function(event){
48040				self._checkExternalClick(event);
48041			});
48042		},
48043		
48044		// Public Methods
48045		
48046		value: function( newValue ) {
48047			
48048		},
48049		
48050		// Private Methods
48051		
48052		_bindTriggerClicks: function() {
48053			var self = this;
48054			
48055			self.element.find('a').click(function(){				
48056				if ( self.active && $(this).hasClass('active') ) {
48057					self._hideWidgets();
48058				} else {
48059					self._showWidget( $(this) );
48060				}
48061				return false;
48062			});
48063		},
48064		
48065		_showWidget: function( $trigger ) {
48066			var self = this;
48067			var widget_class = $trigger.attr('href').replace(/^#/, '');
48068			
48069			if (!self.active) {
48070				self._showWidgets();
48071			}
48072			
48073			$('#widgets .widget').hide();
48074			$('#widget_triggers a').removeClass('active');
48075			
48076			$('#widgets').find('.'+widget_class).show();
48077			$trigger.addClass("active");
48078			
48079			ga('send', 'event', widget_class, 'click', 'footer widgets');
48080		},
48081		
48082		_showWidgets: function() {
48083			var self = this;
48084			
48085			self.active = true;
48086			
48087			closeGrid();
48088			
48089			$('#widgets').animate({
48090				height: '455px'
48091			}, 400, function() {
48092				// Animation complete.
48093			});
48094			pause_full_screen_bg();
48095		},
48096		
48097		_hideWidgets: function() {
48098			var self = this;
48099			
48100			self.active = false;
48101			$('#widget_triggers a').removeClass('active');
48102			
48103			$('#widgets').animate({
48104				height: '0px'
48105			}, 400, function() {
48106				// Animation complete.
48107			});
48108			resume_full_screen_bg();
48109		},
48110		
48111		_checkExternalClick: function(event) {
48112			var self = this;
48113			
48114			if (self.active == false) {
48115				return;
48116			}
48117				
48118			var $target = $(event.target);
48119			if ($target[0].id != '#widgets' &&
48120					$target[0].id != '#widget_triggers' &&
48121					$target.parents('#widgets').length == 0 &&
48122					$target.parents('#widget_triggers').length == 0) {
48123						self._hideWidgets();
48124					}
48125		},
48126	
48127		destroy: function() {
48128			$.Widget.prototype.destroy.apply(this, arguments); // default destroy
48129			// now do other stuff particular to this widget
48130		}
48131	});
48132
48133})(jQuery);
48134// GROUSE MAIN DESKTOP JS FILE
48135
48136// Not required anymore, JQuery 1.9 infers data type from header.
48137// Besides, this brakes the whole AJAX framework, forcing 
48138// everything to be JSON.
48139// $.ajaxSettings.dataType = "json";
48140
48141jQuery.fn.fadeToggle = function(speed, easing, callback) { 
48142  return this.animate({opacity: 'toggle'}, speed, easing, callback); 
48143};
48144
48145jQuery.fn.lazyLoadImages = function() {
48146
48147  return this.each(function() {
48148
48149    var $grid_image = $(this);
48150    $grid_image.addClass("loading");
48151    var url = $grid_image.data('url');
48152    var img = new Image();
48153    $(img).load(function() {
48154      $(this).hide();
48155      $grid_image.replaceWith(this);
48156      $(this).fadeIn();
48157    }).attr('src', url);
48158
48159  });
48160
48161};
48162
48163Array.prototype.unique =
48164  function() {
48165  var a = [];
48166  var l = this.length;
48167  for(var i=0; i<l; i++) {
48168    for(var j=i+1; j<l; j++) {
48169      // If this[i] is found later in the array
48170      if (this[i] === this[j])
48171        j = ++i;
48172    }
48173    a.push(this[i]);
48174  }
48175  return a;
48176};
48177
48178// ====================
48179// = CMS Help Buttons =
48180// ====================
48181
48182$(document).ready(function(){
48183  $('div.help').livequery(function(){
48184    var $self = $(this);
48185    var button = $('<a/>', {
48186      "class": "help",
48187      mouseenter: function(){
48188        $self.css({
48189          top: button.position().top,
48190          left: button.position().left
48191        });
48192        $self.fadeIn('fast');		
48193      }
48194    });
48195
48196    $self.prev('label').append( button );
48197
48198    $self.bind('mouseout', function(){
48199      $(this).fadeOut('fast');
48200    }).bind('click', function(){
48201      $(this).fadeOut('fast');
48202    });
48203
48204  });
48205
48206
48207
48208});
48209
48210
48211// ===================
48212// = Notify Function =
48213// ===================
48214function notify(message,status) {
48215  var repeat = false;
48216  if (!message) { return false; }
48217  if (!status) { status = "notice"; }
48218
48219  if ( !$('#ts-notify').length ) { 
48220    $('<div/>', {
48221      "id": "ts-notify"
48222    }).hover(function(){			// stop fadeout on hover
48223      $(this).stop(true);
48224      $(this).fadeTo(300,1);
48225    },function(){							// re-instate fadeout on mouseLeave
48226      $(this).delay(10000).fadeTo(600,0,function(){ $(this).remove(); });
48227    }).appendTo('body');	
48228  }	
48229
48230  var $close_button = $('<button/>', {
48231    "class": "close",
48232    "html": "x",
48233    click : function(){
48234      $(this).parent().hide().remove();
48235      if ( !$('#ts-notify .notification').length ) {
48236        $('#ts-notify').remove();
48237      }
48238    }
48239  });
48240
48241  var parsedMessage = $.parseHTML(message);
48242  if (parsedMessage.length > 0)
48243    parsedMessage = parsedMessage[0].textContent
48244  else
48245    parsedMessage = message
48246
48247  var $body = $('<div/>', {
48248    "class": "notification-body",
48249    "html": parsedMessage
48250  })
48251
48252  var notification = $('<div/>', {
48253    "class": "notification "+status
48254  }).prepend($body).prepend($close_button);
48255
48256
48257  $('#ts-notify > div').each(function(){
48258    if ( $(this).html() == notification.html() ) { repeat = true; }
48259  });
48260
48261  if ( repeat == false ) {
48262    $('#ts-notify').prepend(notification);
48263
48264    $('#ts-notify').stop(true).fadeTo(1,1);
48265
48266    $('#ts-notify').show().fadeTo(600,1,function(){
48267      //delay and fadeout
48268      $(this).delay(5000).fadeTo(600,0,function(){$(this).remove();});
48269    });
48270  }
48271
48272}
48273
48274// ===========================
48275// = AJAX Response Processor =
48276// ===========================
48277function processResponse(response) {
48278  if (response.message) {
48279    notify(response.message,response.status);
48280  }
48281  
48282  if ( response.html ) {
48283    if (response.mode == "replace") {
48284      $($('[id="'+response.dom_id+'"]')).each(function(){
48285        $(this).replaceWith(response.html)
48286      }) 
48287      $('body').trigger('content_replaced');
48288    }
48289    if (response.mode == "insert") {
48290      $($('[id="'+response.dom_id+'"]')).each(function(){
48291        $(this).append(response.html);
48292      }) 
48293    }
48294  // Special case: Remove image
48295  } else if (response.mode == "replace" && response.dom_id.indexOf("container_media") >= 0) {
48296    $($('[id="'+response.dom_id+'"]')).each(function(){
48297      $(this).find('img').remove();
48298    }) 
48299    $('body').trigger('content_replaced');
48300  }
48301
48302  if (response.mode == "remove") {
48303    $($('[id="'+response.dom_id+'"]')).each(function(){
48304      $(this).slideUp(600, function(){ $(this).remove(); });
48305    }) 
48306  }
48307
48308  if (response.mode == "redirect") {
48309    window.location = response.url;
48310  }
48311
48312  $('.loading').removeClass("loading");
48313
48314}
48315
48316$(document).ready(function(){
48317  $(document).on('ajax:success', 'form[data-remote=true], a[data-remote=true]', function(evt, data, status, xhr) {
48318    processResponse(data);
48319  });
48320
48321
48322  $(document).on('change', '.submit_onChange', function(event) {
48323    if ($("form#"+$(this).attr('form')).length > 0) {
48324      $("form#"+$(this).attr('form')).submit().addClass("loading");
48325    } else {
48326      $(this).closest('form').submit().addClass("loading");
48327    }
48328    $(this).addClass("loading");
48329    if ($(this).hasClass('reload_onSubmit')) window.location.reload();
48330  });
48331
48332});
48333
48334
48335// =======================
48336// = cObject Fit support =
48337// =======================
48338$(document).ready(function() {
48339  if ( ! Modernizr.objectfit ) {
48340    $('.feature-block__image .media, .banner__image .media').each(function () {
48341      var $container = $(this),
48342          imgUrl = $container.find('img').prop('src');
48343      if (imgUrl) {
48344        $container
48345          .css('backgroundImage', 'url(' + imgUrl + ')')
48346          .addClass('compat-object-fit');
48347      }  
48348    });
48349  }
48350});
48351
48352
48353// ======================
48354// = disable_with a tags =
48355// ======================
48356// $(document).ready(function(){
48357//   $('a[data-disable-with]').click(function(){
48358//     $(this).text( $(this).data('disable-with') );
48359//   });  
48360// });
48361
48362// =======================================
48363// = common inline form show/hide events =
48364// =======================================
48365
48366$(document).ready(function(){	
48367
48368  // $('input.telephone').mask("999-999-9999");
48369
48370  // external links open in new window
48371  $("a[href^='http']").not("a[href*='grousemountain.com']").attr('target','_blank');
48372
48373
48374  $('.inline_form').hide();
48375
48376  // toggle open form
48377  $(document).on('click', '.show_inline_form', function(){
48378    var form_id = $(this).attr('href');
48379    if ( $(this).hasClass('open')) {
48380      $(form_id).parent().slideUp();
48381      $(this).removeClass("open");
48382    } else {
48383      $('.inline_form').slideUp(); // close all open forms
48384      $(form_id).parent().slideDown();
48385      $(this).addClass("open");
48386    }
48387    return false;
48388  });
48389
48390  // close form on successful submission
48391  $(document).on('ajax:success', '.inline_form form[data-remote=true]', function(evt, data, status, xhr) {
48392    $('.inline_form').slideUp(); // close all open forms
48393    if ( $(this).hasClass('form_method_create')) {
48394      $(this).find('input').val('');
48395    }
48396  });
48397
48398  // close form on successful submission
48399  $(document).on('ajax:success', '#new_user', function(evt, data, status, xhr) {
48400    if (data.status == "exists") {
48401      $('.panel-login .step2').hide();
48402      $('.panel-login .step_forgot').show();
48403    }
48404  });
48405
48406  $('.field.link_to div.opt2').hide();
48407  $('body').on('click','.field.link_to a.opt2',function(){
48408    $('.field.link_to div.opt1').hide();
48409    $('.field.link_to div.opt2').show();
48410    $('.field.link_to a').removeClass('active');
48411    $(this).addClass('active');
48412  });
48413  $('body').on('click','.field.link_to a.opt1',function(){
48414    $('.field.link_to div.opt2').hide();
48415    $('.field.link_to div.opt1').show();
48416    $('.field.link_to a').removeClass('active');
48417    $(this).addClass('active');
48418  });
48419
48420});
48421
48422
48423// ====================
48424// = Full Screen BG's =
48425// ====================
48426
48427jQuery.fn.full_screen_bg = function(url,gravity,slideshow,link_url, rate) {
48428  var $container = $(this);
48429  if (!gravity) { gravity = "c"; }
48430
48431  if ( $('#fsbg').length == 0 ) {
48432    var $bg_wrapper = $('<div/>',{
48433      "id" : "fsbg",
48434      "class" : "media full_screen_bg"
48435    });
48436  } else {
48437    var $bg_wrapper = $('#fsbg');	
48438  }
48439
48440  $container.prepend($bg_wrapper);
48441
48442  var img = new Image();
48443  $(img).load(function() {
48444    $(this).hide();
48445    $bg_wrapper.append(this);
48446    $(this).addClass(gravity);
48447    if ( link_url ) {
48448      $(this).click(function(){
48449        window.location = link_url;
48450      });
48451      $(this).css('cursor','pointer');
48452    }
48453    // positionBackground();
48454    if ( slideshow ) {
48455      if ( !$bg_wrapper.data('tsSlideshow') ) {
48456        if (!rate) { rate = 3 }
48457        $bg_wrapper.tsSlideshow({ rate: parseInt(rate) * 1000 } );
48458      }
48459    } else {
48460      $(this).fadeIn(600,function(){
48461        if (typeof firstVisit == 'function') {
48462          firstVisit();					
48463        }
48464      });
48465    }		
48466  }).attr('src', url);
48467
48468};
48469
48470function pause_full_screen_bg() {
48471  if ( $('#fsbg').data('tsSlideshow') ) {
48472    $('#fsbg').tsSlideshow('stop');
48473  }
48474}
48475
48476function resume_full_screen_bg() {
48477  if ( $('#fsbg').data('tsSlideshow') ) {
48478    $('#fsbg').tsSlideshow('start');
48479  }
48480}
48481
48482function loadBackgrounds(editMode) {
48483  if (editMode ==  true) {
48484    var noCache = '?'+new Date().getTime();
48485  } else {
48486    var noCache = '';
48487  }
48488}
48489
48490function loadSidebarBanners(editMode) {
48491  if (editMode ==  true) {
48492    var noCache = '?'+new Date().getTime();
48493  } else {
48494    var noCache = '';
48495  }
48496}
48497
48498function positionBackground() {	
48499  if ($('#fsbg img').length > 0) {
48500    var bg_height = $('#fsbg img').first().height();
48501    if ( bg_height > 1000 ) {
48502      $('#site_container img.e, #site_container img.c, #site_container img.w').css('margin-top', "-" + (bg_height/2) + "px");
48503    }
48504  }
48505}
48506
48507$(document).ready(function(){
48508
48509  loadBackgrounds();
48510
48511  // this may or may not be needed...
48512  $(window).resize(function() {
48513    positionBackground();
48514  });
48515  positionBackground();
48516
48517  //$('#site_wide_alert').slideDown();
48518});
48519
48520// ===============
48521// = Grid Panels =
48522// ===============
48523
48524function closeGrid() {
48525  $('body').removeClass("panel_open");
48526  $('#nav li').removeClass('active');
48527  $('.panel').fadeOut(400);
48528  $('#pullout').animate({
48529    left: '-762px'
48530  }, 400, function(){
48531    $(this).removeClass("open");
48532    $(this).find('.media .slideshow').cycle('pause');
48533    resume_full_screen_bg();
48534  });
48535}
48536
48537function openGrid(panel_id) {
48538	if (!panel_id) { return false; } 
48539  if (panel_id.match(/itinerary/)) {
48540    return false;
48541  }
48542  try {
48543    if ( $('#pullout #'+panel_id).length > 0 ) {
48544      $('body').addClass("panel_open");
48545      $('.panel').fadeOut(400);
48546      $('#nav li').removeClass('active');
48547      $('#nav a[href="#'+panel_id+'"]').closest('li').addClass('active');
48548      $('#pullout').not('.open').animate({
48549        left: '236px'
48550      }, 400, function() {
48551        $(this).addClass("open");
48552      });
48553      $('#pullout #'+panel_id).fadeIn(400, function(){
48554        $(this).find('div.img').lazyLoadImages();
48555        $(this).find('.media .slideshow').cycle('resume');
48556        pause_full_screen_bg();
48557      });
48558      
48559      //_gaq.push(['_trackEvent', 'Grids', panel_id]);
48560      if (typeof ga !== 'undefined')
48561        ga('send', 'event', panel_id, 'click', 'grid panels');
48562    }    
48563  } catch (e) {
48564    console.log('Failed to open grid', e);
48565  }
48566
48567}
48568
48569$(document).ready(function(){
48570
48571  // pause all cycle slideshows
48572  if($('#pullout .media .slideshow').length > 0)
48573    $('#pullout .media .slideshow').cycle('pause');
48574
48575  // Main Nav Links: Open panel or follow href
48576  $(document).on('click', '#nav.main-nav li a, a.open_grid, #pullout li a.cell_link', function(e) {
48577    var href = $(this).attr('href');
48578    if (href && href.match(/^#/)) {
48579      // close if active
48580      if ( $(this).closest('li').hasClass('active') && $('#pullout').is('.o
48580pen') ) {
48581        closeGrid();
48582      } else {	
48583        // open pullout and show panel		
48584        panel_id = href.replace(/^#/,"").replace(/\//, "");
48585          openGrid(panel_id);
48586        if (typeof _gaq == 'object') {
48587          _gaq.push(['_trackPageview', href]);
48588        }
48589      }
48590      // return false;
48591    }
48592    if ( $('#pullout.edit-mode').length == 0 ) {
48593      window.location = href;
48594    }
48595    return false;
48596  });
48597
48598  // Close Panel Button
48599  $(document).on('click', '.panel a.close_panel', function(event) {
48600    closeGrid();
48601  });
48602
48603  // if url includes hash, open grid
48604  var current_hash = location.hash.replace(/\?.*$/, '');
48605  if (current_hash.length > 0) {
48606    grid = current_hash.replace(/^#/,"");
48607    grid = grid.replace(/\//,"");
48608    openGrid(grid);
48609  }
48610
48611  // // toggle grids: hide grid menu links & create toggle button
48612
48613  $('#nav a:contains("|")').each(function(){ 
48614    $(this).hide();
48615    var labels = $(this).text().split("|");
48616    var ids = [];
48617    $('#nav a:contains('+labels[0]+')').each(function(){
48618      ids.push($(this).attr('href'));
48619    });
48620    $('#nav a:contains('+labels[0]+')').each(function(){
48621      var cur = $(this).attr('href');
48622      var list = $('<ul/>',{
48623        "class" : "toggle"
48624      });
48625      for (var i=1; i<labels.length; i++) {
48626        var list_item = $('<li/>',{
48627          "class": "t"+i
48628        });
48629        var link = $('<a/>',{
48630          href : ids[i-1],
48631          text : labels[i],
48632          click : function(){
48633            openGrid( $(this).attr('href').replace(/^#/,"") );
48634          }
48635        });
48636        list_item.append(link);
48637        list_item.appendTo(list);
48638      }
48639      $(cur+' .title').append(list);
48640    });
48641  });
48642
48643  // ===================
48644  // = end grid panels =
48645  // ===================	
48646
48647
48648  // ====================================
48649  // = ecom category page tag filtering =
48650  // ====================================
48651  $('#filter_by_tag a.filter_by').click(function(){
48652    var tag = $(this).data('tag');
48653    var rxp = new RegExp(tag)
48654
48655
48656    $('#category-list li').each(function(){    
48657      $(this).data('tags').match(rxp) ?	$(this).show() : $(this).hide();			
48658    });
48659
48660    $('#filter_by_tag a.filter_by').removeClass("active");
48661    $(this).addClass("active");
48662    return false;
48663  });
48664
48665
48666
48667  // other stuff. should be moved somewhere more logical
48668
48669
48670  $('.dropdowns div').hide();
48671  $('.dropdowns a').click(function() {
48672
48673    var href = $(this).attr('href');
48674    //$('.dropdowns .terms').slideToggle();
48675
48676    if (href.match(/^#/)) {
48677
48678      href = href.replace(/^#/,"");
48679      $('.dropdowns a').removeClass('active');
48680      $(this).addClass('active');
48681
48682      $('.dropdowns div.'+href).slideToggle();
48683      return false;
48684
48685    }
48686  });
48687
48688  // Share Tab on Pages
48689  $('#main li.share a').click(function(){
48690    if ( $('#share_box').hasClass("visible") ) {
48691      $('#share_box').slideUp().removeClass("visible");
48692      $(this).removeClass("active");
48693    } else {
48694      if ( $('#share_box').length == 0 ) {
48695        
48696        var addthis_buttons = $('<!-- AddThis Button BEGIN --> \
48697        <div class="addthis_toolbox addthis_default_style addthis_32x32_style"> \
48698        <a class="addthis_button_facebook"></a> \
48699        <a class="addthis_button_twitter"></a> \
48700        <a class="addthis_button_pinterest_share"></a> \
48701        <a class="addthis_button_google_plusone_share"></a> \
48702        <a class="addthis_button_compact"></a><a class="addthis_counter addthis_bubble_style"></a> \
48703        </div> \
48704        <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-536803930156f630"></script> \
48705        <!-- AddThis Button END -->');
48706        var addthis = $('<li class="addthis"/>').append(addthis_buttons);
48707
48708        var pdf_button = $('<a/>', {
48709          "href" : window.location+".pdf",
48710          "text" : "Download a PDF of this page."
48711        });
48712        var pdf = $('<li class="pdf"/>').append(pdf_button);
48713
48714        var share_button = $('<ul/>',{
48715          "id" : "share_box",
48716          "class" : "share_box"
48717        }).hide().append(addthis,pdf).insertAfter($(this));
48718
48719        // position off left or right side of link
48720        var offset = $(this).position();
48721        if (offset.left < (422 - 109)) {
48722          share_button.css({
48723            left: offset.left
48724          });
48725        } else {
48726          share_button.css({
48727            left: offset.left - 422 + 109
48728          });
48729        }
48730
48731      }
48732      $('#share_box').slideDown().addClass("visible");
48733      $(this).addClass("active");
48734    }
48735    return false;
48736  });
48737
48738  $('#main .menubar li.active').click(function(e){
48739    e.preventDefault();
48740    var tabs = $('#main .menubar li:not(.active)');
48741    if ($(this).hasClass('open')) {
48742      tabs.slideUp();
48743      $(this).removeClass('open');
48744    } else {
48745      tabs.slideDown();
48746      $(this).addClass('open');
48747    }
48748  });
48749
48750  // Footer Widgets	
48751  $('#widget_triggers').tsWidgets();
48752
48753  // Grind Time Lazy Load
48754  $('#footer a.grind:not(.snowshoe-grind) span.grind_time').load('/grind_stats/widget?top_time=true');
48755  $('#widget_grind .live_times').load('/grind_stats/widget');
48756
48757  // Footer News Rotation
48758  if($('#js-news-rotate').length > 0)
48759    $('#js-news-rotate').cycle({
48760      containerResize: 0,
48761      slideResize: 0
48762    });
48763
48764  // ====================
48765  // = Placeholder Text =
48766  // ====================
48767
48768  // store default values
48769  $('.placeholder').each(function(){
48770    $(this).data('placeholder', $(this).val());
48771  });
48772
48773  // remove placeholder on focus
48774  $('.placeholder').focus(function(){
48775    if ($(this).val() == $(this).data('placeholder') ) {
48776      $(this).val("");
48777    }
48778  });
48779
48780  // restore placeholder on blur
48781  $('.placeholder').blur(function(){
48782    if ($(this).val() == "" ) {
48783      $(this).val( $(this).data('placeholder') );
48784    }
48785  });
48786
48787});
48788
48789// ======================================
48790// = other dev code that needs clean up =
48791// ======================================
48792
48793$(document).ready(function(){
48794
48795  // checkout login - forgot password
48796  $(document).on('click', '#login_signup a.forgot_password', function(){
48797    $(this).closest('form').slideUp();
48798    $('#login_signup .step_forgot').slideDown();
48799    return false;
48800  });
48801  $(document).on('click', '#login_signup a.show_login', function(){
48802    $('#login_signup .step_forgot').slideUp();
48803    $('form#user_login').slideDown();
48804    return false;
48805  });
48806
48807  $("#pullout .panel li a").hover(
48808    function () {
48809    $(this).find("div.grid_caption").animate({
48810      bottom: '-5px'
48811    }, 200, function() {
48812      // Animation complete.
48813    });
48814  }, 
48815  function () {
48816    $(this).find("div.grid_caption").animate({
48817      bottom: '-56px'
48818    }, 100, function() {
48819      // Animation complete.
48820    });
48821  }
48822  );
48823
48824
48825
48826  /* ADMINISTRATIVE JS BELOW -- TO BE MOVED TO APP-ADMIN.JS */
48827
48828
48829
48830  $('.gallery .slide_nav a').hide();
48831
48832  $('.gallery .slide_contain').hover(
48833    function () {
48834    $('.gallery .slide_nav a').fadeIn(500);
48835  }, 
48836  function () {
48837    $('.gallery .slide_nav a').fadeOut(300);
48838  }
48839  );
48840
48841
48842  $('.datetimepicker').livequery(function(){		
48843    $(this).datetimepicker({
48844      ampm: true,
48845      dateFormat: 'yy-mm-dd'
48846    });
48847  });
48848  $('.datepicker').livequery(function(){		
48849    $(this).datepicker({
48850      dateFormat: 'yy-mm-dd'
48851    });
48852  });
48853
48854});
48855
48856// ============================
48857// = TopNav AJAX =
48858// ============================
48859$(document).ready(function() {
48860
48861  // TOGGLE TRANSACTIONS IN MY ACCOUNT
48862  $(document).on('click', '.transaction h4', function(){
48863    if ($(this).closest('#offline_sales').length > 0 && !$(this).data('loaded')) {
48864      var self = $(this);
48865      self.siblings('ul').addClass('loading');
48866      $.ajax({
48867        url: self.data('summary'),
48868        type: 'get',
48869        dataType: 'json',
48870        success: function(data) {
48871          self.data('loaded', true);
48872          self.siblings('ul').replaceWith($(data.html));
48873          self.siblings('ul').show();
48874        },
48875        error: function() {
48876        }
48877      });
48878    }
48879    $(this).siblings('ul').slideToggle();
48880    $(this).toggleClass('open');	
48881    return false;
48882  });
48883
48884  // SHOW PASSWORD FORM IN ACCOUNT EDIT MODE
48885  $('form.change_password').hide();
48886  $('h3 a.change').click(function(){
48887    $(this).parent('h3').siblings('form.change_password').slideToggle();
48888    return false;	
48889  });
48890
48891  // SHOW/HIDE FOR ACCOUNT LOGIN PANEL
48892  $('.panel-login a.show_new_account').click(function(){
48893    $('.panel-login .step1').hide();
48894    $('.panel-login .step2').show();
48895    $('.panel-login .step_forgot').hide();
48896  });
48897
48898  // SHOW/HIDE FOR ACCOUNT LOGIN PANEL
48899  $('.panel-login .step2').hide();
48900  $('.panel-login .step3').hide();
48901  $('.panel-login .step1 a.btn').click(function(){
48902    $('.panel-login .step1').fadeOut(200);
48903    $('.panel-login .step2').delay(200).fadeIn(200);
48904  });
48905
48906  $('.panel-login .step2 a.btn').click(function(){
48907    $('.panel-login .step2').fadeOut(200);
48908    $('.panel-login .step3').delay(200).fadeIn(200);
48909  });
48910
48911  $('.acct_options li a, a.show_login').click(function(){
48912    $('.panel-login .step1').show();
48913    $('.panel-login .step2').hide();
48914    $('.panel-login .step3').hide();
48915    $('.panel-login .step_forgot').hide();
48916  });
48917
48918  $('.panel-login a.forgot').click(function(){
48919    // $('.panel-login .step1').hide();
48920    // $('.panel-login .step_forgot').show();
48921  });
48922
48923  // $('.panel-login .step_forgot form button').click(function(){
48924  //   $('.panel-login .enter_pass').hide();
48925  //   $('.panel-login .msg_success').show();
48926  // });
48927
48928  // $('.panel-balance .step1 form button').click(function(){
48929  //  $('.panel-balance .step1').fadeOut(200);
48930  //  $('.panel-balance .step2').delay(250).fadeIn(200);
48931  // });
48932
48933  $('.ccv_btn').click(function(){
48934    $('#ccv').slideToggle();
48935    return false;
48936  });
48937  $('#ccv a.close').click(function(){
48938    $('#ccv').slideUp();
48939    return false;	
48940  });
48941  $('#cc_cvv').keydown(function(){
48942    $('#ccv').slideUp();
48943  });
48944
48945  //REVEAL FORM TO CONNECT NEW PASS IN MY ACCOUNT
48946  // $('.passes a.add').click(function(e){
48947  //    e.preventDefault();
48948  //    $('.passes form.connect_pass').slideDown();
48949  //    // $('.passes p.description').hide();
48950  //    return false;
48951  // });
48952
48953  $('.acct_options li a').hover(function(){
48954    $(this).find('span.hover').css('display','block');
48955    $(this).find('span.hover').delay(220).animate({
48956      top: 32,
48957      opacity: 100
48958    }, 300 );
48959  }, function(){
48960    $(this).find('span.hover').animate({
48961      top: 28,
48962      opacity: 0
48963    }, 300 );
48964    $(this).find('span.hover').css('display','none');
48965  });
48966
48967  // MOUNTAIN MAP POPUP NAVIGATION
48968  $('.points li a.dot').click(function(){
48969    $('.popup').fadeOut(400);
48970    $('.popup').css('z-index','1');
48971    $('#mm_legend li a').removeClass('active');
48972    $(this).siblings('.popup').fadeIn(400);
48973
48974    $('#mm_view .points li').css('z-index','5');
48975    $(this).parent('li').css('z-index','10');
48976
48977    $('#mm_view .points li .popup').css('z-index','10');
48978    $(this).siblings('.popup').css('z-index','20');
48979
48980    return false;	
48981  });
48982
48983  $('#points li a.dot').click(function(){
48984
48985    $('.popup').fadeOut(400);
48986    $('.popup').css('z-index','1');
48987    $('#mm_legend li a').removeClass('active');
48988    $(this).siblings('.popup').fadeIn(400);
48989
48990    $('#mm_view #points li').css('z-index','5');
48991    $(this).parent('li').css('z-index','10');
48992
48993    $('#mm_view #points li .popup').css('z-index','10');
48994    $(this).siblings('.popup').css('z-index','20');
48995
48996    return false;	
48997  });
48998
48999  $('#mm_legend li a').click(function() {
49000    var href = $(this).attr('href');
49001    href = href.replace(/^#/,"");
49002    $('#mm_legend li a').removeClass('active');
49003    $(this).addClass('active');
49004    $('.popup').fadeOut(400);
49005    $('.popup').css('z-index','1');
49006    $('#mm_view #points #'+href+' .popup').fadeIn(400);
49007    $('#mm_view #points li').css('z-index','5');
49008    $('#mm_view #points #'+href).css('z-index','10');
49009    $('#mm_view #points li .popup').css('z-index','10');
49010    $('#mm_view #points #'+href+' .popup').css('z-index','20');
49011    return false;
49012  });
49013
49014  $('.mountain_map img.view').click(function() {
49015    $('.popup').fadeOut(400);
49016  });
49017
49018  $('.conditions_tabs ul.tabs a').click(function(){
49019    $('.tab_container .tab').fadeOut(300);
49020    $('.conditions_tabs ul.tabs a').removeClass('active');
49021    $(this).addClass('active');
49022    var href = $(this).attr('href');
49023    href = href.replace(/^#/,"");
49024    $('.tab_container #'+href).delay(350).fadeIn(400);
49025    return true;
49026  });
49027
49028  if($("#main.current_conditions .cycle").length > 0)
49029    $("#main.current_conditions .cycle").cycle();
49030
49031  // $('.tab_container tr:even').addClass('odd');
49032  $('.now a.view').click(function(){
49033    $('.tab_container .tab').fadeOut(300);
49034    $('.tab_container #forecast').delay(350).fadeIn(400);
49035    $('.conditions_tabs ul.tabs a').removeClass('active');
49036    $('ul.tabs a[href=#forecast]').addClass('active');
49037    return false;	
49038  });
49039
49040  // Current Conditions Metric/Imperial Toggle
49041  $('#units_toggle .show_metric a').click(function(){
49042    $('#main.current_conditions .imperial, .feature-block--snow-report .imperial').fadeOut(500, function(){
49043      $('#main.current_conditions .metric, .feature-block--snow-report .metric').fadeIn(500);
49044    });
49045    $('#units_toggle li').removeClass('active');
49046    $(this).parent().addClass('active');
49047    return false;
49048  });
49049  $('#units_toggle .show_imperial a').click(function(){
49050    $('#main.current_conditions .metric, .feature-block--snow-report .metric').fadeOut(500, function(){
49051      $('#main.current_conditions .imperial, .feature-block--snow-report .imperial').fadeIn(500);
49052    });
49053    $('#units_toggle li').removeClass('active');
49054    $(this).parent().addClass('active');
49055    return false;
49056  });
49057  
49058  // Current conditions modal livecam/gallery toggle
49059  // $('.visual_toggle a').on("click", function(){
49060  //   if ($(this).parent().hasClass('active')) {
49061  //     $("#visual-modal").modal('show');      
49062  //   } else {
49063  //     var target = $(this).data('target');
49064  //     var that = $(this).attr('href');    
49065
49066  //     $('.visuals > div').fadeOut(300);
49067  //     $('.visuals .'+target).delay(301).fadeIn(300);
49068  //     $('.visual_toggle li').removeClass('active');
49069  //     $('.visual_toggle li.'+target).addClass('active');
49070  //   }
49071  //   return false;    
49072  // });
49073  
49074  $("#livecam_btn").on("click", function(){
49075    $("#livecam_holder").html('<iframe src="/grouse_livecam_html.html" width="640" height="480" alt="" seamless></iframe>');
49076  });
49077
49078  // $("#livecam_btn").click(function(){
49079  //   $('.visuals > div').fadeOut(300);
49080  //   $('.visuals .livecam').delay(301).fadeIn(300);
49081  //   $('.visual_toggle li').removeClass('active');
49082  //   $('.visual_toggle li.livecam').addClass('active');
49083  // });
49084  // $("#recent-gallery").click(function(){
49085  //   $('.visuals > div').fadeOut(300);
49086  //   $('.visuals .recent-gallery').delay(301).fadeIn(300);
49087  //   $('.visual_toggle li').removeClass('active');
49088  //   $('.visual_toggle li.recent-gallery').addClass('active');
49089  // });
49090  
49091  if($('#summer_events .attractions').length > 0)
49092    $('#summer_events .attractions').cycle({
49093      fx: 'scrollLeft', 
49094      timeout: 6400,
49095      speed: 800
49096    });
49097
49098  $('#season_toggle a').click(function(){
49099    $('#season_toggle li').toggleClass("active");
49100    $(".season_toggle").toggle("slow");
49101    // if ( $(this).attr('href') == "#snow" ) {
49102    //   $('#summer_events .attractions').cycle('pause');
49103    // } else {
49104    //   $('#summer_events .attractions').cycle('resume');
49105    // }
49106    return false;
49107  });
49108
49109
49110  // lazy load mini cart
49111  $('#nav li.n_cart_trigger a').bind('click',function(){
49112    if (!$.trim( $('#cart_preview').html() ).length) {
49113      $('#cart_preview').load('/cart/mini_cart');
49114    }
49115  });
49116
49117});
49118
49119// mini cart badge
49120function updateMiniCartBadge() {
49121  $.getJSON('/cart/mini_cart_badge', function(data) {
49122    $("#mini_cart_badge").text(data.count)
49123  });
49124}
49125
49126// ====================================
49127// = Custom global validation methods =
49128// ====================================
49129
49130// Add method to validate phone number
49131jQuery.validator.addMethod("phoneno", function(phone_number, element) {
49132    phone_number = phone_number.replace(/\s+/g, "");
49133    return this.optional(element) || phone_number.length > 9 && phone_number.length < 16
49134    phone_number.match(/^((\+[1-9]{1,4}[ \-]*)|(\([0-9]{2,3}\)[ \-]*)|([0-9]{2,4})[ \-]*)*?[0-9]{3,4}?[ \-]*[0-9]{3,4}?$/);
49135}, "Please specify a valid phone number");
49136
49137
49138// ==========================
49139// = Photo form item helper =
49140// ==========================
49141
49142$(document).ready(function(){
49143
49144  function readPhotoURL(input) {
49145      if (input.files && input.files[0]) {
49146          var reader = new FileReader();
49147
49148          reader.onload = function (e) {
49149              $(input).siblings('.form-item--photo-preview').find('img').attr('src', e.target.result);
49150          }
49151
49152          reader.readAsDataURL(input.files[0]);
49153
49154          $(input).siblings('input').val('');
49155      }
49156  }
49157
49158  $('.form-item--photo-upload input').change(function(){
49159    readPhotoURL(this);
49160  }); 
49161
49162});
49163
49164
49165$(document).on('click', '.collapsible-form-item', function() {
49166  $(this).siblings('.collapsible-form-item--form').slideToggle();
49167  $(this).find('i').toggleClass('icon-plus icon-minus');
49168});
49169
49170
49171// ==========================
49172// = Responsive image maps =
49173// ==========================
49174$(document).ready(function(){
49175  $('map').imageMapResize();
49176});
49177
49178// ==========================
49179// = Collapsible menubar on mobile=
49180// ==========================
49181$(document).ready(function() {
49182  if ($(window).width() < 720) {
49183    $('ul.menubar').addClass('collapsible');
49184  }
49185});
49186
49187
49188// ==========================
49189// = Helper =
49190// ==========================
49191function urlHasParam(name){
49192    var results = new RegExp('[\?&]' + name + '([^]*)').exec(window.location.href);
49193    if (results==null){
49194       return false;
49195    }
49196    else{
49197      return true;
49198    }
49199}
49200
49201function getFormattedDate(date) {
49202    let year = date.getFullYear();
49203    let month = (1 + date.getMonth()).toString().padStart(2, '0');
49204    let day = date.getDate().toString().padStart(2, '0');
49205  
49206    return year + '-' + month + '-' + day;
49207}
49208
49209function activityDateAvailable(date, start, end, days, blackouts) {
49210  var formatted_date = getFormattedDate(date);
49211  var show = true;
49212
49213  if (start !== '') 
49214    show = formatted_date >= start
49215
49216  if (show && end !== '')
49217    show = formatted_date <= end
49218
49219  if (show && days && days !== ''){
49220    show = $.inArray(date.getDay().toString(), days.toString().split(',')) !== -1;
49221  }
49222
49223  if (show && blackouts && blackouts.length > 0) {
49224    
49225    for (var i = 0; i < blackouts.length; ++i) {
49226      if (blackouts[i][0] <= formatted_date && blackouts[i][1] >= formatted_date) {
49227        show = false;
49228        break;
49229      }
49230    }
49231  }
49232
49233  return show;
49234}
49235
49236
49237// ==========================
49238// = IE 11 Compatibility =
49239// ==========================
49240if (!String.prototype.padStart) {
49241  String.prototype.padStart = function padStart(targetLength,padString) {
49242    targetLength = targetLength>>0; //truncate if number or convert non-number to 0;
49243    padString = String((typeof padString !== 'undefined' ? padString : ' '));
49244    if (this.length > targetLength) {
49245      return String(this);
49246    }
49247    else {
49248      targetLength = targetLength-this.length;
49249      if (targetLength > padString.length) {
49250        padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
49251      }
49252      return padString.slice(0,targetLength) + String(this);
49253    }
49254  };
49255}
49256
49257
49258
49259
49260
49261
49262;
49263// ======================
49264// = Mobile Menu Toggle =
49265// ======================
49266
49267$(document).ready(function() {
49268
49269  $('.js-menu-main-toggle').on('click', function() {
49270    $(this).toggleClass('js-menu-main-toggle-active');
49271    $(this).toggleClass('menu--main__toggle--active');
49272    $('.layout-container-inner, .menu--main').toggleClass('menu--active');
49273  });
49274
49275  $('.layout-container-inner.menu--active').on('click', function() {
49276      $('.menu--main__toggle').removeClass('js-menu-main-toggle-active');
49277      $('.menu--main__toggle').removeClass('menu--main__toggle--active');
49278      $('.layout-container-inner, .menu--main').removeClass('menu--active');
49279  });
49280
49281});
49282
49283// ======================
49284// = Sticky Menu Header =
49285// ======================
49286
49287$(window).bind('scroll', function () {
49288  if ($(window).scrollTop() > ($(window).height() / 2.5) && $('#header:not(.scrolling)')) {
49289    $('#header, .layout-container').addClass('scrolling');
49290  } else {
49291    $('#header, .layout-container').removeClass('scrolling');
49292  }
49293});
49294
49295// =================
49296// = Mega Sub Menu =
49297// =================
49298
49299$(document).ready(function() {
49300
49301  if ($(window).width() > 1069) {
49302
49303    $('.menu-level-1 > li').on('mouseover', function() {
49304      $(this).find('.menu-level-2').addClass('menu-level-2--active');
49305    });
49306    $('.menu-level-1 > li').on('mouseout', function() {
49307      $(this).find('.menu-level-2').removeClass('menu-level-2--active');
49308    });
49309    $('.menu--secondary-level-1 > li').on('mouseover', function() {
49310      $(this).find('.menu--secondary-level-2').addClass('menu--secondary-level-2--active');
49311    });
49312    $('.menu--secondary-level-1 > li').on('mouseout', function() {
49313      $(this).find('.menu--secondary-level-2').removeClass('menu--secondary-level-2--active');
49314    });
49315
49316
49317  } else {
49318
49319    $('.js-menu-item-toggle').on('click', function(event) {
49320      $(this).toggleClass('js-menu-toggle-active');
49321      $(this).toggleClass('menu__button-toggle--active');
49322      $(this).parents('li').toggleClass('js-menu-toggle-active').find('.menu-level-2').slideToggle('fast');
49323    });
49324
49325  }
49326
49327});
49328
49329// ===============
49330// = Menu Search =
49331// ===============
49332
49333$(document).ready(function() {
49334
49335  $('.js-menu-search').on('click', function() {
49336    if ($(this).hasClass('js-menu-search-active')) {
49337      $(this).removeClass('js-menu-search-active');
49338      $('.menu-search').removeClass('menu-search--active');
49339    } else {
49340      $(this).addClass('js-menu-search-active');
49341      $('.menu-search').addClass('menu-search--active');
49342    }
49343  });
49344  $('.js-menu-search-close').on('click', function() {
49345    $('.js-menu-search').removeClass('js-menu-search-active');
49346    $('.menu-search').removeClass('menu-search--active');
49347  });
49348
49349});
49350
49351// =====================
49352// = Menu Active State =
49353// =====================
49354
49355$(document).ready(function(){
49356  $('nav a[href="' + location.pathname + '"]').addClass('active');
49357});
49358
49359// =======================
49360// = In page link scroll =
49361// =======================
49362
49363$(document).ready(function(){
49364  // $('a[href^="' + window.location.pathname + '#"]').on('click', function(event) {
49365  //   var target = $(this.getAttribute('href'));
49366  //   if(target.length) {
49367  //     event.preventDefault();
49368  //     var targetOffset = target.offset().top;
49369  //     $('html, body').stop().animate({
49370  //         scrollTop: targetOffset - 80
49371  //     }, 800);
49372  //   }
49373  // });
49374        //$('html, body').hide();
49375
49376        // if (window.location.hash) {
49377        //     setTimeout(function() {
49378        //         $('html, body').scrollTop().show();
49379        //         $('html, body').animate({
49380        //             scrollTop: $(window.location.hash).offset().top
49381        //             }, 1000)
49382        //     }, 0);
49383        // }
49384        // else {
49385        //     $('html, body').show();
49386        // }
49387
49388  function getUrlVars() {
49389    var vars = [], hash;
49390    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
49391    for(var i = 0; i < hashes.length; i++) {
49392      hash = hashes[i].split('=');
49393      vars.push(hash[0]);
49394      vars[hash[0]] = hash[1];
49395    }
49396    return vars;
49397  }
49398
49399  var hash = window.location.hash;
49400
49401  if (hash) {
49402
49403    var hashOnly = hash.split('?')[0];
49404
49405    setTimeout(function() {
49406      try {
49407        $('html, body').animate({
49408          scrollTop: $(hashOnly).offset().top - 135
49409          }, 1000)
49410      } catch (e) {
49411        console.log('Failed to trigger ScrollTop', e);
49412      }
49413    }, 500);
49414
49415    // Active targeted tab
49416    if (hash.indexOf("?tab") >= 0) {
49417      var tab = getUrlVars()["tab"];
49418      $(".tab_container").find(".tab").hide();
49419      $(".tab_container").find(".tab"+ '#' + tab).show();
49420      $("ul.tabs").find('li a.active').removeClass("active");
49421      $("ul.tabs").find('li a[href$="' + '#' + tab + '"]').addClass("active");
49422    }
49423
49424  }
49425
49426});
49427
49428
49429$(document).ready(function(){
49430  if($('#plan_your_day_quiz').length) {
49431
49432    // setup the navigation
49433    $('.quiz_question').first().show();
49434    $('.submit_quiz').last().show();
49435    $('a.next_question').last().hide();
49436
49437    // move to the next section
49438    $('a.next_question').click(function(e) {
49439      e.preventDefault();
49440      var this_question = $(this).closest('.quiz_question')
49441      if (this_question.find('input:checked').length) {
49442        var current_index = this_question.attr('id').replace("quiz_question_","");
49443        this_question.hide();
49444        $('#quiz_question_' + (parseInt(current_index) + 1)).show();
49445      }
49446    });
49447  } 
49448});
49449/* Simple JavaScript Inheritance
49450 * By John Resig http://ejohn.org/
49451 * MIT Licensed.
49452 */
49453// Inspired by base2 and Prototype
49454(function(){
49455	var initializing = false;
49456
49457	// The base JQClass implementation (does nothing)
49458	window.JQClass = function(){};
49459
49460	// Collection of derived classes
49461	JQClass.classes = {};
49462 
49463	// Create a new JQClass that inherits from this class
49464	JQClass.extend = function extender(prop) {
49465		var base = this.prototype;
49466
49467		// Instantiate a base class (but only create the instance,
49468		// don't run the init constructor)
49469		initializing = true;
49470		var prototype = new this();
49471		initializing = false;
49472
49473		// Copy the properties over onto the new prototype
49474		for (var name in prop) {
49475			// Check if we're overwriting an existing function
49476			prototype[name] = typeof prop[name] == 'function' &&
49477				typeof base[name] == 'function' ?
49478				(function(name, fn){
49479					return function() {
49480						var __super = this._super;
49481
49482						// Add a new ._super() method that is the same method
49483						// but on the super-class
49484						this._super = function(args) {
49485							return base[name].apply(this, args || []);
49486						};
49487
49488						var ret = fn.apply(this, arguments);				
49489
49490						// The method only need to be bound temporarily, so we
49491						// remove it when we're done executing
49492						this._super = __super;
49493
49494						return ret;
49495					};
49496				})(name, prop[name]) :
49497				prop[name];
49498		}
49499
49500		// The dummy class constructor
49501		function JQClass() {
49502			// All construction is actually done in the init method
49503			if (!initializing && this._init) {
49504				this._init.apply(this, arguments);
49505			}
49506		}
49507
49508		// Populate our constructed prototype object
49509		JQClass.prototype = prototype;
49510
49511		// Enforce the constructor to be what we expect
49512		JQClass.prototype.constructor = JQClass;
49513
49514		// And make this class extendable
49515		JQClass.extend = extender;
49516
49517		return JQClass;
49518	};
49519})();
49520
49521(function($) { // Ensure $, encapsulate
49522
49523	/** Abstract base class for collection plugins v1.0.1.
49524		Written by Keith Wood (kbwood{at}iinet.com.au) December 2013.
49525		Licensed under the MIT (http://keith-wood.name/licence.html) license.
49526		@module $.JQPlugin
49527		@abstract */
49528	JQClass.classes.JQPlugin = JQClass.extend({
49529
49530		/** Name to identify this plugin.
49531			@example name: 'tabs' */
49532		name: 'plugin',
49533
49534		/** Default options for instances of this plugin (default: {}).
49535			@example defaultOptions: {
49536 	selectedClass: 'selected',
49537 	triggers: 'click'
49538 } */
49539		defaultOptions: {},
49540		
49541		/** Options dependent on the locale.
49542			Indexed by language and (optional) country code, with '' denoting the default language (English/US).
49543			@example regionalOptions: {
49544	'': {
49545		greeting: 'Hi'
49546	}
49547 } */
49548		regionalOptions: {},
49549		
49550		/** Names of getter methods - those that can't be chained (default: []).
49551			@example _getters: ['activeTab'] */
49552		_getters: [],
49553
49554		/** Retrieve a marker class for affected elements.
49555			@private
49556			@return {string} The marker class. */
49557		_getMarker: function() {
49558			return 'is-' + this.name;
49559		},
49560		
49561		/** Initialise the plugin.
49562			Create the jQuery bridge - plugin name <code>xyz</code>
49563			produces <code>$.xyz</code> and <code>$.fn.xyz</code>. */
49564		_init: function() {
49565			// Apply default localisations
49566			$.extend(this.defaultOptions, (this.regionalOptions && this.regionalOptions['']) || {});
49567			// Camel-case the name
49568			var jqName = camelCase(this.name);
49569			// Expose jQuery singleton manager
49570			$[jqName] = this;
49571			// Expose jQuery collection plugin
49572			$.fn[jqName] = function(options) {
49573				var otherArgs = Array.prototype.slice.call(arguments, 1);
49574				if ($[jqName]._isNotChained(options, otherArgs)) {
49575					return $[jqName][options].apply($[jqName], [this[0]].concat(otherArgs));
49576				}
49577				return this.each(function() {
49578					if (typeof options === 'string') {
49579						if (options[0] === '_' || !$[jqName][options]) {
49580							throw 'Unknown method: ' + options;
49581						}
49582						$[jqName][options].apply($[jqName], [this].concat(otherArgs));
49583					}
49584					else {
49585						$[jqName]._attach(this, options);
49586					}
49587				});
49588			};
49589		},
49590
49591		/** Set default values for all subsequent instances.
49592			@param options {object} The new default options.
49593			@example $.plugin.setDefauls({name: value}) */
49594		setDefaults: function(options) {
49595			$.extend(this.defaultOptions, options || {});
49596		},
49597		
49598		/** Determine whether a method is a getter and doesn't permit chaining.
49599			@private
49600			@param name {string}
49600 The method name.
49601			@param otherArgs {any[]} Any other arguments for the method.
49602			@return {boolean} True if this method is a getter, false otherwise. */
49603		_isNotChained: function(name, otherArgs) {
49604			if (name === 'option' && (otherArgs.length === 0 ||
49605					(otherArgs.length === 1 && typeof otherArgs[0] === 'string'))) {
49606				return true;
49607			}
49608			return $.inArray(name, this._getters) > -1;
49609		},
49610		
49611		/** Initialise an element. Called internally only.
49612			Adds an instance object as data named for the plugin.
49613			@param elem {Element} The element to enhance.
49614			@param options {object} Overriding settings. */
49615		_attach: function(elem, options) {
49616			elem = $(elem);
49617			if (elem.hasClass(this._getMarker())) {
49618				return;
49619			}
49620			elem.addClass(this._getMarker());
49621			options = $.extend({}, this.defaultOptions, this._getMetadata(elem), options || {});
49622			var inst = $.extend({name: this.name, elem: elem, options: options},
49623				this._instSettings(elem, options));
49624			elem.data(this.name, inst); // Save instance against element
49625			this._postAttach(elem, inst);
49626			this.option(elem, options);
49627		},
49628
49629		/** Retrieve additional instance settings.
49630			Override this in a sub-class to provide extra settings.
49631			@param elem {jQuery} The current jQuery element.
49632			@param options {object} The instance options.
49633			@return {object} Any extra instance values.
49634			@example _instSettings: function(elem, options) {
49635 	return {nav: elem.find(options.navSelector)};
49636 } */
49637		_instSettings: function(elem, options) {
49638			return {};
49639		},
49640
49641		/** Plugin specific post initialisation.
49642			Override this in a sub-class to perform extra activities.
49643			@param elem {jQuery} The current jQuery element.
49644			@param inst {object} The instance settings.
49645			@example _postAttach: function(elem, inst) {
49646 	elem.on('click.' + this.name, function() {
49647 		...
49648 	});
49649 } */
49650		_postAttach: function(elem, inst) {
49651		},
49652
49653		/** Retrieve metadata configuration from the element.
49654			Metadata is specified as an attribute:
49655			<code>data-&lt;plugin name>="&lt;setting name>: '&lt;value>', ..."</code>.
49656			Dates should be specified as strings in this format: 'new Date(y, m-1, d)'.
49657			@private
49658			@param elem {jQuery} The source element.
49659			@return {object} The inline configuration or {}. */
49660		_getMetadata: function(elem) {
49661			try {
49662				var data = elem.data(this.name.toLowerCase()) || '';
49663				data = data.replace(/'/g, '"');
49664				data = data.replace(/([a-zA-Z0-9]+):/g, function(match, group, i) { 
49665					var count = data.substring(0, i).match(/"/g); // Handle embedded ':'
49666					return (!count || count.length % 2 === 0 ? '"' + group + '":' : group + ':');
49667				});
49668				data = $.parseJSON('{' + data + '}');
49669				for (var name in data) { // Convert dates
49670					var value = data[name];
49671					if (typeof value === 'string' && value.match(/^new Date\((.*)\)$/)) {
49672						data[name] = eval(value);
49673					}
49674				}
49675				return data;
49676			}
49677			catch (e) {
49678				return {};
49679			}
49680		},
49681
49682		/** Retrieve the instance data for element.
49683			@param elem {Element} The source element.
49684			@return {object} The instance data or {}. */
49685		_getInst: function(elem) {
49686			return $(elem).data(this.name) || {};
49687		},
49688		
49689		/** Retrieve or reconfigure the settings for a plugin.
49690			@param elem {Element} The source element.
49691			@param name {object|string} The collection of new option values or the name of a single option.
49692			@param [value] {any} The value for a single named option.
49693			@return {any|object} If retrieving a single value or all options.
49694			@example $(selector).plugin('option', 'name', value)
49695 $(selector).plugin('option', {name: value, ...})
49696 var value = $(selector).plugin('option', 'name')
49697 var options = $(selector).plugin('option') */
49698		option: function(elem, name, value) {
49699			elem = $(elem);
49700			var inst = elem.data(this.name);
49701			if  (!name || (typeof name === 'string' && value == null)) {
49702				var options = (inst || {}).options;
49703				return (options && name ? options[name] : options);
49704			}
49705			if (!elem.hasClass(this._getMarker())) {
49706				return;
49707			}
49708			var options = name || {};
49709			if (typeof name === 'string') {
49710				options = {};
49711				options[name] = value;
49712			}
49713			this._optionsChanged(elem, inst, options);
49714			$.extend(inst.options, options);
49715		},
49716		
49717		/** Plugin specific options processing.
49718			Old value available in <code>inst.options[name]</code>, new value in <code>options[name]</code>.
49719			Override this in a sub-class to perform extra activities.
49720			@param elem {jQuery} The current jQuery element.
49721			@param inst {object} The instance settings.
49722			@param options {object} The new options.
49723			@example _optionsChanged: function(elem, inst, options) {
49724 	if (options.name != inst.options.name) {
49725 		elem.removeClass(inst.options.name).addClass(options.name);
49726 	}
49727 } */
49728		_optionsChanged: function(elem, inst, options) {
49729		},
49730		
49731		/** Remove all trace of the plugin.
49732			Override <code>_preDestroy</code> for plugin-specific processing.
49733			@param elem {Element} The source element.
49734			@example $(selector).plugin('destroy') */
49735		destroy: function(elem) {
49736			elem = $(elem);
49737			if (!elem.hasClass(this._getMarker())) {
49738				return;
49739			}
49740			this._preDestroy(elem, this._getInst(elem));
49741			elem.removeData(this.name).removeClass(this._getMarker());
49742		},
49743
49744		/** Plugin specific pre destruction.
49745			Override this in a sub-class to perform extra activities and undo everything that was
49746			done in the <code>_postAttach</code> or <code>_optionsChanged</code> functions.
49747			@param elem {jQuery} The current jQuery element.
49748			@param inst {object} The instance settings.
49749			@example _preDestroy: function(elem, inst) {
49750 	elem.off('.' + this.name);
49751 } */
49752		_preDestroy: function(elem, inst) {
49753		}
49754	});
49755	
49756	/** Convert names from hyphenated to camel-case.
49757		@private
49758		@param value {string} The original hyphenated name.
49759		@return {string} The camel-case version. */
49760	function camelCase(name) {
49761		return name.replace(/-([a-z])/g, function(match, group) {
49762			return group.toUpperCase();
49763		});
49764	}
49765	
49766	/** Expose the plugin base.
49767		@namespace "$.JQPlugin" */
49768	$.JQPlugin = {
49769	
49770		/** Create a new collection plugin.
49771			@memberof "$.JQPlugin"
49772			@param [superClass='JQPlugin'] {string} The name of the parent class to inherit from.
49773			@param overrides {object} The property/function overrides for the new class.
49774			@example $.JQPlugin.createPlugin({
49775 	name: 'tabs',
49776 	defaultOptions: {selectedClass: 'selected'},
49777 	_initSettings: function(elem, options) { return {...}; },
49778 	_postAttach: function(elem, inst) { ... }
49779 }); */
49780		createPlugin: function(superClass, overrides) {
49781			if (typeof superClass === 'object') {
49782				overrides = superClass;
49783				superClass = 'JQPlugin';
49784			}
49785			superClass = camelCase(superClass);
49786			var className = camelCase(overrides.name);
49787			JQClass.classes[className] = JQClass.classes[superClass].extend(overrides);
49788			new JQClass.classes[className]();
49789		}
49790	};
49791
49792})(jQuery);
49793/* http://keith-wood.name/countdown.html
49794   Countdown for jQuery v2.0.2.
49795   Written by Keith Wood (kbwood{at}iinet.com.au) January 2008.
49796   Available under the MIT (http://keith-wood.name/licence.html) license. 
49797   Please attribute the author if you use it. */
49798
49799
49800(function($) { // Hide scope, no $ conflict
49801
49802	var pluginName = 'countdown';
49803
49804	var Y = 0; // Years
49805	var O = 1; // Months
49806	var W = 2; // Weeks
49807	var D = 3; // Days
49808	var H = 4; // Hours
49809	var M = 5; // Minutes
49810	var S = 6; // Seconds
49811
49812	/** Create the countdown plugin.
49813		<p>Sets an element to show the time remaining until a given instant.</p>
49814		<p>Expects HTML like:</p>
49815		<pre>&lt;div>&lt;/div></pre>
49816		<p>Provide inline configuration like:</p>
49817		<pre>&lt;div data-countdown="name: 'value'">&lt;/div></pre>
49818	 	@module Countdown
49819		@augments JQPlugin
49820		@example $(selector).countdown({until: +300}) */
49821	$.JQPlugin.createPlugin({
49822	
49823		/** The name of the plugin. */
49824		name: pluginName,
49825
49826		/** Countdown expiry callback.
49827			Triggered when the countdown expires.
49828			@callback expiryCallback */
49829
49830		/** Countdown server synchronisation callback.
49831			Triggered when the countdown is initialised.
49832			@callback serverSyncCallback
49833			@return {Date} The current date/time on the server as expressed in the local timezone. */
49834			
49835		/** Countdown tick callback.
49836			Triggered on every <code>tickInterval</code> ticks of the countdown.
49837			@callback tickCallback
49838			@param periods {number[]} The breakdown by period (years, months, weeks, days,
49839					hours, minutes, seconds) of the time remaining/passed. */
49840
49841		/** Countdown which labels callback.
49842			Triggered when the countdown is being display to determine which set of labels
49843			(<code>labels</code>, <code>labels1</code>, ...) are to be used for the current period value.
49844			@callback whichLabelsCallback
49845			@param num {number} The current period value.
49846			@return {number} The suffix for the label set to use. */
49847			
49848		/** Default settings for the plugin.
49849			@property until {Date|number|string} The date/time to count down to, or number of seconds
49850						offset from now, or string of amounts and units for offset(s) from now:
49851						'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds.
49852			@example until: new Date(2013, 12-1, 25, 13, 30)
49853 until: +300
49854 until: '+1O -2D'
49855			@property [since] {Date|number|string} The date/time to count up from, or
49856						number of seconds offset from now, or string for unit offset(s):
49857						'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds.
49858			@example since: new Date(2013, 1-1, 1)
49859 since: -300
49860 since: '-1O +2D'
49861			@property [timezone=null] {number} The timezone (hours or minutes from GMT) for the target times,
49862						or null for client local timezone.
49863			@example timezone: +10
49864 timezone: -60
49865			@property [serverSync=null] {serverSyncCallback} A function to retrieve the current server time
49866						for synchronisation.
49867			@property [format='dHMS'] {string} The format for display - upper case for always, lower case only if non-zero,
49868						'Y' years, 'O' months, 'W' weeks, 'D' days, 'H' hours, 'M' minutes, 'S' seconds.
49869			@property [layout=''] {string} Build your own layout for the countdown.
49870			@example layout: '{d<}{dn} {dl}{d>} {hnn}:{mnn}:{snn}'
49871			@property [compact=false] {boolean} True to display in a compact format, false for an expanded one.
49872			@property [padZeroes=false] {boolean} True to add leading zeroes
49873			@property [significant=0] {number} The number of periods with non-zero values to show, zero for all.
49874			@property [description=''] {string} The description displayed for the countdown.
49875			@property [expiryUrl=''] {string} A URL to load upon expiry, replacing the current page.
49876			@property [expiryText=''] {string} Text to display upon expiry, replacing the countdown. This may be HTML.
49877			@property [alwaysExpire=false] {boolean} True to trigger <code>onExpiry</code> even if target time has passed.
49878			@property [onExpiry=null] {expiryCallback} Callback when the countdown expires -
49879						receives no parameters and <code>this</code> is the containing division.
49880			@example onExpiry: function() {
49881	...
49882 }
49883			@property [onTick=null] {tickCallback} Callback when the countdown is updated -
49884						receives <code>number[7]</code> being the breakdown by period
49885						(years, months, weeks, days, hours, minutes, seconds - based on
49886						<code>format</code>) and <code>this</code> is the containing division.
49887			@example onTick: function(periods) {
49888 	var secs = $.countdown.periodsToSeconds(periods);
49889 	if (secs < 300) { // Last five minutes
49890		...
49891 	}
49892 }
49893			@property [tickInterval=1] {number} The interval (seconds) between <code>onTick</code> callbacks. */
49894		defaultOptions: {
49895			until: null,
49896			since: null,
49897			timezone: null,
49898			serverSync: null,
49899			format: 'dHMS',
49900			layout: '',
49901			compact: false,
49902			padZeroes: false,
49903			significant: 0,
49904			description: '',
49905			expiryUrl: '',
49906			expiryText: '',
49907			alwaysExpire: false,
49908			onExpiry: null,
49909			onTick: null,
49910			tickInterval: 1
49911		},
49912
49913		/** Localisations for the plugin.
49914			Entries are objects indexed by the language code ('' being the default US/English).
49915			Each object has the following attributes.
49916			@property [labels=['Years','Months','Weeks','Days','Hours','Minutes','Seconds']] {string[]}
49917						The display texts for the counter periods.
49918			@property [labels1=['Year','Month','Week','Day','Hour','Minute','Second']] {string[]}
49919						The display texts for the counter periods if they have a value of 1.
49920						Add other <code>labels<em>n</em></code> attributes as necessary to
49921						cater for other numeric idiosyncrasies of the localisation.
49922			@property [compactLabels=['y','m','w','d']] {string[]} The compact texts for the counter periods.
49923			@property [whichLabels=null] {whichLabelsCallback} A function to determine which
49924						<code>labels<em>n</em></code> to use.
49925			@example whichLabels: function(num) {
49926	return (num > 1 ? 0 : 1);
49927 }
49928			@property [digits=['0','1',...,'9']] {number[]} The digits to display (0-9).
49929			@property [timeSeparator=':'] {string} Separator for time periods in the compact layout.
49930			@property [isRTL=false] {boolean} True for right-to-left languages, false for left-to-right. */
49931		regionalOptions: { // Available regional settings, indexed by language/country code
49932			'': { // Default regional settings - English/US
49933				labels: ['Years', 'Months', 'Weeks', 'Days', 'Hours', 'Minutes', 'Seconds'],
49934				labels1: ['Year', 'Month', 'Week', 'Day', 'Hour', 'Minute', 'Second'],
49935				compactLabels: ['y', 'm', 'w', 'd'],
49936				whichLabels: null,
49937				digits: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
49938				timeSeparator: ':',
49939				isRTL: false
49940			}
49941		},
49942		
49943		/** Names of getter methods - those that can't be chained. */
49944		_getters: ['getTimes'],
49945
49946		/* Class name for the right-to-left marker. */
49947		_rtlClass: pluginName + '-rtl',
49948		/* Class name for the countdown section marker. */
49949		_sectionClass: pluginName + '-section',
49950		/* Class name for the period amount marker. */
49951		_amountClass: pluginName + '-amount',
49952		/* Class name for the period name marker. */
49953		_periodClass: pluginName + '-period',
49954		/* Class name for the countdown row marker. */
49955		_rowClass: pluginName + '-row',
49956		/* Class name for the holding countdown marker. */
49957		_holdingClass: pluginName + '-holding',
49958		/* Class name for the showing countdown marker. */
49959		_showClass: pluginName + '-show',
49960		/* Class name for the description marker. */
49961		_descrClass: pluginName + '-descr',
49962
49963		/* List of currently active countdown elements. */
49964		_timerElems: [],
49965
49966		/** Additional setup for the countdown.
49967			Apply default localisations.
49968			Create the timer. */
49969		_init: function() {
49970			var self = this;
49971			this._super();
49972			this._serverSyncs = [];
49973			var now = (typeof Date.now == 'function' ? Date.now :
49974				function() { return new Date().getTime(); });
49975			var perfAvail = (window.performance && typeof window.performance.now == 'function');
49976			// Shared timer for all countdowns
49977			function timerCallBack(timestamp) {
49978				var drawStart = (timestamp < 1e12 ? // New HTML5 high resolution timer
49979					(perfAvail ? (performance.now() + performance.timing.navigationStart) : now()) :
49980					// Integer milliseconds since unix epoch
49981					timestamp || now());
49982				if (drawStart - animationStartTime >= 1000) {
49983							self._updateElems();
49984					animationStartTime = drawStart;
49985				}
49986				requestAnimationFrame(timerCallBack);
49987			}
49988			var requestAnimationFrame = window.requestAnimationFrame ||
49989				window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame ||
49990				window.oRequestAnimationFrame || window.msRequestAnimationFrame || null;
49991				// This is when we expect a fall-back to setInterval as it's much more fluid
49992			var animationStartTime = 0;
49993			if (!requestAnimationFrame || $.noRequestAnimationFrame) {
49994				$.noRequestAnimationFrame = null;
49995						setInterval(function() { self._updateElems(); }, 980); // Fall back to good old setInterval
49996			}
49997			else {
49998				animationStartTime = window.animationStartTime ||
49999					window.webkitAnimationStartTime || window.mozAnimationStartTime ||
50000					window.oAnimationStartTime || window.msAnimationStartTime || now();
50001				requestAnimationFrame(timerCallBack);
50002			}
50003		},
50004	
50005		/** Convert a date/time to UTC.
50006			@param tz {number} The hour or minute offset from GMT, e.g. +9, -360.
50007			@param year {Date|number} the date/time in that timezone or the year in that timezone.
50008			@param [month] {number} The month (0 - 11) (omit if <code>year</code> is a <code>Date</code>).
50009			@param [day] {number} The day (omit if <code>year</code> is a <code>Date</code>).
50010			@param [hours] {number} The hour (omit if <code>year</code> is a <code>Date</code>).
50011			@param [mins] {number} The minute (omit if <code>year</code> is a <code>Date</code>).
50012			@param [secs] {number} The second (omit if <code>year</code> is a <code>Date</code>).
50013			@param [ms] {number} The millisecond (omit if <code>year</code> is a <code>Date</code>).
50014			@return {Date} The equivalent UTC date/time.
50015			@example $.countdown.UTCDate(+10, 2013, 12-1, 25, 12, 0)
50016 $.countdown.UTCDate(-7, new Date(2013, 12-1, 25, 12, 0)) */
50017		UTCDate: function(tz, year, month, day, hours, mins, secs, ms) {
50018			if (typeof year == 'object' && year.constructor == Date) {
50019				ms = year.getMilliseconds();
50020				secs = year.getSeconds();
50021				mins = year.getMinutes();
50022				hours = year.getHours();
50023				day = year.getDate();
50024				month = year.getMonth();
50025				year = year.getFullYear();
50026			}
50027			var d = new Date();
50028			d.setUTCFullYear(year);
50029			d.setUTCDate(1);
50030			d.setUTCMonth(month || 0);
50031			d.setUTCDate(day || 1);
50032			d.setUTCHours(hours || 0);
50033			d.setUTCMinutes((mins || 0) - (Math.abs(tz) < 30 ? tz * 60 : tz));
50034			d.setUTCSeconds(secs || 0);
50035			d.setUTCMilliseconds(ms || 0);
50036			return d;
50037		},
50038
50039		/** Convert a set of periods into seconds.
50040	   Averaged for months and years.
50041			@param periods {number[]} The periods per year/month/week/day/hour/minute/second.
50042			@return {number} The corresponding number of seconds.
50043			@example var secs = $.countdown.periodsToSeconds(periods) */
50044		periodsToSeconds: function(periods) {
50045			return periods[0] * 31557600 + periods[1] * 2629800 + periods[2] * 604800 +
50046				periods[3] * 86400 + periods[4] * 3600 + periods[5] * 60 + periods[6];
50047		},
50048
50049		/** Resynchronise the countdowns with the server.
50050			@example $.countdown.resync() */
50051		resync: function() {
50052			var self = this;
50053			$('.' + this._getMarker()).each(function() { // Each countdown
50054				var inst = $.data(this, self.name);
50055				if (inst.options.serverSync) { // If synced
50056					var serverSync = null;
50057					for (var i = 0; i < self._serverSyncs.length; i++) {
50058						if (self._serverSyncs[i][0] == inst.options.serverSync) { // Find sync details
50059							serverSync = self._serverSyncs[i];
50060							break;
50061						}
50062					}
50063					if (serverSync[2] == null) { // Recalculate if missing
50064						var serverResult = ($.isFunction(inst.options.serverSync) ?
50065							inst.options.serverSync.apply(this, []) : null);
50066						serverSync[2] =
50067							(serverResult ? new Date().getTime() - serverResult.getTime() : 0) - serverSync[1];
50068					}
50069					if (inst._since) { // Apply difference
50070						inst._since.setMilliseconds(inst._since.getMilliseconds() + serverSync[2]);
50071					}
50072					inst._until.setMilliseconds(inst._until.getMilliseconds() + serverSync[2]);
50073				}
50074			});
50075			for (var i = 0; i < self._serverSyncs.length; i++) { // Update sync details
50076				if (self._serverSyncs[i][2] != null) {
50077					self._serverSyncs[i][1] += self._serverSyncs[i][2];
50078					delete self._serverSyncs[i][2];
50079				}
50080			}
50081		},
50082
50083		_instSettings: function(elem, options) {
50084			return {_periods: [0, 0, 0, 0, 0, 0, 0]};
50085		},
50086
50087		/** Add an element to the list of active ones.
50088			@private
50089			@param elem {Element} The countdown element. */
50090		_addElem: function(elem) {
50091			if (!this._hasElem(elem)) {
50092				this._timerElems.push(elem);
50093			}
50094		},
50095
50096		/** See if an element is in the list of active ones.
50097			@private
50098			@param elem {Element} The countdown element.
50099			@return {boolean} True if present, false if not. */
50100		_hasElem: function(elem) {
50101			return ($.inArray(elem, this._timerElems) > -1);
50102		},
50103
50104		/** Remove an element from the list of active ones.
50105			@private
50106			@param elem {Element} The countdown element. */
50107		_removeElem: function(elem) {
50108			this._timerElems = $.map(this._timerElems,
50109				function(value) { return (value == elem ? null : value); }); // delete entry
50110		},
50111
50112		/** Update each active timer element.
50113			@private */
50114		_updateElems: function() {
50115			for (var i = this._timerElems.length - 1; i >= 0; i--) {
50116				this._updateCountdown(this._timerElems[i]);
50117			}
50118		},
50119
50120		_optionsChanged: function(elem, inst, options) {
50121			if (options.layout) {
50122				options.layout = options.layout.replace(/&lt;/g, '<').replace(/&gt;/g, '>');
50123			}
50124			this._resetExtraLabels(inst.options, options);
50125			var timezoneChanged = (inst.options.timezone != options.timezone);
50126			$.extend(inst.options, options);
50127			this._adjustSettings(elem, inst,
50128				options.until != null || options.since != null || timezoneChanged);
50129			var now = new Date();
50130			if ((inst._since && inst._since < now) || (inst._until && inst._until > now)) {
50131				this._addElem(elem[0]);
50132			}
50133			this._updateCountdown(elem, inst);
50134		},
50135
50136		/** Redisplay the countdown with an updated display.
50137			@private
50138			@param elem {Element|jQuery} The containing division.
50139			@param inst {object} The current settings for this instance. */
50140		_updateCountdown: function(elem, inst) {
50141			elem = elem.jquery ? elem : $(elem);
50142			inst = inst || this._getInst(elem);
50143			if (!inst) {
50144				return;
50145			}
50146			elem.html(this._generateHTML(inst)).toggleClass(this._rtlClass, inst.options.isRTL);
50147			if ($.isFunction(inst.options.onTick)) {
50148				var periods = inst._hold != 'lap' ? inst._periods :
50149					this._calculatePeriods(inst, inst._show, inst.options.significant, new Date());
50150				if (inst.options.tickInterval == 1 ||
50151						this.periodsToSeconds(periods) % inst.options.tickInterval == 0) {
50152					inst.options.onTick.apply(elem[0], [periods]);
50153				}
50154			}
50155			var expired = inst._hold != 'pause' &&
50156				(inst._since ? inst._now.getTime() < inst._since.getTime() :
50157				inst._now.getTime() >= inst._until.getTime());
50158			if (expired && !inst._expiring) {
50159				inst._expiring = true;
50160				if (this._hasElem(elem[0]) || inst.options.alwaysExpire) {
50161					this._removeElem(elem[0]);
50162					if ($.isFunction(inst.options.onExpiry)) {
50163						inst.options.onExpiry.apply(elem[0], []);
50164					}
50165					if (inst.options.expiryText) {
50166						var layout = inst.options.layout;
50167						inst.options.layout = inst.options.expiryText;
50168						this._updateCountdown(elem[0], inst);
50169						inst.options.layout = layout;
50170					}
50171					if (inst.options.expiryUrl) {
50172						window.location = inst.options.expiryUrl;
50173					}
50174				}
50175				inst._expiring = false;
50176			}
50177			else if (inst._hold == 'pause') {
50178				this._removeElem(elem[0]);
50179			}
50180		},
50181
50182		/** Reset any extra labelsn and compactLabelsn entries if changing labels.
50183			@private
50184			@param base {object} The options to be updated.
50185			@param options {object} The new option values. */
50186		_resetExtraLabels: function(base, options) {
50187			for (var n in options) {
50188				if (n.match(/[Ll]abels[02-9]|compactLabels1/)) {
50189					base[n] = options[n];
50190				}
50191			}
50192			for (var n in base) { // Remove custom numbered labels
50193				if (n.match(/[Ll]abels[02-9]|compactLabels1/) && typeof options[n] === 'undefined') {
50194					base[n] = null;
50195				}
50196			}
50197		},
50198	
50199		/** Calculate internal settings for an instance.
50200			@private
50201			@param elem {jQuery} The containing division.
50202			@param inst {object} The current settings for this instance.
50203			@param recalc {boolean} True if until or since are set. */
50204		_adjustSettings: function(elem, inst, recalc) {
50205		var serverEntry = null;
50206		for (var i = 0; i < this._serverSyncs.length; i++) {
50207			if (this._serverSyncs[i][0] == inst.options.serverSync) {
50208				serverEntry = this._serverSyncs[i][1];
50209				break;
50210			}
50211		}
50212		if (serverEntry != null) {
50213				var serverOffset = (inst.options.serverSync ? serverEntry : 0);
50214				var now = new Date();
50215		}
50216		else {
50217			var serverResult = ($.isFunction(inst.options.serverSync) ?
50218					inst.options.serverSync.apply(elem[0], []) : null);
50219				var now = new Date();
50220				var serverOffset = (serverResult ? now.getTime() - serverResult.getTime() : 0);
50221			this._serverSyncs.push([inst.options.serverSync, serverOffset]);
50222		}
50223		var timezone = inst.options.timezone;
50224		timezone = (timezone == null ? -now.getTimezoneOffset() : timezone);
50225		if (recalc || (!recalc && inst._until == null && inst._since == null)) {
50226			inst._since = inst.options.since;
50227			if (inst._since != null) {
50228				inst._since = this.UTCDate(timezone, this._determineTime(inst._since, null));
50229				if (inst._since && serverOffset) {
50230					inst._since.setMilliseconds(inst._since.getMilliseconds() + serverOffset);
50231				}
50232			}
50233			inst._until = this.UTCDate(timezone, this._determineTime(inst.options.until, now));
50234			if (serverOffset) {
50235				inst._until.setMilliseconds(inst._until.getMilliseconds() + serverOffset);
50236			}
50237		}
50238		inst._show = this._determineShow(inst);
50239	},
50240
50241		/** Remove the countdown widget from a div.
50242			@param elem {jQuery} The containing division.
50243			@param inst {object} The current instance object. */
50244		_preDestroy: function(elem, inst) {
50245			this._removeElem(elem[0]);
50246			elem.empty();
50247	},
50248
50249		/** Pause a countdown widget at the current time.
50250	   Stop it running but remember and display the current time.
50251			@param elem {Element} The containing division.
50252			@example $(selector).countdown('pause') */
50253		pause: function(elem) {
50254			this._hold(elem, 'pause');
50255	},
50256
50257		/** Pause a countdown widget at the current time.
50258	   Stop the display but keep the countdown running.
50259			@param elem {Element} The containing division.
50260			@example $(selector).countdown('lap') */
50261		lap: function(elem) {
50262			this._hold(elem, 'lap');
50263		},
50264
50265		/** Resume a paused countdown widget.
50266			@param elem {Element} The containing division.
50267			@example $(selector).countdown('resume') */
50268		resume: function(elem) {
50269			this._hold(elem, null);
50270		},
50271
50272		/** Toggle a paused countdown widget.
50273			@param elem {Element} The containing division.
50274			@example $(selector).countdown('toggle') */
50275		toggle: function(elem) {
50276			var inst = $.data(elem, this.name) || {};
50277			this[!inst._hold ? 'pause' : 'resume'](elem);
50278		},
50279
50280		/** Toggle a lapped countdown widget.
50281			@param elem {Element} The containing division.
50282			@example $(selector).countdown('toggleLap') */
50283		toggleLap: function(elem) {
50284			var inst = $.data(elem, this.name) || {};
50285			this[!inst._hold ? 'lap' : 'resume'](elem);
50286		},
50287
50288		/** Pause or resume a countdown widget.
50289			@private
50290			@param elem {Element} The containing division.
50291			@param hold {string} The new hold setting. */
50292		_hold: function(elem, hold) {
50293			var inst = $.data(elem, this.name);
50294		if (inst) {
50295			if (inst._hold == 'pause' && !hold) {
50296				inst._periods = inst._savePeriods;
50297				var sign = (inst._since ? '-' : '+');
50298				inst[inst._since ? '_since' : '_until'] =
50299					this._determineTime(sign + inst._periods[0] + 'y' +
50300						sign + inst._periods[1] + 'o' + sign + inst._periods[2] + 'w' +
50301						sign + inst._periods[3] + 'd' + sign + inst._periods[4] + 'h' + 
50302						sign + inst._periods[5] + 'm' + sign + inst._periods[6] + 's');
50303					this._addElem(elem);
50304			}
50305			inst._hold = hold;
50306			inst._savePeriods = (hold == 'pause' ? inst._periods : null);
50307				$.data(elem, this.name, inst);
50308				this._updateCountdown(elem, inst);
50309		}
50310	},
50311
50312		/** Return the current time periods.
50313			@param elem {Element} The containing division.
50314			@return {number[]} The current periods for the countdown.
50315			@example var periods = $(selector).countdown('getTimes') */
50316		getTimes: function(elem) {
50317			var inst = $.data(elem, this.name);
50318		return (!inst ? null : (inst._hold == 'pause' ? inst._savePeriods : (!inst._hold ? inst._periods :
50319			this._calculatePeriods(inst, inst._show, inst.options.significant, new Date()))));
50320	},
50321
50322		/** A time may be specified as an exact value or a relative one.
50323			@private
50324			@param setting {string|number|Date} The date/time value as a relative or absolute value.
50325			@param defaultTime {Date} The date/time to use if no other is supplied.
50326			@return {Date} The corresponding date/time. */
50327	_determineTime: function(setting, defaultTime) {
50328			var self = this;
50329		var offsetNumeric = function(offset) { // e.g. +300, -2
50330			var time = new Date();
50331			time.setTime(time.getTime() + offset * 1000);
50332			return time;
50333		};
50334		var offsetString = function(offset) { // e.g. '+2d', '-4w', '+3h +30m'
50335			offset = offset.toLowerCase();
50336			var time = new Date();
50337			var year = time.getFullYear();
50338			var month = time.getMonth();
50339			var day = time.getDate();
50340			var hour = time.getHours();
50341			var minute = time.getMinutes();
50342			var second = time.getSeconds();
50343			var pattern = /([+-]?[0-9]+)\s*(s|m|h|d|w|o|y)?/g;
50344			var matches = pattern.exec(offset);
50345			while (matches) {
50346				switch (matches[2] || 's') {
50347					case 's': second += parseInt(matches[1], 10); break;
50348					case 'm': minute += parseInt(matches[1], 10); break;
50349					case 'h': hour += parseInt(matches[1], 10); break;
50350					case 'd': day += parseInt(matches[1], 10); break;
50351					case 'w': day += parseInt(matches[1], 10) * 7; break;
50352					case 'o':
50353						month += parseInt(matches[1], 10); 
50354							day = Math.min(day, self._getDaysInMonth(year, month));
50355						break;
50356					case 'y':
50357						year += parseInt(matches[1], 10);
50358							day = Math.min(day, self._getDaysInMonth(year, month));
50359						break;
50360				}
50361				matches = pattern.exec(offset);
50362			}
50363			return new Date(year, month, day, hour, minute, second, 0);
50364		};
50365		var time = (setting == null ? defaultTime :
50366			(typeof setting == 'string' ? offsetString(setting) :
50367			(typeof setting == 'number' ? offsetNumeric(setting) : setting)));
50368		if (time) time.setMilliseconds(0);
50369		return time;
50370	},
50371
50372		/** Determine the number of days in a month.
50373			@private
50374			@param year {number} The year.
50375			@param month {number} The month.
50376			@return {number} The days in that month. */
50377	_getDaysInMonth: function(year, month) {
50378		return 32 - new Date(year, month, 32).getDate();
50379	},
50380
50381		/** Default implementation to determine which set of labels should be used for an amount.
50382			Use the <code>labels</code> attribute with the same numeric suffix (if it exists).
50383			@private
50384			@param num {number} The amount to be displayed.
50385			@return {number} The set of labels to be used for this amount. */
50386	_normalLabels: function(num) {
50387		return num;
50388	},
50389
50390		/** Generate the HTML to display the countdown widget.
50391			@private
50392			@param inst {object} The current settings for this instance.
50393			@return {string} The new HTML for the countdown display. */
50394	_generateHTML: function(inst) {
50395		var self = this;
50396		// Determine what to show
50397		inst._periods = (inst._hold ? inst._periods :
50398			this._calculatePeriods(inst, inst._show, inst.options.significant, new Date()));
50399		// Show all 'asNeeded' after first non-zero value
50400		var shownNonZero = false;
50401		var showCount = 0;
50402		var sigCount = inst.options.significant;
50403		var show = $.extend({}, inst._show);
50404		for (var period = Y; period <= S; period++) {
50405			shownNonZero |= (inst._show[period] == '?' && inst._periods[period] > 0);
50406			show[period] = (inst._show[period] == '?' && !shownNonZero ? null : inst._show[period]);
50407			showCount += (show[period] ? 1 : 0);
50408			sigCount -= (inst._periods[period] > 0 ? 1 : 0);
50409		}
50410		var showSignificant = [false, false, false, false, false, false, false];
50411		for (var period = S; period >= Y; period--) { // Determine significant periods
50412			if (inst._show[period]) {
50413				if (inst._periods[period]) {
50414					showSignificant[period] = true;
50415				}
50416				else {
50417					showSignificant[period] = sigCount > 0;
50418					sigCount--;
50419				}
50420			}
50421		}
50422		var labels = (inst.options.compact ? inst.options.compactLabels : inst.options.labels);
50423		var whichLabels = inst.options.whichLabels || this._normalLabels;
50424		var showCompact = function(period) {
50425			var labelsNum = inst.options['compactLabels' + whichLabels(inst._periods[period])];
50426			return (show[period] ? self._translateDigits(inst, inst._periods[period]) +
50427				(labelsNum ? labelsNum[period] : labels[period]) + ' ' : '');
50428		};
50429		var minDigits = (inst.options.padZeroes ? 2 : 1);
50430		var showFull = function(period) {
50431			var labelsNum = inst.options['labels' + whichLabels(inst._periods[period])];
50432			return ((!inst.options.significant && show[period]) ||
50433				(inst.options.significant && showSignificant[period]) ?
50434					'<span class="' + self._sectionClass + '">' +
50435					'<span class="' + self._amountClass + '">' +
50436				self._minDigits(inst, inst._periods[period], minDigits) + '</span>' +
50437				'<span class="' + self._periodClass + '">' +
50438				(labelsNum ? labelsNum[period] : labels[period]) + '</span></span>' : '');
50439		};
50440		return (inst.options.layout ? this._buildLayout(inst, show, inst.options.layout,
50441			inst.options.compact, inst.options.significant, showSignificant) :
50442			((inst.options.compact ? // Compact version
50443			'<span class="' + this._rowClass + ' ' + this._amountClass +
50444			(inst._hold ? ' ' + this._holdingClass : '') + '">' + 
50445			showCompact(Y) + showCompact(O) + showCompact(W) + showCompact(D) + 
50446			(show[H] ? this._minDigits(inst, inst._periods[H], 2) : '') +
50447			(show[M] ? (show[H] ? inst.options.timeSeparator : '') +
50448			this._minDigits(inst, inst._periods[M], 2) : '') +
50449			(show[S] ? (show[H] || show[M] ? inst.options.timeSeparator : '') +
50450			this._minDigits(inst, inst._periods[S], 2) : '') :
50451			// Full version
50452			'<span class="' + this._rowClass + ' ' + this._showClass + (inst.options.significant || showCount) +
50453			(inst._hold ? ' ' + this._holdingClass : '') + '">' +
50454			showFull(Y) + showFull(O) + showFull(W) + showFull(D) +
50455			showFull(H) + showFull(M) + showFull(S)) + '</span>' +
50456			(inst.options.description ? '<span class="' + this._rowClass + ' ' + this._descrClass + '">' +
50457			inst.options.description + '</span>' : '')));
50458	},
50459
50460		/** Construct a custom layout.
50461			@private
50462			@param inst {object} The current settings for this instance.
50463			@param show {boolean[]} Flags indicating which periods are requested.
50464			@param layout {string} The customised layout.
50465			@param compact {boolean} True if using compact labels.
50466			@param significant {number} The number of periods with values to show, zero for all.
50467			@param showSignificant {boolean[]} Other periods to show for significance.
50468			@return {string} The custom HTML. */
50469	_buildLayout: function(inst, show, layout, compact, significant, showSignificant) {
50470		var labels = inst.options[compact ? 'compactLabels' : 'labels'];
50471		var whichLabels = inst.options.whichLabels || this._normalLabels;
50472		var labelFor = function(index) {
50473			return (inst.options[(compact ? 'compactLabels' : 'labels') +
50474				whichLabels(inst._periods[index])] || labels)[index];
50475		};
50476		var digit = function(value, position) {
50477			return inst.options.digits[Math.floor(value / position) % 10];
50478		};
50479		var subs = {desc: inst.options.description, sep: inst.options.timeSeparator,
50480			yl: labelFor(Y), yn: this._minDigits(inst, inst._periods[Y], 1),
50481			ynn: this._minDigits(inst, inst._periods[Y], 2),
50482			ynnn: this._minDigits(inst, inst._periods[Y], 3), y1: digit(inst._periods[Y], 1),
50483			y10: digit(inst._periods[Y], 10), y100: digit(inst._periods[Y], 100),
50484			y1000: digit(inst._periods[Y], 1000),
50485			ol: labelFor(O), on: this._minDigits(inst, inst._periods[O], 1),
50486			onn: this._minDigits(inst, inst._periods[O], 2),
50487			onnn: this._minDigits(inst, inst._periods[O], 3), o1: digit(inst._periods[O], 1),
50488			o10: digit(inst._periods[O], 10), o100: digit(inst._periods[O], 100),
50489			o1000: digit(inst._periods[O], 1000),
50490			wl: labelFor(W), wn: this._minDigits(inst, inst._periods[W], 1),
50491			wnn: this._minDigits(inst, inst._periods[W], 2),
50492			wnnn: this._minDigits(inst, inst._periods[W], 3), w1: digit(inst._periods[W], 1),
50493			w10: digit(inst._periods[W], 10), w100: digit(inst._periods[W], 100),
50494			w1000: digit(inst._periods[W], 1000),
50495			dl: labelFor(D), dn: this._minDigits(inst, inst._periods[D], 1),
50496			dnn: this._minDigits(inst, inst._periods[D], 2),
50497			dnnn: this._minDigits(inst, inst._periods[D], 3), d1: digit(inst._periods[D], 1),
50498			d10: digit(inst._periods[D], 10), d100: digit(inst._periods[D], 100),
50499			d1000: digit(inst._periods[D], 1000),
50500			hl: labelFor(H), hn: this._minDigits(inst, inst._periods[H], 1),
50501			hnn: this._minDigits(inst, inst._periods[H], 2),
50502			hnnn: this._minDigits(inst, inst._periods[H], 3), h1: digit(inst._periods[H], 1),
50503			h10: digit(inst._periods[H], 10), h100: digit(inst._periods[H], 100),
50504			h1000: digit(inst._periods[H], 1000),
50505			ml: labelFor(M), mn: this._minDigits(inst, inst._periods[M], 1),
50506			mnn: this._minDigits(inst, inst._periods[M], 2),
50507			mnnn: this._minDigits(inst, inst._periods[M], 3), m1: digit(inst._periods[M], 1),
50508			m10: digit(inst._periods[M], 10), m100: digit(inst._periods[M], 100),
50509			m1000: digit(inst._periods[M], 1000),
50510			sl: labelFor(S), sn: this._minDigits(inst, inst._periods[S], 1),
50511			snn: this._minDigits(inst, inst._periods[S], 2),
50512			snnn: this._minDigits(inst, inst._periods[S], 3), s1: digit(inst._periods[S], 1),
50513			s10: digit(inst._periods[S], 10), s100: digit(inst._periods[S], 100),
50514			s1000: digit(inst._periods[S], 1000)};
50515		var html = layout;
50516		// Replace period containers: {p<}...{p>}
50517		for (var i = Y; i <= S; i++) {
50518			var period = 'yowdhms'.charAt(i);
50519			var re = new RegExp('\\{' + period + '<\\}([\\s\\S]*)\\{' + period + '>\\}', 'g');
50520			html = html.replace(re, ((!significant && show[i]) ||
50521				(significant && showSignificant[i]) ? '$1' : ''));
50522		}
50523		// Replace period values: {pn}
50524		$.each(subs, function(n, v) {
50525			var re = new RegExp('\\{' + n + '\\}', 'g');
50526			html = html.replace(re, v);
50527		});
50528		return html;
50529	},
50530
50531		/** Ensure a numeric value has at least n digits for display.
50532			@private
50533			@param inst {object} The current settings for this instance.
50534			@param value {number} The value to display.
50535			@param len {number} The minimum length.
50536			@return {string} The display text. */
50537	_minDigits: function(inst, value, len) {
50538		value = '' + value;
50539		if (value.length >= len) {
50540			return this._translateDigits(inst, value);
50541		}
50542		value = '0000000000' + value;
50543		return this._translateDigits(inst, value.substr(value.length - len));
50544	},
50545
50546		/** Translate digits into other representations.
50547			@private
50548			@param inst {object} The current settings for this instance.
50549			@param value {string} The text to translate.
50550			@return {string} The translated text. */
50551	_translateDigits: function(inst, value) {
50552		return ('' + value).replace(/[0-9]/g, function(digit) {
50553				return inst.options.digits[digit];
50554			});
50555	},
50556
50557		/** Translate the format into flags for each period.
50558			@private
50559			@param inst {object} The current settings for this instance.
50560			@return {string[]} Flags indicating which periods are requested (?) or
50561					required (!) by year, month, week, day, hour, minute, second. */
50562	_determineShow: function(inst) {
50563		var format = inst.options.format;
50564		var show = [];
50565		show[Y] = (format.match('y') ? '?' : (format.match('Y') ? '!' : null));
50566		show[O] = (format.match('o') ? '?' : (format.match('O') ? '!' : null));
50567		show[W] = (format.match('w') ? '?' : (format.match('W') ? '!' : null));
50568		show[D] = (format.match('d') ? '?' : (format.match('D') ? '!' : null));
50569		show[H] = (format.match('h') ? '?' : (format.match('H') ? '!' : null));
50570		show[M] = (format.match('m') ? '?' : (format.match('M') ? '!' : null));
50571		show[S] = (format.match('s') ? '?' : (format.match('S') ? '!' : null));
50572		return show;
50573	},
50574	
50575		/** Calculate the requested periods between now and the target time.
50576			@private
50577			@param inst {object} The current settings for this instance.
50578			@param show {string[]} Flags indicating which periods are requested/required.
50579			@param significant {number} The number of periods with values to show, zero for all.
50580			@param now {Date} The current date and time.
50581			@return {number[]} The current time periods (always positive)
50582					by year, month, week, day, hour, minute, second. */
50583	_calculatePeriods: function(inst, show, significant, now) {
50584		// Find endpoints
50585		inst._now = now;
50586		inst._now.setMilliseconds(0);
50587		var until = new Date(inst._now.getTime());
50588		if (inst._since) {
50589			if (now.getTime() < inst._since.getTime()) {
50590				inst._now = now = until;
50591			}
50592			else {
50593				now = inst._since;
50594			}
50595		}
50596		else {
50597			until.setTime(inst._until.getTime());
50598			if (now.getTime() > inst._until.getTime()) {
50599				inst._now = now = until;
50600			}
50601		}
50602		// Calculate differences by period
50603		var periods = [0, 0, 0, 0, 0, 0, 0];
50604		if (show[Y] || show[O]) {
50605			// Treat end of months as the same
50606			var lastNow = this._getDaysInMonth(now.getFullYear(), now.getMonth());
50607			var lastUntil = this._getDaysInMonth(until.getFullYear(), until.getMonth());
50608			var sameDay = (until.getDate() == now.getDate() ||
50609				(until.getDate() >= Math.min(lastNow, lastUntil) &&
50610				now.getDate() >= Math.min(lastNow, lastUntil)));
50611			var getSecs = function(date) {
50612				return (date.getHours() * 60 + date.getMinutes()) * 60 + date.getSeconds();
50613			};
50614			var months = Math.max(0,
50615				(until.getFullYear() - now.getFullYear()) * 12 + until.getMonth() - now.getMonth() +
50616				((until.getDate() < now.getDate() && !sameDay) ||
50617				(sameDay && getSecs(until) < getSecs(now)) ? -1 : 0));
50618			periods[Y] = (show[Y] ? Math.floor(months / 12) : 0);
50619			periods[O] = (show[O] ? months - periods[Y] * 12 : 0);
50620			// Adjust for months difference and end of month if necessary
50621			now = new Date(now.getTime());
50622			var wasLastDay = (now.getDate() == lastNow);
50623			var lastDay = this._getDaysInMonth(now.getFullYear() + periods[Y],
50624				now.getMonth() + periods[O]);
50625			if (now.getDate() > lastDay) {
50626				now.setDate(lastDay);
50627			}
50628			now.setFullYear(now.getFullYear() + periods[Y]);
50629			now.setMonth(now.getMonth() + periods[O]);
50630			if (wasLastDay) {
50631				now.setDate(lastDay);
50632			}
50633		}
50634		var diff = Math.floor((until.getTime() - now.getTime()) / 1000);
50635		var extractPeriod = function(period, numSecs) {
50636			periods[period] = (show[period] ? Math.floor(diff / numSecs) : 0);
50637			diff -= periods[period] * numSecs;
50638		};
50639		extractPeriod(W, 604800);
50640		extractPeriod(D, 86400);
50641		extractPeriod(H, 3600);
50642		extractPeriod(M, 60);
50643		extractPeriod(S, 1);
50644		if (diff > 0 && !inst._since) { // Round up if left overs
50645			var multiplier = [1, 12, 4.3482, 7, 24, 60, 60];
50646			var lastShown = S;
50647			var max = 1;
50648			for (var period = S; period >= Y; period--) {
50649				if (show[period]) {
50650					if (periods[lastShown] >= max) {
50651						periods[lastShown] = 0;
50652						diff = 1;
50653					}
50654					if (diff > 0) {
50655						periods[period]++;
50656						diff = 0;
50657						lastShown = period;
50658						max = 1;
50659					}
50660				}
50661				max *= multiplier[period];
50662			}
50663		}
50664		if (significant) { // Zero out insignificant periods
50665			for (var period = Y; period <= S; period++) {
50666				if (significant && periods[period]) {
50667					significant--;
50668				}
50669				else if (!significant) {
50670					periods[period] = 0;
50671				}
50672			}
50673		}
50674		return periods;
50675	}
50676	});
50677
50678})(jQuery);
50679// Countdown dependency as a manifest
50680
50681
50682;
50683
50684
50685
50686
50687
50688
50689
50690
50691

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.