PageSourceSearch

https://hotel-hammer.com/assets/scripts.js

js hotel-hammer.com collected 2026-10-04 21:57:21 UTC 816,829 bytes, 29,197 lines download raw bytes

vendor: 4,496 bytes, lines 1-184
1//-------------------------------------------\\
2// Generic Libraries                         \\
3// ------------------------------------------\\
4
5/*!
6 * jQuery JavaScript Library v2.2.0
7 * http://jquery.com/
8 *
9 * Includes Sizzle.js
10 * http://sizzlejs.com/
11 *
12 * Copyright jQuery Foundation and other contributors
13 * Released under the MIT license
14 * http://jquery.org/license
15 *
16 * Date: 2016-01-08T20:02Z
17 */
18
19(function( global, factory ) {
20
21	if ( typeof module === "object" && typeof module.exports === "object" ) {
22		// For CommonJS and CommonJS-like environments where a proper `window`
23		// is present, execute the factory and get jQuery.
24		// For environments that do not have a `window` with a `document`
25		// (such as Node.js), expose a factory as module.exports.
26		// This accentuates the need for the creation of a real `window`.
27		// e.g. var jQuery = require("jquery")(window);
28		// See ticket #14549 for more info.
29		module.exports = global.document ?
30			factory( global, true ) :
31			function( w ) {
32				if ( !w.document ) {
33					throw new Error( "jQuery requires a window with a document" );
34				}
35				return factory( w );
36			};
37	} else {
38		factory( global );
39	}
40
41// Pass this if window is not defined yet
42}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
43
44// Support: Firefox 18+
45// Can't be in strict mode, several libs including ASP.NET trace
46// the stack via arguments.caller.callee and Firefox dies if
47// you try to trace through "use strict" call chains. (#13335)
48//"use strict";
49var arr = [];
50
51var document = window.document;
52
53var slice = arr.slice;
54
55var concat = arr.concat;
56
57var push = arr.push;
58
59var indexOf = arr.indexOf;
60
61var class2type = {};
62
63var toString = class2type.toString;
64
65var hasOwn = class2type.hasOwnProperty;
66
67var support = {};
68
69
70
71var
72	version = "2.2.0",
73
74	// Define a local copy of jQuery
75	jQuery = function( selector, context ) {
76
77		// The jQuery object is actually just the init constructor 'enhanced'
78		// Need init if jQuery is called (just allow error to be thrown if not included)
79		return new jQuery.fn.init( selector, context );
80	},
81
82	// Support: Android<4.1
83	// Make sure we trim BOM and NBSP
84	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
85
86	// Matches dashed string for camelizing
87	rmsPrefix = /^-ms-/,
88	rdashAlpha = /-([\da-z])/gi,
89
90	// Used by jQuery.camelCase as callback to replace()
91	fcamelCase = function( all, letter ) {
92		return letter.toUpperCase();
93	};
94
95jQuery.fn = jQuery.prototype = {
96
97	// The current version of jQuery being used
98	jquery: version,
99
100	constructor: jQuery,
101
102	// Start with an empty selector
103	selector: "",
104
105	// The default length of a jQuery object is 0
106	length: 0,
107
108	toArray: function() {
109		return slice.call( this );
110	},
111
112	// Get the Nth element in the matched element set OR
113	// Get the whole matched element set as a clean array
114	get: function( num ) {
115		return num != null ?
116
117			// Return just the one element from the set
118			( num < 0 ? this[ num + this.length ] : this[ num ] ) :
119
120			// Return all the elements in a clean array
121			slice.call( this );
122	},
123
124	// Take an array of elements and push it onto the stack
125	// (returning the new matched element set)
126	pushStack: function( elems ) {
127
128		// Build a new jQuery matched element set
129		var ret = jQuery.merge( this.constructor(), elems );
130
131		// Add the old object onto the stack (as a reference)
132		ret.prevObject = this;
133		ret.context = this.context;
134
135		// Return the newly-formed element set
136		return ret;
137	},
138
139	// Execute a callback for every element in the matched set.
140	each: function( callback ) {
141		return jQuery.each( this, callback );
142	},
143
144	map: function( callback ) {
145		return this.pushStack( jQuery.map( this, function( elem, i ) {
146			return callback.call( elem, i, elem );
147		} ) );
148	},
149
150	slice: function() {
151		return this.pushStack( slice.apply( this, arguments ) );
152	},
153
154	first: function() {
155		return this.eq( 0 );
156	},
157
158	last: function() {
159		return this.eq( -1 );
160	},
161
162	eq: function( i ) {
163		var len = this.length,
164			j = +i + ( i < 0 ? len : 0 );
165		return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
166	},
167
168	end: function() {
169		return this.prevObject || this.constructor();
170	},
171
172	// For internal use only.
173	// Behaves like an Array's method, not like a jQuery method.
174	push: push,
175	sort: arr.sort,
176	splice: arr.splice
177};
178
179jQuery.extend = jQuery.fn.extend = function() {
180	var options, name, src, copy, copyIsArray, clone,
181		target = arguments[ 0 ] || {},
182		i = 1,
183		length = arguments.length,
184		deep = false;
vendor: 2,870 bytes, lines 185-299
185
186	// Handle a deep copy situation
187	if ( typeof target === "boolean" ) {
188		deep = target;
189
190		// Skip the boolean and the target
191		target = arguments[ i ] || {};
192		i++;
193	}
194
195	// Handle case when target is a string or something (possible in deep copy)
196	if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
197		target = {};
198	}
199
200	// Extend jQuery itself if only one argument is passed
201	if ( i === length ) {
202		target = this;
203		i--;
204	}
205
206	for ( ; i < length; i++ ) {
207
208		// Only deal with non-null/undefined values
209		if ( ( options = arguments[ i ] ) != null ) {
210
211			// Extend the base object
212			for ( name in options ) {
213				src = target[ name ];
214				copy = options[ name ];
215
216				// Prevent never-ending loop
217				if ( target === copy ) {
218					continue;
219				}
220
221				// Recurse if we're merging plain objects or arrays
222				if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
223					( copyIsArray = jQuery.isArray( copy ) ) ) ) {
224
225					if ( copyIsArray ) {
226						copyIsArray = false;
227						clone = src && jQuery.isArray( src ) ? src : [];
228
229					} else {
230						clone = src && jQuery.isPlainObject( src ) ? src : {};
231					}
232
233					// Never move original objects, clone them
234					target[ name ] = jQuery.extend( deep, clone, copy );
235
236				// Don't bring in undefined values
237				} else if ( copy !== undefined ) {
238					target[ name ] = copy;
239				}
240			}
241		}
242	}
243
244	// Return the modified object
245	return target;
246};
247
248jQuery.extend( {
249
250	// Unique for each copy of jQuery on the page
251	expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
252
253	// Assume jQuery is ready without the ready module
254	isReady: true,
255
256	error: function( msg ) {
257		throw new Error( msg );
258	},
259
260	noop: function() {},
261
262	isFunction: function( obj ) {
263		return jQuery.type( obj ) === "function";
264	},
265
266	isArray: Array.isArray,
267
268	isWindow: function( obj ) {
269		return obj != null && obj === obj.window;
270	},
271
272	isNumeric: function( obj ) {
273
274		// parseFloat NaNs numeric-cast false positives (null|true|false|"")
275		// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
276		// subtraction forces infinities to NaN
277		// adding 1 corrects loss of precision from parseFloat (#15100)
278		var realStringObj = obj && obj.toString();
279		return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
280	},
281
282	isPlainObject: function( obj ) {
283
284		// Not plain objects:
285		// - Any object or value whose internal [[Class]] property is not "[object Object]"
286		// - DOM nodes
287		// - window
288		if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
289			return false;
290		}
291
292		if ( obj.constructor &&
293				!hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
294			return false;
295		}
296
297		// If the function hasn't returned already, we're confident that
298		// |obj| is a plain object, created by {} or constructed with new Object
299		return true
vendor: 111,662 bytes, lines 299-4486
299;
300	},
301
302	isEmptyObject: function( obj ) {
303		var name;
304		for ( name in obj ) {
305			return false;
306		}
307		return true;
308	},
309
310	type: function( obj ) {
311		if ( obj == null ) {
312			return obj + "";
313		}
314
315		// Support: Android<4.0, iOS<6 (functionish RegExp)
316		return typeof obj === "object" || typeof obj === "function" ?
317			class2type[ toString.call( obj ) ] || "object" :
318			typeof obj;
319	},
320
321	// Evaluates a script in a global context
322	globalEval: function( code ) {
323		var script,
324			indirect = eval;
325
326		code = jQuery.trim( code );
327
328		if ( code ) {
329
330			// If the code includes a valid, prologue position
331			// strict mode pragma, execute code by injecting a
332			// script tag into the document.
333			if ( code.indexOf( "use strict" ) === 1 ) {
334				script = document.createElement( "script" );
335				script.text = code;
336				document.head.appendChild( script ).parentNode.removeChild( script );
337			} else {
338
339				// Otherwise, avoid the DOM node creation, insertion
340				// and removal by using an indirect global eval
341
342				indirect( code );
343			}
344		}
345	},
346
347	// Convert dashed to camelCase; used by the css and data modules
348	// Support: IE9-11+
349	// Microsoft forgot to hump their vendor prefix (#9572)
350	camelCase: function( string ) {
351		return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
352	},
353
354	nodeName: function( elem, name ) {
355		return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
356	},
357
358	each: function( obj, callback ) {
359		var length, i = 0;
360
361		if ( isArrayLike( obj ) ) {
362			length = obj.length;
363			for ( ; i < length; i++ ) {
364				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
365					break;
366				}
367			}
368		} else {
369			for ( i in obj ) {
370				if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
371					break;
372				}
373			}
374		}
375
376		return obj;
377	},
378
379	// Support: Android<4.1
380	trim: function( text ) {
381		return text == null ?
382			"" :
383			( text + "" ).replace( rtrim, "" );
384	},
385
386	// results is for internal usage only
387	makeArray: function( arr, results ) {
388		var ret = results || [];
389
390		if ( arr != null ) {
391			if ( isArrayLike( Object( arr ) ) ) {
392				jQuery.merge( ret,
393					typeof arr === "string" ?
394					[ arr ] : arr
395				);
396			} else {
397				push.call( ret, arr );
398			}
399		}
400
401		return ret;
402	},
403
404	inArray: function( elem, arr, i ) {
405		return arr == null ? -1 : indexOf.call( arr, elem, i );
406	},
407
408	merge: function( first, second ) {
409		var len = +second.length,
410			j = 0,
411			i = first.length;
412
413		for ( ; j < len; j++ ) {
414			first[ i++ ] = second[ j ];
415		}
416
417		first.length = i;
418
419		return first;
420	},
421
422	grep: function( elems, callback, invert ) {
423		var callbackInverse,
424			matches = [],
425			i = 0,
426			length = elems.length,
427			callbackExpect = !invert;
428
429		// Go through the array, only saving the items
430		// that pass the validator function
431		for ( ; i < length; i++ ) {
432			callbackInverse = !callback( elems[ i ], i );
433			if ( callbackInverse !== callbackExpect ) {
434				matches.push( elems[ i ] );
435			}
436		}
437
438		return matches;
439	},
440
441	// arg is for internal usage only
442	map: function( elems, callback, arg ) {
443		var length, value,
444			i = 0,
445			ret = [];
446
447		// Go through the array, translating each of the items to their new values
448		if ( isArrayLike( elems ) ) {
449			length = elems.length;
450			for ( ; i < length; i++ ) {
451				value = callback( elems[ i ], i, arg );
452
453				if ( value != null ) {
454					ret.push( value );
455				}
456			}
457
458		// Go through every key on the object,
459		} else {
460			for ( i in elems ) {
461				value = callback( elems[ i ], i, arg );
462
463				if ( value != null ) {
464					ret.push( value );
465				}
466			}
467		}
468
469		// Flatten any nested arrays
470		return concat.apply( [], ret );
471	},
472
473	// A global GUID counter for objects
474	guid: 1,
475
476	// Bind a function to a context, optionally partially applying any
477	// arguments.
478	proxy: function( fn, context ) {
479		var tmp, args, proxy;
480
481		if ( typeof context === "string" ) {
482			tmp = fn[ context ];
483			context = fn;
484			fn = tmp;
485		}
486
487		// Quick check to determine if target is callable, in the spec
488		// this throws a TypeError, but we will just return undefined.
489		if ( !jQuery.isFunction( fn ) ) {
490			return undefined;
491		}
492
493		// Simulated bind
494		args = slice.call( arguments, 2 );
495		proxy = function() {
496			return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
497		};
498
499		// Set the guid of unique handler to the same of original handler, so it can be removed
500		proxy.guid = fn.guid = fn.guid || jQuery.guid++;
501
502		return proxy;
503	},
504
505	now: Date.now,
506
507	// jQuery.support is not used in Core but other projects attach their
508	// properties to it so it needs to exist.
509	support: support
510} );
511
512// JSHint would error on this code due to the Symbol not being defined in ES5.
513// Defining this global in .jshintrc would create a danger of using the global
514// unguarded in another place, it seems safer to just disable JSHint for these
515// three lines.
516/* jshint ignore: start */
517if ( typeof Symbol === "function" ) {
518	jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
519}
520/* jshint ignore: end */
521
522// Populate the class2type map
523jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
524function( i, name ) {
525	class2type[ "[object " + name + "]" ] = name.toLowerCase();
526} );
527
528function isArrayLike( obj ) {
529
530	// Support: iOS 8.2 (not reproducible in simulator)
531	// `in` check used to prevent JIT error (gh-2145)
532	// hasOwn isn't used here due to false negatives
533	// regarding Nodelist length in IE
534	var length = !!obj && "length" in obj && obj.length,
535		type = jQuery.type( obj );
536
537	if ( type === "function" || jQuery.isWindow( obj ) ) {
538		return false;
539	}
540
541	return type === "array" || length === 0 ||
542		typeof length === "number" && length > 0 && ( length - 1 ) in obj;
543}
544var Sizzle =
545/*!
546 * Sizzle CSS Selector Engine v2.2.1
547 * http://sizzlejs.com/
548 *
549 * Copyright jQuery Foundation and other contributors
550 * Released under the MIT license
551 * http://jquery.org/license
552 *
553 * Date: 2015-10-17
554 */
555(function( window ) {
556
557var i,
558	support,
559	Expr,
560	getText,
561	isXML,
562	tokenize,
563	compile,
564	select,
565	outermostContext,
566	sortInput,
567	hasDuplicate,
568
569	// Local document vars
570	setDocument,
571	document,
572	docElem,
573	documentIsHTML,
574	rbuggyQSA,
575	rbuggyMatches,
576	matches,
577	contains,
578
579	// Instance-specific data
580	expando = "sizzle" + 1 * new Date(),
581	preferredDoc = window.document,
582	dirruns = 0,
583	done = 0,
584	classCache = createCache(),
585	tokenCache = createCache(),
586	compilerCache = createCache(),
587	sortOrder = function( a, b ) {
588		if ( a === b ) {
589			hasDuplicate = true;
590		}
591		return 0;
592	},
593
594	// General-purpose constants
595	MAX_NEGATIVE = 1 << 31,
596
597	// Instance methods
598	hasOwn = ({}).hasOwnProperty,
599	arr = [],
600	pop = arr.pop,
601	push_native = arr.push,
602	push = arr.push,
603	slice = arr.slice,
604	// Use a stripped-down indexOf as it's faster than native
605	// http://jsperf.com/thor-indexof-vs-for/5
606	indexOf = function( list, elem ) {
607		var i = 0,
608			len = list.length;
609		for ( ; i < len; i++ ) {
610			if ( list[i] === elem ) {
611				return i;
612			}
613		}
614		return -1;
615	},
616
617	booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
618
619	// Regular expressions
620
621	// http://www.w3.org/TR/css3-selectors/#whitespace
622	whitespace = "[\\x20\\t\\r\\n\\f]",
623
624	// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
625	identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
626
627	// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
628	attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
629		// Operator (capture 2)
630		"*([*^$|!~]?=)" + whitespace +
631		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
632		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
633		"*\\]",
634
635	pseudos = ":(" + identifier + ")(?:\\((" +
636		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
637		// 1. quoted (capture 3; capture 4 or capture 5)
638		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
639		// 2. simple (capture 6)
640		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
641		// 3. anything else (capture 2)
642		".*" +
643		")\\)|)",
644
645	// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
646	rwhitespace = new RegExp( whitespace + "+", "g" ),
647	rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
648
649	rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
650	rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
651
652	rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
653
654	rpseudo = new RegExp( pseudos ),
655	ridentifier = new RegExp( "^" + identifier + "$" ),
656
657	matchExpr = {
658		"ID": new RegExp( "^#(" + identifier + ")" ),
659		"CLASS": new RegExp( "^\\.(" + identifier + ")" ),
660		"TAG": new RegExp( "^(" + identifier + "|[*])" ),
661		"ATTR": new RegExp( "^" + attributes ),
662		"PSEUDO": new RegExp( "^" + pseudos ),
663		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
664			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
665			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
666		"bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
667		// For use in libraries implementing .is()
668		// We use this for POS matching in `select`
669		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
670			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
671	},
672
673	rinputs = /^(?:input|select|textarea|button)$/i,
674	rheader = /^h\d$/i,
675
676	rnative = /^[^{]+\{\s*\[native \w/,
677
678	// Easily-parseable/retrievable ID or TAG or CLASS selectors
679	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
680
681	rsibling = /[+~]/,
682	rescape = /'|\\/g,
683
684	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
685	runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
686	funescape = function( _, escaped, escapedWhitespace ) {
687		var high = "0x" + escaped - 0x10000;
688		// NaN means non-codepoint
689		// Support: Firefox<24
690		// Workaround erroneous numeric interpretation of +"0x"
691		return high !== high || escapedWhitespace ?
692			escaped :
693			high < 0 ?
694				// BMP codepoint
695				String.fromCharCode( high + 0x10000 ) :
696				// Supplemental Plane codepoint (surrogate pair)
697				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
698	},
699
700	// Used for iframes
701	// See setDocument()
702	// Removing the function wrapper causes a "Permission Denied"
703	// error in IE
704	unloadHandler = function() {
705		setDocument();
706	};
707
708// Optimize for push.apply( _, NodeList )
709try {
710	push.apply(
711		(arr = slice.call( preferredDoc.childNodes )),
712		preferredDoc.childNodes
713	);
714	// Support: Android<4.0
715	// Detect silently failing push.apply
716	arr[ preferredDoc.childNodes.length ].nodeType;
717} catch ( e ) {
718	push = { apply: arr.length ?
719
720		// Leverage slice if possible
721		function( target, els ) {
722			push_native.apply( target, slice.call(els) );
723		} :
724
725		// Support: IE<9
726		// Otherwise append directly
727		function( target, els ) {
728			var j = target.length,
729				i = 0;
730			// Can't trust NodeList.length
731			while ( (target[j++] = els[i++]) ) {}
732			target.length = j - 1;
733		}
734	};
735}
736
737function Sizzle( selector, context, results, seed ) {
738	var m, i, elem, nid, nidselect, match, groups, newSelector,
739		newContext = context && context.ownerDocument,
740
741		// nodeType defaults to 9, since context defaults to document
742		nodeType = context ? context.nodeType : 9;
743
744	results = results || [];
745
746	// Return early from calls with invalid selector or context
747	if ( typeof selector !== "string" || !selector ||
748		nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
749
750		return results;
751	}
752
753	// Try to shortcut find operations (as opposed to filters) in HTML documents
754	if ( !seed ) {
755
756		if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
757			setDocument( context );
758		}
759		context = context || document;
760
761		if ( documentIsHTML ) {
762
763			// If the selector is sufficiently simple, try using a "get*By*" DOM method
764			// (excepting DocumentFragment context, where the methods don't exist)
765			if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
766
767				// ID selector
768				if ( (m = match[1]) ) {
769
770					// Document context
771					if ( nodeType === 9 ) {
772						if ( (elem = context.getElementById( m )) ) {
773
774							// Support: IE, Opera, Webkit
775							// TODO: identify versions
776							// getElementById can match elements by name instead of ID
777							if ( elem.id === m ) {
778								results.push( elem );
779								return results;
780							}
781						} else {
782							return results;
783						}
784
785					// Element context
786					} else {
787
788						// Support: IE, Opera, Webkit
789						// TODO: identify versions
790						// getElementById can match elements by name instead of ID
791						if ( newContext && (elem = newContext.getElementById( m )) &&
792							contains( context, elem ) &&
793							elem.id === m ) {
794
795							results.push( elem );
796							return results;
797						}
798					}
799
800				// Type selector
801				} else if ( match[2] ) {
802					push.apply( results, context.getElementsByTagName( selector ) );
803					return results;
804
805				// Class selector
806				} else if ( (m = match[3]) && support.getElementsByClassName &&
807					context.getElementsByClassName ) {
808
809					push.apply( results, context.getElementsByClassName( m ) );
810					return results;
811				}
812			}
813
814			// Take advantage of querySelectorAll
815			if ( support.qsa &&
816				!compilerCache[ selector + " " ] &&
817				(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
818
819				if ( nodeType !== 1 ) {
820					newContext = context;
821					newSelector = selector;
822
823				// qSA looks outside Element context, which is not what we want
824				// Thanks to Andrew Dupont for this workaround technique
825				// Support: IE <=8
826				// Exclude object elements
827				} else if ( context.nodeName.toLowerCase() !== "object" ) {
828
829					// Capture the context ID, setting it first if necessary
830					if ( (nid = context.getAttribute( "id" )) ) {
831						nid = nid.replace( rescape, "\\$&" );
832					} else {
833						context.setAttribute( "id", (nid = expando) );
834					}
835
836					// Prefix every selector in the list
837					groups = tokenize( selector );
838					i = groups.length;
839					nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
840					while ( i-- ) {
841						groups[i] = nidselect + " " + toSelector( groups[i] );
842					}
843					newSelector = groups.join( "," );
844
845					// Expand context for sibling selectors
846					newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
847						context;
848				}
849
850				if ( newSelector ) {
851					try {
852						push.apply( results,
853							newContext.querySelectorAll( newSelector )
854						);
855						return results;
856					} catch ( qsaError ) {
857					} finally {
858						if ( nid === expando ) {
859							context.removeAttribute( "id" );
860						}
861					}
862				}
863			}
864		}
865	}
866
867	// All others
868	return select( selector.replace( rtrim, "$1" ), context, results, seed );
869}
870
871/**
872 * Create key-value caches of limited size
873 * @returns {function(string, object)} Returns the Object data after storing it on itself with
874 *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
875 *	deleting the oldest entry
876 */
877function createCache() {
878	var keys = [];
879
880	function cache( key, value ) {
881		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
882		if ( keys.push( key + " " ) > Expr.cacheLength ) {
883			// Only keep the most recent entries
884			delete cache[ keys.shift() ];
885		}
886		return (cache[ key + " " ] = value);
887	}
888	return cache;
889}
890
891/**
892 * Mark a function for special use by Sizzle
893 * @param {Function} fn The function to mark
894 */
895function markFunction( fn ) {
896	fn[ expando ] = true;
897	return fn;
898}
899
900/**
901 * Support testing using an element
902 * @param {Function} fn Passed the created div and expects a boolean result
903 */
904function assert( fn ) {
905	var div = document.createElement("div");
906
907	try {
908		return !!fn( div );
909	} catch (e) {
910		return false;
911	} finally {
912		// Remove from its parent by default
913		if ( div.parentNode ) {
914			div.parentNode.removeChild( div );
915		}
916		// release memory in IE
917		div = null;
918	}
919}
920
921/**
922 * Adds the same handler for all of the specified attrs
923 * @param {String} attrs Pipe-separated list of attributes
924 * @param {Function} handler The method that will be applied
925 */
926function addHandle( attrs, handler ) {
927	var arr = attrs.split("|"),
928		i = arr.length;
929
930	while ( i-- ) {
931		Expr.attrHandle[ arr[i] ] = handler;
932	}
933}
934
935/**
936 * Checks document order of two siblings
937 * @param {Element} a
938 * @param {Element} b
939 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
940 */
941function siblingCheck( a, b ) {
942	var cur = b && a,
943		diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
944			( ~b.sourceIndex || MAX_NEGATIVE ) -
945			( ~a.sourceIndex || MAX_NEGATIVE );
946
947	// Use IE sourceIndex if available on both nodes
948	if ( diff ) {
949		return diff;
950	}
951
952	// Check if b follows a
953	if ( cur ) {
954		while ( (cur = cur.nextSibling) ) {
955			if ( cur === b ) {
956				return -1;
957			}
958		}
959	}
960
961	return a ? 1 : -1;
962}
963
964/**
965 * Returns a function to use in pseudos for input types
966 * @param {String} type
967 */
968function createInputPseudo( type ) {
969	return function( elem ) {
970		var name = elem.nodeName.toLowerCase();
971		return name === "input" && elem.type === type;
972	};
973}
974
975/**
976 * Returns a function to use in pseudos for buttons
977 * @param {String} type
978 */
979function createButtonPseudo( type ) {
980	return function( elem ) {
981		var name = elem.nodeName.toLowerCase();
982		return (name === "input" || name === "button") && elem.type === type;
983	};
984}
985
986/**
987 * Returns a function to use in pseudos for positionals
988 * @param {Function} fn
989 */
990function createPositionalPseudo( fn ) {
991	return markFunction(function( argument ) {
992		argument = +argument;
993		return markFunction(function( seed, matches ) {
994			var j,
995				matchIndexes = fn( [], seed.length, argument ),
996				i = matchIndexes.length;
997
998			// Match elements found at the specified indexes
999			while ( i-- ) {
1000				if ( seed[ (j = matchIndexes[i]) ] ) {
1001					seed[j] = !(matches[j] = seed[j]);
1002				}
1003			}
1004		});
1005	});
1006}
1007
1008/**
1009 * Checks a node for validity as a Sizzle context
1010 * @param {Element|Object=} context
1011 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1012 */
1013function testContext( context ) {
1014	return context && typeof context.getElementsByTagName !== "undefined" && context;
1015}
1016
1017// Expose support vars for convenience
1018support = Sizzle.support = {};
1019
1020/**
1021 * Detects XML nodes
1022 * @param {Element|Object} elem An element or a document
1023 * @returns {Boolean} True iff elem is a non-HTML XML node
1024 */
1025isXML = Sizzle.isXML = function( elem ) {
1026	// documentElement is verified for cases where it doesn't yet exist
1027	// (such as loading iframes in IE - #4833)
1028	var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1029	return documentElement ? documentElement.nodeName !== "HTML" : false;
1030};
1031
1032/**
1033 * Sets document-related variables once based on the current document
1034 * @param {Element|Object} [doc] An element or document object to use to set the document
1035 * @returns {Object} Returns the current document
1036 */
1037setDocument = Sizzle.setDocument = function( node ) {
1038	var hasCompare, parent,
1039		doc = node ? node.ownerDocument || node : preferredDoc;
1040
1041	// Return early if doc is invalid or already selected
1042	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1043		return document;
1044	}
1045
1046	// Update global variables
1047	document = doc;
1048	docElem = document.documentElement;
1049	documentIsHTML = !isXML( document );
1050
1051	// Support: IE 9-11, Edge
1052	// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1053	if ( (parent = document.defaultView) && parent.top !== parent ) {
1054		// Support: IE 11
1055		if ( parent.addEventListener ) {
1056			parent.addEventListener( "unload", unloadHandler, false );
1057
1058		// Support: IE 9 - 10 only
1059		} else if ( parent.attachEvent ) {
1060			parent.attachEvent( "onunload", unloadHandler );
1061		}
1062	}
1063
1064	/* Attributes
1065	---------------------------------------------------------------------- */
1066
1067	// Support: IE<8
1068	// Verify that getAttribute really returns attributes and not properties
1069	// (excepting IE8 booleans)
1070	support.attributes = assert(function( div ) {
1071		div.className = "i";
1072		return !div.getAttribute("className");
1073	});
1074
1075	/* getElement(s)By*
1076	---------------------------------------------------------------------- */
1077
1078	// Check if getElementsByTagName("*") returns only elements
1079	support.getElementsByTagName = assert(function( div ) {
1080		div.appendChild( document.createComment("") );
1081		return !div.getElementsByTagName("*").length;
1082	});
1083
1084	// Support: IE<9
1085	support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1086
1087	// Support: IE<10
1088	// Check if getElementById returns elements by name
1089	// The broken getElementById methods don't pick up programatically-set names,
1090	// so use a roundabout getElementsByName test
1091	support.getById = assert(function( div ) {
1092		docElem.appendChild( div ).id = expando;
1093		return !document.getElementsByName || !document.getElementsByName( expando ).length;
1094	});
1095
1096	// ID find and filter
1097	if ( support.getById ) {
1098		Expr.find["ID"] = function( id, context ) {
1099			if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1100				var m = context.getElementById( id );
1101				return m ? [ m ] : [];
1102			}
1103		};
1104		Expr.filter["ID"] = function( id ) {
1105			var attrId = id.replace( runescape, funescape );
1106			return function( elem ) {
1107				return elem.getAttribute("id") === attrId;
1108			};
1109		};
1110	} else {
1111		// Support: IE6/7
1112		// getElementById is not reliable as a find shortcut
1113		delete Expr.find["ID"];
1114
1115		Expr.filter["ID"] =  function( id ) {
1116			var attrId = id.replace( runescape, funescape );
1117			return function( elem ) {
1118				var node = typeof elem.getAttributeNode !== "undefined" &&
1119					elem.getAttributeNode("id");
1120				return node && node.value === attrId;
1121			};
1122		};
1123	}
1124
1125	// Tag
1126	Expr.find["TAG"] = support.getElementsByTagName ?
1127		function( tag, context ) {
1128			if ( typeof context.getElementsByTagName !== "undefined" ) {
1129				return context.getElementsByTagName( tag );
1130
1131			// DocumentFragment nodes don't have gEBTN
1132			} else if ( support.qsa ) {
1133				return context.querySelectorAll( tag );
1134			}
1135		} :
1136
1137		function( tag, context ) {
1138			var elem,
1139				tmp = [],
1140				i = 0,
1141				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1142				results = context.getElementsByTagName( tag );
1143
1144			// Filter out possible comments
1145			if ( tag === "*" ) {
1146				while ( (elem = results[i++]) ) {
1147					if ( elem.nodeType === 1 ) {
1148						tmp.push( elem );
1149					}
1150				}
1151
1152				return tmp;
1153			}
1154			return results;
1155		};
1156
1157	// Class
1158	Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1159		if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1160			return context.getElementsByClassName( className );
1161		}
1162	};
1163
1164	/* QSA/matchesSelector
1165	---------------------------------------------------------------------- */
1166
1167	// QSA and matchesSelector support
1168
1169	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1170	rbuggyMatches = [];
1171
1172	// qSa(:focus) reports false when true (Chrome 21)
1173	// We allow this because of a bug in IE8/9 that throws an error
1174	// whenever `document.activeElement` is accessed on an iframe
1175	// So, we allow :focus to pass through QSA all the time to avoid the IE error
1176	// See http://bugs.jquery.com/ticket/13378
1177	rbuggyQSA = [];
1178
1179	if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
1180		// Build QSA regex
1181		// Regex strategy adopted from Diego Perini
1182		assert(function( div ) {
1183			// Select is set to empty string on purpose
1184			// This is to test IE's treatment of not explicitly
1185			// setting a boolean content attribute,
1186			// since its presence should be enough
1187			// http://bugs.jquery.com/ticket/12359
1188			docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
1189				"<select id='" + expando + "-\r\\' msallowcapture=''>" +
1190				"<option selected=''></option></select>";
1191
1192			// Support: IE8, Opera 11-12.16
1193			// Nothing should be selected when empty strings follow ^= or $= or *=
1194			// The test attribute must be unknown in Opera but "safe" for WinRT
1195			// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1196			if ( div.querySelectorAll("[msallowcapture^='']").length ) {
1197				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1198			}
1199
1200			// Support: IE8
1201			// Boolean attributes and "value" are not treated correctly
1202			if ( !div.querySelectorAll("[selected]").length ) {
1203				rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1204			}
1205
1206			// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1207			if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1208				rbuggyQSA.push("~=");
1209			}
1210
1211			// Webkit/Opera - :checked should return selected option elements
1212			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1213			// IE8 throws error here and will not see later tests
1214			if ( !div.querySelectorAll(":checked").length ) {
1215				rbuggyQSA.push(":checked");
1216			}
1217
1218			// Support: Safari 8+, iOS 8+
1219			// https://bugs.webkit.org/show_bug.cgi?id=136851
1220			// In-page `selector#id sibing-combinator selector` fails
1221			if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
1222				rbuggyQSA.push(".#.+[+~]");
1223			}
1224		});
1225
1226		assert(function( div ) {
1227			// Support: Windows 8 Native Apps
1228			// The type and name attributes are restricted during .innerHTML assignment
1229			var input = document.createElement("input");
1230			input.setAttribute( "type", "hidden" );
1231			div.appendChild( input ).setAttribute( "name", "D" );
1232
1233			// Support: IE8
1234			// Enforce case-sensitivity of name attribute
1235			if ( div.querySelectorAll("[name=d]").length ) {
1236				rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1237			}
1238
1239			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1240			// IE8 throws error here and will not see later tests
1241			if ( !div.querySelectorAll(":enabled").length ) {
1242				rbuggyQSA.push( ":enabled", ":disabled" );
1243			}
1244
1245			// Opera 10-11 does not throw on post-comma invalid pseudos
1246			div.querySelectorAll("*,:x");
1247			rbuggyQSA.push(",.*:");
1248		});
1249	}
1250
1251	if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
1252		docElem.webkitMatchesSelector ||
1253		docElem.mozMatchesSelector ||
1254		docElem.oMatchesSelector ||
1255		docElem.msMatchesSelector) )) ) {
1256
1257		assert(function( div ) {
1258			// Check to see if it's possible to do matchesSelector
1259			// on a disconnected node (IE 9)
1260			support.disconnectedMatch = matches.call( div, "div" );
1261
1262			// This should fail with an exception
1263			// Gecko does not error, returns false instead
1264			matches.call( div, "[s!='']:x" );
1265			rbuggyMatches.push( "!=", pseudos );
1266		});
1267	}
1268
1269	rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1270	rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1271
1272	/* Contains
1273	---------------------------------------------------------------------- */
1274	hasCompare = rnative.test( docElem.compareDocumentPosition );
1275
1276	// Element contains another
1277	// Purposefully self-exclusive
1278	// As in, an element does not contain itself
1279	contains = hasCompare || rnative.test( docElem.contains ) ?
1280		function( a, b ) {
1281			var adown = a.nodeType === 9 ? a.documentElement : a,
1282				bup = b && b.parentNode;
1283			return a === bup || !!( bup && bup.nodeType === 1 && (
1284				adown.contains ?
1285					adown.contains( bup ) :
1286					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1287			));
1288		} :
1289		function( a, b ) {
1290			if ( b ) {
1291				while ( (b = b.parentNode) ) {
1292					if ( b === a ) {
1293						return true;
1294					}
1295				}
1296			}
1297			return false;
1298		};
1299
1300	/* Sorting
1301	---------------------------------------------------------------------- */
1302
1303	// Document order sorting
1304	sortOrder = hasCompare ?
1305	function( a, b ) {
1306
1307		// Flag for duplicate removal
1308		if ( a === b ) {
1309			hasDuplicate = true;
1310			return 0;
1311		}
1312
1313		// Sort on method existence if only one input has compareDocumentPosition
1314		var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1315		if ( compare ) {
1316			return compare;
1317		}
1318
1319		// Calculate position if both inputs belong to the same document
1320		compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1321			a.compareDocumentPosition( b ) :
1322
1323			// Otherwise we know they are disconnected
1324			1;
1325
1326		// Disconnected nodes
1327		if ( compare & 1 ||
1328			(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1329
1330			// Choose the first element that is related to our preferred document
1331			if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1332				return -1;
1333			}
1334			if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1335				return 1;
1336			}
1337
1338			// Maintain original order
1339			return sortInput ?
1340				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1341				0;
1342		}
1343
1344		return compare & 4 ? -1 : 1;
1345	} :
1346	function( a, b ) {
1347		// Exit early if the nodes are identical
1348		if ( a === b ) {
1349			hasDuplicate = true;
1350			return 0;
1351		}
1352
1353		var cur,
1354			i = 0,
1355			aup = a.parentNode,
1356			bup = b.parentNode,
1357			ap = [ a ],
1358			bp = [ b ];
1359
1360		// Parentless nodes are either documents or disconnected
1361		if ( !aup || !bup ) {
1362			return a === document ? -1 :
1363				b === document ? 1 :
1364				aup ? -1 :
1365				bup ? 1 :
1366				sortInput ?
1367				( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1368				0;
1369
1370		// If the nodes are siblings, we can do a quick check
1371		} else if ( aup === bup ) {
1372			return siblingCheck( a, b );
1373		}
1374
1375		// Otherwise we need full lists of their ancestors for comparison
1376		cur = a;
1377		while ( (cur = cur.parentNode) ) {
1378			ap.unshift( cur );
1379		}
1380		cur = b;
1381		while ( (cur = cur.parentNode) ) {
1382			bp.unshift( cur );
1383		}
1384
1385		// Walk down the tree looking for a discrepancy
1386		while ( ap[i] === bp[i] ) {
1387			i++;
1388		}
1389
1390		return i ?
1391			// Do a sibling check if the nodes have a common ancestor
1392			siblingCheck( ap[i], bp[i] ) :
1393
1394			// Otherwise nodes in our document sort first
1395			ap[i] === preferredDoc ? -1 :
1396			bp[i] === preferredDoc ? 1 :
1397			0;
1398	};
1399
1400	return document;
1401};
1402
1403Sizzle.matches = function( expr, elements ) {
1404	return Sizzle( expr, null, null, elements );
1405};
1406
1407Sizzle.matchesSelector = function( elem, expr ) {
1408	// Set document vars if needed
1409	if ( ( elem.ownerDocument || elem ) !== document ) {
1410		setDocument( elem );
1411	}
1412
1413	// Make sure that attribute selectors are quoted
1414	expr = expr.replace( rattributeQuotes, "='$1']" );
1415
1416	if ( support.matchesSelector && documentIsHTML &&
1417		!compilerCache[ expr + " " ] &&
1418		( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1419		( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
1420
1421		try {
1422			var ret = matches.call( elem, expr );
1423
1424			// IE 9's matchesSelector returns false on disconnected nodes
1425			if ( ret || support.disconnectedMatch ||
1426					// As well, disconnected nodes are said to be in a document
1427					// fragment in IE 9
1428					elem.document && elem.document.nodeType !== 11 ) {
1429				return ret;
1430			}
1431		} catch (e) {}
1432	}
1433
1434	return Sizzle( expr, document, null, [ elem ] ).length > 0;
1435};
1436
1437Sizzle.contains = function( context, elem ) {
1438	// Set document vars if needed
1439	if ( ( context.ownerDocument || context ) !== document ) {
1440		setDocument( context );
1441	}
1442	return contains( context, elem );
1443};
1444
1445Sizzle.attr = function( elem, name ) {
1446	// Set document vars if needed
1447	if ( ( elem.ownerDocument || elem ) !== document ) {
1448		setDocument( elem );
1449	}
1450
1451	var fn = Expr.attrHandle[ name.toLowerCase() ],
1452		// Don't get fooled by Object.prototype properties (jQuery #13807)
1453		val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1454			fn( elem, name, !documentIsHTML ) :
1455			undefined;
1456
1457	return val !== undefined ?
1458		val :
1459		support.attributes || !documentIsHTML ?
1460			elem.getAttribute( name ) :
1461			(val = elem.getAttributeNode(name)) && val.specified ?
1462				val.value :
1463				null;
1464};
1465
1466Sizzle.error = function( msg ) {
1467	throw new Error( "Syntax error, unrecognized expression: " + msg );
1468};
1469
1470/**
1471 * Document sorting and removing duplicates
1472 * @param {ArrayLike} results
1473 */
1474Sizzle.uniqueSort = function( results ) {
1475	var elem,
1476		duplicates = [],
1477		j = 0,
1478		i = 0;
1479
1480	// Unless we *know* we can detect duplicates, assume their presence
1481	hasDuplicate = !support.detectDuplicates;
1482	sortInput = !support.sortStable && results.slice( 0 );
1483	results.sort( sortOrder );
1484
1485	if ( hasDuplicate ) {
1486		while ( (elem = results[i++]) ) {
1487			if ( elem === results[ i ] ) {
1488				j = duplicates.push( i );
1489			}
1490		}
1491		while ( j-- ) {
1492			results.splice( duplicates[ j ], 1 );
1493		}
1494	}
1495
1496	// Clear input after sorting to release objects
1497	// See https://github.com/jquery/sizzle/pull/225
1498	sortInput = null;
1499
1500	return results;
1501};
1502
1503/**
1504 * Utility function for retrieving the text value of an array of DOM nodes
1505 * @param {Array|Element} elem
1506 */
1507getText = Sizzle.getText = function( elem ) {
1508	var node,
1509		ret = "",
1510		i = 0,
1511		nodeType = elem.nodeType;
1512
1513	if ( !nodeType ) {
1514		// If no nodeType, this is expected to be an array
1515		while ( (node = elem[i++]) ) {
1516			// Do not traverse comment nodes
1517			ret += getText( node );
1518		}
1519	} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1520		// Use textContent for elements
1521		// innerText usage removed for consistency of new lines (jQuery #11153)
1522		if ( typeof elem.textContent === "string" ) {
1523			return elem.textContent;
1524		} else {
1525			// Traverse its children
1526			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1527				ret += getText( elem );
1528			}
1529		}
1530	} else if ( nodeType === 3 || nodeType === 4 ) {
1531		return elem.nodeValue;
1532	}
1533	// Do not include comment or processing instruction nodes
1534
1535	return ret;
1536};
1537
1538Expr = Sizzle.selectors = {
1539
1540	// Can be adjusted by the user
1541	cacheLength: 50,
1542
1543	createPseudo: markFunction,
1544
1545	match: matchExpr,
1546
1547	attrHandle: {},
1548
1549	find: {},
1550
1551	relative: {
1552		">": { dir: "parentNode", first: true },
1553		" ": { dir: "parentNode" },
1554		"+": { dir: "previousSibling", first: true },
1555		"~": { dir: "previousSibling" }
1556	},
1557
1558	preFilter: {
1559		"ATTR": function( match ) {
1560			match[1] = match[1].replace( runescape, funescape );
1561
1562			// Move the given value to match[3] whether quoted or unquoted
1563			match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
1564
1565			if ( match[2] === "~=" ) {
1566				match[3] = " " + match[3] + " ";
1567			}
1568
1569			return match.slice( 0, 4 );
1570		},
1571
1572		"CHILD": function( match ) {
1573			/* matches from matchExpr["CHILD"]
1574				1 type (only|nth|...)
1575				2 what (child|of-type)
1576				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1577				4 xn-component of xn+y argument ([+-]?\d*n|)
1578				5 sign of xn-component
1579				6 x of xn-component
1580				7 sign of y-component
1581				8 y of y-component
1582			*/
1583			match[1] = match[1].toLowerCase();
1584
1585			if ( match[1].slice( 0, 3 ) === "nth" ) {
1586				// nth-* requires argument
1587				if ( !match[3] ) {
1588					Sizzle.error( match[0] );
1589				}
1590
1591				// numeric x and y parameters for Expr.filter.CHILD
1592				// remember that false/true cast respectively to 0/1
1593				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1594				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1595
1596			// other types prohibit arguments
1597			} else if ( match[3] ) {
1598				Sizzle.error( match[0] );
1599			}
1600
1601			return match;
1602		},
1603
1604		"PSEUDO": function( match ) {
1605			var excess,
1606				unquoted = !match[6] && match[2];
1607
1608			if ( matchExpr["CHILD"].test( match[0] ) ) {
1609				return null;
1610			}
1611
1612			// Accept quoted arguments as-is
1613			if ( match[3] ) {
1614				match[2] = match[4] || match[5] || "";
1615
1616			// Strip excess characters from unquoted arguments
1617			} else if ( unquoted && rpseudo.test( unquoted ) &&
1618				// Get excess from tokenize (recursively)
1619				(excess = tokenize( unquoted, true )) &&
1620				// advance to the next closing parenthesis
1621				(excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1622
1623				// excess is a negative index
1624				match[0] = match[0].slice( 0, excess );
1625				match[2] = unquoted.slice( 0, excess );
1626			}
1627
1628			// Return only captures needed by the pseudo filter method (type and argument)
1629			return match.slice( 0, 3 );
1630		}
1631	},
1632
1633	filter: {
1634
1635		"TAG": function( nodeNameSelector ) {
1636			var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1637			return nodeNameSelector === "*" ?
1638				function() { return true; } :
1639				function( elem ) {
1640					return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1641				};
1642		},
1643
1644		"CLASS": function( className ) {
1645			var pattern = classCache[ className + " " ];
1646
1647			return pattern ||
1648				(pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1649				classCache( className, function( elem ) {
1650					return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
1651				});
1652		},
1653
1654		"ATTR": function( name, operator, check ) {
1655			return function( elem ) {
1656				var result = Sizzle.attr( elem, name );
1657
1658				if ( result == null ) {
1659					return operator === "!=";
1660				}
1661				if ( !operator ) {
1662					return true;
1663				}
1664
1665				result += "";
1666
1667				return operator === "=" ? result === check :
1668					operator === "!=" ? result !== check :
1669					operator === "^=" ? check && result.indexOf( check ) === 0 :
1670					operator === "*=" ? check && result.indexOf( check ) > -1 :
1671					operator === "$=" ? check && result.slice( -check.length ) === check :
1672					operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
1673					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1674					false;
1675			};
1676		},
1677
1678		"CHILD": function( type, what, argument, first, last ) {
1679			var simple = type.slice( 0, 3 ) !== "nth",
1680				forward = type.slice( -4 ) !== "last",
1681				ofType = what === "of-type";
1682
1683			return first === 1 && last === 0 ?
1684
1685				// Shortcut for :nth-*(n)
1686				function( elem ) {
1687					return !!elem.parentNode;
1688				} :
1689
1690				function( elem, context, xml ) {
1691					var cache, uniqueCache, outerCache, node, nodeIndex, start,
1692						dir = simple !== forward ? "nextSibling" : "previousSibling",
1693						parent = elem.parentNode,
1694						name = ofType && elem.nodeName.toLowerCase(),
1695						useCache = !xml && !ofType,
1696						diff = false;
1697
1698					if ( parent ) {
1699
1700						// :(first|last|only)-(child|of-type)
1701						if ( simple ) {
1702							while ( dir ) {
1703								node = elem;
1704								while ( (node = node[ dir ]) ) {
1705									if ( ofType ?
1706										node.nodeName.toLowerCase() === name :
1707										node.nodeType === 1 ) {
1708
1709										return false;
1710									}
1711								}
1712								// Reverse direction for :only-* (if we haven't yet done so)
1713								start = dir = type === "only" && !start && "nextSibling";
1714							}
1715							return true;
1716						}
1717
1718						start = [ forward ? parent.firstChild : parent.lastChild ];
1719
1720						// non-xml :nth-child(...) stores cache data on `parent`
1721						if ( forward && useCache ) {
1722
1723							// Seek `elem` from a previously-cached index
1724
1725							// ...in a gzip-friendly way
1726							node = parent;
1727							outerCache = node[ expando ] || (node[ expando ] = {});
1728
1729							// Support: IE <9 only
1730							// Defend against cloned attroperties (jQuery gh-1709)
1731							uniqueCache = outerCache[ node.uniqueID ] ||
1732								(outerCache[ node.uniqueID ] = {});
1733
1734							cache = uniqueCache[ type ] || [];
1735							nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1736							diff = nodeIndex && cache[ 2 ];
1737							node = nodeIndex && parent.childNodes[ nodeIndex ];
1738
1739							while ( (node = ++nodeIndex && node && node[ dir ] ||
1740
1741								// Fallback to seeking `elem` from the start
1742								(diff = nodeIndex = 0) || start.pop()) ) {
1743
1744								// When found, cache indexes on `parent` and break
1745								if ( node.nodeType === 1 && ++diff && node === elem ) {
1746									uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
1747									break;
1748								}
1749							}
1750
1751						} else {
1752							// Use previously-cached element index if available
1753							if ( useCache ) {
1754								// ...in a gzip-friendly way
1755								node = elem;
1756								outerCache = node[ expando ] || (node[ expando ] = {});
1757
1758								// Support: IE <9 only
1759								// Defend against cloned attroperties (jQuery gh-1709)
1760								uniqueCache = outerCache[ node.uniqueID ] ||
1761									(outerCache[ node.uniqueID ] = {});
1762
1763								cache = uniqueCache[ type ] || [];
1764								nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
1765								diff = nodeIndex;
1766							}
1767
1768							// xml :nth-child(...)
1769							// or :nth-last-child(...) or :nth(-last)?-of-type(...)
1770							if ( diff === false ) {
1771								// Use the same loop as above to seek `elem` from the start
1772								while ( (node = ++nodeIndex && node && node[ dir ] ||
1773									(diff = nodeIndex = 0) || start.pop()) ) {
1774
1775									if ( ( ofType ?
1776										node.nodeName.toLowerCase() === name :
1777										node.nodeType === 1 ) &&
1778										++diff ) {
1779
1780										// Cache the index of each encountered element
1781										if ( useCache ) {
1782											outerCache = node[ expando ] || (node[ expando ] = {});
1783
1784											// Support: IE <9 only
1785											// Defend against cloned attroperties (jQuery gh-1709)
1786											uniqueCache = outerCache[ node.uniqueID ] ||
1787												(outerCache[ node.uniqueID ] = {});
1788
1789											uniqueCache[ type ] = [ dirruns, diff ];
1790										}
1791
1792										if ( node === elem ) {
1793											break;
1794										}
1795									}
1796								}
1797							}
1798						}
1799
1800						// Incorporate the offset, then check against cycle size
1801						diff -= last;
1802						return diff === first || ( diff % first === 0 && diff / first >= 0 );
1803					}
1804				};
1805		},
1806
1807		"PSEUDO": function( pseudo, argument ) {
1808			// pseudo-class names are case-insensitive
1809			// http://www.w3.org/TR/selectors/#pseudo-classes
1810			// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
1811			// Remember that setFilters inherits from pseudos
1812			var args,
1813				fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
1814					Sizzle.error( "unsupported pseudo: " + pseudo );
1815
1816			// The user may use createPseudo to indicate that
1817			// arguments are needed to create the filter function
1818			// just as Sizzle does
1819			if ( fn[ expando ] ) {
1820				return fn( argument );
1821			}
1822
1823			// But maintain support for old signatures
1824			if ( fn.length > 1 ) {
1825				args = [ pseudo, pseudo, "", argument ];
1826				return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
1827					markFunction(function( seed, matches ) {
1828						var idx,
1829							matched = fn( seed, argument ),
1830							i = matched.length;
1831						while ( i-- ) {
1832							idx = indexOf( seed, matched[i] );
1833							seed[ idx ] = !( matches[ idx ] = matched[i] );
1834						}
1835					}) :
1836					function( elem ) {
1837						return fn( elem, 0, args );
1838					};
1839			}
1840
1841			return fn;
1842		}
1843	},
1844
1845	pseudos: {
1846		// Potentially complex pseudos
1847		"not": markFunction(function( selector ) {
1848			// Trim the selector passed to compile
1849			// to avoid treating leading and trailing
1850			// spaces as combinators
1851			var input = [],
1852				results = [],
1853				matcher = compile( selector.replace( rtrim, "$1" ) );
1854
1855			return matcher[ expando ] ?
1856				markFunction(function( seed, matches, context, xml ) {
1857					var elem,
1858						unmatched = matcher( seed, null, xml, [] ),
1859						i = seed.length;
1860
1861					// Match elements unmatched by `matcher`
1862					while ( i-- ) {
1863						if ( (elem = unmatched[i]) ) {
1864							seed[i] = !(matches[i] = elem);
1865						}
1866					}
1867				}) :
1868				function( elem, context, xml ) {
1869					input[0] = elem;
1870					matcher( input, null, xml, results );
1871					// Don't keep the element (issue #299)
1872					input[0] = null;
1873					return !results.pop();
1874				};
1875		}),
1876
1877		"has": markFunction(function( selector ) {
1878			return function( elem ) {
1879				return Sizzle( selector, elem ).length > 0;
1880			};
1881		}),
1882
1883		"contains": markFunction(function( text ) {
1884			text = text.replace( runescape, funescape );
1885			return function( elem ) {
1886				return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
1887			};
1888		}),
1889
1890		// "Whether an element is represented by a :lang() selector
1891		// is based solely on the element's language value
1892		// being equal to the identifier C,
1893		// or beginning with the identifier C immediately followed by "-".
1894		// The matching of C against the element's language value is performed case-insensitively.
1895		// The identifier C does not have to be a valid language name."
1896		// http://www.w3.org/TR/selectors/#lang-pseudo
1897		"lang": markFunction( function( lang ) {
1898			// lang value must be a valid identifier
1899			if ( !ridentifier.test(lang || "") ) {
1900				Sizzle.error( "unsupported lang: " + lang );
1901			}
1902			lang = lang.replace( runescape, funescape ).toLowerCase();
1903			return function( elem ) {
1904				var elemLang;
1905				do {
1906					if ( (elemLang = documentIsHTML ?
1907						elem.lang :
1908						elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
1909
1910						elemLang = elemLang.toLowerCase();
1911						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
1912					}
1913				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
1914				return false;
1915			};
1916		}),
1917
1918		// Miscellaneous
1919		"target": function( elem ) {
1920			var hash = window.location && window.location.hash;
1921			return hash && hash.slice( 1 ) === elem.id;
1922		},
1923
1924		"root": function( elem ) {
1925			return elem === docElem;
1926		},
1927
1928		"focus": function( elem ) {
1929			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
1930		},
1931
1932		// Boolean properties
1933		"enabled": function( elem ) {
1934			return elem.disabled === false;
1935		},
1936
1937		"disabled": function( elem ) {
1938			return elem.disabled === true;
1939		},
1940
1941		"checked": function( elem ) {
1942			// In CSS3, :checked should return both checked and selected elements
1943			// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1944			var nodeName = elem.nodeName.toLowerCase();
1945			return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
1946		},
1947
1948		"selected": function( elem ) {
1949			// Accessing this property makes selected-by-default
1950			// options in Safari work properly
1951			if ( elem.parentNode ) {
1952				elem.parentNode.selectedIndex;
1953			}
1954
1955			return elem.selected === true;
1956		},
1957
1958		// Contents
1959		"empty": function( elem ) {
1960			// http://www.w3.org/TR/selectors/#empty-pseudo
1961			// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
1962			//   but not by others (comment: 8; processing instruction: 7; etc.)
1963			// nodeType < 6 works because attributes (2) do not appear as children
1964			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1965				if ( elem.nodeType < 6 ) {
1966					return false;
1967				}
1968			}
1969			return true;
1970		},
1971
1972		"parent": function( elem ) {
1973			return !Expr.pseudos["empty"]( elem );
1974		},
1975
1976		// Element/input types
1977		"header": function( elem ) {
1978			return rheader.test( elem.nodeName );
1979		},
1980
1981		"input": function( elem ) {
1982			return rinputs.test( elem.nodeName );
1983		},
1984
1985		"button": function( elem ) {
1986			var name = elem.nodeName.toLowerCase();
1987			return name === "input" && elem.type === "button" || name === "button";
1988		},
1989
1990		"text": function( elem ) {
1991			var attr;
1992			return elem.nodeName.toLowerCase() === "input" &&
1993				elem.type === "text" &&
1994
1995				// Support: IE<8
1996				// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
1997				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
1998		},
1999
2000		// Position-in-collection
2001		"first": createPositionalPseudo(function() {
2002			return [ 0 ];
2003		}),
2004
2005		"last": createPositionalPseudo(function( matchIndexes, length ) {
2006			return [ length - 1 ];
2007		}),
2008
2009		"eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2010			return [ argument < 0 ? argument + length : argument ];
2011		}),
2012
2013		"even": createPositionalPseudo(function( matchIndexes, length ) {
2014			var i = 0;
2015			for ( ; i < length; i += 2 ) {
2016				matchIndexes.push( i );
2017			}
2018			return matchIndexes;
2019		}),
2020
2021		"odd": createPositionalPseudo(function( matchIndexes, length ) {
2022			var i = 1;
2023			for ( ; i < length; i += 2 ) {
2024				matchIndexes.push( i );
2025			}
2026			return matchIndexes;
2027		}),
2028
2029		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2030			var i = argument < 0 ? argument + length : argument;
2031			for ( ; --i >= 0; ) {
2032				matchIndexes.push( i );
2033			}
2034			return matchIndexes;
2035		}),
2036
2037		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2038			var i = argument < 0 ? argument + length : argument;
2039			for ( ; ++i < length; ) {
2040				matchIndexes.push( i );
2041			}
2042			return matchIndexes;
2043		})
2044	}
2045};
2046
2047Expr.pseudos["nth"] = Expr.pseudos["eq"];
2048
2049// Add button/input type pseudos
2050for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2051	Expr.pseudos[ i ] = createInputPseudo( i );
2052}
2053for ( i in { submit: true, reset: true } ) {
2054	Expr.pseudos[ i ] = createButtonPseudo( i );
2055}
2056
2057// Easy API for creating new setFilters
2058function setFilters() {}
2059setFilters.prototype = Expr.filters = Expr.pseudos;
2060Expr.setFilters = new setFilters();
2061
2062tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2063	var matched, match, tokens, type,
2064		soFar, groups, preFilters,
2065		cached = tokenCache[ selector + " " ];
2066
2067	if ( cached ) {
2068		return parseOnly ? 0 : cached.slice( 0 );
2069	}
2070
2071	soFar = selector;
2072	groups = [];
2073	preFilters = Expr.preFilter;
2074
2075	while ( soFar ) {
2076
2077		// Comma and first run
2078		if ( !matched || (match = rcomma.exec( soFar )) ) {
2079			if ( match ) {
2080				// Don't consume trailing commas as valid
2081				soFar = soFar.slice( match[0].length ) || soFar;
2082			}
2083			groups.push( (tokens = []) );
2084		}
2085
2086		matched = false;
2087
2088		// Combinators
2089		if ( (match = rcombinators.exec( soFar )) ) {
2090			matched = match.shift();
2091			tokens.push({
2092				value: matched,
2093				// Cast descendant combinators to space
2094				type: match[0].replace( rtrim, " " )
2095			});
2096			soFar = soFar.slice( matched.length );
2097		}
2098
2099		// Filters
2100		for ( type in Expr.filter ) {
2101			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2102				(match = preFilters[ type ]( match ))) ) {
2103				matched = match.shift();
2104				tokens.push({
2105					value: matched,
2106					type: type,
2107					matches: match
2108				});
2109				soFar = soFar.slice( matched.length );
2110			}
2111		}
2112
2113		if ( !matched ) {
2114			break;
2115		}
2116	}
2117
2118	// Return the length of the invalid excess
2119	// if we're just parsing
2120	// Otherwise, throw an error or return tokens
2121	return parseOnly ?
2122		soFar.length :
2123		soFar ?
2124			Sizzle.error( selector ) :
2125			// Cache the tokens
2126			tokenCache( selector, groups ).slice( 0 );
2127};
2128
2129function toSelector( tokens ) {
2130	var i = 0,
2131		len = tokens.length,
2132		selector = "";
2133	for ( ; i < len; i++ ) {
2134		selector += tokens[i].value;
2135	}
2136	return selector;
2137}
2138
2139function addCombinator( matcher, combinator, base ) {
2140	var dir = combinator.dir,
2141		checkNonElements = base && dir === "parentNode",
2142		doneName = done++;
2143
2144	return combinator.first ?
2145		// Check against closest ancestor/preceding element
2146		function( elem, context, xml ) {
2147			while ( (elem = elem[ dir ]) ) {
2148				if ( elem.nodeType === 1 || checkNonElements ) {
2149					return matcher( elem, context, xml );
2150				}
2151			}
2152		} :
2153
2154		// Check against all ancestor/preceding elements
2155		function( elem, context, xml ) {
2156			var oldCache, uniqueCache, outerCache,
2157				newCache = [ dirruns, doneName ];
2158
2159			// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2160			if ( xml ) {
2161				while ( (elem = elem[ dir ]) ) {
2162					if ( elem.nodeType === 1 || checkNonElements ) {
2163						if ( matcher( elem, context, xml ) ) {
2164							return true;
2165						}
2166					}
2167				}
2168			} else {
2169				while ( (elem = elem[ dir ]) ) {
2170					if ( elem.nodeType === 1 || checkNonElements ) {
2171						outerCache = elem[ expando ] || (elem[ expando ] = {});
2172
2173						// Support: IE <9 only
2174						// Defend against cloned attroperties (jQuery gh-1709)
2175						uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
2176
2177						if ( (oldCache = uniqueCache[ dir ]) &&
2178							oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2179
2180							// Assign to newCache so results back-propagate to previous elements
2181							return (newCache[ 2 ] = oldCache[ 2 ]);
2182						} else {
2183							// Reuse newcache so results back-propagate to previous elements
2184							uniqueCache[ dir ] = newCache;
2185
2186							// A match means we're done; a fail means we have to keep checking
2187							if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2188								return true;
2189							}
2190						}
2191					}
2192				}
2193			}
2194		};
2195}
2196
2197function elementMatcher( matchers ) {
2198	return matchers.length > 1 ?
2199		function( elem, context, xml ) {
2200			var i = matchers.length;
2201			while ( i-- ) {
2202				if ( !matchers[i]( elem, context, xml ) ) {
2203					return false;
2204				}
2205			}
2206			return true;
2207		} :
2208		matchers[0];
2209}
2210
2211function multipleContexts( selector, contexts, results ) {
2212	var i = 0,
2213		len = contexts.length;
2214	for ( ; i < len; i++ ) {
2215		Sizzle( selector, contexts[i], results );
2216	}
2217	return results;
2218}
2219
2220function condense( unmatched, map, filter, context, xml ) {
2221	var elem,
2222		newUnmatched = [],
2223		i = 0,
2224		len = unmatched.length,
2225		mapped = map != null;
2226
2227	for ( ; i < len; i++ ) {
2228		if ( (elem = unmatched[i]) ) {
2229			if ( !filter || filter( elem, context, xml ) ) {
2230				newUnmatched.push( elem );
2231				if ( mapped ) {
2232					map.push( i );
2233				}
2234			}
2235		}
2236	}
2237
2238	return newUnmatched;
2239}
2240
2241function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2242	if ( postFilter && !postFilter[ expando ] ) {
2243		postFilter = setMatcher( postFilter );
2244	}
2245	if ( postFinder && !postFinder[ expando ] ) {
2246		postFinder = setMatcher( postFinder, postSelector );
2247	}
2248	return markFunction(function( seed, results, context, xml ) {
2249		var temp, i, elem,
2250			preMap = [],
2251			postMap = [],
2252			preexisting = results.length,
2253
2254			// Get initial elements from seed or context
2255			elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2256
2257			// Prefilter to get matcher input, preserving a map for seed-results synchronization
2258			matcherIn = preFilter && ( seed || !selector ) ?
2259				condense( elems, preMap, preFilter, context, xml ) :
2260				elems,
2261
2262			matcherOut = matcher ?
2263				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2264				postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2265
2266					// ...intermediate processing is necessary
2267					[] :
2268
2269					// ...otherwise use results directly
2270					results :
2271				matcherIn;
2272
2273		// Find primary matches
2274		if ( matcher ) {
2275			matcher( matcherIn, matcherOut, context, xml );
2276		}
2277
2278		// Apply postFilter
2279		if ( postFilter ) {
2280			temp = condense( matcherOut, postMap );
2281			postFilter( temp, [], context, xml );
2282
2283			// Un-match failing elements by moving them back to matcherIn
2284			i = temp.length;
2285			while ( i-- ) {
2286				if ( (elem = temp[i]) ) {
2287					matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2288				}
2289			}
2290		}
2291
2292		if ( seed ) {
2293			if ( postFinder || preFilter ) {
2294				if ( postFinder ) {
2295					// Get the final matcherOut by condensing this intermediate into postFinder contexts
2296					temp = [];
2297					i = matcherOut.length;
2298					while ( i-- ) {
2299						if ( (elem = matcherOut[i]) ) {
2300							// Restore matcherIn since elem is not yet a final match
2301							temp.push( (matcherIn[i] = elem) );
2302						}
2303					}
2304					postFinder( null, (matcherOut = []), temp, xml );
2305				}
2306
2307				// Move matched elements from seed to results to keep them synchronized
2308				i = matcherOut.length;
2309				while ( i-- ) {
2310					if ( (elem = matcherOut[i]) &&
2311						(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
2312
2313						seed[temp] = !(results[temp] = elem);
2314					}
2315				}
2316			}
2317
2318		// Add elements to results, through postFinder if defined
2319		} else {
2320			matcherOut = condense(
2321				matcherOut === results ?
2322					matcherOut.splice( preexisting, matcherOut.length ) :
2323					matcherOut
2324			);
2325			if ( postFinder ) {
2326				postFinder( null, results, matcherOut, xml );
2327			} else {
2328				push.apply( results, matcherOut );
2329			}
2330		}
2331	});
2332}
2333
2334function matcherFromTokens( tokens ) {
2335	var checkContext, matcher, j,
2336		len = tokens.length,
2337		leadingRelative = Expr.relative[ tokens[0].type ],
2338		implicitRelative = leadingRelative || Expr.relative[" "],
2339		i = leadingRelative ? 1 : 0,
2340
2341		// The foundational matcher ensures that elements are reachable from top-level context(s)
2342		matchContext = addCombinator( function( elem ) {
2343			return elem === checkContext;
2344		}, implicitRelative, true ),
2345		matchAnyContext = addCombinator( function( elem ) {
2346			return indexOf( checkContext, elem ) > -1;
2347		}, implicitRelative, true ),
2348		matchers = [ function( elem, context, xml ) {
2349			var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2350				(checkContext = context).nodeType ?
2351					matchContext( elem, context, xml ) :
2352					matchAnyContext( elem, context, xml ) );
2353			// Avoid hanging onto element (issue #299)
2354			checkContext = null;
2355			return ret;
2356		} ];
2357
2358	for ( ; i < len; i++ ) {
2359		if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2360			matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2361		} else {
2362			matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2363
2364			// Return special upon seeing a positional matcher
2365			if ( matcher[ expando ] ) {
2366				// Find the next relative operator (if any) for proper handling
2367				j = ++i;
2368				for ( ; j < len; j++ ) {
2369					if ( Expr.relative[ tokens[j].type ] ) {
2370						break;
2371					}
2372				}
2373				return setMatcher(
2374					i > 1 && elementMatcher( matchers ),
2375					i > 1 && toSelector(
2376						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
2377						tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2378					).replace( rtrim, "$1" ),
2379					matcher,
2380					i < j && matcherFromTokens( tokens.slice( i, j ) ),
2381					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2382					j < len && toSelector( tokens )
2383				);
2384			}
2385			matchers.push( matcher );
2386		}
2387	}
2388
2389	return elementMatcher( matchers );
2390}
2391
2392function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2393	var bySet = setMatchers.length > 0,
2394		byElement = elementMatchers.length > 0,
2395		superMatcher = function( seed, context, xml, results, outermost ) {
2396			var elem, j, matcher,
2397				matchedCount = 0,
2398				i = "0",
2399				unmatched = seed && [],
2400				setMatched = [],
2401				contextBackup = outermostContext,
2402				// We must always have either seed elements or outermost context
2403				elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2404				// Use integer dirruns iff this is the outermost matcher
2405				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2406				len = elems.length;
2407
2408			if ( outermost ) {
2409				outermostContext = context === document || context || outermost;
2410			}
2411
2412			// Add elements passing elementMatchers directly to results
2413			// Support: IE<9, Safari
2414			// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2415			for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2416				if ( byElement && elem ) {
2417					j = 0;
2418					if ( !context && elem.ownerDocument !== document ) {
2419						setDocument( elem );
2420						xml = !documentIsHTML;
2421					}
2422					while ( (matcher = elementMatchers[j++]) ) {
2423						if ( matcher( elem, context || document, xml) ) {
2424							results.push( elem );
2425							break;
2426						}
2427					}
2428					if ( outermost ) {
2429						dirruns = dirrunsUnique;
2430					}
2431				}
2432
2433				// Track unmatched elements for set filters
2434				if ( bySet ) {
2435					// They will have gone through all possible matchers
2436					if ( (elem = !matcher && elem) ) {
2437						matchedCount--;
2438					}
2439
2440					// Lengthen the array for every element, matched or not
2441					if ( seed ) {
2442						unmatched.push( elem );
2443					}
2444				}
2445			}
2446
2447			// `i` is now the count of elements visited above, and adding it to `matchedCount`
2448			// makes the latter nonnegative.
2449			matchedCount += i;
2450
2451			// Apply set filters to unmatched elements
2452			// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
2453			// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
2454			// no element matchers and no seed.
2455			// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
2456			// case, which will result in a "00" `matchedCount` that differs from `i` but is also
2457			// numerically zero.
2458			if ( bySet && i !== matchedCount ) {
2459				j = 0;
2460				while ( (matcher = setMatchers[j++]) ) {
2461					matcher( unmatched, setMatched, context, xml );
2462				}
2463
2464				if ( seed ) {
2465					// Reintegrate element matches to eliminate the need for sorting
2466					if ( matchedCount > 0 ) {
2467						while ( i-- ) {
2468							if ( !(unmatched[i] || setMatched[i]) ) {
2469								setMatched[i] = pop.call( results );
2470							}
2471						}
2472					}
2473
2474					// Discard index placeholder values to get only actual matches
2475					setMatched = condense( setMatched );
2476				}
2477
2478				// Add matches to results
2479				push.apply( results, setMatched );
2480
2481				// Seedless set matches succeeding multiple successful matchers stipulate sorting
2482				if ( outermost && !seed && setMatched.length > 0 &&
2483					( matchedCount + setMatchers.length ) > 1 ) {
2484
2485					Sizzle.uniqueSort( results );
2486				}
2487			}
2488
2489			// Override manipulation of globals by nested matchers
2490			if ( outermost ) {
2491				dirruns = dirrunsUnique;
2492				outermostContext = contextBackup;
2493			}
2494
2495			return unmatched;
2496		};
2497
2498	return bySet ?
2499		markFunction( superMatcher ) :
2500		superMatcher;
2501}
2502
2503compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2504	var i,
2505		setMatchers = [],
2506		elementMatchers = [],
2507		cached = compilerCache[ selector + " " ];
2508
2509	if ( !cached ) {
2510		// Generate a function of recursive functions that can be used to check each element
2511		if ( !match ) {
2512			match = tokenize( selector );
2513		}
2514		i = match.length;
2515		while ( i-- ) {
2516			cached = matcherFromTokens( match[i] );
2517			if ( cached[ expando ] ) {
2518				setMatchers.push( cached );
2519			} else {
2520				elementMatchers.push( cached );
2521			}
2522		}
2523
2524		// Cache the compiled function
2525		cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2526
2527		// Save selector and tokenization
2528		cached.selector = selector;
2529	}
2530	return cached;
2531};
2532
2533/**
2534 * A low-level selection function that works with Sizzle's compiled
2535 *  selector functions
2536 * @param {String|Function} selector A selector or a pre-compiled
2537 *  selector function built with Sizzle.compile
2538 * @param {Element} context
2539 * @param {Array} [results]
2540 * @param {Array} [seed] A set of elements to match against
2541 */
2542select = Sizzle.select = function( selector, context, results, seed ) {
2543	var i, tokens, token, type, find,
2544		compiled = typeof selector === "function" && selector,
2545		match = !seed && tokenize( (selector = compiled.selector || selector) );
2546
2547	results = results || [];
2548
2549	// Try to minimize operations if there is only one selector in the list and no seed
2550	// (the latter of which guarantees us context)
2551	if ( match.length === 1 ) {
2552
2553		// Reduce context if the leading compound selector is an ID
2554		tokens = match[0] = match[0].slice( 0 );
2555		if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2556				support.getById && context.nodeType === 9 && documentIsHTML &&
2557				Expr.relative[ tokens[1].type ] ) {
2558
2559			context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2560			if ( !context ) {
2561				return results;
2562
2563			// Precompiled matchers will still verify ancestry, so step up a level
2564			} else if ( compiled ) {
2565				context = context.parentNode;
2566			}
2567
2568			selector = selector.slice( tokens.shift().value.length );
2569		}
2570
2571		// Fetch a seed set for right-to-left matching
2572		i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2573		while ( i-- ) {
2574			token = tokens[i];
2575
2576			// Abort if we hit a combinator
2577			if ( Expr.relative[ (type = token.type) ] ) {
2578				break;
2579			}
2580			if ( (find = Expr.find[ type ]) ) {
2581				// Search, expanding context for leading sibling combinators
2582				if ( (seed = find(
2583					token.matches[0].replace( runescape, funescape ),
2584					rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2585				)) ) {
2586
2587					// If seed is empty or no tokens remain, we can return early
2588					tokens.splice( i, 1 );
2589					selector = seed.length && toSelector( tokens );
2590					if ( !selector ) {
2591						push.apply( results, seed );
2592						return results;
2593					}
2594
2595					break;
2596				}
2597			}
2598		}
2599	}
2600
2601	// Compile and execute a filtering function if one is not provided
2602	// Provide `match` to avoid retokenization if we modified the selector above
2603	( compiled || compile( selector, match ) )(
2604		seed,
2605		context,
2606		!documentIsHTML,
2607		results,
2608		!context || rsibling.test( selector ) && testContext( context.parentNode ) || context
2609	);
2610	return results;
2611};
2612
2613// One-time assignments
2614
2615// Sort stability
2616support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2617
2618// Support: Chrome 14-35+
2619// Always assume duplicates if they aren't passed to the comparison function
2620support.detectDuplicates = !!hasDuplicate;
2621
2622// Initialize against the default document
2623setDocument();
2624
2625// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2626// Detached nodes confoundingly follow *each other*
2627support.sortDetached = assert(function( div1 ) {
2628	// Should return 1, but returns 4 (following)
2629	return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2630});
2631
2632// Support: IE<8
2633// Prevent attribute/property "interpolation"
2634// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2635if ( !assert(function( div ) {
2636	div.innerHTML = "<a href='#'></a>";
2637	return div.firstChild.getAttribute("href") === "#" ;
2638}) ) {
2639	addHandle( "type|href|height|width", function( elem, name, isXML ) {
2640		if ( !isXML ) {
2641			return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2642		}
2643	});
2644}
2645
2646// Support: IE<9
2647// Use defaultValue in place of getAttribute("value")
2648if ( !support.attributes || !assert(function( div ) {
2649	div.innerHTML = "<input/>";
2650	div.firstChild.setAttribute( "value", "" );
2651	return div.firstChild.getAttribute( "value" ) === "";
2652}) ) {
2653	addHandle( "value", function( elem, name, isXML ) {
2654		if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2655			return elem.defaultValue;
2656		}
2657	});
2658}
2659
2660// Support: IE<9
2661// Use getAttributeNode to fetch booleans when getAttribute lies
2662if ( !assert(function( div ) {
2663	return div.getAttribute("disabled") == null;
2664}) ) {
2665	addHandle( booleans, function( elem, name, isXML ) {
2666		var val;
2667		if ( !isXML ) {
2668			return elem[ name ] === true ? name.toLowerCase() :
2669					(val = elem.getAttributeNode( name )) && val.specified ?
2670					val.value :
2671				null;
2672		}
2673	});
2674}
2675
2676return Sizzle;
2677
2678})( window );
2679
2680
2681
2682jQuery.find = Sizzle;
2683jQuery.expr = Sizzle.selectors;
2684jQuery.expr[ ":" ] = jQuery.expr.pseudos;
2685jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
2686jQuery.text = Sizzle.getText;
2687jQuery.isXMLDoc = Sizzle.isXML;
2688jQuery.contains = Sizzle.contains;
2689
2690
2691
2692var dir = function( elem, dir, until ) {
2693	var matched = [],
2694		truncate = until !== undefined;
2695
2696	while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
2697		if ( elem.nodeType === 1 ) {
2698			if ( truncate && jQuery( elem ).is( until ) ) {
2699				break;
2700			}
2701			matched.push( elem );
2702		}
2703	}
2704	return matched;
2705};
2706
2707
2708var siblings = function( n, elem ) {
2709	var matched = [];
2710
2711	for ( ; n; n = n.nextSibling ) {
2712		if ( n.nodeType === 1 && n !== elem ) {
2713			matched.push( n );
2714		}
2715	}
2716
2717	return matched;
2718};
2719
2720
2721var rneedsContext = jQuery.expr.match.needsContext;
2722
2723var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
2724
2725
2726
2727var risSimple = /^.[^:#\[\.,]*$/;
2728
2729// Implement the identical functionality for filter and not
2730function winnow( elements, qualifier, not ) {
2731	if ( jQuery.isFunction( qualifier ) ) {
2732		return jQuery.grep( elements, function( elem, i ) {
2733			/* jshint -W018 */
2734			return !!qualifier.call( elem, i, elem ) !== not;
2735		} );
2736
2737	}
2738
2739	if ( qualifier.nodeType ) {
2740		return jQuery.grep( elements, function( elem ) {
2741			return ( elem === qualifier ) !== not;
2742		} );
2743
2744	}
2745
2746	if ( typeof qualifier === "string" ) {
2747		if ( risSimple.test( qualifier ) ) {
2748			return jQuery.filter( qualifier, elements, not );
2749		}
2750
2751		qualifier = jQuery.filter( qualifier, elements );
2752	}
2753
2754	return jQuery.grep( elements, function( elem ) {
2755		return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
2756	} );
2757}
2758
2759jQuery.filter = function( expr, elems, not ) {
2760	var elem = elems[ 0 ];
2761
2762	if ( not ) {
2763		expr = ":not(" + expr + ")";
2764	}
2765
2766	return elems.length === 1 && elem.nodeType === 1 ?
2767		jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
2768		jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
2769			return elem.nodeType === 1;
2770		} ) );
2771};
2772
2773jQuery.fn.extend( {
2774	find: function( selector ) {
2775		var i,
2776			len = this.length,
2777			ret = [],
2778			self = this;
2779
2780		if ( typeof selector !== "string" ) {
2781			return this.pushStack( jQuery( selector ).filter( function() {
2782				for ( i = 0; i < len; i++ ) {
2783					if ( jQuery.contains( self[ i ], this ) ) {
2784						return true;
2785					}
2786				}
2787			} ) );
2788		}
2789
2790		for ( i = 0; i < len; i++ ) {
2791			jQuery.find( selector, self[ i ], ret );
2792		}
2793
2794		// Needed because $( selector, context ) becomes $( context ).find( selector )
2795		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
2796		ret.selector = this.selector ? this.selector + " " + selector : selector;
2797		return ret;
2798	},
2799	filter: function( selector ) {
2800		return this.pushStack( winnow( this, selector || [], false ) );
2801	},
2802	not: function( selector ) {
2803		return this.pushStack( winnow( this, selector || [], true ) );
2804	},
2805	is: function( selector ) {
2806		return !!winnow(
2807			this,
2808
2809			// If this is a positional/relative selector, check membership in the returned set
2810			// so $("p:first").is("p:last") won't return true for a doc with two "p".
2811			typeof selector === "string" && rneedsContext.test( selector ) ?
2812				jQuery( selector ) :
2813				selector || [],
2814			false
2815		).length;
2816	}
2817} );
2818
2819
2820// Initialize a jQuery object
2821
2822
2823// A central reference to the root jQuery(document)
2824var rootjQuery,
2825
2826	// A simple way to check for HTML strings
2827	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
2828	// Strict HTML recognition (#11290: must start with <)
2829	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
2830
2831	init = jQuery.fn.init = function( selector, context, root ) {
2832		var match, elem;
2833
2834		// HANDLE: $(""), $(null), $(undefined), $(false)
2835		if ( !selector ) {
2836			return this;
2837		}
2838
2839		// Method init() accepts an alternate rootjQuery
2840		// so migrate can support jQuery.sub (gh-2101)
2841		root = root || rootjQuery;
2842
2843		// Handle HTML strings
2844		if ( typeof selector === "string" ) {
2845			if ( selector[ 0 ] === "<" &&
2846				selector[ selector.length - 1 ] === ">" &&
2847				selector.length >= 3 ) {
2848
2849				// Assume that strings that start and end with <> are HTML and skip the regex check
2850				match = [ null, selector, null ];
2851
2852			} else {
2853				match = rquickExpr.exec( selector );
2854			}
2855
2856			// Match html or make sure no context is specified for #id
2857			if ( match && ( match[ 1 ] || !context ) ) {
2858
2859				// HANDLE: $(html) -> $(array)
2860				if ( match[ 1 ] ) {
2861					context = context instanceof jQuery ? context[ 0 ] : context;
2862
2863					// Option to run scripts is true for back-compat
2864					// Intentionally let the error be thrown if parseHTML is not present
2865					jQuery.merge( this, jQuery.parseHTML(
2866						match[ 1 ],
2867						context && context.nodeType ? context.ownerDocument || context : document,
2868						true
2869					) );
2870
2871					// HANDLE: $(html, props)
2872					if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
2873						for ( match in context ) {
2874
2875							// Properties of context are called as methods if possible
2876							if ( jQuery.isFunction( this[ match ] ) ) {
2877								this[ match ]( context[ match ] );
2878
2879							// ...and otherwise set as attributes
2880							} else {
2881								this.attr( match, context[ match ] );
2882							}
2883						}
2884					}
2885
2886					return this;
2887
2888				// HANDLE: $(#id)
2889				} else {
2890					elem = document.getElementById( match[ 2 ] );
2891
2892					// Support: Blackberry 4.6
2893					// gEBID returns nodes no longer in the document (#6963)
2894					if ( elem && elem.parentNode ) {
2895
2896						// Inject the element directly into the jQuery object
2897						this.length = 1;
2898						this[ 0 ] = elem;
2899					}
2900
2901					this.context = document;
2902					this.selector = selector;
2903					return this;
2904				}
2905
2906			// HANDLE: $(expr, $(...))
2907			} else if ( !context || context.jquery ) {
2908				return ( context || root ).find( selector );
2909
2910			// HANDLE: $(expr, context)
2911			// (which is just equivalent to: $(context).find(expr)
2912			} else {
2913				return this.constructor( context ).find( selector );
2914			}
2915
2916		// HANDLE: $(DOMElement)
2917		} else if ( selector.nodeType ) {
2918			this.context = this[ 0 ] = selector;
2919			this.length = 1;
2920			return this;
2921
2922		// HANDLE: $(function)
2923		// Shortcut for document ready
2924		} else if ( jQuery.isFunction( selector ) ) {
2925			return root.ready !== undefined ?
2926				root.ready( selector ) :
2927
2928				// Execute immediately if ready is not present
2929				selector( jQuery );
2930		}
2931
2932		if ( selector.selector !== undefined ) {
2933			this.selector = selector.selector;
2934			this.context = selector.context;
2935		}
2936
2937		return jQuery.makeArray( selector, this );
2938	};
2939
2940// Give the init function the jQuery prototype for later instantiation
2941init.prototype = jQuery.fn;
2942
2943// Initialize central reference
2944rootjQuery = jQuery( document );
2945
2946
2947var rparentsprev = /^(?:parents|prev(?:Until|All))/,
2948
2949	// Methods guaranteed to produce a unique set when starting from a unique set
2950	guaranteedUnique = {
2951		children: true,
2952		contents: true,
2953		next: true,
2954		prev: true
2955	};
2956
2957jQuery.fn.extend( {
2958	has: function( target ) {
2959		var targets = jQuery( target, this ),
2960			l = targets.length;
2961
2962		return this.filter( function() {
2963			var i = 0;
2964			for ( ; i < l; i++ ) {
2965				if ( jQuery.contains( this, targets[ i ] ) ) {
2966					return true;
2967				}
2968			}
2969		} );
2970	},
2971
2972	closest: function( selectors, context ) {
2973		var cur,
2974			i = 0,
2975			l = this.length,
2976			matched = [],
2977			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
2978				jQuery( selectors, context || this.context ) :
2979				0;
2980
2981		for ( ; i < l; i++ ) {
2982			for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
2983
2984				// Always skip document fragments
2985				if ( cur.nodeType < 11 && ( pos ?
2986					pos.index( cur ) > -1 :
2987
2988					// Don't pass non-elements to Sizzle
2989					cur.nodeType === 1 &&
2990						jQuery.find.matchesSelector( cur, selectors ) ) ) {
2991
2992					matched.push( cur );
2993					break;
2994				}
2995			}
2996		}
2997
2998		return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
2999	},
3000
3001	// Determine the position of an element within the set
3002	index: function( elem ) {
3003
3004		// No argument, return index in parent
3005		if ( !elem ) {
3006			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3007		}
3008
3009		// Index in selector
3010		if ( typeof elem === "string" ) {
3011			return indexOf.call( jQuery( elem ), this[ 0 ] );
3012		}
3013
3014		// Locate the position of the desired element
3015		return indexOf.call( this,
3016
3017			// If it receives a jQuery object, the first element is used
3018			elem.jquery ? elem[ 0 ] : elem
3019		);
3020	},
3021
3022	add: function( selector, context ) {
3023		return this.pushStack(
3024			jQuery.uniqueSort(
3025				jQuery.merge( this.get(), jQuery( selector, context ) )
3026			)
3027		);
3028	},
3029
3030	addBack: function( selector ) {
3031		return this.add( selector == null ?
3032			this.prevObject : this.prevObject.filter( selector )
3033		);
3034	}
3035} );
3036
3037function sibling( cur, dir ) {
3038	while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3039	return cur;
3040}
3041
3042jQuery.each( {
3043	parent: function( elem ) {
3044		var parent = elem.parentNode;
3045		return parent && parent.nodeType !== 11 ? parent : null;
3046	},
3047	parents: function( elem ) {
3048		return dir( elem, "parentNode" );
3049	},
3050	parentsUntil: function( elem, i, until ) {
3051		return dir( elem, "parentNode", until );
3052	},
3053	next: function( elem ) {
3054		return sibling( elem, "nextSibling" );
3055	},
3056	prev: function( elem ) {
3057		return sibling( elem, "previousSibling" );
3058	},
3059	nextAll: function( elem ) {
3060		return dir( elem, "nextSibling" );
3061	},
3062	prevAll: function( elem ) {
3063		return dir( elem, "previousSibling" );
3064	},
3065	nextUntil: function( elem, i, until ) {
3066		return dir( elem, "nextSibling", until );
3067	},
3068	prevUntil: function( elem, i, until ) {
3069		return dir( elem, "previousSibling", until );
3070	},
3071	siblings: function( elem ) {
3072		return siblings( ( elem.parentNode || {} ).firstChild, elem );
3073	},
3074	children: function( elem ) {
3075		return siblings( elem.firstChild );
3076	},
3077	contents: function( elem ) {
3078		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
3079	}
3080}, function( name, fn ) {
3081	jQuery.fn[ name ] = function( until, selector ) {
3082		var matched = jQuery.map( this, fn, until );
3083
3084		if ( name.slice( -5 ) !== "Until" ) {
3085			selector = until;
3086		}
3087
3088		if ( selector && typeof selector === "string" ) {
3089			matched = jQuery.filter( selector, matched );
3090		}
3091
3092		if ( this.length > 1 ) {
3093
3094			// Remove duplicates
3095			if ( !guaranteedUnique[ name ] ) {
3096				jQuery.uniqueSort( matched );
3097			}
3098
3099			// Reverse order for parents* and prev-derivatives
3100			if ( rparentsprev.test( name ) ) {
3101				matched.reverse();
3102			}
3103		}
3104
3105		return this.pushStack( matched );
3106	};
3107} );
3108var rnotwhite = ( /\S+/g );
3109
3110
3111
3112// Convert String-formatted options into Object-formatted ones
3113function createOptions( options ) {
3114	var object = {};
3115	jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
3116		object[ flag ] = true;
3117	} );
3118	return object;
3119}
3120
3121/*
3122 * Create a callback list using the following parameters:
3123 *
3124 *	options: an optional list of space-separated options that will change how
3125 *			the callback list behaves or a more traditional option object
3126 *
3127 * By default a callback list will act like an event callback list and can be
3128 * "fired" multiple times.
3129 *
3130 * Possible options:
3131 *
3132 *	once:			will ensure the callback list can only be fired once (like a Deferred)
3133 *
3134 *	memory:			will keep track of previous values and will call any callback added
3135 *					after the list has been fired right away with the latest "memorized"
3136 *					values (like a Deferred)
3137 *
3138 *	unique:			will ensure a callback can only be added once (no duplicate in the list)
3139 *
3140 *	stopOnFalse:	interrupt callings when a callback returns false
3141 *
3142 */
3143jQuery.Callbacks = function( options ) {
3144
3145	// Convert options from String-formatted to Object-formatted if needed
3146	// (we check in cache first)
3147	options = typeof options === "string" ?
3148		createOptions( options ) :
3149		jQuery.extend( {}, options );
3150
3151	var // Flag to know if list is currently firing
3152		firing,
3153
3154		// Last fire value for non-forgettable lists
3155		memory,
3156
3157		// Flag to know if list was already fired
3158		fired,
3159
3160		// Flag to prevent firing
3161		locked,
3162
3163		// Actual callback list
3164		list = [],
3165
3166		// Queue of execution data for repeatable lists
3167		queue = [],
3168
3169		// Index of currently firing callback (modified by add/remove as needed)
3170		firingIndex = -1,
3171
3172		// Fire callbacks
3173		fire = function() {
3174
3175			// Enforce single-firing
3176			locked = options.once;
3177
3178			// Execute callbacks for all pending executions,
3179			// respecting firingIndex overrides and runtime changes
3180			fired = firing = true;
3181			for ( ; queue.length; firingIndex = -1 ) {
3182				memory = queue.shift();
3183				while ( ++firingIndex < list.length ) {
3184
3185					// Run callback and check for early termination
3186					if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3187						options.stopOnFalse ) {
3188
3189						// Jump to end and forget the data so .add doesn't re-fire
3190						firingIndex = list.length;
3191						memory = false;
3192					}
3193				}
3194			}
3195
3196			// Forget the data if we're done with it
3197			if ( !options.memory ) {
3198				memory = false;
3199			}
3200
3201			firing = false;
3202
3203			// Clean up if we're done firing for good
3204			if ( locked ) {
3205
3206				// Keep an empty list if we have data for future add calls
3207				if ( memory ) {
3208					list = [];
3209
3210				// Otherwise, this object is spent
3211				} else {
3212					list = "";
3213				}
3214			}
3215		},
3216
3217		// Actual Callbacks object
3218		self = {
3219
3220			// Add a callback or a collection of callbacks to the list
3221			add: function() {
3222				if ( list ) {
3223
3224					// If we have memory from a past run, we should fire after adding
3225					if ( memory && !firing ) {
3226						firingIndex = list.length - 1;
3227						queue.push( memory );
3228					}
3229
3230					( function add( args ) {
3231						jQuery.each( args, function( _, arg ) {
3232							if ( jQuery.isFunction( arg ) ) {
3233								if ( !options.unique || !self.has( arg ) ) {
3234									list.push( arg );
3235								}
3236							} else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
3237
3238								// Inspect recursively
3239								add( arg );
3240							}
3241						} );
3242					} )( arguments );
3243
3244					if ( memory && !firing ) {
3245						fire();
3246					}
3247				}
3248				return this;
3249			},
3250
3251			// Remove a callback from the list
3252			remove: function() {
3253				jQuery.each( arguments, function( _, arg ) {
3254					var index;
3255					while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3256						list.splice( index, 1 );
3257
3258						// Handle firing indexes
3259						if ( index <= firingIndex ) {
3260							firingIndex--;
3261						}
3262					}
3263				} );
3264				return this;
3265			},
3266
3267			// Check if a given callback is in the list.
3268			// If no argument is given, return whether or not list has callbacks attached.
3269			has: function( fn ) {
3270				return fn ?
3271					jQuery.inArray( fn, list ) > -1 :
3272					list.length > 0;
3273			},
3274
3275			// Remove all callbacks from the list
3276			empty: function() {
3277				if ( list ) {
3278					list = [];
3279				}
3280				return this;
3281			},
3282
3283			// Disable .fire and .add
3284			// Abort any current/pending executions
3285			// Clear all callbacks and values
3286			disable: function() {
3287				locked = queue = [];
3288				list = memory = "";
3289				return this;
3290			},
3291			disabled: function() {
3292				return !list;
3293			},
3294
3295			// Disable .fire
3296			// Also disable .add unless we have memory (since it would have no effect)
3297			// Abort any pending executions
3298			lock: function() {
3299				locked = queue = [];
3300				if ( !memory ) {
3301					list = memory = "";
3302				}
3303				return this;
3304			},
3305			locked: function() {
3306				return !!locked;
3307			},
3308
3309			// Call all callbacks with the given context and arguments
3310			fireWith: function( context, args ) {
3311				if ( !locked ) {
3312					args = args || [];
3313					args = [ context, args.slice ? args.slice() : args ];
3314					queue.push( args );
3315					if ( !firing ) {
3316						fire();
3317					}
3318				}
3319				return this;
3320			},
3321
3322			// Call all the callbacks with the given arguments
3323			fire: function() {
3324				self.fireWith( this, arguments );
3325				return this;
3326			},
3327
3328			// To know if the callbacks have already been called at least once
3329			fired: function() {
3330				return !!fired;
3331			}
3332		};
3333
3334	return self;
3335};
3336
3337
3338jQuery.extend( {
3339
3340	Deferred: function( func ) {
3341		var tuples = [
3342
3343				// action, add listener, listener list, final state
3344				[ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
3345				[ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
3346				[ "notify", "progress", jQuery.Callbacks( "memory" ) ]
3347			],
3348			state = "pending",
3349			promise = {
3350				state: function() {
3351					return state;
3352				},
3353				always: function() {
3354					deferred.done( arguments ).fail( arguments );
3355					return this;
3356				},
3357				then: function( /* fnDone, fnFail, fnProgress */ ) {
3358					var fns = arguments;
3359					return jQuery.Deferred( function( newDefer ) {
3360						jQuery.each( tuples, function( i, tuple ) {
3361							var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3362
3363							// deferred[ done | fail | progress ] for forwarding actions to newDefer
3364							deferred[ tuple[ 1 ] ]( function() {
3365								var returned = fn && fn.apply( this, arguments );
3366								if ( returned && jQuery.isFunction( returned.promise ) ) {
3367									returned.promise()
3368										.progress( newDefer.notify )
3369										.done( newDefer.resolve )
3370										.fail( newDefer.reject );
3371								} else {
3372									newDefer[ tuple[ 0 ] + "With" ](
3373										this === promise ? newDefer.promise() : this,
3374										fn ? [ returned ] : arguments
3375									);
3376								}
3377							} );
3378						} );
3379						fns = null;
3380					} ).promise();
3381				},
3382
3383				// Get a promise for this deferred
3384				// If obj is provided, the promise aspect is added to the object
3385				promise: function( obj ) {
3386					return obj != null ? jQuery.extend( obj, promise ) : promise;
3387				}
3388			},
3389			deferred = {};
3390
3391		// Keep pipe for back-compat
3392		promise.pipe = promise.then;
3393
3394		// Add list-specific methods
3395		jQuery.each( tuples, function( i, tuple ) {
3396			var list = tuple[ 2 ],
3397				stateString = tuple[ 3 ];
3398
3399			// promise[ done | fail | progress ] = list.add
3400			promise[ tuple[ 1 ] ] = list.add;
3401
3402			// Handle state
3403			if ( stateString ) {
3404				list.add( function() {
3405
3406					// state = [ resolved | rejected ]
3407					state = stateString;
3408
3409				// [ reject_list | resolve_list ].disable; progress_list.lock
3410				}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3411			}
3412
3413			// deferred[ resolve | reject | notify ]
3414			deferred[ tuple[ 0 ] ] = function() {
3415				deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
3416				return this;
3417			};
3418			deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
3419		} );
3420
3421		// Make the deferred a promise
3422		promise.promise( deferred );
3423
3424		// Call given func if any
3425		if ( func ) {
3426			func.call( deferred, deferred );
3427		}
3428
3429		// All done!
3430		return deferred;
3431	},
3432
3433	// Deferred helper
3434	when: function( subordinate /* , ..., subordinateN */ ) {
3435		var i = 0,
3436			resolveValues = slice.call( arguments ),
3437			length = resolveValues.length,
3438
3439			// the count of uncompleted subordinates
3440			remaining = length !== 1 ||
3441				( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3442
3443			// the master Deferred.
3444			// If resolveValues consist of only a single Deferred, just use that.
3445			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3446
3447			// Update function for both resolve and progress values
3448			updateFunc = function( i, contexts, values ) {
3449				return function( value ) {
3450					contexts[ i ] = this;
3451					values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
3452					if ( values === progressValues ) {
3453						deferred.notifyWith( contexts, values );
3454					} else if ( !( --remaining ) ) {
3455						deferred.resolveWith( contexts, values );
3456					}
3457				};
3458			},
3459
3460			progressValues, progressContexts, resolveContexts;
3461
3462		// Add listeners to Deferred subordinates; treat others as resolved
3463		if ( length > 1 ) {
3464			progressValues = new Array( length );
3465			progressContexts = new Array( length );
3466			resolveContexts = new Array( length );
3467			for ( ; i < length; i++ ) {
3468				if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3469					resolveValues[ i ].promise()
3470						.progress( updateFunc( i, progressContexts, progressValues ) )
3471						.done( updateFunc( i, resolveContexts, resolveValues ) )
3472						.fail( deferred.reject );
3473				} else {
3474					--remaining;
3475				}
3476			}
3477		}
3478
3479		// If we're not waiting on anything, resolve the master
3480		if ( !remaining ) {
3481			deferred.resolveWith( resolveContexts, resolveValues );
3482		}
3483
3484		return deferred.promise();
3485	}
3486} );
3487
3488
3489// The deferred used on DOM ready
3490var readyList;
3491
3492jQuery.fn.ready = function( fn ) {
3493
3494	// Add the callback
3495	jQuery.ready.promise().done( fn );
3496
3497	return this;
3498};
3499
3500jQuery.extend( {
3501
3502	// Is the DOM ready to be used? Set to true once it occurs.
3503	isReady: false,
3504
3505	// A counter to track how many items to wait for before
3506	// the ready event fires. See #6781
3507	readyWait: 1,
3508
3509	// Hold (or release) the ready event
3510	holdReady: function( hold ) {
3511		if ( hold ) {
3512			jQuery.readyWait++;
3513		} else {
3514			jQuery.ready( true );
3515		}
3516	},
3517
3518	// Handle when the DOM is ready
3519	ready: function( wait ) {
3520
3521		// Abort if there are pending holds or we're already ready
3522		if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
3523			return;
3524		}
3525
3526		// Remember that the DOM is ready
3527		jQuery.isReady = true;
3528
3529		// If a normal DOM Ready event fired, decrement, and wait if need be
3530		if ( wait !== true && --jQuery.readyWait > 0 ) {
3531			return;
3532		}
3533
3534		// If there are functions bound, to execute
3535		readyList.resolveWith( document, [ jQuery ] );
3536
3537		// Trigger any bound ready events
3538		if ( jQuery.fn.triggerHandler ) {
3539			jQuery( document ).triggerHandler( "ready" );
3540			jQuery( document ).off( "ready" );
3541		}
3542	}
3543} );
3544
3545/**
3546 * The ready event handler and self cleanup method
3547 */
3548function completed() {
3549	document.removeEventListener( "DOMContentLoaded", completed );
3550	window.removeEventListener( "load", completed );
3551	jQuery.ready();
3552}
3553
3554jQuery.ready.promise = function( obj ) {
3555	if ( !readyList ) {
3556
3557		readyList = jQuery.Deferred();
3558
3559		// Catch cases where $(document).ready() is called
3560		// after the browser event has already occurred.
3561		// Support: IE9-10 only
3562		// Older IE sometimes signals "interactive" too soon
3563		if ( document.readyState === "complete" ||
3564			( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
3565
3566			// Handle it asynchronously to allow scripts the opportunity to delay ready
3567			window.setTimeout( jQuery.ready );
3568
3569		} else {
3570
3571			// Use the handy event callback
3572			document.addEventListener( "DOMContentLoaded", completed );
3573
3574			// A fallback to window.onload, that will always work
3575			window.addEventListener( "load", completed );
3576		}
3577	}
3578	return readyList.promise( obj );
3579};
3580
3581// Kick off the DOM ready check even if the user does not
3582jQuery.ready.promise();
3583
3584
3585
3586
3587// Multifunctional method to get and set values of a collection
3588// The value/s can optionally be executed if it's a function
3589var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
3590	var i = 0,
3591		len = elems.length,
3592		bulk = key == null;
3593
3594	// Sets many values
3595	if ( jQuery.type( key ) === "object" ) {
3596		chainable = true;
3597		for ( i in key ) {
3598			access( elems, fn, i, key[ i ], true, emptyGet, raw );
3599		}
3600
3601	// Sets one value
3602	} else if ( value !== undefined ) {
3603		chainable = true;
3604
3605		if ( !jQuery.isFunction( value ) ) {
3606			raw = true;
3607		}
3608
3609		if ( bulk ) {
3610
3611			// Bulk operations run against the entire set
3612			if ( raw ) {
3613				fn.call( elems, value );
3614				fn = null;
3615
3616			// ...except when executing function values
3617			} else {
3618				bulk = fn;
3619				fn = function( elem, key, value ) {
3620					return bulk.call( jQuery( elem ), value );
3621				};
3622			}
3623		}
3624
3625		if ( fn ) {
3626			for ( ; i < len; i++ ) {
3627				fn(
3628					elems[ i ], key, raw ?
3629					value :
3630					value.call( elems[ i ], i, fn( elems[ i ], key ) )
3631				);
3632			}
3633		}
3634	}
3635
3636	return chainable ?
3637		elems :
3638
3639		// Gets
3640		bulk ?
3641			fn.call( elems ) :
3642			len ? fn( elems[ 0 ], key ) : emptyGet;
3643};
3644var acceptData = function( owner ) {
3645
3646	// Accepts only:
3647	//  - Node
3648	//    - Node.ELEMENT_NODE
3649	//    - Node.DOCUMENT_NODE
3650	//  - Object
3651	//    - Any
3652	/* jshint -W018 */
3653	return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
3654};
3655
3656
3657
3658
3659function Data() {
3660	this.expando = jQuery.expando + Data.uid++;
3661}
3662
3663Data.uid = 1;
3664
3665Data.prototype = {
3666
3667	register: function( owner, initial ) {
3668		var value = initial || {};
3669
3670		// If it is a node unlikely to be stringify-ed or looped over
3671		// use plain assignment
3672		if ( owner.nodeType ) {
3673			owner[ this.expando ] = value;
3674
3675		// Otherwise secure it in a non-enumerable, non-writable property
3676		// configurability must be true to allow the property to be
3677		// deleted with the delete operator
3678		} else {
3679			Object.defineProperty( owner, this.expando, {
3680				value: value,
3681				writable: true,
3682				configurable: true
3683			} );
3684		}
3685		return owner[ this.expando ];
3686	},
3687	cache: function( owner ) {
3688
3689		// We can accept data for non-element nodes in modern browsers,
3690		// but we should not, see #8335.
3691		// Always return an empty object.
3692		if ( !acceptData( owner ) ) {
3693			return {};
3694		}
3695
3696		// Check if the owner object already has a cache
3697		var value = owner[ this.expando ];
3698
3699		// If not, create one
3700		if ( !value ) {
3701			value = {};
3702
3703			// We can accept data for non-element nodes in modern browsers,
3704			// but we should not, see #8335.
3705			// Always return an empty object.
3706			if ( acceptData( owner ) ) {
3707
3708				// If it is a node unlikely to be stringify-ed or looped over
3709				// use plain assignment
3710				if ( owner.nodeType ) {
3711					owner[ this.expando ] = value;
3712
3713				// Otherwise secure it in a non-enumerable property
3714				// configurable must be true to allow the property to be
3715				// deleted when data is removed
3716				} else {
3717					Object.defineProperty( owner, this.expando, {
3718						value: value,
3719						configurable: true
3720					} );
3721				}
3722			}
3723		}
3724
3725		return value;
3726	},
3727	set: function( owner, data, value ) {
3728		var prop,
3729			cache = this.cache( owner );
3730
3731		// Handle: [ owner, key, value ] args
3732		if ( typeof data === "string" ) {
3733			cache[ data ] = value;
3734
3735		// Handle: [ owner, { properties } ] args
3736		} else {
3737
3738			// Copy the properties one-by-one to the cache object
3739			for ( prop in data ) {
3740				cache[ prop ] = data[ prop ];
3741			}
3742		}
3743		return cache;
3744	},
3745	get: function( owner, key ) {
3746		return key === undefined ?
3747			this.cache( owner ) :
3748			owner[ this.expando ] && owner[ this.expando ][ key ];
3749	},
3750	access: function( owner, key, value ) {
3751		var stored;
3752
3753		// In cases where either:
3754		//
3755		//   1. No key was specified
3756		//   2. A string key was specified, but no value provided
3757		//
3758		// Take the "read" path and allow the get method to determine
3759		// which value to return, respectively either:
3760		//
3761		//   1. The entire cache object
3762		//   2. The data stored at the key
3763		//
3764		if ( key === undefined ||
3765				( ( key && typeof key === "string" ) && value === undefined ) ) {
3766
3767			stored = this.get( owner, key );
3768
3769			return stored !== undefined ?
3770				stored : this.get( owner, jQuery.camelCase( key ) );
3771		}
3772
3773		// When the key is not a string, or both a key and value
3774		// are specified, set or extend (existing objects) with either:
3775		//
3776		//   1. An object of properties
3777		//   2. A key and value
3778		//
3779		this.set( owner, key, value );
3780
3781		// Since the "set" path can have two possible entry points
3782		// return the expected data based on which path was taken[*]
3783		return value !== undefined ? value : key;
3784	},
3785	remove: function( owner, key ) {
3786		var i, name, camel,
3787			cache = owner[ this.expando ];
3788
3789		if ( cache === undefined ) {
3790			return;
3791		}
3792
3793		if ( key === undefined ) {
3794			this.register( owner );
3795
3796		} else {
3797
3798			// Support array or space separated string of keys
3799			if ( jQuery.isArray( key ) ) {
3800
3801				// If "name" is an array of keys...
3802				// When data is initially created, via ("key", "val") signature,
3803				// keys will be converted to camelCase.
3804				// Since there is no way to tell _how_ a key was added, remove
3805				// both plain key and camelCase key. #12786
3806				// This will only penalize the array argument path.
3807				name = key.concat( key.map( jQuery.camelCase ) );
3808			} else {
3809				camel = jQuery.camelCase( key );
3810
3811				// Try the string as a key before any manipulation
3812				if ( key in cache ) {
3813					name = [ key, camel ];
3814				} else {
3815
3816					// If a key with the spaces exists, use it.
3817					// Otherwise, create an array by matching non-whitespace
3818					name = camel;
3819					name = name in cache ?
3820						[ name ] : ( name.match( rnotwhite ) || [] );
3821				}
3822			}
3823
3824			i = name.length;
3825
3826			while ( i-- ) {
3827				delete cache[ name[ i ] ];
3828			}
3829		}
3830
3831		// Remove the expando if there's no more data
3832		if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
3833
3834			// Support: Chrome <= 35-45+
3835			// Webkit & Blink performance suffers when deleting properties
3836			// from DOM nodes, so set to undefined instead
3837			// https://code.google.com/p/chromium/issues/detail?id=378607
3838			if ( owner.nodeType ) {
3839				owner[ this.expando ] = undefined;
3840			} else {
3841				delete owner[ this.expando ];
3842			}
3843		}
3844	},
3845	hasData: function( owner ) {
3846		var cache = owner[ this.expando ];
3847		return cache !== undefined && !jQuery.isEmptyObject( cache );
3848	}
3849};
3850var dataPriv = new Data();
3851
3852var dataUser = new Data();
3853
3854
3855
3856//	Implementation Summary
3857//
3858//	1. Enforce API surface and semantic compatibility with 1.9.x branch
3859//	2. Improve the module's maintainability by reducing the storage
3860//		paths to a single mechanism.
3861//	3. Use the same single mechanism to support "private" and "user" data.
3862//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3863//	5. Avoid exposing implementation details on user objects (eg. expando properties)
3864//	6. Provide a clear path for implementation upgrade to WeakMap in 2014
3865
3866var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
3867	rmultiDash = /[A-Z]/g;
3868
3869function dataAttr( elem, key, data ) {
3870	var name;
3871
3872	// If nothing was found internally, try to fetch any
3873	// data from the HTML5 data-* attribute
3874	if ( data === undefined && elem.nodeType === 1 ) {
3875		name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
3876		data = elem.getAttribute( name );
3877
3878		if ( typeof data === "string" ) {
3879			try {
3880				data = data === "true" ? true :
3881					data === "false" ? false :
3882					data === "null" ? null :
3883
3884					// Only convert to a number if it doesn't change the string
3885					+data + "" === data ? +data :
3886					rbrace.test( data ) ? jQuery.parseJSON( data ) :
3887					data;
3888			} catch ( e ) {}
3889
3890			// Make sure we set the data so it isn't changed later
3891			dataUser.set( elem, key, data );
3892		} else {
3893			data = undefined;
3894		}
3895	}
3896	return data;
3897}
3898
3899jQuery.extend( {
3900	hasData: function( elem ) {
3901		return dataUser.hasData( elem ) || dataPriv.hasData( elem );
3902	},
3903
3904	data: function( elem, name, data ) {
3905		return dataUser.access( elem, name, data );
3906	},
3907
3908	removeData: function( elem, name ) {
3909		dataUser.remove( elem, name );
3910	},
3911
3912	// TODO: Now that all calls to _data and _removeData have been replaced
3913	// with direct calls to dataPriv methods, these can be deprecated.
3914	_data: function( elem, name, data ) {
3915		return dataPriv.access( elem, name, data );
3916	},
3917
3918	_removeData: function( elem, name ) {
3919		dataPriv.remove( elem, name );
3920	}
3921} );
3922
3923jQuery.fn.extend( {
3924	data: function( key, value ) {
3925		var i, name, data,
3926			elem = this[ 0 ],
3927			attrs = elem && elem.attributes;
3928
3929		// Gets all values
3930		if ( key === undefined ) {
3931			if ( this.length ) {
3932				data = dataUser.get( elem );
3933
3934				if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
3935					i = attrs.length;
3936					while ( i-- ) {
3937
3938						// Support: IE11+
3939						// The attrs elements can be null (#14894)
3940						if ( attrs[ i ] ) {
3941							name = attrs[ i ].name;
3942							if ( name.indexOf( "data-" ) === 0 ) {
3943								name = jQuery.camelCase( name.slice( 5 ) );
3944								dataAttr( elem, name, data[ name ] );
3945							}
3946						}
3947					}
3948					dataPriv.set( elem, "hasDataAttrs", true );
3949				}
3950			}
3951
3952			return data;
3953		}
3954
3955		// Sets multiple values
3956		if ( typeof key === "object" ) {
3957			return this.each( function() {
3958				dataUser.set( this, key );
3959			} );
3960		}
3961
3962		return access( this, function( value ) {
3963			var data, camelKey;
3964
3965			// The calling jQuery object (element matches) is not empty
3966			// (and therefore has an element appears at this[ 0 ]) and the
3967			// `value` parameter was not undefined. An empty jQuery object
3968			// will result in `undefined` for elem = this[ 0 ] which will
3969			// throw an exception if an attempt to read a data cache is made.
3970			if ( elem && value === undefined ) {
3971
3972				// Attempt to get data from the cache
3973				// with the key as-is
3974				data = dataUser.get( elem, key ) ||
3975
3976					// Try to find dashed key if it exists (gh-2779)
3977					// This is for 2.2.x only
3978					dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
3979
3980				if ( data !== undefined ) {
3981					return data;
3982				}
3983
3984				camelKey = jQuery.camelCase( key );
3985
3986				// Attempt to get data from the cache
3987				// with the key camelized
3988				data = dataUser.get( elem, camelKey );
3989				if ( data !== undefined ) {
3990					return data;
3991				}
3992
3993				// Attempt to "discover" the data in
3994				// HTML5 custom data-* attrs
3995				data = dataAttr( elem, camelKey, undefined );
3996				if ( data !== undefined ) {
3997					return data;
3998				}
3999
4000				// We tried really hard, but the data doesn't exist.
4001				return;
4002			}
4003
4004			// Set the data...
4005			camelKey = jQuery.camelCase( key );
4006			this.each( function() {
4007
4008				// First, attempt to store a copy or reference of any
4009				// data that might've been store with a camelCased key.
4010				var data = dataUser.get( this, camelKey );
4011
4012				// For HTML5 data-* attribute interop, we have to
4013				// store property names with dashes in a camelCase form.
4014				// This might not apply to all properties...*
4015				dataUser.set( this, camelKey, value );
4016
4017				// *... In the case of properties that might _actually_
4018				// have dashes, we need to also store a copy of that
4019				// unchanged property.
4020				if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
4021					dataUser.set( this, key, value );
4022				}
4023			} );
4024		}, null, value, arguments.length > 1, null, true );
4025	},
4026
4027	removeData: function( key ) {
4028		return this.each( function() {
4029			dataUser.remove( this, key );
4030		} );
4031	}
4032} );
4033
4034
4035jQuery.extend( {
4036	queue: function( elem, type, data ) {
4037		var queue;
4038
4039		if ( elem ) {
4040			type = ( type || "fx" ) + "queue";
4041			queue = dataPriv.get( elem, type );
4042
4043			// Speed up dequeue by getting out quickly if this is just a lookup
4044			if ( data ) {
4045				if ( !queue || jQuery.isArray( data ) ) {
4046					queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
4047				} else {
4048					queue.push( data );
4049				}
4050			}
4051			return queue || [];
4052		}
4053	},
4054
4055	dequeue: function( elem, type ) {
4056		type = type || "fx";
4057
4058		var queue = jQuery.queue( elem, type ),
4059			startLength = queue.length,
4060			fn = queue.shift(),
4061			hooks = jQuery._queueHooks( elem, type ),
4062			next = function() {
4063				jQuery.dequeue( elem, type );
4064			};
4065
4066		// If the fx queue is dequeued, always remove the progress sentinel
4067		if ( fn === "inprogress" ) {
4068			fn = queue.shift();
4069			startLength--;
4070		}
4071
4072		if ( fn ) {
4073
4074			// Add a progress sentinel to prevent the fx queue from being
4075			// automatically dequeued
4076			if ( type === "fx" ) {
4077				queue.unshift( "inprogress" );
4078			}
4079
4080			// Clear up the last queue stop function
4081			delete hooks.stop;
4082			fn.call( elem, next, hooks );
4083		}
4084
4085		if ( !startLength && hooks ) {
4086			hooks.empty.fire();
4087		}
4088	},
4089
4090	// Not public - generate a queueHooks object, or return the current one
4091	_queueHooks: function( elem, type ) {
4092		var key = type + "queueHooks";
4093		return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
4094			empty: jQuery.Callbacks( "once memory" ).add( function() {
4095				dataPriv.remove( elem, [ type + "queue", key ] );
4096			} )
4097		} );
4098	}
4099} );
4100
4101jQuery.fn.extend( {
4102	queue: function( type, data ) {
4103		var setter = 2;
4104
4105		if ( typeof type !== "string" ) {
4106			data = type;
4107			type = "fx";
4108			setter--;
4109		}
4110
4111		if ( arguments.length < setter ) {
4112			return jQuery.queue( this[ 0 ], type );
4113		}
4114
4115		return data === undefined ?
4116			this :
4117			this.each( function() {
4118				var queue = jQuery.queue( this, type, data );
4119
4120				// Ensure a hooks for this queue
4121				jQuery._queueHooks( this, type );
4122
4123				if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
4124					jQuery.dequeue( this, type );
4125				}
4126			} );
4127	},
4128	dequeue: function( type ) {
4129		return this.each( function() {
4130			jQuery.dequeue( this, type );
4131		} );
4132	},
4133	clearQueue: function( type ) {
4134		return this.queue( type || "fx", [] );
4135	},
4136
4137	// Get a promise resolved when queues of a certain type
4138	// are emptied (fx is the type by default)
4139	promise: function( type, obj ) {
4140		var tmp,
4141			count = 1,
4142			defer = jQuery.Deferred(),
4143			elements = this,
4144			i = this.length,
4145			resolve = function() {
4146				if ( !( --count ) ) {
4147					defer.resolveWith( elements, [ elements ] );
4148				}
4149			};
4150
4151		if ( typeof type !== "string" ) {
4152			obj = type;
4153			type = undefined;
4154		}
4155		type = type || "fx";
4156
4157		while ( i-- ) {
4158			tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
4159			if ( tmp && tmp.empty ) {
4160				count++;
4161				tmp.empty.add( resolve );
4162			}
4163		}
4164		resolve();
4165		return defer.promise( obj );
4166	}
4167} );
4168var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
4169
4170var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
4171
4172
4173var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
4174
4175var isHidden = function( elem, el ) {
4176
4177		// isHidden might be called from jQuery#filter function;
4178		// in that case, element will be second argument
4179		elem = el || elem;
4180		return jQuery.css( elem, "display" ) === "none" ||
4181			!jQuery.contains( elem.ownerDocument, elem );
4182	};
4183
4184
4185
4186function adjustCSS( elem, prop, valueParts, tween ) {
4187	var adjusted,
4188		scale = 1,
4189		maxIterations = 20,
4190		currentValue = tween ?
4191			function() { return tween.cur(); } :
4192			function() { return jQuery.css( elem, prop, "" ); },
4193		initial = currentValue(),
4194		unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
4195
4196		// Starting value computation is required for potential unit mismatches
4197		initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
4198			rcssNum.exec( jQuery.css( elem, prop ) );
4199
4200	if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
4201
4202		// Trust units reported by jQuery.css
4203		unit = unit || initialInUnit[ 3 ];
4204
4205		// Make sure we update the tween properties later on
4206		valueParts = valueParts || [];
4207
4208		// Iteratively approximate from a nonzero starting point
4209		initialInUnit = +initial || 1;
4210
4211		do {
4212
4213			// If previous iteration zeroed out, double until we get *something*.
4214			// Use string for doubling so we don't accidentally see scale as unchanged below
4215			scale = scale || ".5";
4216
4217			// Adjust and apply
4218			initialInUnit = initialInUnit / scale;
4219			jQuery.style( elem, prop, initialInUnit + unit );
4220
4221		// Update scale, tolerating zero or NaN from tween.cur()
4222		// Break the loop if scale is unchanged or perfect, or if we've just had enough.
4223		} while (
4224			scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
4225		);
4226	}
4227
4228	if ( valueParts ) {
4229		initialInUnit = +initialInUnit || +initial || 0;
4230
4231		// Apply relative offset (+=/-=) if specified
4232		adjusted = valueParts[ 1 ] ?
4233			initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
4234			+valueParts[ 2 ];
4235		if ( tween ) {
4236			tween.unit = unit;
4237			tween.start = initialInUnit;
4238			tween.end = adjusted;
4239		}
4240	}
4241	return adjusted;
4242}
4243var rcheckableType = ( /^(?:checkbox|radio)$/i );
4244
4245var rtagName = ( /<([\w:-]+)/ );
4246
4247var rscriptType = ( /^$|\/(?:java|ecma)script/i );
4248
4249
4250
4251// We have to close these tags to support XHTML (#13200)
4252var wrapMap = {
4253
4254	// Support: IE9
4255	option: [ 1, "<select multiple='multiple'>", "</select>" ],
4256
4257	// XHTML parsers do not magically insert elements in the
4258	// same way that tag soup parsers do. So we cannot shorten
4259	// this by omitting <tbody> or other required elements.
4260	thead: [ 1, "<table>", "</table>" ],
4261	col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
4262	tr: [ 2, "<table><tbody>", "</tbody></table>" ],
4263	td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
4264
4265	_default: [ 0, "", "" ]
4266};
4267
4268// Support: IE9
4269wrapMap.optgroup = wrapMap.option;
4270
4271wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
4272wrapMap.th = wrapMap.td;
4273
4274
4275function getAll( context, tag ) {
4276
4277	// Support: IE9-11+
4278	// Use typeof to avoid zero-argument method invocation on host objects (#15151)
4279	var ret = typeof context.getElementsByTagName !== "undefined" ?
4280			context.getElementsByTagName( tag || "*" ) :
4281			typeof context.querySelectorAll !== "undefined" ?
4282				context.querySelectorAll( tag || "*" ) :
4283			[];
4284
4285	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
4286		jQuery.merge( [ context ], ret ) :
4287		ret;
4288}
4289
4290
4291// Mark scripts as having already been evaluated
4292function setGlobalEval( elems, refElements ) {
4293	var i = 0,
4294		l = elems.length;
4295
4296	for ( ; i < l; i++ ) {
4297		dataPriv.set(
4298			elems[ i ],
4299			"globalEval",
4300			!refElements || dataPriv.get( refElements[ i ], "globalEval" )
4301		);
4302	}
4303}
4304
4305
4306var rhtml = /<|&#?\w+;/;
4307
4308function buildFragment( elems, context, scripts, selection, ignored ) {
4309	var elem, tmp, tag, wrap, contains, j,
4310		fragment = context.createDocumentFragment(),
4311		nodes = [],
4312		i = 0,
4313		l = elems.length;
4314
4315	for ( ; i < l; i++ ) {
4316		elem = elems[ i ];
4317
4318		if ( elem || elem === 0 ) {
4319
4320			// Add nodes directly
4321			if ( jQuery.type( elem ) === "object" ) {
4322
4323				// Support: Android<4.1, PhantomJS<2
4324				// push.apply(_, arraylike) throws on ancient WebKit
4325				jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
4326
4327			// Convert non-html into a text node
4328			} else if ( !rhtml.test( elem ) ) {
4329				nodes.push( context.createTextNode( elem ) );
4330
4331			// Convert html into DOM nodes
4332			} else {
4333				tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
4334
4335				// Deserialize a standard representation
4336				tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
4337				wrap = wrapMap[ tag ] || wrapMap._default;
4338				tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
4339
4340				// Descend through wrappers to the right content
4341				j = wrap[ 0 ];
4342				while ( j-- ) {
4343					tmp = tmp.lastChild;
4344				}
4345
4346				// Support: Android<4.1, PhantomJS<2
4347				// push.apply(_, arraylike) throws on ancient WebKit
4348				jQuery.merge( nodes, tmp.childNodes );
4349
4350				// Remember the top-level container
4351				tmp = fragment.firstChild;
4352
4353				// Ensure the created nodes are orphaned (#12392)
4354				tmp.textContent = "";
4355			}
4356		}
4357	}
4358
4359	// Remove wrapper from fragment
4360	fragment.textContent = "";
4361
4362	i = 0;
4363	while ( ( elem = nodes[ i++ ] ) ) {
4364
4365		// Skip elements already in the context collection (trac-4087)
4366		if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
4367			if ( ignored ) {
4368				ignored.push( elem );
4369			}
4370			continue;
4371		}
4372
4373		contains = jQuery.contains( elem.ownerDocument, elem );
4374
4375		// Append to fragment
4376		tmp = getAll( fragment.appendChild( elem ), "script" );
4377
4378		// Preserve script evaluation history
4379		if ( contains ) {
4380			setGlobalEval( tmp );
4381		}
4382
4383		// Capture executables
4384		if ( scripts ) {
4385			j = 0;
4386			while ( ( elem = tmp[ j++ ] ) ) {
4387				if ( rscriptType.test( elem.type || "" ) ) {
4388					scripts.push( elem );
4389				}
4390			}
4391		}
4392	}
4393
4394	return fragment;
4395}
4396
4397
4398( function() {
4399	var fragment = document.createDocumentFragment(),
4400		div = fragment.appendChild( document.createElement( "div" ) ),
4401		input = document.createElement( "input" );
4402
4403	// Support: Android 4.0-4.3, Safari<=5.1
4404	// Check state lost if the name is set (#11217)
4405	// Support: Windows Web Apps (WWA)
4406	// `name` and `type` must use .setAttribute for WWA (#14901)
4407	input.setAttribute( "type", "radio" );
4408	input.setAttribute( "checked", "checked" );
4409	input.setAttribute( "name", "t" );
4410
4411	div.appendChild( input );
4412
4413	// Support: Safari<=5.1, Android<4.2
4414	// Older WebKit doesn't clone checked state correctly in fragments
4415	support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
4416
4417	// Support: IE<=11+
4418	// Make sure textarea (and checkbox) defaultValue is properly cloned
4419	div.innerHTML = "<textarea>x</textarea>";
4420	support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
4421} )();
4422
4423
4424var
4425	rkeyEvent = /^key/,
4426	rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
4427	rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
4428
4429function returnTrue() {
4430	return true;
4431}
4432
4433function returnFalse() {
4434	return false;
4435}
4436
4437// Support: IE9
4438// See #13393 for more info
4439function safeActiveElement() {
4440	try {
4441		return document.activeElement;
4442	} catch ( err ) { }
4443}
4444
4445function on( elem, types, selector, data, fn, one ) {
4446	var origFn, type;
4447
4448	// Types can be a map of types/handlers
4449	if ( typeof types === "object" ) {
4450
4451		// ( types-Object, selector, data )
4452		if ( typeof selector !== "string" ) {
4453
4454			// ( types-Object, data )
4455			data = data || selector;
4456			selector = undefined;
4457		}
4458		for ( type in types ) {
4459			on( elem, type, selector, data, types[ type ], one );
4460		}
4461		return elem;
4462	}
4463
4464	if ( data == null && fn == null ) {
4465
4466		// ( types, fn )
4467		fn = selector;
4468		data = selector = undefined;
4469	} else if ( fn == null ) {
4470		if ( typeof selector === "string" ) {
4471
4472			// ( types, selector, fn )
4473			fn = data;
4474			data = undefined;
4475		} else {
4476
4477			// ( types, data, fn )
4478			fn = data;
4479			data = selector;
4480			selector = undefined;
4481		}
4482	}
4483	if ( fn === false ) {
4484		fn = returnFalse;
4485	} else if ( !fn ) {
4486		return 
4486this
vendor: 14,986 bytes, lines 4486-5007
4486;
4487	}
4488
4489	if ( one === 1 ) {
4490		origFn = fn;
4491		fn = function( event ) {
4492
4493			// Can use an empty set, since event contains the info
4494			jQuery().off( event );
4495			return origFn.apply( this, arguments );
4496		};
4497
4498		// Use same guid so caller can remove using origFn
4499		fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
4500	}
4501	return elem.each( function() {
4502		jQuery.event.add( this, types, fn, data, selector );
4503	} );
4504}
4505
4506/*
4507 * Helper functions for managing events -- not part of the public interface.
4508 * Props to Dean Edwards' addEvent library for many of the ideas.
4509 */
4510jQuery.event = {
4511
4512	global: {},
4513
4514	add: function( elem, types, handler, data, selector ) {
4515
4516		var handleObjIn, eventHandle, tmp,
4517			events, t, handleObj,
4518			special, handlers, type, namespaces, origType,
4519			elemData = dataPriv.get( elem );
4520
4521		// Don't attach events to noData or text/comment nodes (but allow plain objects)
4522		if ( !elemData ) {
4523			return;
4524		}
4525
4526		// Caller can pass in an object of custom data in lieu of the handler
4527		if ( handler.handler ) {
4528			handleObjIn = handler;
4529			handler = handleObjIn.handler;
4530			selector = handleObjIn.selector;
4531		}
4532
4533		// Make sure that the handler has a unique ID, used to find/remove it later
4534		if ( !handler.guid ) {
4535			handler.guid = jQuery.guid++;
4536		}
4537
4538		// Init the element's event structure and main handler, if this is the first
4539		if ( !( events = elemData.events ) ) {
4540			events = elemData.events = {};
4541		}
4542		if ( !( eventHandle = elemData.handle ) ) {
4543			eventHandle = elemData.handle = function( e ) {
4544
4545				// Discard the second event of a jQuery.event.trigger() and
4546				// when an event is called after a page has unloaded
4547				return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
4548					jQuery.event.dispatch.apply( elem, arguments ) : undefined;
4549			};
4550		}
4551
4552		// Handle multiple events separated by a space
4553		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4554		t = types.length;
4555		while ( t-- ) {
4556			tmp = rtypenamespace.exec( types[ t ] ) || [];
4557			type = origType = tmp[ 1 ];
4558			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4559
4560			// There *must* be a type, no attaching namespace-only handlers
4561			if ( !type ) {
4562				continue;
4563			}
4564
4565			// If event changes its type, use the special event handlers for the changed type
4566			special = jQuery.event.special[ type ] || {};
4567
4568			// If selector defined, determine special event api type, otherwise given type
4569			type = ( selector ? special.delegateType : special.bindType ) || type;
4570
4571			// Update special based on newly reset type
4572			special = jQuery.event.special[ type ] || {};
4573
4574			// handleObj is passed to all event handlers
4575			handleObj = jQuery.extend( {
4576				type: type,
4577				origType: origType,
4578				data: data,
4579				handler: handler,
4580				guid: handler.guid,
4581				selector: selector,
4582				needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4583				namespace: namespaces.join( "." )
4584			}, handleObjIn );
4585
4586			// Init the event handler queue if we're the first
4587			if ( !( handlers = events[ type ] ) ) {
4588				handlers = events[ type ] = [];
4589				handlers.delegateCount = 0;
4590
4591				// Only use addEventListener if the special events handler returns false
4592				if ( !special.setup ||
4593					special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4594
4595					if ( elem.addEventListener ) {
4596						elem.addEventListener( type, eventHandle );
4597					}
4598				}
4599			}
4600
4601			if ( special.add ) {
4602				special.add.call( elem, handleObj );
4603
4604				if ( !handleObj.handler.guid ) {
4605					handleObj.handler.guid = handler.guid;
4606				}
4607			}
4608
4609			// Add to the element's handler list, delegates in front
4610			if ( selector ) {
4611				handlers.splice( handlers.delegateCount++, 0, handleObj );
4612			} else {
4613				handlers.push( handleObj );
4614			}
4615
4616			// Keep track of which events have ever been used, for event optimization
4617			jQuery.event.global[ type ] = true;
4618		}
4619
4620	},
4621
4622	// Detach an event or set of events from an element
4623	remove: function( elem, types, handler, selector, mappedTypes ) {
4624
4625		var j, origCount, tmp,
4626			events, t, handleObj,
4627			special, handlers, type, namespaces, origType,
4628			elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
4629
4630		if ( !elemData || !( events = elemData.events ) ) {
4631			return;
4632		}
4633
4634		// Once for each type.namespace in types; type may be omitted
4635		types = ( types || "" ).match( rnotwhite ) || [ "" ];
4636		t = types.length;
4637		while ( t-- ) {
4638			tmp = rtypenamespace.exec( types[ t ] ) || [];
4639			type = origType = tmp[ 1 ];
4640			namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
4641
4642			// Unbind all events (on this namespace, if provided) for the element
4643			if ( !type ) {
4644				for ( type in events ) {
4645					jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4646				}
4647				continue;
4648			}
4649
4650			special = jQuery.event.special[ type ] || {};
4651			type = ( selector ? special.delegateType : special.bindType ) || type;
4652			handlers = events[ type ] || [];
4653			tmp = tmp[ 2 ] &&
4654				new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
4655
4656			// Remove matching events
4657			origCount = j = handlers.length;
4658			while ( j-- ) {
4659				handleObj = handlers[ j ];
4660
4661				if ( ( mappedTypes || origType === handleObj.origType ) &&
4662					( !handler || handler.guid === handleObj.guid ) &&
4663					( !tmp || tmp.test( handleObj.namespace ) ) &&
4664					( !selector || selector === handleObj.selector ||
4665						selector === "**" && handleObj.selector ) ) {
4666					handlers.splice( j, 1 );
4667
4668					if ( handleObj.selector ) {
4669						handlers.delegateCount--;
4670					}
4671					if ( special.remove ) {
4672						special.remove.call( elem, handleObj );
4673					}
4674				}
4675			}
4676
4677			// Remove generic event handler if we removed something and no more handlers exist
4678			// (avoids potential for endless recursion during removal of special event handlers)
4679			if ( origCount && !handlers.length ) {
4680				if ( !special.teardown ||
4681					special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4682
4683					jQuery.removeEvent( elem, type, elemData.handle );
4684				}
4685
4686				delete events[ type ];
4687			}
4688		}
4689
4690		// Remove data and the expando if it's no longer used
4691		if ( jQuery.isEmptyObject( events ) ) {
4692			dataPriv.remove( elem, "handle events" );
4693		}
4694	},
4695
4696	dispatch: function( event ) {
4697
4698		// Make a writable jQuery.Event from the native event object
4699		event = jQuery.event.fix( event );
4700
4701		var i, j, ret, matched, handleObj,
4702			handlerQueue = [],
4703			args = slice.call( arguments ),
4704			handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
4705			special = jQuery.event.special[ event.type ] || {};
4706
4707		// Use the fix-ed jQuery.Event rather than the (read-only) native event
4708		args[ 0 ] = event;
4709		event.delegateTarget = this;
4710
4711		// Call the preDispatch hook for the mapped type, and let it bail if desired
4712		if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4713			return;
4714		}
4715
4716		// Determine handlers
4717		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4718
4719		// Run delegates first; they may want to stop propagation beneath us
4720		i = 0;
4721		while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
4722			event.currentTarget = matched.elem;
4723
4724			j = 0;
4725			while ( ( handleObj = matched.handlers[ j++ ] ) &&
4726				!event.isImmediatePropagationStopped() ) {
4727
4728				// Triggered event must either 1) have no namespace, or 2) have namespace(s)
4729				// a subset or equal to those in the bound event (both can have no namespace).
4730				if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
4731
4732					event.handleObj = handleObj;
4733					event.data = handleObj.data;
4734
4735					ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
4736						handleObj.handler ).apply( matched.elem, args );
4737
4738					if ( ret !== undefined ) {
4739						if ( ( event.result = ret ) === false ) {
4740							event.preventDefault();
4741							event.stopPropagation();
4742						}
4743					}
4744				}
4745			}
4746		}
4747
4748		// Call the postDispatch hook for the mapped type
4749		if ( special.postDispatch ) {
4750			special.postDispatch.call( this, event );
4751		}
4752
4753		return event.result;
4754	},
4755
4756	handlers: function( event, handlers ) {
4757		var i, matches, sel, handleObj,
4758			handlerQueue = [],
4759			delegateCount = handlers.delegateCount,
4760			cur = event.target;
4761
4762		// Support (at least): Chrome, IE9
4763		// Find delegate handlers
4764		// Black-hole SVG <use> instance trees (#13180)
4765		//
4766		// Support: Firefox<=42+
4767		// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
4768		if ( delegateCount && cur.nodeType &&
4769			( event.type !== "click" || isNaN( event.button ) || event.button < 1 ) ) {
4770
4771			for ( ; cur !== this; cur = cur.parentNode || this ) {
4772
4773				// Don't check non-elements (#13208)
4774				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4775				if ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== "click" ) ) {
4776					matches = [];
4777					for ( i = 0; i < delegateCount; i++ ) {
4778						handleObj = handlers[ i ];
4779
4780						// Don't conflict with Object.prototype properties (#13203)
4781						sel = handleObj.selector + " ";
4782
4783						if ( matches[ sel ] === undefined ) {
4784							matches[ sel ] = handleObj.needsContext ?
4785								jQuery( sel, this ).index( cur ) > -1 :
4786								jQuery.find( sel, this, null, [ cur ] ).length;
4787						}
4788						if ( matches[ sel ] ) {
4789							matches.push( handleObj );
4790						}
4791					}
4792					if ( matches.length ) {
4793						handlerQueue.push( { elem: cur, handlers: matches } );
4794					}
4795				}
4796			}
4797		}
4798
4799		// Add the remaining (directly-bound) handlers
4800		if ( delegateCount < handlers.length ) {
4801			handlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );
4802		}
4803
4804		return handlerQueue;
4805	},
4806
4807	// Includes some event props shared by KeyEvent and MouseEvent
4808	props: ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
4809		"metaKey relatedTarget shiftKey target timeStamp view which" ).split( " " ),
4810
4811	fixHooks: {},
4812
4813	keyHooks: {
4814		props: "char charCode key keyCode".split( " " ),
4815		filter: function( event, original ) {
4816
4817			// Add which for key events
4818			if ( event.which == null ) {
4819				event.which = original.charCode != null ? original.charCode : original.keyCode;
4820			}
4821
4822			return event;
4823		}
4824	},
4825
4826	mouseHooks: {
4827		props: ( "button buttons clientX clientY offsetX offsetY pageX pageY " +
4828			"screenX screenY toElement" ).split( " " ),
4829		filter: function( event, original ) {
4830			var eventDoc, doc, body,
4831				button = original.button;
4832
4833			// Calculate pageX/Y if missing and clientX/Y available
4834			if ( event.pageX == null && original.clientX != null ) {
4835				eventDoc = event.target.ownerDocument || document;
4836				doc = eventDoc.documentElement;
4837				body = eventDoc.body;
4838
4839				event.pageX = original.clientX +
4840					( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -
4841					( doc && doc.clientLeft || body && body.clientLeft || 0 );
4842				event.pageY = original.clientY +
4843					( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -
4844					( doc && doc.clientTop  || body && body.clientTop  || 0 );
4845			}
4846
4847			// Add which for click: 1 === left; 2 === middle; 3 === right
4848			// Note: button is not normalized, so don't use it
4849			if ( !event.which && button !== undefined ) {
4850				event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4851			}
4852
4853			return event;
4854		}
4855	},
4856
4857	fix: function( event ) {
4858		if ( event[ jQuery.expando ] ) {
4859			return event;
4860		}
4861
4862		// Create a writable copy of the event object and normalize some properties
4863		var i, prop, copy,
4864			type = event.type,
4865			originalEvent = event,
4866			fixHook = this.fixHooks[ type ];
4867
4868		if ( !fixHook ) {
4869			this.fixHooks[ type ] = fixHook =
4870				rmouseEvent.test( type ) ? this.mouseHooks :
4871				rkeyEvent.test( type ) ? this.keyHooks :
4872				{};
4873		}
4874		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4875
4876		event = new jQuery.Event( originalEvent );
4877
4878		i = copy.length;
4879		while ( i-- ) {
4880			prop = copy[ i ];
4881			event[ prop ] = originalEvent[ prop ];
4882		}
4883
4884		// Support: Cordova 2.5 (WebKit) (#13255)
4885		// All events should have a target; Cordova deviceready doesn't
4886		if ( !event.target ) {
4887			event.target = document;
4888		}
4889
4890		// Support: Safari 6.0+, Chrome<28
4891		// Target should not be a text node (#504, #13143)
4892		if ( event.target.nodeType === 3 ) {
4893			event.target = event.target.parentNode;
4894		}
4895
4896		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
4897	},
4898
4899	special: {
4900		load: {
4901
4902			// Prevent triggered image.load events from bubbling to window.load
4903			noBubble: true
4904		},
4905		focus: {
4906
4907			// Fire native event if possible so blur/focus sequence is correct
4908			trigger: function() {
4909				if ( this !== safeActiveElement() && this.focus ) {
4910					this.focus();
4911					return false;
4912				}
4913			},
4914			delegateType: "focusin"
4915		},
4916		blur: {
4917			trigger: function() {
4918				if ( this === safeActiveElement() && this.blur ) {
4919					this.blur();
4920					return false;
4921				}
4922			},
4923			delegateType: "focusout"
4924		},
4925		click: {
4926
4927			// For checkbox, fire native event so checked state will be right
4928			trigger: function() {
4929				if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4930					this.click();
4931					return false;
4932				}
4933			},
4934
4935			// For cross-browser consistency, don't fire native .click() on links
4936			_default: function( event ) {
4937				return jQuery.nodeName( event.target, "a" );
4938			}
4939		},
4940
4941		beforeunload: {
4942			postDispatch: function( event ) {
4943
4944				// Support: Firefox 20+
4945				// Firefox doesn't alert if the returnValue field is not set.
4946				if ( event.result !== undefined && event.originalEvent ) {
4947					event.originalEvent.returnValue = event.result;
4948				}
4949			}
4950		}
4951	}
4952};
4953
4954jQuery.removeEvent = function( elem, type, handle ) {
4955
4956	// This "if" is needed for plain objects
4957	if ( elem.removeEventListener ) {
4958		elem.removeEventListener( type, handle );
4959	}
4960};
4961
4962jQuery.Event = function( src, props ) {
4963
4964	// Allow instantiation without the 'new' keyword
4965	if ( !( this instanceof jQuery.Event ) ) {
4966		return new jQuery.Event( src, props );
4967	}
4968
4969	// Event object
4970	if ( src && src.type ) {
4971		this.originalEvent = src;
4972		this.type = src.type;
4973
4974		// Events bubbling up the document may have been marked as prevented
4975		// by a handler lower down the tree; reflect the correct value.
4976		this.isDefaultPrevented = src.defaultPrevented ||
4977				src.defaultPrevented === undefined &&
4978
4979				// Support: Android<4.0
4980				src.returnValue === false ?
4981			returnTrue :
4982			returnFalse;
4983
4984	// Event type
4985	} else {
4986		this.type = src;
4987	}
4988
4989	// Put explicitly provided properties onto the event object
4990	if ( props ) {
4991		jQuery.extend( this, props );
4992	}
4993
4994	// Create a timestamp if incoming event doesn't have one
4995	this.timeStamp = src && src.timeStamp || jQuery.now();
4996
4997	// Mark it as fixed
4998	this[ jQuery.expando ] = true;
4999};
5000
5001// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5002// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5003jQuery.Event.prototype = {
5004	constructor: jQuery.Event,
5005	isDefaultPrevented: returnFalse,
5006	isPropagationStopped: returnFalse,
5007	isImmediatePropagationStopped: returnFalse,
vendor: 3,469 bytes, lines 5008-5142
5008
5009	preventDefault: function() {
5010		var e = this.originalEvent;
5011
5012		this.isDefaultPrevented = returnTrue;
5013
5014		if ( e ) {
5015			e.preventDefault();
5016		}
5017	},
5018	stopPropagation: function() {
5019		var e = this.originalEvent;
5020
5021		this.isPropagationStopped = returnTrue;
5022
5023		if ( e ) {
5024			e.stopPropagation();
5025		}
5026	},
5027	stopImmediatePropagation: function() {
5028		var e = this.originalEvent;
5029
5030		this.isImmediatePropagationStopped = returnTrue;
5031
5032		if ( e ) {
5033			e.stopImmediatePropagation();
5034		}
5035
5036		this.stopPropagation();
5037	}
5038};
5039
5040// Create mouseenter/leave events using mouseover/out and event-time checks
5041// so that event delegation works in jQuery.
5042// Do the same for pointerenter/pointerleave and pointerover/pointerout
5043//
5044// Support: Safari 7 only
5045// Safari sends mouseenter too often; see:
5046// https://code.google.com/p/chromium/issues/detail?id=470258
5047// for the description of the bug (it existed in older Chrome versions as well).
5048jQuery.each( {
5049	mouseenter: "mouseover",
5050	mouseleave: "mouseout",
5051	pointerenter: "pointerover",
5052	pointerleave: "pointerout"
5053}, function( orig, fix ) {
5054	jQuery.event.special[ orig ] = {
5055		delegateType: fix,
5056		bindType: fix,
5057
5058		handle: function( event ) {
5059			var ret,
5060				target = this,
5061				related = event.relatedTarget,
5062				handleObj = event.handleObj;
5063
5064			// For mouseenter/leave call the handler if related is outside the target.
5065			// NB: No relatedTarget if the mouse left/entered the browser window
5066			if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
5067				event.type = handleObj.origType;
5068				ret = handleObj.handler.apply( this, arguments );
5069				event.type = fix;
5070			}
5071			return ret;
5072		}
5073	};
5074} );
5075
5076jQuery.fn.extend( {
5077	on: function( types, selector, data, fn ) {
5078		return on( this, types, selector, data, fn );
5079	},
5080	one: function( types, selector, data, fn ) {
5081		return on( this, types, selector, data, fn, 1 );
5082	},
5083	off: function( types, selector, fn ) {
5084		var handleObj, type;
5085		if ( types && types.preventDefault && types.handleObj ) {
5086
5087			// ( event )  dispatched jQuery.Event
5088			handleObj = types.handleObj;
5089			jQuery( types.delegateTarget ).off(
5090				handleObj.namespace ?
5091					handleObj.origType + "." + handleObj.namespace :
5092					handleObj.origType,
5093				handleObj.selector,
5094				handleObj.handler
5095			);
5096			return this;
5097		}
5098		if ( typeof types === "object" ) {
5099
5100			// ( types-object [, selector] )
5101			for ( type in types ) {
5102				this.off( type, selector, types[ type ] );
5103			}
5104			return this;
5105		}
5106		if ( selector === false || typeof selector === "function" ) {
5107
5108			// ( types [, fn] )
5109			fn = selector;
5110			selector = undefined;
5111		}
5112		if ( fn === false ) {
5113			fn = returnFalse;
5114		}
5115		return this.each( function() {
5116			jQuery.event.remove( this, types, fn, selector );
5117		} );
5118	}
5119} );
5120
5121
5122var
5123	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,
5124
5125	// Support: IE 10-11, Edge 10240+
5126	// In IE/Edge using regex groups here causes severe slowdowns.
5127	// See https://connect.microsoft.com/IE/feedback/details/1736512/
5128	rnoInnerhtml = /<script|<style|<link/i,
5129
5130	// checked="checked" or checked
5131	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5132	rscriptTypeMasked = /^true\/(.*)/,
5133	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
5134
5135function manipulationTarget( elem, content ) {
5136	if ( jQuery.nodeName( elem, "table" ) &&
5137		jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
5138
5139		return elem.getElementsByTagName( "tbody" )[ 0 ] || elem;
5140	}
5141
5142	return 
vendor: 12,777 bytes, lines 5142-5649
5142elem;
5143}
5144
5145// Replace/restore the type attribute of script elements for safe DOM manipulation
5146function disableScript( elem ) {
5147	elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
5148	return elem;
5149}
5150function restoreScript( elem ) {
5151	var match = rscriptTypeMasked.exec( elem.type );
5152
5153	if ( match ) {
5154		elem.type = match[ 1 ];
5155	} else {
5156		elem.removeAttribute( "type" );
5157	}
5158
5159	return elem;
5160}
5161
5162function cloneCopyEvent( src, dest ) {
5163	var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
5164
5165	if ( dest.nodeType !== 1 ) {
5166		return;
5167	}
5168
5169	// 1. Copy private data: events, handlers, etc.
5170	if ( dataPriv.hasData( src ) ) {
5171		pdataOld = dataPriv.access( src );
5172		pdataCur = dataPriv.set( dest, pdataOld );
5173		events = pdataOld.events;
5174
5175		if ( events ) {
5176			delete pdataCur.handle;
5177			pdataCur.events = {};
5178
5179			for ( type in events ) {
5180				for ( i = 0, l = events[ type ].length; i < l; i++ ) {
5181					jQuery.event.add( dest, type, events[ type ][ i ] );
5182				}
5183			}
5184		}
5185	}
5186
5187	// 2. Copy user data
5188	if ( dataUser.hasData( src ) ) {
5189		udataOld = dataUser.access( src );
5190		udataCur = jQuery.extend( {}, udataOld );
5191
5192		dataUser.set( dest, udataCur );
5193	}
5194}
5195
5196// Fix IE bugs, see support tests
5197function fixInput( src, dest ) {
5198	var nodeName = dest.nodeName.toLowerCase();
5199
5200	// Fails to persist the checked state of a cloned checkbox or radio button.
5201	if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
5202		dest.checked = src.checked;
5203
5204	// Fails to return the selected option to the default selected state when cloning options
5205	} else if ( nodeName === "input" || nodeName === "textarea" ) {
5206		dest.defaultValue = src.defaultValue;
5207	}
5208}
5209
5210function domManip( collection, args, callback, ignored ) {
5211
5212	// Flatten any nested arrays
5213	args = concat.apply( [], args );
5214
5215	var fragment, first, scripts, hasScripts, node, doc,
5216		i = 0,
5217		l = collection.length,
5218		iNoClone = l - 1,
5219		value = args[ 0 ],
5220		isFunction = jQuery.isFunction( value );
5221
5222	// We can't cloneNode fragments that contain checked, in WebKit
5223	if ( isFunction ||
5224			( l > 1 && typeof value === "string" &&
5225				!support.checkClone && rchecked.test( value ) ) ) {
5226		return collection.each( function( index ) {
5227			var self = collection.eq( index );
5228			if ( isFunction ) {
5229				args[ 0 ] = value.call( this, index, self.html() );
5230			}
5231			domManip( self, args, callback, ignored );
5232		} );
5233	}
5234
5235	if ( l ) {
5236		fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
5237		first = fragment.firstChild;
5238
5239		if ( fragment.childNodes.length === 1 ) {
5240			fragment = first;
5241		}
5242
5243		// Require either new content or an interest in ignored elements to invoke the callback
5244		if ( first || ignored ) {
5245			scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5246			hasScripts = scripts.length;
5247
5248			// Use the original fragment for the last item
5249			// instead of the first because it can end up
5250			// being emptied incorrectly in certain situations (#8070).
5251			for ( ; i < l; i++ ) {
5252				node = fragment;
5253
5254				if ( i !== iNoClone ) {
5255					node = jQuery.clone( node, true, true );
5256
5257					// Keep references to cloned scripts for later restoration
5258					if ( hasScripts ) {
5259
5260						// Support: Android<4.1, PhantomJS<2
5261						// push.apply(_, arraylike) throws on ancient WebKit
5262						jQuery.merge( scripts, getAll( node, "script" ) );
5263					}
5264				}
5265
5266				callback.call( collection[ i ], node, i );
5267			}
5268
5269			if ( hasScripts ) {
5270				doc = scripts[ scripts.length - 1 ].ownerDocument;
5271
5272				// Reenable scripts
5273				jQuery.map( scripts, restoreScript );
5274
5275				// Evaluate executable scripts on first document insertion
5276				for ( i = 0; i < hasScripts; i++ ) {
5277					node = scripts[ i ];
5278					if ( rscriptType.test( node.type || "" ) &&
5279						!dataPriv.access( node, "globalEval" ) &&
5280						jQuery.contains( doc, node ) ) {
5281
5282						if ( node.src ) {
5283
5284							// Optional AJAX dependency, but won't run scripts if not present
5285							if ( jQuery._evalUrl ) {
5286								jQuery._evalUrl( node.src );
5287							}
5288						} else {
5289							jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5290						}
5291					}
5292				}
5293			}
5294		}
5295	}
5296
5297	return collection;
5298}
5299
5300function remove( elem, selector, keepData ) {
5301	var node,
5302		nodes = selector ? jQuery.filter( selector, elem ) : elem,
5303		i = 0;
5304
5305	for ( ; ( node = nodes[ i ] ) != null; i++ ) {
5306		if ( !keepData && node.nodeType === 1 ) {
5307			jQuery.cleanData( getAll( node ) );
5308		}
5309
5310		if ( node.parentNode ) {
5311			if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
5312				setGlobalEval( getAll( node, "script" ) );
5313			}
5314			node.parentNode.removeChild( node );
5315		}
5316	}
5317
5318	return elem;
5319}
5320
5321jQuery.extend( {
5322	htmlPrefilter: function( html ) {
5323		return html.replace( rxhtmlTag, "<$1></$2>" );
5324	},
5325
5326	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5327		var i, l, srcElements, destElements,
5328			clone = elem.cloneNode( true ),
5329			inPage = jQuery.contains( elem.ownerDocument, elem );
5330
5331		// Fix IE cloning issues
5332		if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
5333				!jQuery.isXMLDoc( elem ) ) {
5334
5335			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5336			destElements = getAll( clone );
5337			srcElements = getAll( elem );
5338
5339			for ( i = 0, l = srcElements.length; i < l; i++ ) {
5340				fixInput( srcElements[ i ], destElements[ i ] );
5341			}
5342		}
5343
5344		// Copy the events from the original to the clone
5345		if ( dataAndEvents ) {
5346			if ( deepDataAndEvents ) {
5347				srcElements = srcElements || getAll( elem );
5348				destElements = destElements || getAll( clone );
5349
5350				for ( i = 0, l = srcElements.length; i < l; i++ ) {
5351					cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5352				}
5353			} else {
5354				cloneCopyEvent( elem, clone );
5355			}
5356		}
5357
5358		// Preserve script evaluation history
5359		destElements = getAll( clone, "script" );
5360		if ( destElements.length > 0 ) {
5361			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5362		}
5363
5364		// Return the cloned set
5365		return clone;
5366	},
5367
5368	cleanData: function( elems ) {
5369		var data, elem, type,
5370			special = jQuery.event.special,
5371			i = 0;
5372
5373		for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
5374			if ( acceptData( elem ) ) {
5375				if ( ( data = elem[ dataPriv.expando ] ) ) {
5376					if ( data.events ) {
5377						for ( type in data.events ) {
5378							if ( special[ type ] ) {
5379								jQuery.event.remove( elem, type );
5380
5381							// This is a shortcut to avoid jQuery.event.remove's overhead
5382							} else {
5383								jQuery.removeEvent( elem, type, data.handle );
5384							}
5385						}
5386					}
5387
5388					// Support: Chrome <= 35-45+
5389					// Assign undefined instead of using delete, see Data#remove
5390					elem[ dataPriv.expando ] = undefined;
5391				}
5392				if ( elem[ dataUser.expando ] ) {
5393
5394					// Support: Chrome <= 35-45+
5395					// Assign undefined instead of using delete, see Data#remove
5396					elem[ dataUser.expando ] = undefined;
5397				}
5398			}
5399		}
5400	}
5401} );
5402
5403jQuery.fn.extend( {
5404
5405	// Keep domManip exposed until 3.0 (gh-2225)
5406	domManip: domManip,
5407
5408	detach: function( selector ) {
5409		return remove( this, selector, true );
5410	},
5411
5412	remove: function( selector ) {
5413		return remove( this, selector );
5414	},
5415
5416	text: function( value ) {
5417		return access( this, function( value ) {
5418			return value === undefined ?
5419				jQuery.text( this ) :
5420				this.empty().each( function() {
5421					if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5422						this.textContent = value;
5423					}
5424				} );
5425		}, null, value, arguments.length );
5426	},
5427
5428	append: function() {
5429		return domManip( this, arguments, function( elem ) {
5430			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5431				var target = manipulationTarget( this, elem );
5432				target.appendChild( elem );
5433			}
5434		} );
5435	},
5436
5437	prepend: function() {
5438		return domManip( this, arguments, function( elem ) {
5439			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5440				var target = manipulationTarget( this, elem );
5441				target.insertBefore( elem, target.firstChild );
5442			}
5443		} );
5444	},
5445
5446	before: function() {
5447		return domManip( this, arguments, function( elem ) {
5448			if ( this.parentNode ) {
5449				this.parentNode.insertBefore( elem, this );
5450			}
5451		} );
5452	},
5453
5454	after: function() {
5455		return domManip( this, arguments, function( elem ) {
5456			if ( this.parentNode ) {
5457				this.parentNode.insertBefore( elem, this.nextSibling );
5458			}
5459		} );
5460	},
5461
5462	empty: function() {
5463		var elem,
5464			i = 0;
5465
5466		for ( ; ( elem = this[ i ] ) != null; i++ ) {
5467			if ( elem.nodeType === 1 ) {
5468
5469				// Prevent memory leaks
5470				jQuery.cleanData( getAll( elem, false ) );
5471
5472				// Remove any remaining nodes
5473				elem.textContent = "";
5474			}
5475		}
5476
5477		return this;
5478	},
5479
5480	clone: function( dataAndEvents, deepDataAndEvents ) {
5481		dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5482		deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5483
5484		return this.map( function() {
5485			return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5486		} );
5487	},
5488
5489	html: function( value ) {
5490		return access( this, function( value ) {
5491			var elem = this[ 0 ] || {},
5492				i = 0,
5493				l = this.length;
5494
5495			if ( value === undefined && elem.nodeType === 1 ) {
5496				return elem.innerHTML;
5497			}
5498
5499			// See if we can take a shortcut and just use innerHTML
5500			if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5501				!wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5502
5503				value = jQuery.htmlPrefilter( value );
5504
5505				try {
5506					for ( ; i < l; i++ ) {
5507						elem = this[ i ] || {};
5508
5509						// Remove element nodes and prevent memory leaks
5510						if ( elem.nodeType === 1 ) {
5511							jQuery.cleanData( getAll( elem, false ) );
5512							elem.innerHTML = value;
5513						}
5514					}
5515
5516					elem = 0;
5517
5518				// If using innerHTML throws an exception, use the fallback method
5519				} catch ( e ) {}
5520			}
5521
5522			if ( elem ) {
5523				this.empty().append( value );
5524			}
5525		}, null, value, arguments.length );
5526	},
5527
5528	replaceWith: function() {
5529		var ignored = [];
5530
5531		// Make the changes, replacing each non-ignored context element with the new content
5532		return domManip( this, arguments, function( elem ) {
5533			var parent = this.parentNode;
5534
5535			if ( jQuery.inArray( this, ignored ) < 0 ) {
5536				jQuery.cleanData( getAll( this ) );
5537				if ( parent ) {
5538					parent.replaceChild( elem, this );
5539				}
5540			}
5541
5542		// Force callback invocation
5543		}, ignored );
5544	}
5545} );
5546
5547jQuery.each( {
5548	appendTo: "append",
5549	prependTo: "prepend",
5550	insertBefore: "before",
5551	insertAfter: "after",
5552	replaceAll: "replaceWith"
5553}, function( name, original ) {
5554	jQuery.fn[ name ] = function( selector ) {
5555		var elems,
5556			ret = [],
5557			insert = jQuery( selector ),
5558			last = insert.length - 1,
5559			i = 0;
5560
5561		for ( ; i <= last; i++ ) {
5562			elems = i === last ? this : this.clone( true );
5563			jQuery( insert[ i ] )[ original ]( elems );
5564
5565			// Support: QtWebKit
5566			// .get() because push.apply(_, arraylike) throws
5567			push.apply( ret, elems.get() );
5568		}
5569
5570		return this.pushStack( ret );
5571	};
5572} );
5573
5574
5575var iframe,
5576	elemdisplay = {
5577
5578		// Support: Firefox
5579		// We have to pre-define these values for FF (#10227)
5580		HTML: "block",
5581		BODY: "block"
5582	};
5583
5584/**
5585 * Retrieve the actual display of a element
5586 * @param {String} name nodeName of the element
5587 * @param {Object} doc Document object
5588 */
5589
5590// Called only from within defaultDisplay
5591function actualDisplay( name, doc ) {
5592	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
5593
5594		display = jQuery.css( elem[ 0 ], "display" );
5595
5596	// We don't have any data stored on the element,
5597	// so use "detach" method as fast way to get rid of the element
5598	elem.detach();
5599
5600	return display;
5601}
5602
5603/**
5604 * Try to determine the default display value of an element
5605 * @param {String} nodeName
5606 */
5607function defaultDisplay( nodeName ) {
5608	var doc = document,
5609		display = elemdisplay[ nodeName ];
5610
5611	if ( !display ) {
5612		display = actualDisplay( nodeName, doc );
5613
5614		// If the simple way fails, read from inside an iframe
5615		if ( display === "none" || !display ) {
5616
5617			// Use the already-created iframe if possible
5618			iframe = ( iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" ) )
5619				.appendTo( doc.documentElement );
5620
5621			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
5622			doc = iframe[ 0 ].contentDocument;
5623
5624			// Support: IE
5625			doc.write();
5626			doc.close();
5627
5628			display = actualDisplay( nodeName, doc );
5629			iframe.detach();
5630		}
5631
5632		// Store the correct default display
5633		elemdisplay[ nodeName ] = display;
5634	}
5635
5636	return display;
5637}
5638var rmargin = ( /^margin/ );
5639
5640var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
5641
5642var getStyles = function( elem ) {
5643
5644		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
5645		// IE throws on elements created in popups
5646		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
5647		var view = elem.ownerDocument.defaultView;
5648
5649		if ( !view
vendor: 9,038 bytes, lines 5649-5964
5649.opener ) {
5650			view = window;
5651		}
5652
5653		return view.getComputedStyle( elem );
5654	};
5655
5656var swap = function( elem, options, callback, args ) {
5657	var ret, name,
5658		old = {};
5659
5660	// Remember the old values, and insert the new ones
5661	for ( name in options ) {
5662		old[ name ] = elem.style[ name ];
5663		elem.style[ name ] = options[ name ];
5664	}
5665
5666	ret = callback.apply( elem, args || [] );
5667
5668	// Revert the old values
5669	for ( name in options ) {
5670		elem.style[ name ] = old[ name ];
5671	}
5672
5673	return ret;
5674};
5675
5676
5677var documentElement = document.documentElement;
5678
5679
5680
5681( function() {
5682	var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
5683		container = document.createElement( "div" ),
5684		div = document.createElement( "div" );
5685
5686	// Finish early in limited (non-browser) environments
5687	if ( !div.style ) {
5688		return;
5689	}
5690
5691	// Support: IE9-11+
5692	// Style of cloned element affects source element cloned (#8908)
5693	div.style.backgroundClip = "content-box";
5694	div.cloneNode( true ).style.backgroundClip = "";
5695	support.clearCloneStyle = div.style.backgroundClip === "content-box";
5696
5697	container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
5698		"padding:0;margin-top:1px;position:absolute";
5699	container.appendChild( div );
5700
5701	// Executing both pixelPosition & boxSizingReliable tests require only one layout
5702	// so they're executed at the same time to save the second computation.
5703	function computeStyleTests() {
5704		div.style.cssText =
5705
5706			// Support: Firefox<29, Android 2.3
5707			// Vendor-prefix box-sizing
5708			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" +
5709			"position:relative;display:block;" +
5710			"margin:auto;border:1px;padding:1px;" +
5711			"top:1%;width:50%";
5712		div.innerHTML = "";
5713		documentElement.appendChild( container );
5714
5715		var divStyle = window.getComputedStyle( div );
5716		pixelPositionVal = divStyle.top !== "1%";
5717		reliableMarginLeftVal = divStyle.marginLeft === "2px";
5718		boxSizingReliableVal = divStyle.width === "4px";
5719
5720		// Support: Android 4.0 - 4.3 only
5721		// Some styles come back with percentage values, even though they shouldn't
5722		div.style.marginRight = "50%";
5723		pixelMarginRightVal = divStyle.marginRight === "4px";
5724
5725		documentElement.removeChild( container );
5726	}
5727
5728	jQuery.extend( support, {
5729		pixelPosition: function() {
5730
5731			// This test is executed only once but we still do memoizing
5732			// since we can use the boxSizingReliable pre-computing.
5733			// No need to check if the test was already performed, though.
5734			computeStyleTests();
5735			return pixelPositionVal;
5736		},
5737		boxSizingReliable: function() {
5738			if ( boxSizingReliableVal == null ) {
5739				computeStyleTests();
5740			}
5741			return boxSizingReliableVal;
5742		},
5743		pixelMarginRight: function() {
5744
5745			// Support: Android 4.0-4.3
5746			// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
5747			// since that compresses better and they're computed together anyway.
5748			if ( boxSizingReliableVal == null ) {
5749				computeStyleTests();
5750			}
5751			return pixelMarginRightVal;
5752		},
5753		reliableMarginLeft: function() {
5754
5755			// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
5756			if ( boxSizingReliableVal == null ) {
5757				computeStyleTests();
5758			}
5759			return reliableMarginLeftVal;
5760		},
5761		reliableMarginRight: function() {
5762
5763			// Support: Android 2.3
5764			// Check if div with explicit width and no margin-right incorrectly
5765			// gets computed margin-right based on width of container. (#3333)
5766			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
5767			// This support function is only executed once so no memoizing is needed.
5768			var ret,
5769				marginDiv = div.appendChild( document.createElement( "div" ) );
5770
5771			// Reset CSS: box-sizing; display; margin; border; padding
5772			marginDiv.style.cssText = div.style.cssText =
5773
5774				// Support: Android 2.3
5775				// Vendor-prefix box-sizing
5776				"-webkit-box-sizing:content-box;box-sizing:content-box;" +
5777				"display:block;margin:0;border:0;padding:0";
5778			marginDiv.style.marginRight = marginDiv.style.width = "0";
5779			div.style.width = "1px";
5780			documentElement.appendChild( container );
5781
5782			ret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );
5783
5784			documentElement.removeChild( container );
5785			div.removeChild( marginDiv );
5786
5787			return ret;
5788		}
5789	} );
5790} )();
5791
5792
5793function curCSS( elem, name, computed ) {
5794	var width, minWidth, maxWidth, ret,
5795		style = elem.style;
5796
5797	computed = computed || getStyles( elem );
5798
5799	// Support: IE9
5800	// getPropertyValue is only needed for .css('filter') (#12537)
5801	if ( computed ) {
5802		ret = computed.getPropertyValue( name ) || computed[ name ];
5803
5804		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
5805			ret = jQuery.style( elem, name );
5806		}
5807
5808		// A tribute to the "awesome hack by Dean Edwards"
5809		// Android Browser returns percentage for some values,
5810		// but width seems to be reliably pixels.
5811		// This is against the CSSOM draft spec:
5812		// http://dev.w3.org/csswg/cssom/#resolved-values
5813		if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
5814
5815			// Remember the original values
5816			width = style.width;
5817			minWidth = style.minWidth;
5818			maxWidth = style.maxWidth;
5819
5820			// Put in the new values to get a computed value out
5821			style.minWidth = style.maxWidth = style.width = ret;
5822			ret = computed.width;
5823
5824			// Revert the changed values
5825			style.width = width;
5826			style.minWidth = minWidth;
5827			style.maxWidth = maxWidth;
5828		}
5829	}
5830
5831	return ret !== undefined ?
5832
5833		// Support: IE9-11+
5834		// IE returns zIndex value as an integer.
5835		ret + "" :
5836		ret;
5837}
5838
5839
5840function addGetHookIf( conditionFn, hookFn ) {
5841
5842	// Define the hook, we'll check on the first run if it's really needed.
5843	return {
5844		get: function() {
5845			if ( conditionFn() ) {
5846
5847				// Hook not needed (or it's not possible to use it due
5848				// to missing dependency), remove it.
5849				delete this.get;
5850				return;
5851			}
5852
5853			// Hook needed; redefine it so that the support test is not executed again.
5854			return ( this.get = hookFn ).apply( this, arguments );
5855		}
5856	};
5857}
5858
5859
5860var
5861
5862	// Swappable if display is none or starts with table
5863	// except "table", "table-cell", or "table-caption"
5864	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
5865	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
5866
5867	cssShow = { position: "absolute", visibility: "hidden", display: "block" },
5868	cssNormalTransform = {
5869		letterSpacing: "0",
5870		fontWeight: "400"
5871	},
5872
5873	cssPrefixes = [ "Webkit", "O", "Moz", "ms" ],
5874	emptyStyle = document.createElement( "div" ).style;
5875
5876// Return a css property mapped to a potentially vendor prefixed property
5877function vendorPropName( name ) {
5878
5879	// Shortcut for names that are not vendor prefixed
5880	if ( name in emptyStyle ) {
5881		return name;
5882	}
5883
5884	// Check for vendor prefixed names
5885	var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
5886		i = cssPrefixes.length;
5887
5888	while ( i-- ) {
5889		name = cssPrefixes[ i ] + capName;
5890		if ( name in emptyStyle ) {
5891			return name;
5892		}
5893	}
5894}
5895
5896function setPositiveNumber( elem, value, subtract ) {
5897
5898	// Any relative (+/-) values have already been
5899	// normalized at this point
5900	var matches = rcssNum.exec( value );
5901	return matches ?
5902
5903		// Guard against undefined "subtract", e.g., when used as in cssHooks
5904		Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
5905		value;
5906}
5907
5908function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
5909	var i = extra === ( isBorderBox ? "border" : "content" ) ?
5910
5911		// If we already have the right measurement, avoid augmentation
5912		4 :
5913
5914		// Otherwise initialize for horizontal or vertical properties
5915		name === "width" ? 1 : 0,
5916
5917		val = 0;
5918
5919	for ( ; i < 4; i += 2 ) {
5920
5921		// Both box models exclude margin, so add it if we want it
5922		if ( extra === "margin" ) {
5923			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
5924		}
5925
5926		if ( isBorderBox ) {
5927
5928			// border-box includes padding, so remove it if we want content
5929			if ( extra === "content" ) {
5930				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5931			}
5932
5933			// At this point, extra isn't border nor margin, so remove border
5934			if ( extra !== "margin" ) {
5935				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5936			}
5937		} else {
5938
5939			// At this point, extra isn't content, so add padding
5940			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
5941
5942			// At this point, extra isn't content nor padding, so add border
5943			if ( extra !== "padding" ) {
5944				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
5945			}
5946		}
5947	}
5948
5949	return val;
5950}
5951
5952function getWidthOrHeight( elem, name, extra ) {
5953
5954	// Start with offset property, which is equivalent to the border-box value
5955	var valueIsBorderBox = true,
5956		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
5957		styles = getStyles( elem ),
5958		isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
5959
5960	// Support: IE11 only
5961	// In IE 11 fullscreen elements inside of an iframe have
5962	// 100x too small dimensions (gh-1764).
5963	if ( document.msFullscreenElement && window.top !== window ) {
5964
5965		// Support: IE11 only
5966		// Running getBoundingClientRect on a disconnected node
5967		// in IE throws an error.
5968		if ( elem.getClientRects().length ) {
5969			val = Math.round( elem.getBoundingClientRect()[ name ] * 100 );
5970		}
5971	}
vendor: 34,435 bytes, lines 5971-7328
5971
5972
5973	// Some non-html elements return undefined for offsetWidth, so check for null/undefined
5974	// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
5975	// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
5976	if ( val <= 0 || val == null ) {
5977
5978		// Fall back to computed then uncomputed css if necessary
5979		val = curCSS( elem, name, styles );
5980		if ( val < 0 || val == null ) {
5981			val = elem.style[ name ];
5982		}
5983
5984		// Computed unit is not pixels. Stop here and return.
5985		if ( rnumnonpx.test( val ) ) {
5986			return val;
5987		}
5988
5989		// Check for style in case a browser which returns unreliable values
5990		// for getComputedStyle silently falls back to the reliable elem.style
5991		valueIsBorderBox = isBorderBox &&
5992			( support.boxSizingReliable() || val === elem.style[ name ] );
5993
5994		// Normalize "", auto, and prepare for extra
5995		val = parseFloat( val ) || 0;
5996	}
5997
5998	// Use the active box-sizing model to add/subtract irrelevant styles
5999	return ( val +
6000		augmentWidthOrHeight(
6001			elem,
6002			name,
6003			extra || ( isBorderBox ? "border" : "content" ),
6004			valueIsBorderBox,
6005			styles
6006		)
6007	) + "px";
6008}
6009
6010function showHide( elements, show ) {
6011	var display, elem, hidden,
6012		values = [],
6013		index = 0,
6014		length = elements.length;
6015
6016	for ( ; index < length; index++ ) {
6017		elem = elements[ index ];
6018		if ( !elem.style ) {
6019			continue;
6020		}
6021
6022		values[ index ] = dataPriv.get( elem, "olddisplay" );
6023		display = elem.style.display;
6024		if ( show ) {
6025
6026			// Reset the inline display of this element to learn if it is
6027			// being hidden by cascaded rules or not
6028			if ( !values[ index ] && display === "none" ) {
6029				elem.style.display = "";
6030			}
6031
6032			// Set elements which have been overridden with display: none
6033			// in a stylesheet to whatever the default browser style is
6034			// for such an element
6035			if ( elem.style.display === "" && isHidden( elem ) ) {
6036				values[ index ] = dataPriv.access(
6037					elem,
6038					"olddisplay",
6039					defaultDisplay( elem.nodeName )
6040				);
6041			}
6042		} else {
6043			hidden = isHidden( elem );
6044
6045			if ( display !== "none" || !hidden ) {
6046				dataPriv.set(
6047					elem,
6048					"olddisplay",
6049					hidden ? display : jQuery.css( elem, "display" )
6050				);
6051			}
6052		}
6053	}
6054
6055	// Set the display of most of the elements in a second loop
6056	// to avoid the constant reflow
6057	for ( index = 0; index < length; index++ ) {
6058		elem = elements[ index ];
6059		if ( !elem.style ) {
6060			continue;
6061		}
6062		if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6063			elem.style.display = show ? values[ index ] || "" : "none";
6064		}
6065	}
6066
6067	return elements;
6068}
6069
6070jQuery.extend( {
6071
6072	// Add in style property hooks for overriding the default
6073	// behavior of getting and setting a style property
6074	cssHooks: {
6075		opacity: {
6076			get: function( elem, computed ) {
6077				if ( computed ) {
6078
6079					// We should always get a number back from opacity
6080					var ret = curCSS( elem, "opacity" );
6081					return ret === "" ? "1" : ret;
6082				}
6083			}
6084		}
6085	},
6086
6087	// Don't automatically add "px" to these possibly-unitless properties
6088	cssNumber: {
6089		"animationIterationCount": true,
6090		"columnCount": true,
6091		"fillOpacity": true,
6092		"flexGrow": true,
6093		"flexShrink": true,
6094		"fontWeight": true,
6095		"lineHeight": true,
6096		"opacity": true,
6097		"order": true,
6098		"orphans": true,
6099		"widows": true,
6100		"zIndex": true,
6101		"zoom": true
6102	},
6103
6104	// Add in properties whose names you wish to fix before
6105	// setting or getting the value
6106	cssProps: {
6107		"float": "cssFloat"
6108	},
6109
6110	// Get and set the style property on a DOM Node
6111	style: function( elem, name, value, extra ) {
6112
6113		// Don't set styles on text and comment nodes
6114		if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6115			return;
6116		}
6117
6118		// Make sure that we're working with the right name
6119		var ret, type, hooks,
6120			origName = jQuery.camelCase( name ),
6121			style = elem.style;
6122
6123		name = jQuery.cssProps[ origName ] ||
6124			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6125
6126		// Gets hook for the prefixed version, then unprefixed version
6127		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6128
6129		// Check if we're setting a value
6130		if ( value !== undefined ) {
6131			type = typeof value;
6132
6133			// Convert "+=" or "-=" to relative numbers (#7345)
6134			if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
6135				value = adjustCSS( elem, name, ret );
6136
6137				// Fixes bug #9237
6138				type = "number";
6139			}
6140
6141			// Make sure that null and NaN values aren't set (#7116)
6142			if ( value == null || value !== value ) {
6143				return;
6144			}
6145
6146			// If a number was passed in, add the unit (except for certain CSS properties)
6147			if ( type === "number" ) {
6148				value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
6149			}
6150
6151			// Support: IE9-11+
6152			// background-* props affect original clone's values
6153			if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
6154				style[ name ] = "inherit";
6155			}
6156
6157			// If a hook was provided, use that value, otherwise just set the specified value
6158			if ( !hooks || !( "set" in hooks ) ||
6159				( value = hooks.set( elem, value, extra ) ) !== undefined ) {
6160
6161				style[ name ] = value;
6162			}
6163
6164		} else {
6165
6166			// If a hook was provided get the non-computed value from there
6167			if ( hooks && "get" in hooks &&
6168				( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
6169
6170				return ret;
6171			}
6172
6173			// Otherwise just get the value from the style object
6174			return style[ name ];
6175		}
6176	},
6177
6178	css: function( elem, name, extra, styles ) {
6179		var val, num, hooks,
6180			origName = jQuery.camelCase( name );
6181
6182		// Make sure that we're working with the right name
6183		name = jQuery.cssProps[ origName ] ||
6184			( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
6185
6186		// Try prefixed name followed by the unprefixed name
6187		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6188
6189		// If a hook was provided get the computed value from there
6190		if ( hooks && "get" in hooks ) {
6191			val = hooks.get( elem, true, extra );
6192		}
6193
6194		// Otherwise, if a way to get the computed value exists, use that
6195		if ( val === undefined ) {
6196			val = curCSS( elem, name, styles );
6197		}
6198
6199		// Convert "normal" to computed value
6200		if ( val === "normal" && name in cssNormalTransform ) {
6201			val = cssNormalTransform[ name ];
6202		}
6203
6204		// Make numeric if forced or a qualifier was provided and val looks numeric
6205		if ( extra === "" || extra ) {
6206			num = parseFloat( val );
6207			return extra === true || isFinite( num ) ? num || 0 : val;
6208		}
6209		return val;
6210	}
6211} );
6212
6213jQuery.each( [ "height", "width" ], function( i, name ) {
6214	jQuery.cssHooks[ name ] = {
6215		get: function( elem, computed, extra ) {
6216			if ( computed ) {
6217
6218				// Certain elements can have dimension info if we invisibly show them
6219				// but it must have a current display style that would benefit
6220				return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
6221					elem.offsetWidth === 0 ?
6222						swap( elem, cssShow, function() {
6223							return getWidthOrHeight( elem, name, extra );
6224						} ) :
6225						getWidthOrHeight( elem, name, extra );
6226			}
6227		},
6228
6229		set: function( elem, value, extra ) {
6230			var matches,
6231				styles = extra && getStyles( elem ),
6232				subtract = extra && augmentWidthOrHeight(
6233					elem,
6234					name,
6235					extra,
6236					jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6237					styles
6238				);
6239
6240			// Convert to pixels if value adjustment is needed
6241			if ( subtract && ( matches = rcssNum.exec( value ) ) &&
6242				( matches[ 3 ] || "px" ) !== "px" ) {
6243
6244				elem.style[ name ] = value;
6245				value = jQuery.css( elem, name );
6246			}
6247
6248			return setPositiveNumber( elem, value, subtract );
6249		}
6250	};
6251} );
6252
6253jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
6254	function( elem, computed ) {
6255		if ( computed ) {
6256			return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
6257				elem.getBoundingClientRect().left -
6258					swap( elem, { marginLeft: 0 }, function() {
6259						return elem.getBoundingClientRect().left;
6260					} )
6261				) + "px";
6262		}
6263	}
6264);
6265
6266// Support: Android 2.3
6267jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
6268	function( elem, computed ) {
6269		if ( computed ) {
6270			return swap( elem, { "display": "inline-block" },
6271				curCSS, [ elem, "marginRight" ] );
6272		}
6273	}
6274);
6275
6276// These hooks are used by animate to expand properties
6277jQuery.each( {
6278	margin: "",
6279	padding: "",
6280	border: "Width"
6281}, function( prefix, suffix ) {
6282	jQuery.cssHooks[ prefix + suffix ] = {
6283		expand: function( value ) {
6284			var i = 0,
6285				expanded = {},
6286
6287				// Assumes a single number if not a string
6288				parts = typeof value === "string" ? value.split( " " ) : [ value ];
6289
6290			for ( ; i < 4; i++ ) {
6291				expanded[ prefix + cssExpand[ i ] + suffix ] =
6292					parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6293			}
6294
6295			return expanded;
6296		}
6297	};
6298
6299	if ( !rmargin.test( prefix ) ) {
6300		jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6301	}
6302} );
6303
6304jQuery.fn.extend( {
6305	css: function( name, value ) {
6306		return access( this, function( elem, name, value ) {
6307			var styles, len,
6308				map = {},
6309				i = 0;
6310
6311			if ( jQuery.isArray( name ) ) {
6312				styles = getStyles( elem );
6313				len = name.length;
6314
6315				for ( ; i < len; i++ ) {
6316					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6317				}
6318
6319				return map;
6320			}
6321
6322			return value !== undefined ?
6323				jQuery.style( elem, name, value ) :
6324				jQuery.css( elem, name );
6325		}, name, value, arguments.length > 1 );
6326	},
6327	show: function() {
6328		return showHide( this, true );
6329	},
6330	hide: function() {
6331		return showHide( this );
6332	},
6333	toggle: function( state ) {
6334		if ( typeof state === "boolean" ) {
6335			return state ? this.show() : this.hide();
6336		}
6337
6338		return this.each( function() {
6339			if ( isHidden( this ) ) {
6340				jQuery( this ).show();
6341			} else {
6342				jQuery( this ).hide();
6343			}
6344		} );
6345	}
6346} );
6347
6348
6349function Tween( elem, options, prop, end, easing ) {
6350	return new Tween.prototype.init( elem, options, prop, end, easing );
6351}
6352jQuery.Tween = Tween;
6353
6354Tween.prototype = {
6355	constructor: Tween,
6356	init: function( elem, options, prop, end, easing, unit ) {
6357		this.elem = elem;
6358		this.prop = prop;
6359		this.easing = easing || jQuery.easing._default;
6360		this.options = options;
6361		this.start = this.now = this.cur();
6362		this.end = end;
6363		this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
6364	},
6365	cur: function() {
6366		var hooks = Tween.propHooks[ this.prop ];
6367
6368		return hooks && hooks.get ?
6369			hooks.get( this ) :
6370			Tween.propHooks._default.get( this );
6371	},
6372	run: function( percent ) {
6373		var eased,
6374			hooks = Tween.propHooks[ this.prop ];
6375
6376		if ( this.options.duration ) {
6377			this.pos = eased = jQuery.easing[ this.easing ](
6378				percent, this.options.duration * percent, 0, 1, this.options.duration
6379			);
6380		} else {
6381			this.pos = eased = percent;
6382		}
6383		this.now = ( this.end - this.start ) * eased + this.start;
6384
6385		if ( this.options.step ) {
6386			this.options.step.call( this.elem, this.now, this );
6387		}
6388
6389		if ( hooks && hooks.set ) {
6390			hooks.set( this );
6391		} else {
6392			Tween.propHooks._default.set( this );
6393		}
6394		return this;
6395	}
6396};
6397
6398Tween.prototype.init.prototype = Tween.prototype;
6399
6400Tween.propHooks = {
6401	_default: {
6402		get: function( tween ) {
6403			var result;
6404
6405			// Use a property on the element directly when it is not a DOM element,
6406			// or when there is no matching style property that exists.
6407			if ( tween.elem.nodeType !== 1 ||
6408				tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
6409				return tween.elem[ tween.prop ];
6410			}
6411
6412			// Passing an empty string as a 3rd parameter to .css will automatically
6413			// attempt a parseFloat and fallback to a string if the parse fails.
6414			// Simple values such as "10px" are parsed to Float;
6415			// complex values such as "rotate(1rad)" are returned as-is.
6416			result = jQuery.css( tween.elem, tween.prop, "" );
6417
6418			// Empty strings, null, undefined and "auto" are converted to 0.
6419			return !result || result === "auto" ? 0 : result;
6420		},
6421		set: function( tween ) {
6422
6423			// Use step hook for back compat.
6424			// Use cssHook if its there.
6425			// Use .style if available and use plain properties where available.
6426			if ( jQuery.fx.step[ tween.prop ] ) {
6427				jQuery.fx.step[ tween.prop ]( tween );
6428			} else if ( tween.elem.nodeType === 1 &&
6429				( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
6430					jQuery.cssHooks[ tween.prop ] ) ) {
6431				jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
6432			} else {
6433				tween.elem[ tween.prop ] = tween.now;
6434			}
6435		}
6436	}
6437};
6438
6439// Support: IE9
6440// Panic based approach to setting things on disconnected nodes
6441Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
6442	set: function( tween ) {
6443		if ( tween.elem.nodeType && tween.elem.parentNode ) {
6444			tween.elem[ tween.prop ] = tween.now;
6445		}
6446	}
6447};
6448
6449jQuery.easing = {
6450	linear: function( p ) {
6451		return p;
6452	},
6453	swing: function( p ) {
6454		return 0.5 - Math.cos( p * Math.PI ) / 2;
6455	},
6456	_default: "swing"
6457};
6458
6459jQuery.fx = Tween.prototype.init;
6460
6461// Back Compat <1.8 extension point
6462jQuery.fx.step = {};
6463
6464
6465
6466
6467var
6468	fxNow, timerId,
6469	rfxtypes = /^(?:toggle|show|hide)$/,
6470	rrun = /queueHooks$/;
6471
6472// Animations created synchronously will run synchronously
6473function createFxNow() {
6474	window.setTimeout( function() {
6475		fxNow = undefined;
6476	} );
6477	return ( fxNow = jQuery.now() );
6478}
6479
6480// Generate parameters to create a standard animation
6481function genFx( type, includeWidth ) {
6482	var which,
6483		i = 0,
6484		attrs = { height: type };
6485
6486	// If we include width, step value is 1 to do all cssExpand values,
6487	// otherwise step value is 2 to skip over Left and Right
6488	includeWidth = includeWidth ? 1 : 0;
6489	for ( ; i < 4 ; i += 2 - includeWidth ) {
6490		which = cssExpand[ i ];
6491		attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
6492	}
6493
6494	if ( includeWidth ) {
6495		attrs.opacity = attrs.width = type;
6496	}
6497
6498	return attrs;
6499}
6500
6501function createTween( value, prop, animation ) {
6502	var tween,
6503		collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
6504		index = 0,
6505		length = collection.length;
6506	for ( ; index < length; index++ ) {
6507		if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
6508
6509			// We're done with this property
6510			return tween;
6511		}
6512	}
6513}
6514
6515function defaultPrefilter( elem, props, opts ) {
6516	/* jshint validthis: true */
6517	var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
6518		anim = this,
6519		orig = {},
6520		style = elem.style,
6521		hidden = elem.nodeType && isHidden( elem ),
6522		dataShow = dataPriv.get( elem, "fxshow" );
6523
6524	// Handle queue: false promises
6525	if ( !opts.queue ) {
6526		hooks = jQuery._queueHooks( elem, "fx" );
6527		if ( hooks.unqueued == null ) {
6528			hooks.unqueued = 0;
6529			oldfire = hooks.empty.fire;
6530			hooks.empty.fire = function() {
6531				if ( !hooks.unqueued ) {
6532					oldfire();
6533				}
6534			};
6535		}
6536		hooks.unqueued++;
6537
6538		anim.always( function() {
6539
6540			// Ensure the complete handler is called before this completes
6541			anim.always( function() {
6542				hooks.unqueued--;
6543				if ( !jQuery.queue( elem, "fx" ).length ) {
6544					hooks.empty.fire();
6545				}
6546			} );
6547		} );
6548	}
6549
6550	// Height/width overflow pass
6551	if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
6552
6553		// Make sure that nothing sneaks out
6554		// Record all 3 overflow attributes because IE9-10 do not
6555		// change the overflow attribute when overflowX and
6556		// overflowY are set to the same value
6557		opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
6558
6559		// Set display property to inline-block for height/width
6560		// animations on inline elements that are having width/height animated
6561		display = jQuery.css( elem, "display" );
6562
6563		// Test default display if display is currently "none"
6564		checkDisplay = display === "none" ?
6565			dataPriv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
6566
6567		if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
6568			style.display = "inline-block";
6569		}
6570	}
6571
6572	if ( opts.overflow ) {
6573		style.overflow = "hidden";
6574		anim.always( function() {
6575			style.overflow = opts.overflow[ 0 ];
6576			style.overflowX = opts.overflow[ 1 ];
6577			style.overflowY = opts.overflow[ 2 ];
6578		} );
6579	}
6580
6581	// show/hide pass
6582	for ( prop in props ) {
6583		value = props[ prop ];
6584		if ( rfxtypes.exec( value ) ) {
6585			delete props[ prop ];
6586			toggle = toggle || value === "toggle";
6587			if ( value === ( hidden ? "hide" : "show" ) ) {
6588
6589				// If there is dataShow left over from a stopped hide or show
6590				// and we are going to proceed with show, we should pretend to be hidden
6591				if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
6592					hidden = true;
6593				} else {
6594					continue;
6595				}
6596			}
6597			orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
6598
6599		// Any non-fx value stops us from restoring the original display value
6600		} else {
6601			display = undefined;
6602		}
6603	}
6604
6605	if ( !jQuery.isEmptyObject( orig ) ) {
6606		if ( dataShow ) {
6607			if ( "hidden" in dataShow ) {
6608				hidden = dataShow.hidden;
6609			}
6610		} else {
6611			dataShow = dataPriv.access( elem, "fxshow", {} );
6612		}
6613
6614		// Store state if its toggle - enables .stop().toggle() to "reverse"
6615		if ( toggle ) {
6616			dataShow.hidden = !hidden;
6617		}
6618		if ( hidden ) {
6619			jQuery( elem ).show();
6620		} else {
6621			anim.done( function() {
6622				jQuery( elem ).hide();
6623			} );
6624		}
6625		anim.done( function() {
6626			var prop;
6627
6628			dataPriv.remove( elem, "fxshow" );
6629			for ( prop in orig ) {
6630				jQuery.style( elem, prop, orig[ prop ] );
6631			}
6632		} );
6633		for ( prop in orig ) {
6634			tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
6635
6636			if ( !( prop in dataShow ) ) {
6637				dataShow[ prop ] = tween.start;
6638				if ( hidden ) {
6639					tween.end = tween.start;
6640					tween.start = prop === "width" || prop === "height" ? 1 : 0;
6641				}
6642			}
6643		}
6644
6645	// If this is a noop like .hide().hide(), restore an overwritten display value
6646	} else if ( ( display === "none" ? defaultDisplay( elem.nodeName ) : display ) === "inline" ) {
6647		style.display = display;
6648	}
6649}
6650
6651function propFilter( props, specialEasing ) {
6652	var index, name, easing, value, hooks;
6653
6654	// camelCase, specialEasing and expand cssHook pass
6655	for ( index in props ) {
6656		name = jQuery.camelCase( index );
6657		easing = specialEasing[ name ];
6658		value = props[ index ];
6659		if ( jQuery.isArray( value ) ) {
6660			easing = value[ 1 ];
6661			value = props[ index ] = value[ 0 ];
6662		}
6663
6664		if ( index !== name ) {
6665			props[ name ] = value;
6666			delete props[ index ];
6667		}
6668
6669		hooks = jQuery.cssHooks[ name ];
6670		if ( hooks && "expand" in hooks ) {
6671			value = hooks.expand( value );
6672			delete props[ name ];
6673
6674			// Not quite $.extend, this won't overwrite existing keys.
6675			// Reusing 'index' because we have the correct "name"
6676			for ( index in value ) {
6677				if ( !( index in props ) ) {
6678					props[ index ] = value[ index ];
6679					specialEasing[ index ] = easing;
6680				}
6681			}
6682		} else {
6683			specialEasing[ name ] = easing;
6684		}
6685	}
6686}
6687
6688function Animation( elem, properties, options ) {
6689	var result,
6690		stopped,
6691		index = 0,
6692		length = Animation.prefilters.length,
6693		deferred = jQuery.Deferred().always( function() {
6694
6695			// Don't match elem in the :animated selector
6696			delete tick.elem;
6697		} ),
6698		tick = function() {
6699			if ( stopped ) {
6700				return false;
6701			}
6702			var currentTime = fxNow || createFxNow(),
6703				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
6704
6705				// Support: Android 2.3
6706				// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
6707				temp = remaining / animation.duration || 0,
6708				percent = 1 - temp,
6709				index = 0,
6710				length = animation.tweens.length;
6711
6712			for ( ; index < length ; index++ ) {
6713				animation.tweens[ index ].run( percent );
6714			}
6715
6716			deferred.notifyWith( elem, [ animation, percent, remaining ] );
6717
6718			if ( percent < 1 && length ) {
6719				return remaining;
6720			} else {
6721				deferred.resolveWith( elem, [ animation ] );
6722				return false;
6723			}
6724		},
6725		animation = deferred.promise( {
6726			elem: elem,
6727			props: jQuery.extend( {}, properties ),
6728			opts: jQuery.extend( true, {
6729				specialEasing: {},
6730				easing: jQuery.easing._default
6731			}, options ),
6732			originalProperties: properties,
6733			originalOptions: options,
6734			startTime: fxNow || createFxNow(),
6735			duration: options.duration,
6736			tweens: [],
6737			createTween: function( prop, end ) {
6738				var tween = jQuery.Tween( elem, animation.opts, prop, end,
6739						animation.opts.specialEasing[ prop ] || animation.opts.easing );
6740				animation.tweens.push( tween );
6741				return tween;
6742			},
6743			stop: function( gotoEnd ) {
6744				var index = 0,
6745
6746					// If we are going to the end, we want to run all the tweens
6747					// otherwise we skip this part
6748					length = gotoEnd ? animation.tweens.length : 0;
6749				if ( stopped ) {
6750					return this;
6751				}
6752				stopped = true;
6753				for ( ; index < length ; index++ ) {
6754					animation.tweens[ index ].run( 1 );
6755				}
6756
6757				// Resolve when we played the last frame; otherwise, reject
6758				if ( gotoEnd ) {
6759					deferred.notifyWith( elem, [ animation, 1, 0 ] );
6760					deferred.resolveWith( elem, [ animation, gotoEnd ] );
6761				} else {
6762					deferred.rejectWith( elem, [ animation, gotoEnd ] );
6763				}
6764				return this;
6765			}
6766		} ),
6767		props = animation.props;
6768
6769	propFilter( props, animation.opts.specialEasing );
6770
6771	for ( ; index < length ; index++ ) {
6772		result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
6773		if ( result ) {
6774			if ( jQuery.isFunction( result.stop ) ) {
6775				jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
6776					jQuery.proxy( result.stop, result );
6777			}
6778			return result;
6779		}
6780	}
6781
6782	jQuery.map( props, createTween, animation );
6783
6784	if ( jQuery.isFunction( animation.opts.start ) ) {
6785		animation.opts.start.call( elem, animation );
6786	}
6787
6788	jQuery.fx.timer(
6789		jQuery.extend( tick, {
6790			elem: elem,
6791			anim: animation,
6792			queue: animation.opts.queue
6793		} )
6794	);
6795
6796	// attach callbacks from options
6797	return animation.progress( animation.opts.progress )
6798		.done( animation.opts.done, animation.opts.complete )
6799		.fail( animation.opts.fail )
6800		.always( animation.opts.always );
6801}
6802
6803jQuery.Animation = jQuery.extend( Animation, {
6804	tweeners: {
6805		"*": [ function( prop, value ) {
6806			var tween = this.createTween( prop, value );
6807			adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
6808			return tween;
6809		} ]
6810	},
6811
6812	tweener: function( props, callback ) {
6813		if ( jQuery.isFunction( props ) ) {
6814			callback = props;
6815			props = [ "*" ];
6816		} else {
6817			props = props.match( rnotwhite );
6818		}
6819
6820		var prop,
6821			index = 0,
6822			length = props.length;
6823
6824		for ( ; index < length ; index++ ) {
6825			prop = props[ index ];
6826			Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
6827			Animation.tweeners[ prop ].unshift( callback );
6828		}
6829	},
6830
6831	prefilters: [ defaultPrefilter ],
6832
6833	prefilter: function( callback, prepend ) {
6834		if ( prepend ) {
6835			Animation.prefilters.unshift( callback );
6836		} else {
6837			Animation.prefilters.push( callback );
6838		}
6839	}
6840} );
6841
6842jQuery.speed = function( speed, easing, fn ) {
6843	var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
6844		complete: fn || !fn && easing ||
6845			jQuery.isFunction( speed ) && speed,
6846		duration: speed,
6847		easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
6848	};
6849
6850	opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ?
6851		opt.duration : opt.duration in jQuery.fx.speeds ?
6852			jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
6853
6854	// Normalize opt.queue - true/undefined/null -> "fx"
6855	if ( opt.queue == null || opt.queue === true ) {
6856		opt.queue = "fx";
6857	}
6858
6859	// Queueing
6860	opt.old = opt.complete;
6861
6862	opt.complete = function() {
6863		if ( jQuery.isFunction( opt.old ) ) {
6864			opt.old.call( this );
6865		}
6866
6867		if ( opt.queue ) {
6868			jQuery.dequeue( this, opt.queue );
6869		}
6870	};
6871
6872	return opt;
6873};
6874
6875jQuery.fn.extend( {
6876	fadeTo: function( speed, to, easing, callback ) {
6877
6878		// Show any hidden elements after setting opacity to 0
6879		return this.filter( isHidden ).css( "opacity", 0 ).show()
6880
6881			// Animate to the value specified
6882			.end().animate( { opacity: to }, speed, easing, callback );
6883	},
6884	animate: function( prop, speed, easing, callback ) {
6885		var empty = jQuery.isEmptyObject( prop ),
6886			optall = jQuery.speed( speed, easing, callback ),
6887			doAnimation = function() {
6888
6889				// Operate on a copy of prop so per-property easing won't be lost
6890				var anim = Animation( this, jQuery.extend( {}, prop ), optall );
6891
6892				// Empty animations, or finishing resolves immediately
6893				if ( empty || dataPriv.get( this, "finish" ) ) {
6894					anim.stop( true );
6895				}
6896			};
6897			doAnimation.finish = doAnimation;
6898
6899		return empty || optall.queue === false ?
6900			this.each( doAnimation ) :
6901			this.queue( optall.queue, doAnimation );
6902	},
6903	stop: function( type, clearQueue, gotoEnd ) {
6904		var stopQueue = function( hooks ) {
6905			var stop = hooks.stop;
6906			delete hooks.stop;
6907			stop( gotoEnd );
6908		};
6909
6910		if ( typeof type !== "string" ) {
6911			gotoEnd = clearQueue;
6912			clearQueue = type;
6913			type = undefined;
6914		}
6915		if ( clearQueue && type !== false ) {
6916			this.queue( type || "fx", [] );
6917		}
6918
6919		return this.each( function() {
6920			var dequeue = true,
6921				index = type != null && type + "queueHooks",
6922				timers = jQuery.timers,
6923				data = dataPriv.get( this );
6924
6925			if ( index ) {
6926				if ( data[ index ] && data[ index ].stop ) {
6927					stopQueue( data[ index ] );
6928				}
6929			} else {
6930				for ( index in data ) {
6931					if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
6932						stopQueue( data[ index ] );
6933					}
6934				}
6935			}
6936
6937			for ( index = timers.length; index--; ) {
6938				if ( timers[ index ].elem === this &&
6939					( type == null || timers[ index ].queue === type ) ) {
6940
6941					timers[ index ].anim.stop( gotoEnd );
6942					dequeue = false;
6943					timers.splice( index, 1 );
6944				}
6945			}
6946
6947			// Start the next in the queue if the last step wasn't forced.
6948			// Timers currently will call their complete callbacks, which
6949			// will dequeue but only if they were gotoEnd.
6950			if ( dequeue || !gotoEnd ) {
6951				jQuery.dequeue( this, type );
6952			}
6953		} );
6954	},
6955	finish: function( type ) {
6956		if ( type !== false ) {
6957			type = type || "fx";
6958		}
6959		return this.each( function() {
6960			var index,
6961				data = dataPriv.get( this ),
6962				queue = data[ type + "queue" ],
6963				hooks = data[ type + "queueHooks" ],
6964				timers = jQuery.timers,
6965				length = queue ? queue.length : 0;
6966
6967			// Enable finishing flag on private data
6968			data.finish = true;
6969
6970			// Empty the queue first
6971			jQuery.queue( this, type, [] );
6972
6973			if ( hooks && hooks.stop ) {
6974				hooks.stop.call( this, true );
6975			}
6976
6977			// Look for any active animations, and finish them
6978			for ( index = timers.length; index--; ) {
6979				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
6980					timers[ index ].anim.stop( true );
6981					timers.splice( index, 1 );
6982				}
6983			}
6984
6985			// Look for any animations in the old queue and finish them
6986			for ( index = 0; index < length; index++ ) {
6987				if ( queue[ index ] && queue[ index ].finish ) {
6988					queue[ index ].finish.call( this );
6989				}
6990			}
6991
6992			// Turn off finishing flag
6993			delete data.finish;
6994		} );
6995	}
6996} );
6997
6998jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
6999	var cssFn = jQuery.fn[ name ];
7000	jQuery.fn[ name ] = function( speed, easing, callback ) {
7001		return speed == null || typeof speed === "boolean" ?
7002			cssFn.apply( this, arguments ) :
7003			this.animate( genFx( name, true ), speed, easing, callback );
7004	};
7005} );
7006
7007// Generate shortcuts for custom animations
7008jQuery.each( {
7009	slideDown: genFx( "show" ),
7010	slideUp: genFx( "hide" ),
7011	slideToggle: genFx( "toggle" ),
7012	fadeIn: { opacity: "show" },
7013	fadeOut: { opacity: "hide" },
7014	fadeToggle: { opacity: "toggle" }
7015}, function( name, props ) {
7016	jQuery.fn[ name ] = function( speed, easing, callback ) {
7017		return this.animate( props, speed, easing, callback );
7018	};
7019} );
7020
7021jQuery.timers = [];
7022jQuery.fx.tick = function() {
7023	var timer,
7024		i = 0,
7025		timers = jQuery.timers;
7026
7027	fxNow = jQuery.now();
7028
7029	for ( ; i < timers.length; i++ ) {
7030		timer = timers[ i ];
7031
7032		// Checks the timer has not already been removed
7033		if ( !timer() && timers[ i ] === timer ) {
7034			timers.splice( i--, 1 );
7035		}
7036	}
7037
7038	if ( !timers.length ) {
7039		jQuery.fx.stop();
7040	}
7041	fxNow = undefined;
7042};
7043
7044jQuery.fx.timer = function( timer ) {
7045	jQuery.timers.push( timer );
7046	if ( timer() ) {
7047		jQuery.fx.start();
7048	} else {
7049		jQuery.timers.pop();
7050	}
7051};
7052
7053jQuery.fx.interval = 13;
7054jQuery.fx.start = function() {
7055	if ( !timerId ) {
7056		timerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );
7057	}
7058};
7059
7060jQuery.fx.stop = function() {
7061	window.clearInterval( timerId );
7062
7063	timerId = null;
7064};
7065
7066jQuery.fx.speeds = {
7067	slow: 600,
7068	fast: 200,
7069
7070	// Default speed
7071	_default: 400
7072};
7073
7074
7075// Based off of the plugin by Clint Helfers, with permission.
7076// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
7077jQuery.fn.delay = function( time, type ) {
7078	time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
7079	type = type || "fx";
7080
7081	return this.queue( type, function( next, hooks ) {
7082		var timeout = window.setTimeout( next, time );
7083		hooks.stop = function() {
7084			window.clearTimeout( timeout );
7085		};
7086	} );
7087};
7088
7089
7090( function() {
7091	var input = document.createElement( "input" ),
7092		select = document.createElement( "select" ),
7093		opt = select.appendChild( document.createElement( "option" ) );
7094
7095	input.type = "checkbox";
7096
7097	// Support: iOS<=5.1, Android<=4.2+
7098	// Default value for a checkbox should be "on"
7099	support.checkOn = input.value !== "";
7100
7101	// Support: IE<=11+
7102	// Must access selectedIndex to make default options select
7103	support.optSelected = opt.selected;
7104
7105	// Support: Android<=2.3
7106	// Options inside disabled selects are incorrectly marked as disabled
7107	select.disabled = true;
7108	support.optDisabled = !opt.disabled;
7109
7110	// Support: IE<=11+
7111	// An input loses its value after becoming a radio
7112	input = document.createElement( "input" );
7113	input.value = "t";
7114	input.type = "radio";
7115	support.radioValue = input.value === "t";
7116} )();
7117
7118
7119var boolHook,
7120	attrHandle = jQuery.expr.attrHandle;
7121
7122jQuery.fn.extend( {
7123	attr: function( name, value ) {
7124		return access( this, jQuery.attr, name, value, arguments.length > 1 );
7125	},
7126
7127	removeAttr: function( name ) {
7128		return this.each( function() {
7129			jQuery.removeAttr( this, name );
7130		} );
7131	}
7132} );
7133
7134jQuery.extend( {
7135	attr: function( elem, name, value ) {
7136		var ret, hooks,
7137			nType = elem.nodeType;
7138
7139		// Don't get/set attributes on text, comment and attribute nodes
7140		if ( nType === 3 || nType === 8 || nType === 2 ) {
7141			return;
7142		}
7143
7144		// Fallback to prop when attributes are not supported
7145		if ( typeof elem.getAttribute === "undefined" ) {
7146			return jQuery.prop( elem, name, value );
7147		}
7148
7149		// All attributes are lowercase
7150		// Grab necessary hook if one is defined
7151		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7152			name = name.toLowerCase();
7153			hooks = jQuery.attrHooks[ name ] ||
7154				( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
7155		}
7156
7157		if ( value !== undefined ) {
7158			if ( value === null ) {
7159				jQuery.removeAttr( elem, name );
7160				return;
7161			}
7162
7163			if ( hooks && "set" in hooks &&
7164				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7165				return ret;
7166			}
7167
7168			elem.setAttribute( name, value + "" );
7169			return value;
7170		}
7171
7172		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7173			return ret;
7174		}
7175
7176		ret = jQuery.find.attr( elem, name );
7177
7178		// Non-existent attributes return null, we normalize to undefined
7179		return ret == null ? undefined : ret;
7180	},
7181
7182	attrHooks: {
7183		type: {
7184			set: function( elem, value ) {
7185				if ( !support.radioValue && value === "radio" &&
7186					jQuery.nodeName( elem, "input" ) ) {
7187					var val = elem.value;
7188					elem.setAttribute( "type", value );
7189					if ( val ) {
7190						elem.value = val;
7191					}
7192					return value;
7193				}
7194			}
7195		}
7196	},
7197
7198	removeAttr: function( elem, value ) {
7199		var name, propName,
7200			i = 0,
7201			attrNames = value && value.match( rnotwhite );
7202
7203		if ( attrNames && elem.nodeType === 1 ) {
7204			while ( ( name = attrNames[ i++ ] ) ) {
7205				propName = jQuery.propFix[ name ] || name;
7206
7207				// Boolean attributes get special treatment (#10870)
7208				if ( jQuery.expr.match.bool.test( name ) ) {
7209
7210					// Set corresponding property to false
7211					elem[ propName ] = false;
7212				}
7213
7214				elem.removeAttribute( name );
7215			}
7216		}
7217	}
7218} );
7219
7220// Hooks for boolean attributes
7221boolHook = {
7222	set: function( elem, value, name ) {
7223		if ( value === false ) {
7224
7225			// Remove boolean attributes when set to false
7226			jQuery.removeAttr( elem, name );
7227		} else {
7228			elem.setAttribute( name, name );
7229		}
7230		return name;
7231	}
7232};
7233jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
7234	var getter = attrHandle[ name ] || jQuery.find.attr;
7235
7236	attrHandle[ name ] = function( elem, name, isXML ) {
7237		var ret, handle;
7238		if ( !isXML ) {
7239
7240			// Avoid an infinite loop by temporarily removing this function from the getter
7241			handle = attrHandle[ name ];
7242			attrHandle[ name ] = ret;
7243			ret = getter( elem, name, isXML ) != null ?
7244				name.toLowerCase() :
7245				null;
7246			attrHandle[ name ] = handle;
7247		}
7248		return ret;
7249	};
7250} );
7251
7252
7253
7254
7255var rfocusable = /^(?:input|select|textarea|button)$/i,
7256	rclickable = /^(?:a|area)$/i;
7257
7258jQuery.fn.extend( {
7259	prop: function( name, value ) {
7260		return access( this, jQuery.prop, name, value, arguments.length > 1 );
7261	},
7262
7263	removeProp: function( name ) {
7264		return this.each( function() {
7265			delete this[ jQuery.propFix[ name ] || name ];
7266		} );
7267	}
7268} );
7269
7270jQuery.extend( {
7271	prop: function( elem, name, value ) {
7272		var ret, hooks,
7273			nType = elem.nodeType;
7274
7275		// Don't get/set properties on text, comment and attribute nodes
7276		if ( nType === 3 || nType === 8 || nType === 2 ) {
7277			return;
7278		}
7279
7280		if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
7281
7282			// Fix name and attach hooks
7283			name = jQuery.propFix[ name ] || name;
7284			hooks = jQuery.propHooks[ name ];
7285		}
7286
7287		if ( value !== undefined ) {
7288			if ( hooks && "set" in hooks &&
7289				( ret = hooks.set( elem, value, name ) ) !== undefined ) {
7290				return ret;
7291			}
7292
7293			return ( elem[ name ] = value );
7294		}
7295
7296		if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
7297			return ret;
7298		}
7299
7300		return elem[ name ];
7301	},
7302
7303	propHooks: {
7304		tabIndex: {
7305			get: function( elem ) {
7306
7307				// elem.tabIndex doesn't always return the
7308				// correct value when it hasn't been explicitly set
7309				// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
7310				// Use proper attribute retrieval(#12072)
7311				var tabindex = jQuery.find.attr( elem, "tabindex" );
7312
7313				return tabindex ?
7314					parseInt( tabindex, 10 ) :
7315					rfocusable.test( elem.nodeName ) ||
7316						rclickable.test( elem.nodeName ) && elem.href ?
7317							0 :
7318							-1;
7319			}
7320		}
7321	},
7322
7323	propFix: {
7324		"for": "htmlFor",
7325		"class": "className"
7326	}
7327} );
7328
vendor: 5,910 bytes, lines 7329-7594
7329if ( !support.optSelected ) {
7330	jQuery.propHooks.selected = {
7331		get: function( elem ) {
7332			var parent = elem.parentNode;
7333			if ( parent && parent.parentNode ) {
7334				parent.parentNode.selectedIndex;
7335			}
7336			return null;
7337		}
7338	};
7339}
7340
7341jQuery.each( [
7342	"tabIndex",
7343	"readOnly",
7344	"maxLength",
7345	"cellSpacing",
7346	"cellPadding",
7347	"rowSpan",
7348	"colSpan",
7349	"useMap",
7350	"frameBorder",
7351	"contentEditable"
7352], function() {
7353	jQuery.propFix[ this.toLowerCase() ] = this;
7354} );
7355
7356
7357
7358
7359var rclass = /[\t\r\n\f]/g;
7360
7361function getClass( elem ) {
7362	return elem.getAttribute && elem.getAttribute( "class" ) || "";
7363}
7364
7365jQuery.fn.extend( {
7366	addClass: function( value ) {
7367		var classes, elem, cur, curValue, clazz, j, finalValue,
7368			i = 0;
7369
7370		if ( jQuery.isFunction( value ) ) {
7371			return this.each( function( j ) {
7372				jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
7373			} );
7374		}
7375
7376		if ( typeof value === "string" && value ) {
7377			classes = value.match( rnotwhite ) || [];
7378
7379			while ( ( elem = this[ i++ ] ) ) {
7380				curValue = getClass( elem );
7381				cur = elem.nodeType === 1 &&
7382					( " " + curValue + " " ).replace( rclass, " " );
7383
7384				if ( cur ) {
7385					j = 0;
7386					while ( ( clazz = classes[ j++ ] ) ) {
7387						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
7388							cur += clazz + " ";
7389						}
7390					}
7391
7392					// Only assign if different to avoid unneeded rendering.
7393					finalValue = jQuery.trim( cur );
7394					if ( curValue !== finalValue ) {
7395						elem.setAttribute( "class", finalValue );
7396					}
7397				}
7398			}
7399		}
7400
7401		return this;
7402	},
7403
7404	removeClass: function( value ) {
7405		var classes, elem, cur, curValue, clazz, j, finalValue,
7406			i = 0;
7407
7408		if ( jQuery.isFunction( value ) ) {
7409			return this.each( function( j ) {
7410				jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
7411			} );
7412		}
7413
7414		if ( !arguments.length ) {
7415			return this.attr( "class", "" );
7416		}
7417
7418		if ( typeof value === "string" && value ) {
7419			classes = value.match( rnotwhite ) || [];
7420
7421			while ( ( elem = this[ i++ ] ) ) {
7422				curValue = getClass( elem );
7423
7424				// This expression is here for better compressibility (see addClass)
7425				cur = elem.nodeType === 1 &&
7426					( " " + curValue + " " ).replace( rclass, " " );
7427
7428				if ( cur ) {
7429					j = 0;
7430					while ( ( clazz = classes[ j++ ] ) ) {
7431
7432						// Remove *all* instances
7433						while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
7434							cur = cur.replace( " " + clazz + " ", " " );
7435						}
7436					}
7437
7438					// Only assign if different to avoid unneeded rendering.
7439					finalValue = jQuery.trim( cur );
7440					if ( curValue !== finalValue ) {
7441						elem.setAttribute( "class", finalValue );
7442					}
7443				}
7444			}
7445		}
7446
7447		return this;
7448	},
7449
7450	toggleClass: function( value, stateVal ) {
7451		var type = typeof value;
7452
7453		if ( typeof stateVal === "boolean" && type === "string" ) {
7454			return stateVal ? this.addClass( value ) : this.removeClass( value );
7455		}
7456
7457		if ( jQuery.isFunction( value ) ) {
7458			return this.each( function( i ) {
7459				jQuery( this ).toggleClass(
7460					value.call( this, i, getClass( this ), stateVal ),
7461					stateVal
7462				);
7463			} );
7464		}
7465
7466		return this.each( function() {
7467			var className, i, self, classNames;
7468
7469			if ( type === "string" ) {
7470
7471				// Toggle individual class names
7472				i = 0;
7473				self = jQuery( this );
7474				classNames = value.match( rnotwhite ) || [];
7475
7476				while ( ( className = classNames[ i++ ] ) ) {
7477
7478					// Check each className given, space separated list
7479					if ( self.hasClass( className ) ) {
7480						self.removeClass( className );
7481					} else {
7482						self.addClass( className );
7483					}
7484				}
7485
7486			// Toggle whole class name
7487			} else if ( value === undefined || type === "boolean" ) {
7488				className = getClass( this );
7489				if ( className ) {
7490
7491					// Store className if set
7492					dataPriv.set( this, "__className__", className );
7493				}
7494
7495				// If the element has a class name or if we're passed `false`,
7496				// then remove the whole classname (if there was one, the above saved it).
7497				// Otherwise bring back whatever was previously saved (if anything),
7498				// falling back to the empty string if nothing was stored.
7499				if ( this.setAttribute ) {
7500					this.setAttribute( "class",
7501						className || value === false ?
7502						"" :
7503						dataPriv.get( this, "__className__" ) || ""
7504					);
7505				}
7506			}
7507		} );
7508	},
7509
7510	hasClass: function( selector ) {
7511		var className, elem,
7512			i = 0;
7513
7514		className = " " + selector + " ";
7515		while ( ( elem = this[ i++ ] ) ) {
7516			if ( elem.nodeType === 1 &&
7517				( " " + getClass( elem ) + " " ).replace( rclass, " " )
7518					.indexOf( className ) > -1
7519			) {
7520				return true;
7521			}
7522		}
7523
7524		return false;
7525	}
7526} );
7527
7528
7529
7530
7531var rreturn = /\r/g;
7532
7533jQuery.fn.extend( {
7534	val: function( value ) {
7535		var hooks, ret, isFunction,
7536			elem = this[ 0 ];
7537
7538		if ( !arguments.length ) {
7539			if ( elem ) {
7540				hooks = jQuery.valHooks[ elem.type ] ||
7541					jQuery.valHooks[ elem.nodeName.toLowerCase() ];
7542
7543				if ( hooks &&
7544					"get" in hooks &&
7545					( ret = hooks.get( elem, "value" ) ) !== undefined
7546				) {
7547					return ret;
7548				}
7549
7550				ret = elem.value;
7551
7552				return typeof ret === "string" ?
7553
7554					// Handle most common string cases
7555					ret.replace( rreturn, "" ) :
7556
7557					// Handle cases where value is null/undef or number
7558					ret == null ? "" : ret;
7559			}
7560
7561			return;
7562		}
7563
7564		isFunction = jQuery.isFunction( value );
7565
7566		return this.each( function( i ) {
7567			var val;
7568
7569			if ( this.nodeType !== 1 ) {
7570				return;
7571			}
7572
7573			if ( isFunction ) {
7574				val = value.call( this, i, jQuery( this ).val() );
7575			} else {
7576				val = value;
7577			}
7578
7579			// Treat null/undefined as ""; convert numbers to string
7580			if ( val == null ) {
7581				val = "";
7582
7583			} else if ( typeof val === "number" ) {
7584				val += "";
7585
7586			} else if ( jQuery.isArray( val ) ) {
7587				val = jQuery.map( val, function( value ) {
7588					return value == null ? "" : value + "";
7589				} );
7590			}
7591
7592			hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
7593
7594			// If set returns undefined, fall back to normal setting
vendor: 7,684 bytes, lines 7595-7867
7595			if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
7596				this.value = val;
7597			}
7598		} );
7599	}
7600} );
7601
7602jQuery.extend( {
7603	valHooks: {
7604		option: {
7605			get: function( elem ) {
7606
7607				// Support: IE<11
7608				// option.value not trimmed (#14858)
7609				return jQuery.trim( elem.value );
7610			}
7611		},
7612		select: {
7613			get: function( elem ) {
7614				var value, option,
7615					options = elem.options,
7616					index = elem.selectedIndex,
7617					one = elem.type === "select-one" || index < 0,
7618					values = one ? null : [],
7619					max = one ? index + 1 : options.length,
7620					i = index < 0 ?
7621						max :
7622						one ? index : 0;
7623
7624				// Loop through all the selected options
7625				for ( ; i < max; i++ ) {
7626					option = options[ i ];
7627
7628					// IE8-9 doesn't update selected after form reset (#2551)
7629					if ( ( option.selected || i === index ) &&
7630
7631							// Don't return options that are disabled or in a disabled optgroup
7632							( support.optDisabled ?
7633								!option.disabled : option.getAttribute( "disabled" ) === null ) &&
7634							( !option.parentNode.disabled ||
7635								!jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
7636
7637						// Get the specific value for the option
7638						value = jQuery( option ).val();
7639
7640						// We don't need an array for one selects
7641						if ( one ) {
7642							return value;
7643						}
7644
7645						// Multi-Selects return an array
7646						values.push( value );
7647					}
7648				}
7649
7650				return values;
7651			},
7652
7653			set: function( elem, value ) {
7654				var optionSet, option,
7655					options = elem.options,
7656					values = jQuery.makeArray( value ),
7657					i = options.length;
7658
7659				while ( i-- ) {
7660					option = options[ i ];
7661					if ( option.selected =
7662							jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
7663					) {
7664						optionSet = true;
7665					}
7666				}
7667
7668				// Force browsers to behave consistently when non-matching value is set
7669				if ( !optionSet ) {
7670					elem.selectedIndex = -1;
7671				}
7672				return values;
7673			}
7674		}
7675	}
7676} );
7677
7678// Radios and checkboxes getter/setter
7679jQuery.each( [ "radio", "checkbox" ], function() {
7680	jQuery.valHooks[ this ] = {
7681		set: function( elem, value ) {
7682			if ( jQuery.isArray( value ) ) {
7683				return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
7684			}
7685		}
7686	};
7687	if ( !support.checkOn ) {
7688		jQuery.valHooks[ this ].get = function( elem ) {
7689			return elem.getAttribute( "value" ) === null ? "on" : elem.value;
7690		};
7691	}
7692} );
7693
7694
7695
7696
7697// Return jQuery for attributes-only inclusion
7698
7699
7700var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
7701
7702jQuery.extend( jQuery.event, {
7703
7704	trigger: function( event, data, elem, onlyHandlers ) {
7705
7706		var i, cur, tmp, bubbleType, ontype, handle, special,
7707			eventPath = [ elem || document ],
7708			type = hasOwn.call( event, "type" ) ? event.type : event,
7709			namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
7710
7711		cur = tmp = elem = elem || document;
7712
7713		// Don't do events on text and comment nodes
7714		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
7715			return;
7716		}
7717
7718		// focus/blur morphs to focusin/out; ensure we're not firing them right now
7719		if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
7720			return;
7721		}
7722
7723		if ( type.indexOf( "." ) > -1 ) {
7724
7725			// Namespaced trigger; create a regexp to match event type in handle()
7726			namespaces = type.split( "." );
7727			type = namespaces.shift();
7728			namespaces.sort();
7729		}
7730		ontype = type.indexOf( ":" ) < 0 && "on" + type;
7731
7732		// Caller can pass in a jQuery.Event object, Object, or just an event type string
7733		event = event[ jQuery.expando ] ?
7734			event :
7735			new jQuery.Event( type, typeof event === "object" && event );
7736
7737		// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
7738		event.isTrigger = onlyHandlers ? 2 : 3;
7739		event.namespace = namespaces.join( "." );
7740		event.rnamespace = event.namespace ?
7741			new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
7742			null;
7743
7744		// Clean up the event in case it is being reused
7745		event.result = undefined;
7746		if ( !event.target ) {
7747			event.target = elem;
7748		}
7749
7750		// Clone any incoming data and prepend the event, creating the handler arg list
7751		data = data == null ?
7752			[ event ] :
7753			jQuery.makeArray( data, [ event ] );
7754
7755		// Allow special events to draw outside the lines
7756		special = jQuery.event.special[ type ] || {};
7757		if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
7758			return;
7759		}
7760
7761		// Determine event propagation path in advance, per W3C events spec (#9951)
7762		// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
7763		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
7764
7765			bubbleType = special.delegateType || type;
7766			if ( !rfocusMorph.test( bubbleType + type ) ) {
7767				cur = cur.parentNode;
7768			}
7769			for ( ; cur; cur = cur.parentNode ) {
7770				eventPath.push( cur );
7771				tmp = cur;
7772			}
7773
7774			// Only add window if we got to document (e.g., not plain obj or detached DOM)
7775			if ( tmp === ( elem.ownerDocument || document ) ) {
7776				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
7777			}
7778		}
7779
7780		// Fire handlers on the event path
7781		i = 0;
7782		while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
7783
7784			event.type = i > 1 ?
7785				bubbleType :
7786				special.bindType || type;
7787
7788			// jQuery handler
7789			handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
7790				dataPriv.get( cur, "handle" );
7791			if ( handle ) {
7792				handle.apply( cur, data );
7793			}
7794
7795			// Native handler
7796			handle = ontype && cur[ ontype ];
7797			if ( handle && handle.apply && acceptData( cur ) ) {
7798				event.result = handle.apply( cur, data );
7799				if ( event.result === false ) {
7800					event.preventDefault();
7801				}
7802			}
7803		}
7804		event.type = type;
7805
7806		// If nobody prevented the default action, do it now
7807		if ( !onlyHandlers && !event.isDefaultPrevented() ) {
7808
7809			if ( ( !special._default ||
7810				special._default.apply( eventPath.pop(), data ) === false ) &&
7811				acceptData( elem ) ) {
7812
7813				// Call a native DOM method on the target with the same name name as the event.
7814				// Don't do default actions on window, that's where global variables be (#6170)
7815				if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
7816
7817					// Don't re-trigger an onFOO event when we call its FOO() method
7818					tmp = elem[ ontype ];
7819
7820					if ( tmp ) {
7821						elem[ ontype ] = null;
7822					}
7823
7824					// Prevent re-triggering of the same event, since we already bubbled it above
7825					jQuery.event.triggered = type;
7826					elem[ type ]();
7827					jQuery.event.triggered = undefined;
7828
7829					if ( tmp ) {
7830						elem[ ontype ] = tmp;
7831					}
7832				}
7833			}
7834		}
7835
7836		return event.result;
7837	},
7838
7839	// Piggyback on a donor event to simulate a different one
7840	simulate: function( type, elem, event ) {
7841		var e = jQuery.extend(
7842			new jQuery.Event(),
7843			event,
7844			{
7845				type: type,
7846				isSimulated: true
7847
7848				// Previously, `originalEvent: {}` was set here, so stopPropagation call
7849				// would not be triggered on donor event, since in our own
7850				// jQuery.event.stopPropagation function we had a check for existence of
7851				// originalEvent.stopPropagation method, so, consequently it would be a noop.
7852				//
7853				// But now, this "simulate" function is used only for events
7854				// for which stopPropagation() is noop, so there is no need for that anymore.
7855				//
7856				// For the compat branch though, guard for "click" and "submit"
7857				// events is still used, but was moved to jQuery.event.stopPropagation function
7858				// because `originalEvent` should point to the original event for the constancy
7859				// with other events and for more focused logic
7860			}
7861		);
7862
7863		jQuery.event.trigger( e, null, elem );
7864
7865		if ( e.isDefaultPrevented() ) {
7866			event.preventDefault();
7867		}
vendor: 37,646 bytes, lines 7867-9357
7867
7868	}
7869
7870} );
7871
7872jQuery.fn.extend( {
7873
7874	trigger: function( type, data ) {
7875		return this.each( function() {
7876			jQuery.event.trigger( type, data, this );
7877		} );
7878	},
7879	triggerHandler: function( type, data ) {
7880		var elem = this[ 0 ];
7881		if ( elem ) {
7882			return jQuery.event.trigger( type, data, elem, true );
7883		}
7884	}
7885} );
7886
7887
7888jQuery.each( ( "blur focus focusin focusout load resize scroll unload click dblclick " +
7889	"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
7890	"change select submit keydown keypress keyup error contextmenu" ).split( " " ),
7891	function( i, name ) {
7892
7893	// Handle event binding
7894	jQuery.fn[ name ] = function( data, fn ) {
7895		return arguments.length > 0 ?
7896			this.on( name, null, data, fn ) :
7897			this.trigger( name );
7898	};
7899} );
7900
7901jQuery.fn.extend( {
7902	hover: function( fnOver, fnOut ) {
7903		return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
7904	}
7905} );
7906
7907
7908
7909
7910support.focusin = "onfocusin" in window;
7911
7912
7913// Support: Firefox
7914// Firefox doesn't have focus(in | out) events
7915// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
7916//
7917// Support: Chrome, Safari
7918// focus(in | out) events fire after focus & blur events,
7919// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
7920// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
7921if ( !support.focusin ) {
7922	jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
7923
7924		// Attach a single capturing handler on the document while someone wants focusin/focusout
7925		var handler = function( event ) {
7926			jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
7927		};
7928
7929		jQuery.event.special[ fix ] = {
7930			setup: function() {
7931				var doc = this.ownerDocument || this,
7932					attaches = dataPriv.access( doc, fix );
7933
7934				if ( !attaches ) {
7935					doc.addEventListener( orig, handler, true );
7936				}
7937				dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
7938			},
7939			teardown: function() {
7940				var doc = this.ownerDocument || this,
7941					attaches = dataPriv.access( doc, fix ) - 1;
7942
7943				if ( !attaches ) {
7944					doc.removeEventListener( orig, handler, true );
7945					dataPriv.remove( doc, fix );
7946
7947				} else {
7948					dataPriv.access( doc, fix, attaches );
7949				}
7950			}
7951		};
7952	} );
7953}
7954var location = window.location;
7955
7956var nonce = jQuery.now();
7957
7958var rquery = ( /\?/ );
7959
7960
7961
7962// Support: Android 2.3
7963// Workaround failure to string-cast null input
7964jQuery.parseJSON = function( data ) {
7965	return JSON.parse( data + "" );
7966};
7967
7968
7969// Cross-browser xml parsing
7970jQuery.parseXML = function( data ) {
7971	var xml;
7972	if ( !data || typeof data !== "string" ) {
7973		return null;
7974	}
7975
7976	// Support: IE9
7977	try {
7978		xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
7979	} catch ( e ) {
7980		xml = undefined;
7981	}
7982
7983	if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
7984		jQuery.error( "Invalid XML: " + data );
7985	}
7986	return xml;
7987};
7988
7989
7990var
7991	rhash = /#.*$/,
7992	rts = /([?&])_=[^&]*/,
7993	rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
7994
7995	// #7653, #8125, #8152: local protocol detection
7996	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
7997	rnoContent = /^(?:GET|HEAD)$/,
7998	rprotocol = /^\/\//,
7999
8000	/* Prefilters
8001	 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
8002	 * 2) These are called:
8003	 *    - BEFORE asking for a transport
8004	 *    - AFTER param serialization (s.data is a string if s.processData is true)
8005	 * 3) key is the dataType
8006	 * 4) the catchall symbol "*" can be used
8007	 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
8008	 */
8009	prefilters = {},
8010
8011	/* Transports bindings
8012	 * 1) key is the dataType
8013	 * 2) the catchall symbol "*" can be used
8014	 * 3) selection will start with transport dataType and THEN go to "*" if needed
8015	 */
8016	transports = {},
8017
8018	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
8019	allTypes = "*/".concat( "*" ),
8020
8021	// Anchor tag for parsing the document origin
8022	originAnchor = document.createElement( "a" );
8023	originAnchor.href = location.href;
8024
8025// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
8026function addToPrefiltersOrTransports( structure ) {
8027
8028	// dataTypeExpression is optional and defaults to "*"
8029	return function( dataTypeExpression, func ) {
8030
8031		if ( typeof dataTypeExpression !== "string" ) {
8032			func = dataTypeExpression;
8033			dataTypeExpression = "*";
8034		}
8035
8036		var dataType,
8037			i = 0,
8038			dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
8039
8040		if ( jQuery.isFunction( func ) ) {
8041
8042			// For each dataType in the dataTypeExpression
8043			while ( ( dataType = dataTypes[ i++ ] ) ) {
8044
8045				// Prepend if requested
8046				if ( dataType[ 0 ] === "+" ) {
8047					dataType = dataType.slice( 1 ) || "*";
8048					( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
8049
8050				// Otherwise append
8051				} else {
8052					( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
8053				}
8054			}
8055		}
8056	};
8057}
8058
8059// Base inspection function for prefilters and transports
8060function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
8061
8062	var inspected = {},
8063		seekingTransport = ( structure === transports );
8064
8065	function inspect( dataType ) {
8066		var selected;
8067		inspected[ dataType ] = true;
8068		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
8069			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
8070			if ( typeof dataTypeOrTransport === "string" &&
8071				!seekingTransport && !inspected[ dataTypeOrTransport ] ) {
8072
8073				options.dataTypes.unshift( dataTypeOrTransport );
8074				inspect( dataTypeOrTransport );
8075				return false;
8076			} else if ( seekingTransport ) {
8077				return !( selected = dataTypeOrTransport );
8078			}
8079		} );
8080		return selected;
8081	}
8082
8083	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
8084}
8085
8086// A special extend for ajax options
8087// that takes "flat" options (not to be deep extended)
8088// Fixes #9887
8089function ajaxExtend( target, src ) {
8090	var key, deep,
8091		flatOptions = jQuery.ajaxSettings.flatOptions || {};
8092
8093	for ( key in src ) {
8094		if ( src[ key ] !== undefined ) {
8095			( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
8096		}
8097	}
8098	if ( deep ) {
8099		jQuery.extend( true, target, deep );
8100	}
8101
8102	return target;
8103}
8104
8105/* Handles responses to an ajax request:
8106 * - finds the right dataType (mediates between content-type and expected dataType)
8107 * - returns the corresponding response
8108 */
8109function ajaxHandleResponses( s, jqXHR, responses ) {
8110
8111	var ct, type, finalDataType, firstDataType,
8112		contents = s.contents,
8113		dataTypes = s.dataTypes;
8114
8115	// Remove auto dataType and get content-type in the process
8116	while ( dataTypes[ 0 ] === "*" ) {
8117		dataTypes.shift();
8118		if ( ct === undefined ) {
8119			ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
8120		}
8121	}
8122
8123	// Check if we're dealing with a known content-type
8124	if ( ct ) {
8125		for ( type in contents ) {
8126			if ( contents[ type ] && contents[ type ].test( ct ) ) {
8127				dataTypes.unshift( type );
8128				break;
8129			}
8130		}
8131	}
8132
8133	// Check to see if we have a response for the expected dataType
8134	if ( dataTypes[ 0 ] in responses ) {
8135		finalDataType = dataTypes[ 0 ];
8136	} else {
8137
8138		// Try convertible dataTypes
8139		for ( type in responses ) {
8140			if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
8141				finalDataType = type;
8142				break;
8143			}
8144			if ( !firstDataType ) {
8145				firstDataType = type;
8146			}
8147		}
8148
8149		// Or just use first one
8150		finalDataType = finalDataType || firstDataType;
8151	}
8152
8153	// If we found a dataType
8154	// We add the dataType to the list if needed
8155	// and return the corresponding response
8156	if ( finalDataType ) {
8157		if ( finalDataType !== dataTypes[ 0 ] ) {
8158			dataTypes.unshift( finalDataType );
8159		}
8160		return responses[ finalDataType ];
8161	}
8162}
8163
8164/* Chain conversions given the request and the original response
8165 * Also sets the responseXXX fields on the jqXHR instance
8166 */
8167function ajaxConvert( s, response, jqXHR, isSuccess ) {
8168	var conv2, current, conv, tmp, prev,
8169		converters = {},
8170
8171		// Work with a copy of dataTypes in case we need to modify it for conversion
8172		dataTypes = s.dataTypes.slice();
8173
8174	// Create converters map with lowercased keys
8175	if ( dataTypes[ 1 ] ) {
8176		for ( conv in s.converters ) {
8177			converters[ conv.toLowerCase() ] = s.converters[ conv ];
8178		}
8179	}
8180
8181	current = dataTypes.shift();
8182
8183	// Convert to each sequential dataType
8184	while ( current ) {
8185
8186		if ( s.responseFields[ current ] ) {
8187			jqXHR[ s.responseFields[ current ] ] = response;
8188		}
8189
8190		// Apply the dataFilter if provided
8191		if ( !prev && isSuccess && s.dataFilter ) {
8192			response = s.dataFilter( response, s.dataType );
8193		}
8194
8195		prev = current;
8196		current = dataTypes.shift();
8197
8198		if ( current ) {
8199
8200		// There's only work to do if current dataType is non-auto
8201			if ( current === "*" ) {
8202
8203				current = prev;
8204
8205			// Convert response if prev dataType is non-auto and differs from current
8206			} else if ( prev !== "*" && prev !== current ) {
8207
8208				// Seek a direct converter
8209				conv = converters[ prev + " " + current ] || converters[ "* " + current ];
8210
8211				// If none found, seek a pair
8212				if ( !conv ) {
8213					for ( conv2 in converters ) {
8214
8215						// If conv2 outputs current
8216						tmp = conv2.split( " " );
8217						if ( tmp[ 1 ] === current ) {
8218
8219							// If prev can be converted to accepted input
8220							conv = converters[ prev + " " + tmp[ 0 ] ] ||
8221								converters[ "* " + tmp[ 0 ] ];
8222							if ( conv ) {
8223
8224								// Condense equivalence converters
8225								if ( conv === true ) {
8226									conv = converters[ conv2 ];
8227
8228								// Otherwise, insert the intermediate dataType
8229								} else if ( converters[ conv2 ] !== true ) {
8230									current = tmp[ 0 ];
8231									dataTypes.unshift( tmp[ 1 ] );
8232								}
8233								break;
8234							}
8235						}
8236					}
8237				}
8238
8239				// Apply converter (if not an equivalence)
8240				if ( conv !== true ) {
8241
8242					// Unless errors are allowed to bubble, catch and return them
8243					if ( conv && s.throws ) {
8244						response = conv( response );
8245					} else {
8246						try {
8247							response = conv( response );
8248						} catch ( e ) {
8249							return {
8250								state: "parsererror",
8251								error: conv ? e : "No conversion from " + prev + " to " + current
8252							};
8253						}
8254					}
8255				}
8256			}
8257		}
8258	}
8259
8260	return { state: "success", data: response };
8261}
8262
8263jQuery.extend( {
8264
8265	// Counter for holding the number of active queries
8266	active: 0,
8267
8268	// Last-Modified header cache for next request
8269	lastModified: {},
8270	etag: {},
8271
8272	ajaxSettings: {
8273		url: location.href,
8274		type: "GET",
8275		isLocal: rlocalProtocol.test( location.protocol ),
8276		global: true,
8277		processData: true,
8278		async: true,
8279		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
8280		/*
8281		timeout: 0,
8282		data: null,
8283		dataType: null,
8284		username: null,
8285		password: null,
8286		cache: null,
8287		throws: false,
8288		traditional: false,
8289		headers: {},
8290		*/
8291
8292		accepts: {
8293			"*": allTypes,
8294			text: "text/plain",
8295			html: "text/html",
8296			xml: "application/xml, text/xml",
8297			json: "application/json, text/javascript"
8298		},
8299
8300		contents: {
8301			xml: /\bxml\b/,
8302			html: /\bhtml/,
8303			json: /\bjson\b/
8304		},
8305
8306		responseFields: {
8307			xml: "responseXML",
8308			text: "responseText",
8309			json: "responseJSON"
8310		},
8311
8312		// Data converters
8313		// Keys separate source (or catchall "*") and destination types with a single space
8314		converters: {
8315
8316			// Convert anything to text
8317			"* text": String,
8318
8319			// Text to html (true = no transformation)
8320			"text html": true,
8321
8322			// Evaluate text as a json expression
8323			"text json": jQuery.parseJSON,
8324
8325			// Parse text as xml
8326			"text xml": jQuery.parseXML
8327		},
8328
8329		// For options that shouldn't be deep extended:
8330		// you can add your own custom options here if
8331		// and when you create one that shouldn't be
8332		// deep extended (see ajaxExtend)
8333		flatOptions: {
8334			url: true,
8335			context: true
8336		}
8337	},
8338
8339	// Creates a full fledged settings object into target
8340	// with both ajaxSettings and settings fields.
8341	// If target is omitted, writes into ajaxSettings.
8342	ajaxSetup: function( target, settings ) {
8343		return settings ?
8344
8345			// Building a settings object
8346			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
8347
8348			// Extending ajaxSettings
8349			ajaxExtend( jQuery.ajaxSettings, target );
8350	},
8351
8352	ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
8353	ajaxTransport: addToPrefiltersOrTransports( transports ),
8354
8355	// Main method
8356	ajax: function( url, options ) {
8357
8358		// If url is an object, simulate pre-1.5 signature
8359		if ( typeof url === "object" ) {
8360			options = url;
8361			url = undefined;
8362		}
8363
8364		// Force options to be an object
8365		options = options || {};
8366
8367		var transport,
8368
8369			// URL without anti-cache param
8370			cacheURL,
8371
8372			// Response headers
8373			responseHeadersString,
8374			responseHeaders,
8375
8376			// timeout handle
8377			timeoutTimer,
8378
8379			// Url cleanup var
8380			urlAnchor,
8381
8382			// To know if global events are to be dispatched
8383			fireGlobals,
8384
8385			// Loop variable
8386			i,
8387
8388			// Create the final options object
8389			s = jQuery.ajaxSetup( {}, options ),
8390
8391			// Callbacks context
8392			callbackContext = s.context || s,
8393
8394			// Context for global events is callbackContext if it is a DOM node or jQuery collection
8395			globalEventContext = s.context &&
8396				( callbackContext.nodeType || callbackContext.jquery ) ?
8397					jQuery( callbackContext ) :
8398					jQuery.event,
8399
8400			// Deferreds
8401			deferred = jQuery.Deferred(),
8402			completeDeferred = jQuery.Callbacks( "once memory" ),
8403
8404			// Status-dependent callbacks
8405			statusCode = s.statusCode || {},
8406
8407			// Headers (they are sent all at once)
8408			requestHeaders = {},
8409			requestHeadersNames = {},
8410
8411			// The jqXHR state
8412			state = 0,
8413
8414			// Default abort message
8415			strAbort = "canceled",
8416
8417			// Fake xhr
8418			jqXHR = {
8419				readyState: 0,
8420
8421				// Builds headers hashtable if needed
8422				getResponseHeader: function( key ) {
8423					var match;
8424					if ( state === 2 ) {
8425						if ( !responseHeaders ) {
8426							responseHeaders = {};
8427							while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
8428								responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
8429							}
8430						}
8431						match = responseHeaders[ key.toLowerCase() ];
8432					}
8433					return match == null ? null : match;
8434				},
8435
8436				// Raw string
8437				getAllResponseHeaders: function() {
8438					return state === 2 ? responseHeadersString : null;
8439				},
8440
8441				// Caches the header
8442				setRequestHeader: function( name, value ) {
8443					var lname = name.toLowerCase();
8444					if ( !state ) {
8445						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
8446						requestHeaders[ name ] = value;
8447					}
8448					return this;
8449				},
8450
8451				// Overrides response content-type header
8452				overrideMimeType: function( type ) {
8453					if ( !state ) {
8454						s.mimeType = type;
8455					}
8456					return this;
8457				},
8458
8459				// Status-dependent callbacks
8460				statusCode: function( map ) {
8461					var code;
8462					if ( map ) {
8463						if ( state < 2 ) {
8464							for ( code in map ) {
8465
8466								// Lazy-add the new callback in a way that preserves old ones
8467								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
8468							}
8469						} else {
8470
8471							// Execute the appropriate callbacks
8472							jqXHR.always( map[ jqXHR.status ] );
8473						}
8474					}
8475					return this;
8476				},
8477
8478				// Cancel the request
8479				abort: function( statusText ) {
8480					var finalText = statusText || strAbort;
8481					if ( transport ) {
8482						transport.abort( finalText );
8483					}
8484					done( 0, finalText );
8485					return this;
8486				}
8487			};
8488
8489		// Attach deferreds
8490		deferred.promise( jqXHR ).complete = completeDeferred.add;
8491		jqXHR.success = jqXHR.done;
8492		jqXHR.error = jqXHR.fail;
8493
8494		// Remove hash character (#7531: and string promotion)
8495		// Add protocol if not provided (prefilters might expect it)
8496		// Handle falsy url in the settings object (#10093: consistency with old signature)
8497		// We also use the url parameter if available
8498		s.url = ( ( url || s.url || location.href ) + "" ).replace( rhash, "" )
8499			.replace( rprotocol, location.protocol + "//" );
8500
8501		// Alias method option to type as per ticket #12004
8502		s.type = options.method || options.type || s.method || s.type;
8503
8504		// Extract dataTypes list
8505		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
8506
8507		// A cross-domain request is in order when the origin doesn't match the current origin.
8508		if ( s.crossDomain == null ) {
8509			urlAnchor = document.createElement( "a" );
8510
8511			// Support: IE8-11+
8512			// IE throws exception if url is malformed, e.g. http://example.com:80x/
8513			try {
8514				urlAnchor.href = s.url;
8515
8516				// Support: IE8-11+
8517				// Anchor's host property isn't correctly set when s.url is relative
8518				urlAnchor.href = urlAnchor.href;
8519				s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
8520					urlAnchor.protocol + "//" + urlAnchor.host;
8521			} catch ( e ) {
8522
8523				// If there is an error parsing the URL, assume it is crossDomain,
8524				// it can be rejected by the transport if it is invalid
8525				s.crossDomain = true;
8526			}
8527		}
8528
8529		// Convert data if not already a string
8530		if ( s.data && s.processData && typeof s.data !== "string" ) {
8531			s.data = jQuery.param( s.data, s.traditional );
8532		}
8533
8534		// Apply prefilters
8535		inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
8536
8537		// If request was aborted inside a prefilter, stop there
8538		if ( state === 2 ) {
8539			return jqXHR;
8540		}
8541
8542		// We can fire global events as of now if asked to
8543		// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
8544		fireGlobals = jQuery.event && s.global;
8545
8546		// Watch for a new set of requests
8547		if ( fireGlobals && jQuery.active++ === 0 ) {
8548			jQuery.event.trigger( "ajaxStart" );
8549		}
8550
8551		// Uppercase the type
8552		s.type = s.type.toUpperCase();
8553
8554		// Determine if request has content
8555		s.hasContent = !rnoContent.test( s.type );
8556
8557		// Save the URL in case we're toying with the If-Modified-Since
8558		// and/or If-None-Match header later on
8559		cacheURL = s.url;
8560
8561		// More options handling for requests with no content
8562		if ( !s.hasContent ) {
8563
8564			// If data is available, append data to url
8565			if ( s.data ) {
8566				cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
8567
8568				// #9682: remove data so that it's not used in an eventual retry
8569				delete s.data;
8570			}
8571
8572			// Add anti-cache in url if needed
8573			if ( s.cache === false ) {
8574				s.url = rts.test( cacheURL ) ?
8575
8576					// If there is already a '_' parameter, set its value
8577					cacheURL.replace( rts, "$1_=" + nonce++ ) :
8578
8579					// Otherwise add one to the end
8580					cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
8581			}
8582		}
8583
8584		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8585		if ( s.ifModified ) {
8586			if ( jQuery.lastModified[ cacheURL ] ) {
8587				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
8588			}
8589			if ( jQuery.etag[ cacheURL ] ) {
8590				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
8591			}
8592		}
8593
8594		// Set the correct header, if data is being sent
8595		if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
8596			jqXHR.setRequestHeader( "Content-Type", s.contentType );
8597		}
8598
8599		// Set the Accepts header for the server, depending on the dataType
8600		jqXHR.setRequestHeader(
8601			"Accept",
8602			s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
8603				s.accepts[ s.dataTypes[ 0 ] ] +
8604					( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
8605				s.accepts[ "*" ]
8606		);
8607
8608		// Check for headers option
8609		for ( i in s.headers ) {
8610			jqXHR.setRequestHeader( i, s.headers[ i ] );
8611		}
8612
8613		// Allow custom headers/mimetypes and early abort
8614		if ( s.beforeSend &&
8615			( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
8616
8617			// Abort if not done already and return
8618			return jqXHR.abort();
8619		}
8620
8621		// Aborting is no longer a cancellation
8622		strAbort = "abort";
8623
8624		// Install callbacks on deferreds
8625		for ( i in { success: 1, error: 1, complete: 1 } ) {
8626			jqXHR[ i ]( s[ i ] );
8627		}
8628
8629		// Get transport
8630		transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
8631
8632		// If no transport, we auto-abort
8633		if ( !transport ) {
8634			done( -1, "No Transport" );
8635		} else {
8636			jqXHR.readyState = 1;
8637
8638			// Send global event
8639			if ( fireGlobals ) {
8640				globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
8641			}
8642
8643			// If request was aborted inside ajaxSend, stop there
8644			if ( state === 2 ) {
8645				return jqXHR;
8646			}
8647
8648			// Timeout
8649			if ( s.async && s.timeout > 0 ) {
8650				timeoutTimer = window.setTimeout( function() {
8651					jqXHR.abort( "timeout" );
8652				}, s.timeout );
8653			}
8654
8655			try {
8656				state = 1;
8657				transport.send( requestHeaders, done );
8658			} catch ( e ) {
8659
8660				// Propagate exception as error if not done
8661				if ( state < 2 ) {
8662					done( -1, e );
8663
8664				// Simply rethrow otherwise
8665				} else {
8666					throw e;
8667				}
8668			}
8669		}
8670
8671		// Callback for when everything is done
8672		function done( status, nativeStatusText, responses, headers ) {
8673			var isSuccess, success, error, response, modified,
8674				statusText = nativeStatusText;
8675
8676			// Called once
8677			if ( state === 2 ) {
8678				return;
8679			}
8680
8681			// State is "done" now
8682			state = 2;
8683
8684			// Clear timeout if it exists
8685			if ( timeoutTimer ) {
8686				window.clearTimeout( timeoutTimer );
8687			}
8688
8689			// Dereference transport for early garbage collection
8690			// (no matter how long the jqXHR object will be used)
8691			transport = undefined;
8692
8693			// Cache response headers
8694			responseHeadersString = headers || "";
8695
8696			// Set readyState
8697			jqXHR.readyState = status > 0 ? 4 : 0;
8698
8699			// Determine if successful
8700			isSuccess = status >= 200 && status < 300 || status === 304;
8701
8702			// Get response data
8703			if ( responses ) {
8704				response = ajaxHandleResponses( s, jqXHR, responses );
8705			}
8706
8707			// Convert no matter what (that way responseXXX fields are always set)
8708			response = ajaxConvert( s, response, jqXHR, isSuccess );
8709
8710			// If successful, handle type chaining
8711			if ( isSuccess ) {
8712
8713				// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
8714				if ( s.ifModified ) {
8715					modified = jqXHR.getResponseHeader( "Last-Modified" );
8716					if ( modified ) {
8717						jQuery.lastModified[ cacheURL ] = modified;
8718					}
8719					modified = jqXHR.getResponseHeader( "etag" );
8720					if ( modified ) {
8721						jQuery.etag[ cacheURL ] = modified;
8722					}
8723				}
8724
8725				// if no content
8726				if ( status === 204 || s.type === "HEAD" ) {
8727					statusText = "nocontent";
8728
8729				// if not modified
8730				} else if ( status === 304 ) {
8731					statusText = "notmodified";
8732
8733				// If we have data, let's convert it
8734				} else {
8735					statusText = response.state;
8736					success = response.data;
8737					error = response.error;
8738					isSuccess = !error;
8739				}
8740			} else {
8741
8742				// Extract error from statusText and normalize for non-aborts
8743				error = statusText;
8744				if ( status || !statusText ) {
8745					statusText = "error";
8746					if ( status < 0 ) {
8747						status = 0;
8748					}
8749				}
8750			}
8751
8752			// Set data for the fake xhr object
8753			jqXHR.status = status;
8754			jqXHR.statusText = ( nativeStatusText || statusText ) + "";
8755
8756			// Success/Error
8757			if ( isSuccess ) {
8758				deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
8759			} else {
8760				deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
8761			}
8762
8763			// Status-dependent callbacks
8764			jqXHR.statusCode( statusCode );
8765			statusCode = undefined;
8766
8767			if ( fireGlobals ) {
8768				globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
8769					[ jqXHR, s, isSuccess ? success : error ] );
8770			}
8771
8772			// Complete
8773			completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
8774
8775			if ( fireGlobals ) {
8776				globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
8777
8778				// Handle the global AJAX counter
8779				if ( !( --jQuery.active ) ) {
8780					jQuery.event.trigger( "ajaxStop" );
8781				}
8782			}
8783		}
8784
8785		return jqXHR;
8786	},
8787
8788	getJSON: function( url, data, callback ) {
8789		return jQuery.get( url, data, callback, "json" );
8790	},
8791
8792	getScript: function( url, callback ) {
8793		return jQuery.get( url, undefined, callback, "script" );
8794	}
8795} );
8796
8797jQuery.each( [ "get", "post" ], function( i, method ) {
8798	jQuery[ method ] = function( url, data, callback, type ) {
8799
8800		// Shift arguments if data argument was omitted
8801		if ( jQuery.isFunction( data ) ) {
8802			type = type || callback;
8803			callback = data;
8804			data = undefined;
8805		}
8806
8807		// The url can be an options object (which then must have .url)
8808		return jQuery.ajax( jQuery.extend( {
8809			url: url,
8810			type: method,
8811			dataType: type,
8812			data: data,
8813			success: callback
8814		}, jQuery.isPlainObject( url ) && url ) );
8815	};
8816} );
8817
8818
8819jQuery._evalUrl = function( url ) {
8820	return jQuery.ajax( {
8821		url: url,
8822
8823		// Make this explicit, since user can override this through ajaxSetup (#11264)
8824		type: "GET",
8825		dataType: "script",
8826		async: false,
8827		global: false,
8828		"throws": true
8829	} );
8830};
8831
8832
8833jQuery.fn.extend( {
8834	wrapAll: function( html ) {
8835		var wrap;
8836
8837		if ( jQuery.isFunction( html ) ) {
8838			return this.each( function( i ) {
8839				jQuery( this ).wrapAll( html.call( this, i ) );
8840			} );
8841		}
8842
8843		if ( this[ 0 ] ) {
8844
8845			// The elements to wrap the target around
8846			wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
8847
8848			if ( this[ 0 ].parentNode ) {
8849				wrap.insertBefore( this[ 0 ] );
8850			}
8851
8852			wrap.map( function() {
8853				var elem = this;
8854
8855				while ( elem.firstElementChild ) {
8856					elem = elem.firstElementChild;
8857				}
8858
8859				return elem;
8860			} ).append( this );
8861		}
8862
8863		return this;
8864	},
8865
8866	wrapInner: function( html ) {
8867		if ( jQuery.isFunction( html ) ) {
8868			return this.each( function( i ) {
8869				jQuery( this ).wrapInner( html.call( this, i ) );
8870			} );
8871		}
8872
8873		return this.each( function() {
8874			var self = jQuery( this ),
8875				contents = self.contents();
8876
8877			if ( contents.length ) {
8878				contents.wrapAll( html );
8879
8880			} else {
8881				self.append( html );
8882			}
8883		} );
8884	},
8885
8886	wrap: function( html ) {
8887		var isFunction = jQuery.isFunction( html );
8888
8889		return this.each( function( i ) {
8890			jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
8891		} );
8892	},
8893
8894	unwrap: function() {
8895		return this.parent().each( function() {
8896			if ( !jQuery.nodeName( this, "body" ) ) {
8897				jQuery( this ).replaceWith( this.childNodes );
8898			}
8899		} ).end();
8900	}
8901} );
8902
8903
8904jQuery.expr.filters.hidden = function( elem ) {
8905	return !jQuery.expr.filters.visible( elem );
8906};
8907jQuery.expr.filters.visible = function( elem ) {
8908
8909	// Support: Opera <= 12.12
8910	// Opera reports offsetWidths and offsetHeights less than zero on some elements
8911	// Use OR instead of AND as the element is not visible if either is true
8912	// See tickets #10406 and #13132
8913	return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
8914};
8915
8916
8917
8918
8919var r20 = /%20/g,
8920	rbracket = /\[\]$/,
8921	rCRLF = /\r?\n/g,
8922	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
8923	rsubmittable = /^(?:input|select|textarea|keygen)/i;
8924
8925function buildParams( prefix, obj, traditional, add ) {
8926	var name;
8927
8928	if ( jQuery.isArray( obj ) ) {
8929
8930		// Serialize array item.
8931		jQuery.each( obj, function( i, v ) {
8932			if ( traditional || rbracket.test( prefix ) ) {
8933
8934				// Treat each array item as a scalar.
8935				add( prefix, v );
8936
8937			} else {
8938
8939				// Item is non-scalar (array or object), encode its numeric index.
8940				buildParams(
8941					prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
8942					v,
8943					traditional,
8944					add
8945				);
8946			}
8947		} );
8948
8949	} else if ( !traditional && jQuery.type( obj ) === "object" ) {
8950
8951		// Serialize object item.
8952		for ( name in obj ) {
8953			buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
8954		}
8955
8956	} else {
8957
8958		// Serialize scalar item.
8959		add( prefix, obj );
8960	}
8961}
8962
8963// Serialize an array of form elements or a set of
8964// key/values into a query string
8965jQuery.param = function( a, traditional ) {
8966	var prefix,
8967		s = [],
8968		add = function( key, value ) {
8969
8970			// If value is a function, invoke it and return its value
8971			value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
8972			s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
8973		};
8974
8975	// Set traditional to true for jQuery <= 1.3.2 behavior.
8976	if ( traditional === undefined ) {
8977		traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
8978	}
8979
8980	// If an array was passed in, assume that it is an array of form elements.
8981	if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
8982
8983		// Serialize the form elements
8984		jQuery.each( a, function() {
8985			add( this.name, this.value );
8986		} );
8987
8988	} else {
8989
8990		// If traditional, encode the "old" way (the way 1.3.2 or older
8991		// did it), otherwise encode params recursively.
8992		for ( prefix in a ) {
8993			buildParams( prefix, a[ prefix ], traditional, add );
8994		}
8995	}
8996
8997	// Return the resulting serialization
8998	return s.join( "&" ).replace( r20, "+" );
8999};
9000
9001jQuery.fn.extend( {
9002	serialize: function() {
9003		return jQuery.param( this.serializeArray() );
9004	},
9005	serializeArray: function() {
9006		return this.map( function() {
9007
9008			// Can add propHook for "elements" to filter or add form elements
9009			var elements = jQuery.prop( this, "elements" );
9010			return elements ? jQuery.makeArray( elements ) : this;
9011		} )
9012		.filter( function() {
9013			var type = this.type;
9014
9015			// Use .is( ":disabled" ) so that fieldset[disabled] works
9016			return this.name && !jQuery( this ).is( ":disabled" ) &&
9017				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9018				( this.checked || !rcheckableType.test( type ) );
9019		} )
9020		.map( function( i, elem ) {
9021			var val = jQuery( this ).val();
9022
9023			return val == null ?
9024				null :
9025				jQuery.isArray( val ) ?
9026					jQuery.map( val, function( val ) {
9027						return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9028					} ) :
9029					{ name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9030		} ).get();
9031	}
9032} );
9033
9034
9035jQuery.ajaxSettings.xhr = function() {
9036	try {
9037		return new window.XMLHttpRequest();
9038	} catch ( e ) {}
9039};
9040
9041var xhrSuccessStatus = {
9042
9043		// File protocol always yields status code 0, assume 200
9044		0: 200,
9045
9046		// Support: IE9
9047		// #1450: sometimes IE returns 1223 when it should be 204
9048		1223: 204
9049	},
9050	xhrSupported = jQuery.ajaxSettings.xhr();
9051
9052support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
9053support.ajax = xhrSupported = !!xhrSupported;
9054
9055jQuery.ajaxTransport( function( options ) {
9056	var callback, errorCallback;
9057
9058	// Cross domain only allowed if supported through XMLHttpRequest
9059	if ( support.cors || xhrSupported && !options.crossDomain ) {
9060		return {
9061			send: function( headers, complete ) {
9062				var i,
9063					xhr = options.xhr();
9064
9065				xhr.open(
9066					options.type,
9067					options.url,
9068					options.async,
9069					options.username,
9070					options.password
9071				);
9072
9073				// Apply custom fields if provided
9074				if ( options.xhrFields ) {
9075					for ( i in options.xhrFields ) {
9076						xhr[ i ] = options.xhrFields[ i ];
9077					}
9078				}
9079
9080				// Override mime type if needed
9081				if ( options.mimeType && xhr.overrideMimeType ) {
9082					xhr.overrideMimeType( options.mimeType );
9083				}
9084
9085				// X-Requested-With header
9086				// For cross-domain requests, seeing as conditions for a preflight are
9087				// akin to a jigsaw puzzle, we simply never set it to be sure.
9088				// (it can always be set on a per-request basis or even using ajaxSetup)
9089				// For same-domain requests, won't change header if already provided.
9090				if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
9091					headers[ "X-Requested-With" ] = "XMLHttpRequest";
9092				}
9093
9094				// Set headers
9095				for ( i in headers ) {
9096					xhr.setRequestHeader( i, headers[ i ] );
9097				}
9098
9099				// Callback
9100				callback = function( type ) {
9101					return function() {
9102						if ( callback ) {
9103							callback = errorCallback = xhr.onload =
9104								xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;
9105
9106							if ( type === "abort" ) {
9107								xhr.abort();
9108							} else if ( type === "error" ) {
9109
9110								// Support: IE9
9111								// On a manual native abort, IE9 throws
9112								// errors on any property access that is not readyState
9113								if ( typeof xhr.status !== "number" ) {
9114									complete( 0, "error" );
9115								} else {
9116									complete(
9117
9118										// File: protocol always yields status 0; see #8605, #14207
9119										xhr.status,
9120										xhr.statusText
9121									);
9122								}
9123							} else {
9124								complete(
9125									xhrSuccessStatus[ xhr.status ] || xhr.status,
9126									xhr.statusText,
9127
9128									// Support: IE9 only
9129									// IE9 has no XHR2 but throws on binary (trac-11426)
9130									// For XHR2 non-text, let the caller handle it (gh-2498)
9131									( xhr.responseType || "text" ) !== "text"  ||
9132									typeof xhr.responseText !== "string" ?
9133										{ binary: xhr.response } :
9134										{ text: xhr.responseText },
9135									xhr.getAllResponseHeaders()
9136								);
9137							}
9138						}
9139					};
9140				};
9141
9142				// Listen to events
9143				xhr.onload = callback();
9144				errorCallback = xhr.onerror = callback( "error" );
9145
9146				// Support: IE9
9147				// Use onreadystatechange to replace onabort
9148				// to handle uncaught aborts
9149				if ( xhr.onabort !== undefined ) {
9150					xhr.onabort = errorCallback;
9151				} else {
9152					xhr.onreadystatechange = function() {
9153
9154						// Check readyState before timeout as it changes
9155						if ( xhr.readyState === 4 ) {
9156
9157							// Allow onerror to be called first,
9158							// but that will not handle a native abort
9159							// Also, save errorCallback to a variable
9160							// as xhr.onerror cannot be accessed
9161							window.setTimeout( function() {
9162								if ( callback ) {
9163									errorCallback();
9164								}
9165							} );
9166						}
9167					};
9168				}
9169
9170				// Create the abort callback
9171				callback = callback( "abort" );
9172
9173				try {
9174
9175					// Do send the request (this may raise an exception)
9176					xhr.send( options.hasContent && options.data || null );
9177				} catch ( e ) {
9178
9179					// #14683: Only rethrow if this hasn't been notified as an error yet
9180					if ( callback ) {
9181						throw e;
9182					}
9183				}
9184			},
9185
9186			abort: function() {
9187				if ( callback ) {
9188					callback();
9189				}
9190			}
9191		};
9192	}
9193} );
9194
9195
9196
9197
9198// Install script dataType
9199jQuery.ajaxSetup( {
9200	accepts: {
9201		script: "text/javascript, application/javascript, " +
9202			"application/ecmascript, application/x-ecmascript"
9203	},
9204	contents: {
9205		script: /\b(?:java|ecma)script\b/
9206	},
9207	converters: {
9208		"text script": function( text ) {
9209			jQuery.globalEval( text );
9210			return text;
9211		}
9212	}
9213} );
9214
9215// Handle cache's special case and crossDomain
9216jQuery.ajaxPrefilter( "script", function( s ) {
9217	if ( s.cache === undefined ) {
9218		s.cache = false;
9219	}
9220	if ( s.crossDomain ) {
9221		s.type = "GET";
9222	}
9223} );
9224
9225// Bind script tag hack transport
9226jQuery.ajaxTransport( "script", function( s ) {
9227
9228	// This transport only deals with cross domain requests
9229	if ( s.crossDomain ) {
9230		var script, callback;
9231		return {
9232			send: function( _, complete ) {
9233				script = jQuery( "<script>" ).prop( {
9234					charset: s.scriptCharset,
9235					src: s.url
9236				} ).on(
9237					"load error",
9238					callback = function( evt ) {
9239						script.remove();
9240						callback = null;
9241						if ( evt ) {
9242							complete( evt.type === "error" ? 404 : 200, evt.type );
9243						}
9244					}
9245				);
9246
9247				// Use native DOM manipulation to avoid our domManip AJAX trickery
9248				document.head.appendChild( script[ 0 ] );
9249			},
9250			abort: function() {
9251				if ( callback ) {
9252					callback();
9253				}
9254			}
9255		};
9256	}
9257} );
9258
9259
9260
9261
9262var oldCallbacks = [],
9263	rjsonp = /(=)\?(?=&|$)|\?\?/;
9264
9265// Default jsonp settings
9266jQuery.ajaxSetup( {
9267	jsonp: "callback",
9268	jsonpCallback: function() {
9269		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
9270		this[ callback ] = true;
9271		return callback;
9272	}
9273} );
9274
9275// Detect, normalize options and install callbacks for jsonp requests
9276jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
9277
9278	var callbackName, overwritten, responseContainer,
9279		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
9280			"url" :
9281			typeof s.data === "string" &&
9282				( s.contentType || "" )
9283					.indexOf( "application/x-www-form-urlencoded" ) === 0 &&
9284				rjsonp.test( s.data ) && "data"
9285		);
9286
9287	// Handle iff the expected data type is "jsonp" or we have a parameter to set
9288	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
9289
9290		// Get callback name, remembering preexisting value associated with it
9291		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
9292			s.jsonpCallback() :
9293			s.jsonpCallback;
9294
9295		// Insert callback into url or form data
9296		if ( jsonProp ) {
9297			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
9298		} else if ( s.jsonp !== false ) {
9299			s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
9300		}
9301
9302		// Use data converter to retrieve json after script execution
9303		s.converters[ "script json" ] = function() {
9304			if ( !responseContainer ) {
9305				jQuery.error( callbackName + " was not called" );
9306			}
9307			return responseContainer[ 0 ];
9308		};
9309
9310		// Force json dataType
9311		s.dataTypes[ 0 ] = "json";
9312
9313		// Install callback
9314		overwritten = window[ callbackName ];
9315		window[ callbackName ] = function() {
9316			responseContainer = arguments;
9317		};
9318
9319		// Clean-up function (fires after converters)
9320		jqXHR.always( function() {
9321
9322			// If previous value didn't exist - remove it
9323			if ( overwritten === undefined ) {
9324				jQuery( window ).removeProp( callbackName );
9325
9326			// Otherwise restore preexisting value
9327			} else {
9328				window[ callbackName ] = overwritten;
9329			}
9330
9331			// Save back as free
9332			if ( s[ callbackName ] ) {
9333
9334				// Make sure that re-using the options doesn't screw things around
9335				s.jsonpCallback = originalSettings.jsonpCallback;
9336
9337				// Save the callback name for future use
9338				oldCallbacks.push( callbackName );
9339			}
9340
9341			// Call if it was a function and we have a response
9342			if ( responseContainer && jQuery.isFunction( overwritten ) ) {
9343				overwritten( responseContainer[ 0 ] );
9344			}
9345
9346			responseContainer = overwritten = undefined;
9347		} );
9348
9349		// Delegate to script
9350		return "script";
9351	}
9352} );
9353
9354
9355
9356
9357// 
9357Support: Safari 8+
9358// In Safari 8 documents created via document.implementation.createHTMLDocument
9359// collapse sibling forms: the second one becomes a child of the first one.
9360// Because of that, this security measure has to be disabled in Safari 8.
9361// https://bugs.webkit.org/show_bug.cgi?id=137337
9362support.createHTMLDocument = ( function() {
9363	var body = document.implementation.createHTMLDocument( "" ).body;
9364	body.innerHTML = "<form></form><form></form>";
9365	return body.childNodes.length === 2;
9366} )();
9367
9368
9369// Argument "data" should be string of html
9370// context (optional): If specified, the fragment will be created in this context,
9371// defaults to document
9372// keepScripts (optional): If true, will include scripts passed in the html string
9373jQuery.parseHTML = function( data, context, keepScripts ) {
9374	if ( !data || typeof data !== "string" ) {
9375		return null;
9376	}
9377	if ( typeof context === "boolean" ) {
9378		keepScripts = context;
9379		context = false;
9380	}
9381
9382	// Stop scripts or inline event handlers from being executed immediately
9383	// by using document.implementation
9384	context = context || ( support.createHTMLDocument ?
9385		document.implementation.createHTMLDocument( "" ) :
9386		document );
9387
9388	var parsed = rsingleTag.exec( data ),
9389		scripts = !keepScripts && [];
9390
9391	// Single tag
9392	if ( parsed ) {
9393		return [ context.createElement( parsed[ 1 ] ) ];
9394	}
9395
9396	parsed = buildFragment( [ data ], context, scripts );
9397
9398	if ( scripts && scripts.length ) {
vendor: 11,150 bytes, lines 9399-9796
9399		jQuery( scripts ).remove();
9400	}
9401
9402	return jQuery.merge( [], parsed.childNodes );
9403};
9404
9405
9406// Keep a copy of the old load method
9407var _load = jQuery.fn.load;
9408
9409/**
9410 * Load a url into a page
9411 */
9412jQuery.fn.load = function( url, params, callback ) {
9413	if ( typeof url !== "string" && _load ) {
9414		return _load.apply( this, arguments );
9415	}
9416
9417	var selector, type, response,
9418		self = this,
9419		off = url.indexOf( " " );
9420
9421	if ( off > -1 ) {
9422		selector = jQuery.trim( url.slice( off ) );
9423		url = url.slice( 0, off );
9424	}
9425
9426	// If it's a function
9427	if ( jQuery.isFunction( params ) ) {
9428
9429		// We assume that it's the callback
9430		callback = params;
9431		params = undefined;
9432
9433	// Otherwise, build a param string
9434	} else if ( params && typeof params === "object" ) {
9435		type = "POST";
9436	}
9437
9438	// If we have elements to modify, make the request
9439	if ( self.length > 0 ) {
9440		jQuery.ajax( {
9441			url: url,
9442
9443			// If "type" variable is undefined, then "GET" method will be used.
9444			// Make value of this field explicit since
9445			// user can override it through ajaxSetup method
9446			type: type || "GET",
9447			dataType: "html",
9448			data: params
9449		} ).done( function( responseText ) {
9450
9451			// Save response for use in complete callback
9452			response = arguments;
9453
9454			self.html( selector ?
9455
9456				// If a selector was specified, locate the right elements in a dummy div
9457				// Exclude scripts to avoid IE 'Permission Denied' errors
9458				jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
9459
9460				// Otherwise use the full result
9461				responseText );
9462
9463		// If the request succeeds, this function gets "data", "status", "jqXHR"
9464		// but they are ignored because response was set above.
9465		// If it fails, this function gets "jqXHR", "status", "error"
9466		} ).always( callback && function( jqXHR, status ) {
9467			self.each( function() {
9468				callback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] );
9469			} );
9470		} );
9471	}
9472
9473	return this;
9474};
9475
9476
9477
9478
9479// Attach a bunch of functions for handling common AJAX events
9480jQuery.each( [
9481	"ajaxStart",
9482	"ajaxStop",
9483	"ajaxComplete",
9484	"ajaxError",
9485	"ajaxSuccess",
9486	"ajaxSend"
9487], function( i, type ) {
9488	jQuery.fn[ type ] = function( fn ) {
9489		return this.on( type, fn );
9490	};
9491} );
9492
9493
9494
9495
9496jQuery.expr.filters.animated = function( elem ) {
9497	return jQuery.grep( jQuery.timers, function( fn ) {
9498		return elem === fn.elem;
9499	} ).length;
9500};
9501
9502
9503
9504
9505/**
9506 * Gets a window from an element
9507 */
9508function getWindow( elem ) {
9509	return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
9510}
9511
9512jQuery.offset = {
9513	setOffset: function( elem, options, i ) {
9514		var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
9515			position = jQuery.css( elem, "position" ),
9516			curElem = jQuery( elem ),
9517			props = {};
9518
9519		// Set position first, in-case top/left are set even on static elem
9520		if ( position === "static" ) {
9521			elem.style.position = "relative";
9522		}
9523
9524		curOffset = curElem.offset();
9525		curCSSTop = jQuery.css( elem, "top" );
9526		curCSSLeft = jQuery.css( elem, "left" );
9527		calculatePosition = ( position === "absolute" || position === "fixed" ) &&
9528			( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
9529
9530		// Need to be able to calculate position if either
9531		// top or left is auto and position is either absolute or fixed
9532		if ( calculatePosition ) {
9533			curPosition = curElem.position();
9534			curTop = curPosition.top;
9535			curLeft = curPosition.left;
9536
9537		} else {
9538			curTop = parseFloat( curCSSTop ) || 0;
9539			curLeft = parseFloat( curCSSLeft ) || 0;
9540		}
9541
9542		if ( jQuery.isFunction( options ) ) {
9543
9544			// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
9545			options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
9546		}
9547
9548		if ( options.top != null ) {
9549			props.top = ( options.top - curOffset.top ) + curTop;
9550		}
9551		if ( options.left != null ) {
9552			props.left = ( options.left - curOffset.left ) + curLeft;
9553		}
9554
9555		if ( "using" in options ) {
9556			options.using.call( elem, props );
9557
9558		} else {
9559			curElem.css( props );
9560		}
9561	}
9562};
9563
9564jQuery.fn.extend( {
9565	offset: function( options ) {
9566		if ( arguments.length ) {
9567			return options === undefined ?
9568				this :
9569				this.each( function( i ) {
9570					jQuery.offset.setOffset( this, options, i );
9571				} );
9572		}
9573
9574		var docElem, win,
9575			elem = this[ 0 ],
9576			box = { top: 0, left: 0 },
9577			doc = elem && elem.ownerDocument;
9578
9579		if ( !doc ) {
9580			return;
9581		}
9582
9583		docElem = doc.documentElement;
9584
9585		// Make sure it's not a disconnected DOM node
9586		if ( !jQuery.contains( docElem, elem ) ) {
9587			return box;
9588		}
9589
9590		box = elem.getBoundingClientRect();
9591		win = getWindow( doc );
9592		return {
9593			top: box.top + win.pageYOffset - docElem.clientTop,
9594			left: box.left + win.pageXOffset - docElem.clientLeft
9595		};
9596	},
9597
9598	position: function() {
9599		if ( !this[ 0 ] ) {
9600			return;
9601		}
9602
9603		var offsetParent, offset,
9604			elem = this[ 0 ],
9605			parentOffset = { top: 0, left: 0 };
9606
9607		// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
9608		// because it is its only offset parent
9609		if ( jQuery.css( elem, "position" ) === "fixed" ) {
9610
9611			// Assume getBoundingClientRect is there when computed position is fixed
9612			offset = elem.getBoundingClientRect();
9613
9614		} else {
9615
9616			// Get *real* offsetParent
9617			offsetParent = this.offsetParent();
9618
9619			// Get correct offsets
9620			offset = this.offset();
9621			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
9622				parentOffset = offsetParent.offset();
9623			}
9624
9625			// Add offsetParent borders
9626			// Subtract offsetParent scroll positions
9627			parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ) -
9628				offsetParent.scrollTop();
9629			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ) -
9630				offsetParent.scrollLeft();
9631		}
9632
9633		// Subtract parent offsets and element margins
9634		return {
9635			top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
9636			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
9637		};
9638	},
9639
9640	// This method will return documentElement in the following cases:
9641	// 1) For the element inside the iframe without offsetParent, this method will return
9642	//    documentElement of the parent window
9643	// 2) For the hidden or detached element
9644	// 3) For body or html element, i.e. in case of the html node - it will return itself
9645	//
9646	// but those exceptions were never presented as a real life use-cases
9647	// and might be considered as more preferable results.
9648	//
9649	// This logic, however, is not guaranteed and can change at any point in the future
9650	offsetParent: function() {
9651		return this.map( function() {
9652			var offsetParent = this.offsetParent;
9653
9654			while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
9655				offsetParent = offsetParent.offsetParent;
9656			}
9657
9658			return offsetParent || documentElement;
9659		} );
9660	}
9661} );
9662
9663// Create scrollLeft and scrollTop methods
9664jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
9665	var top = "pageYOffset" === prop;
9666
9667	jQuery.fn[ method ] = function( val ) {
9668		return access( this, function( elem, method, val ) {
9669			var win = getWindow( elem );
9670
9671			if ( val === undefined ) {
9672				return win ? win[ prop ] : elem[ method ];
9673			}
9674
9675			if ( win ) {
9676				win.scrollTo(
9677					!top ? val : win.pageXOffset,
9678					top ? val : win.pageYOffset
9679				);
9680
9681			} else {
9682				elem[ method ] = val;
9683			}
9684		}, method, val, arguments.length );
9685	};
9686} );
9687
9688// Support: Safari<7-8+, Chrome<37-44+
9689// Add the top/left cssHooks using jQuery.fn.position
9690// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
9691// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
9692// getComputedStyle returns percent when specified for top/left/bottom/right;
9693// rather than make the css module depend on the offset module, just check for it here
9694jQuery.each( [ "top", "left" ], function( i, prop ) {
9695	jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
9696		function( elem, computed ) {
9697			if ( computed ) {
9698				computed = curCSS( elem, prop );
9699
9700				// If curCSS returns percentage, fallback to offset
9701				return rnumnonpx.test( computed ) ?
9702					jQuery( elem ).position()[ prop ] + "px" :
9703					computed;
9704			}
9705		}
9706	);
9707} );
9708
9709
9710// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
9711jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
9712	jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
9713		function( defaultExtra, funcName ) {
9714
9715		// Margin is only for outerHeight, outerWidth
9716		jQuery.fn[ funcName ] = function( margin, value ) {
9717			var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
9718				extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
9719
9720			return access( this, function( elem, type, value ) {
9721				var doc;
9722
9723				if ( jQuery.isWindow( elem ) ) {
9724
9725					// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
9726					// isn't a whole lot we can do. See pull request at this URL for discussion:
9727					// https://github.com/jquery/jquery/pull/764
9728					return elem.document.documentElement[ "client" + name ];
9729				}
9730
9731				// Get document width or height
9732				if ( elem.nodeType === 9 ) {
9733					doc = elem.documentElement;
9734
9735					// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
9736					// whichever is greatest
9737					return Math.max(
9738						elem.body[ "scroll" + name ], doc[ "scroll" + name ],
9739						elem.body[ "offset" + name ], doc[ "offset" + name ],
9740						doc[ "client" + name ]
9741					);
9742				}
9743
9744				return value === undefined ?
9745
9746					// Get width or height on the element, requesting but not forcing parseFloat
9747					jQuery.css( elem, type, extra ) :
9748
9749					// Set width or height on the element
9750					jQuery.style( elem, type, value, extra );
9751			}, type, chainable ? margin : undefined, chainable, null );
9752		};
9753	} );
9754} );
9755
9756
9757jQuery.fn.extend( {
9758
9759	bind: function( types, data, fn ) {
9760		return this.on( types, null, data, fn );
9761	},
9762	unbind: function( types, fn ) {
9763		return this.off( types, null, fn );
9764	},
9765
9766	delegate: function( selector, types, data, fn ) {
9767		return this.on( types, selector, data, fn );
9768	},
9769	undelegate: function( selector, types, fn ) {
9770
9771		// ( namespace ) or ( selector, types [, fn] )
9772		return arguments.length === 1 ?
9773			this.off( selector, "**" ) :
9774			this.off( types, selector || "**", fn );
9775	},
9776	size: function() {
9777		return this.length;
9778	}
9779} );
9780
9781jQuery.fn.andSelf = jQuery.fn.addBack;
9782
9783
9784
9785
9786// Register as a named AMD module, since jQuery can be concatenated with other
9787// files that may use define, but not via a proper concatenation script that
9788// understands anonymous AMD modules. A named AMD is safest and most robust
9789// way to register. Lowercase jquery is used because AMD module names are
9790// derived from file names, and jQuery is normally delivered in a lowercase
9791// file name. Do this after creating the global so that if an AMD module wants
9792// to call noConflict to hide this version of jQuery, it will work.
9793
9794// Note that for maximum portability, libraries that are not jQuery should
9795// declare themselves as anonymous modules, and avoid setting a global if an
9796// AMD loader is present. jQuery is a special case. For more information, see
9797// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
9798
9799if ( typeof define === "function" && define.amd ) {
9800	define( "jquery", [], function() {
9801		return jQuery;
9802	} );
9803}
9804
9805
9806
9807var
9808
9809	// Map over jQuery in case of overwrite
9810	_jQuery = window.jQuery,
9811
9812	// Map over the $ in case of overwrite
9813	_$ = window.$;
9814
9815jQuery.noConflict = function( deep ) {
9816	if ( window.$ === jQuery ) {
9817		window.$ = _$;
9818	}
9819
9820	if ( deep && window.jQuery === jQuery ) {
9821		window.jQuery = _jQuery;
9822	}
9823
9824	return jQuery;
9825};
9826
9827// Expose jQuery and $ identifiers, even in AMD
9828// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
9829// and CommonJS for browser emulators (#13566)
9830if ( !noGlobal ) {
9831	window.jQuery = window.$ = jQuery;
9832}
9833
9834return jQuery;
9835}));
9836
vendor: 33,555 bytes, lines 9837-11039
9837/*! jQuery UI - v1.11.4 - 2015-03-11
9838* http://jqueryui.com
9839* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
9840* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
9841
9842(function( factory ) {
9843	if ( typeof define === "function" && define.amd ) {
9844
9845		// AMD. Register as an anonymous module.
9846		define([ "jquery" ], factory );
9847	} else {
9848
9849		// Browser globals
9850		factory( jQuery );
9851	}
9852}(function( $ ) {
9853/*!
9854 * jQuery UI Core 1.11.4
9855 * http://jqueryui.com
9856 *
9857 * Copyright jQuery Foundation and other contributors
9858 * Released under the MIT license.
9859 * http://jquery.org/license
9860 *
9861 * http://api.jqueryui.com/category/ui-core/
9862 */
9863
9864
9865// $.ui might exist from components with no dependencies, e.g., $.ui.position
9866$.ui = $.ui || {};
9867
9868$.extend( $.ui, {
9869	version: "1.11.4",
9870
9871	keyCode: {
9872		BACKSPACE: 8,
9873		COMMA: 188,
9874		DELETE: 46,
9875		DOWN: 40,
9876		END: 35,
9877		ENTER: 13,
9878		ESCAPE: 27,
9879		HOME: 36,
9880		LEFT: 37,
9881		PAGE_DOWN: 34,
9882		PAGE_UP: 33,
9883		PERIOD: 190,
9884		RIGHT: 39,
9885		SPACE: 32,
9886		TAB: 9,
9887		UP: 38
9888	}
9889});
9890
9891// plugins
9892$.fn.extend({
9893	scrollParent: function( includeHidden ) {
9894		var position = this.css( "position" ),
9895			excludeStaticParent = position === "absolute",
9896			overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
9897			scrollParent = this.parents().filter( function() {
9898				var parent = $( this );
9899				if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
9900					return false;
9901				}
9902				return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) );
9903			}).eq( 0 );
9904
9905		return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;
9906	},
9907
9908	uniqueId: (function() {
9909		var uuid = 0;
9910
9911		return function() {
9912			return this.each(function() {
9913				if ( !this.id ) {
9914					this.id = "ui-id-" + ( ++uuid );
9915				}
9916			});
9917		};
9918	})(),
9919
9920	removeUniqueId: function() {
9921		return this.each(function() {
9922			if ( /^ui-id-\d+$/.test( this.id ) ) {
9923				$( this ).removeAttr( "id" );
9924			}
9925		});
9926	}
9927});
9928
9929// selectors
9930function focusable( element, isTabIndexNotNaN ) {
9931	var map, mapName, img,
9932		nodeName = element.nodeName.toLowerCase();
9933	if ( "area" === nodeName ) {
9934		map = element.parentNode;
9935		mapName = map.name;
9936		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
9937			return false;
9938		}
9939		img = $( "img[usemap='#" + mapName + "']" )[ 0 ];
9940		return !!img && visible( img );
9941	}
9942	return ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?
9943		!element.disabled :
9944		"a" === nodeName ?
9945			element.href || isTabIndexNotNaN :
9946			isTabIndexNotNaN) &&
9947		// the element and all of its ancestors must be visible
9948		visible( element );
9949}
9950
9951function visible( element ) {
9952	return $.expr.filters.visible( element ) &&
9953		!$( element ).parents().addBack().filter(function() {
9954			return $.css( this, "visibility" ) === "hidden";
9955		}).length;
9956}
9957
9958$.extend( $.expr[ ":" ], {
9959	data: $.expr.createPseudo ?
9960		$.expr.createPseudo(function( dataName ) {
9961			return function( elem ) {
9962				return !!$.data( elem, dataName );
9963			};
9964		}) :
9965		// support: jQuery <1.8
9966		function( elem, i, match ) {
9967			return !!$.data( elem, match[ 3 ] );
9968		},
9969
9970	focusable: function( element ) {
9971		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
9972	},
9973
9974	tabbable: function( element ) {
9975		var tabIndex = $.attr( element, "tabindex" ),
9976			isTabIndexNaN = isNaN( tabIndex );
9977		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
9978	}
9979});
9980
9981// support: jQuery <1.8
9982if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
9983	$.each( [ "Width", "Height" ], function( i, name ) {
9984		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
9985			type = name.toLowerCase(),
9986			orig = {
9987				innerWidth: $.fn.innerWidth,
9988				innerHeight: $.fn.innerHeight,
9989				outerWidth: $.fn.outerWidth,
9990				outerHeight: $.fn.outerHeight
9991			};
9992
9993		function reduce( elem, size, border, margin ) {
9994			$.each( side, function() {
9995				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
9996				if ( border ) {
9997					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
9998				}
9999				if ( margin ) {
10000					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
10001				}
10002			});
10003			return size;
10004		}
10005
10006		$.fn[ "inner" + name ] = function( size ) {
10007			if ( size === undefined ) {
10008				return orig[ "inner" + name ].call( this );
10009			}
10010
10011			return this.each(function() {
10012				$( this ).css( type, reduce( this, size ) + "px" );
10013			});
10014		};
10015
10016		$.fn[ "outer" + name] = function( size, margin ) {
10017			if ( typeof size !== "number" ) {
10018				return orig[ "outer" + name ].call( this, size );
10019			}
10020
10021			return this.each(function() {
10022				$( this).css( type, reduce( this, size, true, margin ) + "px" );
10023			});
10024		};
10025	});
10026}
10027
10028// support: jQuery <1.8
10029if ( !$.fn.addBack ) {
10030	$.fn.addBack = function( selector ) {
10031		return this.add( selector == null ?
10032			this.prevObject : this.prevObject.filter( selector )
10033		);
10034	};
10035}
10036
10037// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
10038if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
10039	$.fn.removeData = (function( removeData ) {
10040		return function( key ) {
10041			if ( arguments.length ) {
10042				return removeData.call( this, $.camelCase( key ) );
10043			} else {
10044				return removeData.call( this );
10045			}
10046		};
10047	})( $.fn.removeData );
10048}
10049
10050// deprecated
10051$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
10052
10053$.fn.extend({
10054	focus: (function( orig ) {
10055		return function( delay, fn ) {
10056			return typeof delay === "number" ?
10057				this.each(function() {
10058					var elem = this;
10059					setTimeout(function() {
10060						$( elem ).focus();
10061						if ( fn ) {
10062							fn.call( elem );
10063						}
10064					}, delay );
10065				}) :
10066				orig.apply( this, arguments );
10067		};
10068	})( $.fn.focus ),
10069
10070	disableSelection: (function() {
10071		var eventType = "onselectstart" in document.createElement( "div" ) ?
10072			"selectstart" :
10073			"mousedown";
10074
10075		return function() {
10076			return this.bind( eventType + ".ui-disableSelection", function( event ) {
10077				event.preventDefault();
10078			});
10079		};
10080	})(),
10081
10082	enableSelection: function() {
10083		return this.unbind( ".ui-disableSelection" );
10084	},
10085
10086	zIndex: function( zIndex ) {
10087		if ( zIndex !== undefined ) {
10088			return this.css( "zIndex", zIndex );
10089		}
10090
10091		if ( this.length ) {
10092			var elem = $( this[ 0 ] ), position, value;
10093			while ( elem.length && elem[ 0 ] !== document ) {
10094				// Ignore z-index if position is set to a value where z-index is ignored by the browser
10095				// This makes behavior of this function consistent across browsers
10096				// WebKit always returns auto if the element is positioned
10097				position = elem.css( "position" );
10098				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
10099					// IE returns 0 when zIndex is not specified
10100					// other browsers return a string
10101					// we ignore the case of nested elements with an explicit value of 0
10102					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
10103					value = parseInt( elem.css( "zIndex" ), 10 );
10104					if ( !isNaN( value ) && value !== 0 ) {
10105						return value;
10106					}
10107				}
10108				elem = elem.parent();
10109			}
10110		}
10111
10112		return 0;
10113	}
10114});
10115
10116// $.ui.plugin is deprecated. Use $.widget() extensions instead.
10117$.ui.plugin = {
10118	add: function( module, option, set ) {
10119		var i,
10120			proto = $.ui[ module ].prototype;
10121		for ( i in set ) {
10122			proto.plugins[ i ] = proto.plugins[ i ] || [];
10123			proto.plugins[ i ].push( [ option, set[ i ] ] );
10124		}
10125	},
10126	call: function( instance, name, args, allowDisconnected ) {
10127		var i,
10128			set = instance.plugins[ name ];
10129
10130		if ( !set ) {
10131			return;
10132		}
10133
10134		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
10135			return;
10136		}
10137
10138		for ( i = 0; i < set.length; i++ ) {
10139			if ( instance.options[ set[ i ][ 0 ] ] ) {
10140				set[ i ][ 1 ].apply( instance.element, args );
10141			}
10142		}
10143	}
10144};
10145
10146
10147/*!
10148 * jQuery UI Widget 1.11.4
10149 * http://jqueryui.com
10150 *
10151 * Copyright jQuery Foundation and other contributors
10152 * Released under the MIT license.
10153 * http://jquery.org/license
10154 *
10155 * http://api.jqueryui.com/jQuery.widget/
10156 */
10157
10158
10159var widget_uuid = 0,
10160	widget_slice = Array.prototype.slice;
10161
10162$.cleanData = (function( orig ) {
10163	return function( elems ) {
10164		var events, elem, i;
10165		for ( i = 0; (elem = elems[i]) != null; i++ ) {
10166			try {
10167
10168				// Only trigger remove when necessary to save time
10169				events = $._data( elem, "events" );
10170				if ( events && events.remove ) {
10171					$( elem ).triggerHandler( "remove" );
10172				}
10173
10174			// http://bugs.jquery.com/ticket/8235
10175			} catch ( e ) {}
10176		}
10177		orig( elems );
10178	};
10179})( $.cleanData );
10180
10181$.widget = function( name, base, prototype ) {
10182	var fullName, existingConstructor, constructor, basePrototype,
10183		// proxiedPrototype allows the provided prototype to remain unmodified
10184		// so that it can be used as a mixin for multiple widgets (#8876)
10185		proxiedPrototype = {},
10186		namespace = name.split( "." )[ 0 ];
10187
10188	name = name.split( "." )[ 1 ];
10189	fullName = namespace + "-" + name;
10190
10191	if ( !prototype ) {
10192		prototype = base;
10193		base = $.Widget;
10194	}
10195
10196	// create selector for plugin
10197	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
10198		return !!$.data( elem, fullName );
10199	};
10200
10201	$[ namespace ] = $[ namespace ] || {};
10202	existingConstructor = $[ namespace ][ name ];
10203	constructor = $[ namespace ][ name ] = function( options, element ) {
10204		// allow instantiation without "new" keyword
10205		if ( !this._createWidget ) {
10206			return new constructor( options, element );
10207		}
10208
10209		// allow instantiation without initializing for simple inheritance
10210		// must use "new" keyword (the code above always passes args)
10211		if ( arguments.length ) {
10212			this._createWidget( options, element );
10213		}
10214	};
10215	// extend with the existing constructor to carry over any static properties
10216	$.extend( constructor, existingConstructor, {
10217		version: prototype.version,
10218		// copy the object used to create the prototype in case we need to
10219		// redefine the widget later
10220		_proto: $.extend( {}, prototype ),
10221		// track widgets that inherit from this widget in case this widget is
10222		// redefined after a widget inherits from it
10223		_childConstructors: []
10224	});
10225
10226	basePrototype = new base();
10227	// we need to make the options hash a property directly on the new instance
10228	// otherwise we'll modify the options hash on the prototype that we're
10229	// inheriting from
10230	basePrototype.options = $.widget.extend( {}, basePrototype.options );
10231	$.each( prototype, function( prop, value ) {
10232		if ( !$.isFunction( value ) ) {
10233			proxiedPrototype[ prop ] = value;
10234			return;
10235		}
10236		proxiedPrototype[ prop ] = (function() {
10237			var _super = function() {
10238					return base.prototype[ prop ].apply( this, arguments );
10239				},
10240				_superApply = function( args ) {
10241					return base.prototype[ prop ].apply( this, args );
10242				};
10243			return function() {
10244				var __super = this._super,
10245					__superApply = this._superApply,
10246					returnValue;
10247
10248				this._super = _super;
10249				this._superApply = _superApply;
10250
10251				returnValue = value.apply( this, arguments );
10252
10253				this._super = __super;
10254				this._superApply = __superApply;
10255
10256				return returnValue;
10257			};
10258		})();
10259	});
10260	constructor.prototype = $.widget.extend( basePrototype, {
10261		// TODO: remove support for widgetEventPrefix
10262		// always use the name + a colon as the prefix, e.g., draggable:start
10263		// don't prefix for widgets that aren't DOM-based
10264		widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
10265	}, proxiedPrototype, {
10266		constructor: constructor,
10267		namespace: namespace,
10268		widgetName: name,
10269		widgetFullName: fullName
10270	});
10271
10272	// If this widget is being redefined then we need to find all widgets that
10273	// are inheriting from it and redefine all of them so that they inherit from
10274	// the new version of this widget. We're essentially trying to replace one
10275	// level in the prototype chain.
10276	if ( existingConstructor ) {
10277		$.each( existingConstructor._childConstructors, function( i, child ) {
10278			var childPrototype = child.prototype;
10279
10280			// redefine the child widget using the same prototype that was
10281			// originally used, but inherit from the new version of the base
10282			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
10283		});
10284		// remove the list of existing child constructors from the old constructor
10285		// so the old child constructors can be garbage collected
10286		delete existingConstructor._childConstructors;
10287	} else {
10288		base._childConstructors.push( constructor );
10289	}
10290
10291	$.widget.bridge( name, constructor );
10292
10293	return constructor;
10294};
10295
10296$.widget.extend = function( target ) {
10297	var input = widget_slice.call( arguments, 1 ),
10298		inputIndex = 0,
10299		inputLength = input.length,
10300		key,
10301		value;
10302	for ( ; inputIndex < inputLength; inputIndex++ ) {
10303		for ( key in input[ inputIndex ] ) {
10304			value = input[ inputIndex ][ key ];
10305			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
10306				// Clone objects
10307				if ( $.isPlainObject( value ) ) {
10308					target[ key ] = $.isPlainObject( target[ key ] ) ?
10309						$.widget.extend( {}, target[ key ], value ) :
10310						// Don't extend strings, arrays, etc. with objects
10311						$.widget.extend( {}, value );
10312				// Copy everything else by reference
10313				} else {
10314					target[ key ] = value;
10315				}
10316			}
10317		}
10318	}
10319	return target;
10320};
10321
10322$.widget.bridge = function( name, object ) {
10323	var fullName = object.prototype.widgetFullName || name;
10324	$.fn[ name ] = function( options ) {
10325		var isMethodCall = typeof options === "string",
10326			args = widget_slice.call( arguments, 1 ),
10327			returnValue = this;
10328
10329		if ( isMethodCall ) {
10330			this.each(function() {
10331				var methodValue,
10332					instance = $.data( this, fullName );
10333				if ( options === "instance" ) {
10334					returnValue = instance;
10335					return false;
10336				}
10337				if ( !instance ) {
10338					return $.error( "cannot call methods on " + name + " prior to initialization; " +
10339						"attempted to call method '" + options + "'" );
10340				}
10341				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
10342					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
10343				}
10344				methodValue = instance[ options ].apply( instance, args );
10345				if ( methodValue !== instance && methodValue !== undefined ) {
10346					returnValue = methodValue && methodValue.jquery ?
10347						returnValue.pushStack( methodValue.get() ) :
10348						methodValue;
10349					return false;
10350				}
10351			});
10352		} else {
10353
10354			// Allow multiple hashes to be passed on init
10355			if ( args.length ) {
10356				options = $.widget.extend.apply( null, [ options ].concat(args) );
10357			}
10358
10359			this.each(function() {
10360				var instance = $.data( this, fullName );
10361				if ( instance ) {
10362					instance.option( options || {} );
10363					if ( instance._init ) {
10364						instance._init();
10365					}
10366				} else {
10367					$.data( this, fullName, new object( options, this ) );
10368				}
10369			});
10370		}
10371
10372		return returnValue;
10373	};
10374};
10375
10376$.Widget = function( /* options, element */ ) {};
10377$.Widget._childConstructors = [];
10378
10379$.Widget.prototype = {
10380	widgetName: "widget",
10381	widgetEventPrefix: "",
10382	defaultElement: "<div>",
10383	options: {
10384		disabled: false,
10385
10386		// callbacks
10387		create: null
10388	},
10389	_createWidget: function( options, element ) {
10390		element = $( element || this.defaultElement || this )[ 0 ];
10391		this.element = $( element );
10392		this.uuid = widget_uuid++;
10393		this.eventNamespace = "." + this.widgetName + this.uuid;
10394
10395		this.bindings = $();
10396		this.hoverable = $();
10397		this.focusable = $();
10398
10399		if ( element !== this ) {
10400			$.data( element, this.widgetFullName, this );
10401			this._on( true, this.element, {
10402				remove: function( event ) {
10403					if ( event.target === element ) {
10404						this.destroy();
10405					}
10406				}
10407			});
10408			this.document = $( element.style ?
10409				// element within the document
10410				element.ownerDocument :
10411				// element is window or document
10412				element.document || element );
10413			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
10414		}
10415
10416		this.options = $.widget.extend( {},
10417			this.options,
10418			this._getCreateOptions(),
10419			options );
10420
10421		this._create();
10422		this._trigger( "create", null, this._getCreateEventData() );
10423		this._init();
10424	},
10425	_getCreateOptions: $.noop,
10426	_getCreateEventData: $.noop,
10427	_create: $.noop,
10428	_init: $.noop,
10429
10430	destroy: function() {
10431		this._destroy();
10432		// we can probably remove the unbind calls in 2.0
10433		// all event bindings should go through this._on()
10434		this.element
10435			.unbind( this.eventNamespace )
10436			.removeData( this.widgetFullName )
10437			// support: jquery <1.6.3
10438			// http://bugs.jquery.com/ticket/9413
10439			.removeData( $.camelCase( this.widgetFullName ) );
10440		this.widget()
10441			.unbind( this.eventNamespace )
10442			.removeAttr( "aria-disabled" )
10443			.removeClass(
10444				this.widgetFullName + "-disabled " +
10445				"ui-state-disabled" );
10446
10447		// clean up events and states
10448		this.bindings.unbind( this.eventNamespace );
10449		this.hoverable.removeClass( "ui-state-hover" );
10450		this.focusable.removeClass( "ui-state-focus" );
10451	},
10452	_destroy: $.noop,
10453
10454	widget: function() {
10455		return this.element;
10456	},
10457
10458	option: function( key, value ) {
10459		var options = key,
10460			parts,
10461			curOption,
10462			i;
10463
10464		if ( arguments.length === 0 ) {
10465			// don't return a reference to the internal hash
10466			return $.widget.extend( {}, this.options );
10467		}
10468
10469		if ( typeof key === "string" ) {
10470			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
10471			options = {};
10472			parts = key.split( "." );
10473			key = parts.shift();
10474			if ( parts.length ) {
10475				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
10476				for ( i = 0; i < parts.length - 1; i++ ) {
10477					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
10478					curOption = curOption[ parts[ i ] ];
10479				}
10480				key = parts.pop();
10481				if ( arguments.length === 1 ) {
10482					return curOption[ key ] === undefined ? null : curOption[ key ];
10483				}
10484				curOption[ key ] = value;
10485			} else {
10486				if ( arguments.length === 1 ) {
10487					return this.options[ key ] === undefined ? null : this.options[ key ];
10488				}
10489				options[ key ] = value;
10490			}
10491		}
10492
10493		this._setOptions( options );
10494
10495		return this;
10496	},
10497	_setOptions: function( options ) {
10498		var key;
10499
10500		for ( key in options ) {
10501			this._setOption( key, options[ key ] );
10502		}
10503
10504		return this;
10505	},
10506	_setOption: function( key, value ) {
10507		this.options[ key ] = value;
10508
10509		if ( key === "disabled" ) {
10510			this.widget()
10511				.toggleClass( this.widgetFullName + "-disabled", !!value );
10512
10513			// If the widget is becoming disabled, then nothing is interactive
10514			if ( value ) {
10515				this.hoverable.removeClass( "ui-state-hover" );
10516				this.focusable.removeClass( "ui-state-focus" );
10517			}
10518		}
10519
10520		return this;
10521	},
10522
10523	enable: function() {
10524		return this._setOptions({ disabled: false });
10525	},
10526	disable: function() {
10527		return this._setOptions({ disabled: true });
10528	},
10529
10530	_on: function( suppressDisabledCheck, element, handlers ) {
10531		var delegateElement,
10532			instance = this;
10533
10534		// no suppressDisabledCheck flag, shuffle arguments
10535		if ( typeof suppressDisabledCheck !== "boolean" ) {
10536			handlers = element;
10537			element = suppressDisabledCheck;
10538			suppressDisabledCheck = false;
10539		}
10540
10541		// no element argument, shuffle and use this.element
10542		if ( !handlers ) {
10543			handlers = element;
10544			element = this.element;
10545			delegateElement = this.widget();
10546		} else {
10547			element = delegateElement = $( element );
10548			this.bindings = this.bindings.add( element );
10549		}
10550
10551		$.each( handlers, function( event, handler ) {
10552			function handlerProxy() {
10553				// allow widgets to customize the disabled handling
10554				// - disabled as an array instead of boolean
10555				// - disabled class as method for disabling individual parts
10556				if ( !suppressDisabledCheck &&
10557						( instance.options.disabled === true ||
10558							$( this ).hasClass( "ui-state-disabled" ) ) ) {
10559					return;
10560				}
10561				return ( typeof handler === "string" ? instance[ handler ] : handler )
10562					.apply( instance, arguments );
10563			}
10564
10565			// copy the guid so direct unbinding works
10566			if ( typeof handler !== "string" ) {
10567				handlerProxy.guid = handler.guid =
10568					handler.guid || handlerProxy.guid || $.guid++;
10569			}
10570
10571			var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
10572				eventName = match[1] + instance.eventNamespace,
10573				selector = match[2];
10574			if ( selector ) {
10575				delegateElement.delegate( selector, eventName, handlerProxy );
10576			} else {
10577				element.bind( eventName, handlerProxy );
10578			}
10579		});
10580	},
10581
10582	_off: function( element, eventName ) {
10583		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
10584			this.eventNamespace;
10585		element.unbind( eventName ).undelegate( eventName );
10586
10587		// Clear the stack to avoid memory leaks (#10056)
10588		this.bindings = $( this.bindings.not( element ).get() );
10589		this.focusable = $( this.focusable.not( element ).get() );
10590		this.hoverable = $( this.hoverable.not( element ).get() );
10591	},
10592
10593	_delay: function( handler, delay ) {
10594		function handlerProxy() {
10595			return ( typeof handler === "string" ? instance[ handler ] : handler )
10596				.apply( instance, arguments );
10597		}
10598		var instance = this;
10599		return setTimeout( handlerProxy, delay || 0 );
10600	},
10601
10602	_hoverable: function( element ) {
10603		this.hoverable = this.hoverable.add( element );
10604		this._on( element, {
10605			mouseenter: function( event ) {
10606				$( event.currentTarget ).addClass( "ui-state-hover" );
10607			},
10608			mouseleave: function( event ) {
10609				$( event.currentTarget ).removeClass( "ui-state-hover" );
10610			}
10611		});
10612	},
10613
10614	_focusable: function( element ) {
10615		this.focusable = this.focusable.add( element );
10616		this._on( element, {
10617			focusin: function( event ) {
10618				$( event.currentTarget ).addClass( "ui-state-focus" );
10619			},
10620			focusout: function( event ) {
10621				$( event.currentTarget ).removeClass( "ui-state-focus" );
10622			}
10623		});
10624	},
10625
10626	_trigger: function( type, event, data ) {
10627		var prop, orig,
10628			callback = this.options[ type ];
10629
10630		data = data || {};
10631		event = $.Event( event );
10632		event.type = ( type === this.widgetEventPrefix ?
10633			type :
10634			this.widgetEventPrefix + type ).toLowerCase();
10635		// the original event may come from any element
10636		// so we need to reset the target on the new event
10637		event.target = this.element[ 0 ];
10638
10639		// copy original event properties over to the new event
10640		orig = event.originalEvent;
10641		if ( orig ) {
10642			for ( prop in orig ) {
10643				if ( !( prop in event ) ) {
10644					event[ prop ] = orig[ prop ];
10645				}
10646			}
10647		}
10648
10649		this.element.trigger( event, data );
10650		return !( $.isFunction( callback ) &&
10651			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
10652			event.isDefaultPrevented() );
10653	}
10654};
10655
10656$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
10657	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
10658		if ( typeof options === "string" ) {
10659			options = { effect: options };
10660		}
10661		var hasOptions,
10662			effectName = !options ?
10663				method :
10664				options === true || typeof options === "number" ?
10665					defaultEffect :
10666					options.effect || defaultEffect;
10667		options = options || {};
10668		if ( typeof options === "number" ) {
10669			options = { duration: options };
10670		}
10671		hasOptions = !$.isEmptyObject( options );
10672		options.complete = callback;
10673		if ( options.delay ) {
10674			element.delay( options.delay );
10675		}
10676		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
10677			element[ method ]( options );
10678		} else if ( effectName !== method && element[ effectName ] ) {
10679			element[ effectName ]( options.duration, options.easing, callback );
10680		} else {
10681			element.queue(function( next ) {
10682				$( this )[ method ]();
10683				if ( callback ) {
10684					callback.call( element[ 0 ] );
10685				}
10686				next();
10687			});
10688		}
10689	};
10690});
10691
10692var widget = $.widget;
10693
10694
10695/*!
10696 * jQuery UI Mouse 1.11.4
10697 * http://jqueryui.com
10698 *
10699 * Copyright jQuery Foundation and other contributors
10700 * Released under the MIT license.
10701 * http://jquery.org/license
10702 *
10703 * http://api.jqueryui.com/mouse/
10704 */
10705
10706
10707var mouseHandled = false;
10708$( document ).mouseup( function() {
10709	mouseHandled = false;
10710});
10711
10712var mouse = $.widget("ui.mouse", {
10713	version: "1.11.4",
10714	options: {
10715		cancel: "input,textarea,button,select,option",
10716		distance: 1,
10717		delay: 0
10718	},
10719	_mouseInit: function() {
10720		var that = this;
10721
10722		this.element
10723			.bind("mousedown." + this.widgetName, function(event) {
10724				return that._mouseDown(event);
10725			})
10726			.bind("click." + this.widgetName, function(event) {
10727				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
10728					$.removeData(event.target, that.widgetName + ".preventClickEvent");
10729					event.stopImmediatePropagation();
10730					return false;
10731				}
10732			});
10733
10734		this.started = false;
10735	},
10736
10737	// TODO: make sure destroying one instance of mouse doesn't mess with
10738	// other instances of mouse
10739	_mouseDestroy: function() {
10740		this.element.unbind("." + this.widgetName);
10741		if ( this._mouseMoveDelegate ) {
10742			this.document
10743				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
10744				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
10745		}
10746	},
10747
10748	_mouseDown: function(event) {
10749		// don't let more than one widget handle mouseStart
10750		if ( mouseHandled ) {
10751			return;
10752		}
10753
10754		this._mouseMoved = false;
10755
10756		// we may have missed mouseup (out of window)
10757		(this._mouseStarted && this._mouseUp(event));
10758
10759		this._mouseDownEvent = event;
10760
10761		var that = this,
10762			btnIsLeft = (event.which === 1),
10763			// event.target.nodeName works around a bug in IE 8 with
10764			// disabled inputs (#7620)
10765			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
10766		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
10767			return true;
10768		}
10769
10770		this.mouseDelayMet = !this.options.delay;
10771		if (!this.mouseDelayMet) {
10772			this._mouseDelayTimer = setTimeout(function() {
10773				that.mouseDelayMet = true;
10774			}, this.options.delay);
10775		}
10776
10777		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10778			this._mouseStarted = (this._mouseStart(event) !== false);
10779			if (!this._mouseStarted) {
10780				event.preventDefault();
10781				return true;
10782			}
10783		}
10784
10785		// Click event may never have fired (Gecko & Opera)
10786		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
10787			$.removeData(event.target, this.widgetName + ".preventClickEvent");
10788		}
10789
10790		// these delegates are required to keep context
10791		this._mouseMoveDelegate = function(event) {
10792			return that._mouseMove(event);
10793		};
10794		this._mouseUpDelegate = function(event) {
10795			return that._mouseUp(event);
10796		};
10797
10798		this.document
10799			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
10800			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );
10801
10802		event.preventDefault();
10803
10804		mouseHandled = true;
10805		return true;
10806	},
10807
10808	_mouseMove: function(event) {
10809		// Only check for mouseups outside the document if you've moved inside the document
10810		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
10811		// fire a mousemove event if content is placed under the cursor. See #7778
10812		// Support: IE <9
10813		if ( this._mouseMoved ) {
10814			// IE mouseup check - mouseup happened when mouse was out of window
10815			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
10816				return this._mouseUp(event);
10817
10818			// Iframe mouseup check - mouseup occurred in another document
10819			} else if ( !event.which ) {
10820				return this._mouseUp( event );
10821			}
10822		}
10823
10824		if ( event.which || event.button ) {
10825			this._mouseMoved = true;
10826		}
10827
10828		if (this._mouseStarted) {
10829			this._mouseDrag(event);
10830			return event.preventDefault();
10831		}
10832
10833		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
10834			this._mouseStarted =
10835				(this._mouseStart(this._mouseDownEvent, event) !== false);
10836			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
10837		}
10838
10839		return !this._mouseStarted;
10840	},
10841
10842	_mouseUp: function(event) {
10843		this.document
10844			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
10845			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );
10846
10847		if (this._mouseStarted) {
10848			this._mouseStarted = false;
10849
10850			if (event.target === this._mouseDownEvent.target) {
10851				$.data(event.target, this.widgetName + ".preventClickEvent", true);
10852			}
10853
10854			this._mouseStop(event);
10855		}
10856
10857		mouseHandled = false;
10858		return false;
10859	},
10860
10861	_mouseDistanceMet: function(event) {
10862		return (Math.max(
10863				Math.abs(this._mouseDownEvent.pageX - event.pageX),
10864				Math.abs(this._mouseDownEvent.pageY - event.pageY)
10865			) >= this.options.distance
10866		);
10867	},
10868
10869	_mouseDelayMet: function(/* event */) {
10870		return this.mouseDelayMet;
10871	},
10872
10873	// These are placeholder methods, to be overriden by extending plugin
10874	_mouseStart: function(/* event */) {},
10875	_mouseDrag: function(/* event */) {},
10876	_mouseStop: function(/* event */) {},
10877	_mouseCapture: function(/* event */) { return true; }
10878});
10879
10880
10881/*!
10882 * jQuery UI Position 1.11.4
10883 * http://jqueryui.com
10884 *
10885 * Copyright jQuery Foundation and other contributors
10886 * Released under the MIT license.
10887 * http://jquery.org/license
10888 *
10889 * http://api.jqueryui.com/position/
10890 */
10891
10892(function() {
10893
10894$.ui = $.ui || {};
10895
10896var cachedScrollbarWidth, supportsOffsetFractions,
10897	max = Math.max,
10898	abs = Math.abs,
10899	round = Math.round,
10900	rhorizontal = /left|center|right/,
10901	rvertical = /top|center|bottom/,
10902	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
10903	rposition = /^\w+/,
10904	rpercent = /%$/,
10905	_position = $.fn.position;
10906
10907function getOffsets( offsets, width, height ) {
10908	return [
10909		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
10910		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
10911	];
10912}
10913
10914function parseCss( element, property ) {
10915	return parseInt( $.css( element, property ), 10 ) || 0;
10916}
10917
10918function getDimensions( elem ) {
10919	var raw = elem[0];
10920	if ( raw.nodeType === 9 ) {
10921		return {
10922			width: elem.width(),
10923			height: elem.height(),
10924			offset: { top: 0, left: 0 }
10925		};
10926	}
10927	if ( $.isWindow( raw ) ) {
10928		return {
10929			width: elem.width(),
10930			height: elem.height(),
10931			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
10932		};
10933	}
10934	if ( raw.preventDefault ) {
10935		return {
10936			width: 0,
10937			height: 0,
10938			offset: { top: raw.pageY, left: raw.pageX }
10939		};
10940	}
10941	return {
10942		width: elem.outerWidth(),
10943		height: elem.outerHeight(),
10944		offset: elem.offset()
10945	};
10946}
10947
10948$.position = {
10949	scrollbarWidth: function() {
10950		if ( cachedScrollbarWidth !== undefined ) {
10951			return cachedScrollbarWidth;
10952		}
10953		var w1, w2,
10954			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
10955			innerDiv = div.children()[0];
10956
10957		$( "body" ).append( div );
10958		w1 = innerDiv.offsetWidth;
10959		div.css( "overflow", "scroll" );
10960
10961		w2 = innerDiv.offsetWidth;
10962
10963		if ( w1 === w2 ) {
10964			w2 = div[0].clientWidth;
10965		}
10966
10967		div.remove();
10968
10969		return (cachedScrollbarWidth = w1 - w2);
10970	},
10971	getScrollInfo: function( within ) {
10972		var overflowX = within.isWindow || within.isDocument ? "" :
10973				within.element.css( "overflow-x" ),
10974			overflowY = within.isWindow || within.isDocument ? "" :
10975				within.element.css( "overflow-y" ),
10976			hasOverflowX = overflowX === "scroll" ||
10977				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
10978			hasOverflowY = overflowY === "scroll" ||
10979				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
10980		return {
10981			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
10982			height: hasOverflowX ? $.position.scrollbarWidth() : 0
10983		};
10984	},
10985	getWithinInfo: function( element ) {
10986		var withinElement = $( element || window ),
10987			isWindow = $.isWindow( withinElement[0] ),
10988			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
10989		return {
10990			element: withinElement,
10991			isWindow: isWindow,
10992			isDocument: isDocument,
10993			offset: withinElement.offset() || { left: 0, top: 0 },
10994			scrollLeft: withinElement.scrollLeft(),
10995			scrollTop: withinElement.scrollTop(),
10996
10997			// support: jQuery 1.6.x
10998			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
10999			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
11000			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
11001		};
11002	}
11003};
11004
11005$.fn.position = function( options ) {
11006	if ( !options || !options.of ) {
11007		return _position.apply( this, arguments );
11008	}
11009
11010	// make a copy, we don't want to modify arguments
11011	options = $.extend( {}, options );
11012
11013	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
11014		target = $( options.of ),
11015		within = $.position.getWithinInfo( options.within ),
11016		scrollInfo = $.position.getScrollInfo( within ),
11017		collision = ( options.collision || "flip" ).split( " " ),
11018		offsets = {};
11019
11020	dimensions = getDimensions( target );
11021	if ( target[0].preventDefault ) {
11022		// force left top to allow flipping
11023		options.at = "left top";
11024	}
11025	targetWidth = dimensions.width;
11026	targetHeight = dimensions.height;
11027	targetOffset = dimensions.offset;
11028	// clone to reuse original targetOffset later
11029	basePosition = $.extend( {}, targetOffset );
11030
11031	// force my and at to have valid horizontal and vertical positions
11032	// if a value is missing or invalid, it will be converted to center
11033	$.each( [ "my", "at" ], function() {
11034		var pos = ( options[ this ] || "" ).split( " " ),
11035			horizontalOffset,
11036			verticalOffset;
11037
11038		if ( pos.length === 1) {
11039			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 4,791 bytes, lines 11040-11195
11040				pos.concat( [ "center" ] ) :
11041				rvertical.test( pos[ 0 ] ) ?
11042					[ "center" ].concat( pos ) :
11043					[ "center", "center" ];
11044		}
11045		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
11046		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
11047
11048		// calculate offsets
11049		horizontalOffset = roffset.exec( pos[ 0 ] );
11050		verticalOffset = roffset.exec( pos[ 1 ] );
11051		offsets[ this ] = [
11052			horizontalOffset ? horizontalOffset[ 0 ] : 0,
11053			verticalOffset ? verticalOffset[ 0 ] : 0
11054		];
11055
11056		// reduce to just the positions without the offsets
11057		options[ this ] = [
11058			rposition.exec( pos[ 0 ] )[ 0 ],
11059			rposition.exec( pos[ 1 ] )[ 0 ]
11060		];
11061	});
11062
11063	// normalize collision option
11064	if ( collision.length === 1 ) {
11065		collision[ 1 ] = collision[ 0 ];
11066	}
11067
11068	if ( options.at[ 0 ] === "right" ) {
11069		basePosition.left += targetWidth;
11070	} else if ( options.at[ 0 ] === "center" ) {
11071		basePosition.left += targetWidth / 2;
11072	}
11073
11074	if ( options.at[ 1 ] === "bottom" ) {
11075		basePosition.top += targetHeight;
11076	} else if ( options.at[ 1 ] === "center" ) {
11077		basePosition.top += targetHeight / 2;
11078	}
11079
11080	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
11081	basePosition.left += atOffset[ 0 ];
11082	basePosition.top += atOffset[ 1 ];
11083
11084	return this.each(function() {
11085		var collisionPosition, using,
11086			elem = $( this ),
11087			elemWidth = elem.outerWidth(),
11088			elemHeight = elem.outerHeight(),
11089			marginLeft = parseCss( this, "marginLeft" ),
11090			marginTop = parseCss( this, "marginTop" ),
11091			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
11092			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
11093			position = $.extend( {}, basePosition ),
11094			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
11095
11096		if ( options.my[ 0 ] === "right" ) {
11097			position.left -= elemWidth;
11098		} else if ( options.my[ 0 ] === "center" ) {
11099			position.left -= elemWidth / 2;
11100		}
11101
11102		if ( options.my[ 1 ] === "bottom" ) {
11103			position.top -= elemHeight;
11104		} else if ( options.my[ 1 ] === "center" ) {
11105			position.top -= elemHeight / 2;
11106		}
11107
11108		position.left += myOffset[ 0 ];
11109		position.top += myOffset[ 1 ];
11110
11111		// if the browser doesn't support fractions, then round for consistent results
11112		if ( !supportsOffsetFractions ) {
11113			position.left = round( position.left );
11114			position.top = round( position.top );
11115		}
11116
11117		collisionPosition = {
11118			marginLeft: marginLeft,
11119			marginTop: marginTop
11120		};
11121
11122		$.each( [ "left", "top" ], function( i, dir ) {
11123			if ( $.ui.position[ collision[ i ] ] ) {
11124				$.ui.position[ collision[ i ] ][ dir ]( position, {
11125					targetWidth: targetWidth,
11126					targetHeight: targetHeight,
11127					elemWidth: elemWidth,
11128					elemHeight: elemHeight,
11129					collisionPosition: collisionPosition,
11130					collisionWidth: collisionWidth,
11131					collisionHeight: collisionHeight,
11132					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
11133					my: options.my,
11134					at: options.at,
11135					within: within,
11136					elem: elem
11137				});
11138			}
11139		});
11140
11141		if ( options.using ) {
11142			// adds feedback as second argument to using callback, if present
11143			using = function( props ) {
11144				var left = targetOffset.left - position.left,
11145					right = left + targetWidth - elemWidth,
11146					top = targetOffset.top - position.top,
11147					bottom = top + targetHeight - elemHeight,
11148					feedback = {
11149						target: {
11150							element: target,
11151							left: targetOffset.left,
11152							top: targetOffset.top,
11153							width: targetWidth,
11154							height: targetHeight
11155						},
11156						element: {
11157							element: elem,
11158							left: position.left,
11159							top: position.top,
11160							width: elemWidth,
11161							height: elemHeight
11162						},
11163						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
11164						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
11165					};
11166				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
11167					feedback.horizontal = "center";
11168				}
11169				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
11170					feedback.vertical = "middle";
11171				}
11172				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
11173					feedback.important = "horizontal";
11174				} else {
11175					feedback.important = "vertical";
11176				}
11177				options.using.call( this, props, feedback );
11178			};
11179		}
11180
11181		elem.offset( $.extend( position, { using: using } ) );
11182	});
11183};
11184
11185$.ui.position = {
11186	fit: {
11187		left: function( position, data ) {
11188			var within = data.within,
11189				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
11190				outerWidth = within.width,
11191				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11192				overLeft = withinOffset - collisionPosLeft,
11193				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
11194				newOverRight;
11195
vendor: 7,320 bytes, lines 11196-11428
11196			// element is wider than within
11197			if ( data.collisionWidth > outerWidth ) {
11198				// element is initially over the left side of within
11199				if ( overLeft > 0 && overRight <= 0 ) {
11200					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
11201					position.left += overLeft - newOverRight;
11202				// element is initially over right side of within
11203				} else if ( overRight > 0 && overLeft <= 0 ) {
11204					position.left = withinOffset;
11205				// element is initially over both left and right sides of within
11206				} else {
11207					if ( overLeft > overRight ) {
11208						position.left = withinOffset + outerWidth - data.collisionWidth;
11209					} else {
11210						position.left = withinOffset;
11211					}
11212				}
11213			// too far left -> align with left edge
11214			} else if ( overLeft > 0 ) {
11215				position.left += overLeft;
11216			// too far right -> align with right edge
11217			} else if ( overRight > 0 ) {
11218				position.left -= overRight;
11219			// adjust based on position and margin
11220			} else {
11221				position.left = max( position.left - collisionPosLeft, position.left );
11222			}
11223		},
11224		top: function( position, data ) {
11225			var within = data.within,
11226				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
11227				outerHeight = data.within.height,
11228				collisionPosTop = position.top - data.collisionPosition.marginTop,
11229				overTop = withinOffset - collisionPosTop,
11230				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
11231				newOverBottom;
11232
11233			// element is taller than within
11234			if ( data.collisionHeight > outerHeight ) {
11235				// element is initially over the top of within
11236				if ( overTop > 0 && overBottom <= 0 ) {
11237					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
11238					position.top += overTop - newOverBottom;
11239				// element is initially over bottom of within
11240				} else if ( overBottom > 0 && overTop <= 0 ) {
11241					position.top = withinOffset;
11242				// element is initially over both top and bottom of within
11243				} else {
11244					if ( overTop > overBottom ) {
11245						position.top = withinOffset + outerHeight - data.collisionHeight;
11246					} else {
11247						position.top = withinOffset;
11248					}
11249				}
11250			// too far up -> align with top
11251			} else if ( overTop > 0 ) {
11252				position.top += overTop;
11253			// too far down -> align with bottom edge
11254			} else if ( overBottom > 0 ) {
11255				position.top -= overBottom;
11256			// adjust based on position and margin
11257			} else {
11258				position.top = max( position.top - collisionPosTop, position.top );
11259			}
11260		}
11261	},
11262	flip: {
11263		left: function( position, data ) {
11264			var within = data.within,
11265				withinOffset = within.offset.left + within.scrollLeft,
11266				outerWidth = within.width,
11267				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
11268				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
11269				overLeft = collisionPosLeft - offsetLeft,
11270				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
11271				myOffset = data.my[ 0 ] === "left" ?
11272					-data.elemWidth :
11273					data.my[ 0 ] === "right" ?
11274						data.elemWidth :
11275						0,
11276				atOffset = data.at[ 0 ] === "left" ?
11277					data.targetWidth :
11278					data.at[ 0 ] === "right" ?
11279						-data.targetWidth :
11280						0,
11281				offset = -2 * data.offset[ 0 ],
11282				newOverRight,
11283				newOverLeft;
11284
11285			if ( overLeft < 0 ) {
11286				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
11287				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
11288					position.left += myOffset + atOffset + offset;
11289				}
11290			} else if ( overRight > 0 ) {
11291				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
11292				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
11293					position.left += myOffset + atOffset + offset;
11294				}
11295			}
11296		},
11297		top: function( position, data ) {
11298			var within = data.within,
11299				withinOffset = within.offset.top + within.scrollTop,
11300				outerHeight = within.height,
11301				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
11302				collisionPosTop = position.top - data.collisionPosition.marginTop,
11303				overTop = collisionPosTop - offsetTop,
11304				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
11305				top = data.my[ 1 ] === "top",
11306				myOffset = top ?
11307					-data.elemHeight :
11308					data.my[ 1 ] === "bottom" ?
11309						data.elemHeight :
11310						0,
11311				atOffset = data.at[ 1 ] === "top" ?
11312					data.targetHeight :
11313					data.at[ 1 ] === "bottom" ?
11314						-data.targetHeight :
11315						0,
11316				offset = -2 * data.offset[ 1 ],
11317				newOverTop,
11318				newOverBottom;
11319			if ( overTop < 0 ) {
11320				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
11321				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
11322					position.top += myOffset + atOffset + offset;
11323				}
11324			} else if ( overBottom > 0 ) {
11325				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
11326				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
11327					position.top += myOffset + atOffset + offset;
11328				}
11329			}
11330		}
11331	},
11332	flipfit: {
11333		left: function() {
11334			$.ui.position.flip.left.apply( this, arguments );
11335			$.ui.position.fit.left.apply( this, arguments );
11336		},
11337		top: function() {
11338			$.ui.position.flip.top.apply( this, arguments );
11339			$.ui.position.fit.top.apply( this, arguments );
11340		}
11341	}
11342};
11343
11344// fraction support test
11345(function() {
11346	var testElement, testElementParent, testElementStyle, offsetLeft, i,
11347		body = document.getElementsByTagName( "body" )[ 0 ],
11348		div = document.createElement( "div" );
11349
11350	//Create a "fake body" for testing based on method used in jQuery.support
11351	testElement = document.createElement( body ? "div" : "body" );
11352	testElementStyle = {
11353		visibility: "hidden",
11354		width: 0,
11355		height: 0,
11356		border: 0,
11357		margin: 0,
11358		background: "none"
11359	};
11360	if ( body ) {
11361		$.extend( testElementStyle, {
11362			position: "absolute",
11363			left: "-1000px",
11364			top: "-1000px"
11365		});
11366	}
11367	for ( i in testElementStyle ) {
11368		testElement.style[ i ] = testElementStyle[ i ];
11369	}
11370	testElement.appendChild( div );
11371	testElementParent = body || document.documentElement;
11372	testElementParent.insertBefore( testElement, testElementParent.firstChild );
11373
11374	div.style.cssText = "position: absolute; left: 10.7432222px;";
11375
11376	offsetLeft = $( div ).offset().left;
11377	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
11378
11379	testElement.innerHTML = "";
11380	testElementParent.removeChild( testElement );
11381})();
11382
11383})();
11384
11385var position = $.ui.position;
11386
11387
11388/*!
11389 * jQuery UI Accordion 1.11.4
11390 * http://jqueryui.com
11391 *
11392 * Copyright jQuery Foundation and other contributors
11393 * Released under the MIT license.
11394 * http://jquery.org/license
11395 *
11396 * http://api.jqueryui.com/accordion/
11397 */
11398
11399
11400var accordion = $.widget( "ui.accordion", {
11401	version: "1.11.4",
11402	options: {
11403		active: 0,
11404		animate: {},
11405		collapsible: false,
11406		event: "click",
11407		header: "> li > :first-child,> :not(li):even",
11408		heightStyle: "auto",
11409		icons: {
11410			activeHeader: "ui-icon-triangle-1-s",
11411			header: "ui-icon-triangle-1-e"
11412		},
11413
11414		// callbacks
11415		activate: null,
11416		beforeActivate: null
11417	},
11418
11419	hideProps: {
11420		borderTopWidth: "hide",
11421		borderBottomWidth: "hide",
11422		paddingTop: "hide",
11423		paddingBottom: "hide",
11424		height: "hide"
11425	},
11426
11427	showProps: {
11428		borderTopWidth: "show",
vendor: 4,428 bytes, lines 11429-11605
11429		borderBottomWidth: "show",
11430		paddingTop: "show",
11431		paddingBottom: "show",
11432		height: "show"
11433	},
11434
11435	_create: function() {
11436		var options = this.options;
11437		this.prevShow = this.prevHide = $();
11438		this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
11439			// ARIA
11440			.attr( "role", "tablist" );
11441
11442		// don't allow collapsible: false and active: false / null
11443		if ( !options.collapsible && (options.active === false || options.active == null) ) {
11444			options.active = 0;
11445		}
11446
11447		this._processPanels();
11448		// handle negative values
11449		if ( options.active < 0 ) {
11450			options.active += this.headers.length;
11451		}
11452		this._refresh();
11453	},
11454
11455	_getCreateEventData: function() {
11456		return {
11457			header: this.active,
11458			panel: !this.active.length ? $() : this.active.next()
11459		};
11460	},
11461
11462	_createIcons: function() {
11463		var icons = this.options.icons;
11464		if ( icons ) {
11465			$( "<span>" )
11466				.addClass( "ui-accordion-header-icon ui-icon " + icons.header )
11467				.prependTo( this.headers );
11468			this.active.children( ".ui-accordion-header-icon" )
11469				.removeClass( icons.header )
11470				.addClass( icons.activeHeader );
11471			this.headers.addClass( "ui-accordion-icons" );
11472		}
11473	},
11474
11475	_destroyIcons: function() {
11476		this.headers
11477			.removeClass( "ui-accordion-icons" )
11478			.children( ".ui-accordion-header-icon" )
11479				.remove();
11480	},
11481
11482	_destroy: function() {
11483		var contents;
11484
11485		// clean up main element
11486		this.element
11487			.removeClass( "ui-accordion ui-widget ui-helper-reset" )
11488			.removeAttr( "role" );
11489
11490		// clean up headers
11491		this.headers
11492			.removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " +
11493				"ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
11494			.removeAttr( "role" )
11495			.removeAttr( "aria-expanded" )
11496			.removeAttr( "aria-selected" )
11497			.removeAttr( "aria-controls" )
11498			.removeAttr( "tabIndex" )
11499			.removeUniqueId();
11500
11501		this._destroyIcons();
11502
11503		// clean up content panels
11504		contents = this.headers.next()
11505			.removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " +
11506				"ui-accordion-content ui-accordion-content-active ui-state-disabled" )
11507			.css( "display", "" )
11508			.removeAttr( "role" )
11509			.removeAttr( "aria-hidden" )
11510			.removeAttr( "aria-labelledby" )
11511			.removeUniqueId();
11512
11513		if ( this.options.heightStyle !== "content" ) {
11514			contents.css( "height", "" );
11515		}
11516	},
11517
11518	_setOption: function( key, value ) {
11519		if ( key === "active" ) {
11520			// _activate() will handle invalid values and update this.options
11521			this._activate( value );
11522			return;
11523		}
11524
11525		if ( key === "event" ) {
11526			if ( this.options.event ) {
11527				this._off( this.headers, this.options.event );
11528			}
11529			this._setupEvents( value );
11530		}
11531
11532		this._super( key, value );
11533
11534		// setting collapsible: false while collapsed; open first panel
11535		if ( key === "collapsible" && !value && this.options.active === false ) {
11536			this._activate( 0 );
11537		}
11538
11539		if ( key === "icons" ) {
11540			this._destroyIcons();
11541			if ( value ) {
11542				this._createIcons();
11543			}
11544		}
11545
11546		// #5332 - opacity doesn't cascade to positioned elements in IE
11547		// so we need to add the disabled class to the headers and panels
11548		if ( key === "disabled" ) {
11549			this.element
11550				.toggleClass( "ui-state-disabled", !!value )
11551				.attr( "aria-disabled", value );
11552			this.headers.add( this.headers.next() )
11553				.toggleClass( "ui-state-disabled", !!value );
11554		}
11555	},
11556
11557	_keydown: function( event ) {
11558		if ( event.altKey || event.ctrlKey ) {
11559			return;
11560		}
11561
11562		var keyCode = $.ui.keyCode,
11563			length = this.headers.length,
11564			currentIndex = this.headers.index( event.target ),
11565			toFocus = false;
11566
11567		switch ( event.keyCode ) {
11568			case keyCode.RIGHT:
11569			case keyCode.DOWN:
11570				toFocus = this.headers[ ( currentIndex + 1 ) % length ];
11571				break;
11572			case keyCode.LEFT:
11573			case keyCode.UP:
11574				toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
11575				break;
11576			case keyCode.SPACE:
11577			case keyCode.ENTER:
11578				this._eventHandler( event );
11579				break;
11580			case keyCode.HOME:
11581				toFocus = this.headers[ 0 ];
11582				break;
11583			case keyCode.END:
11584				toFocus = this.headers[ length - 1 ];
11585				break;
11586		}
11587
11588		if ( toFocus ) {
11589			$( event.target ).attr( "tabIndex", -1 );
11590			$( toFocus ).attr( "tabIndex", 0 );
11591			toFocus.focus();
11592			event.preventDefault();
11593		}
11594	},
11595
11596	_panelKeyDown: function( event ) {
11597		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
11598			$( event.currentTarget ).prev().focus();
11599		}
11600	},
11601
11602	refresh: function() {
11603		var options = this.options;
11604		this._processPanels();
11605
vendor: 17,411 bytes, lines 11606-12258
11606		// was collapsed or no panel
11607		if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
11608			options.active = false;
11609			this.active = $();
11610		// active false only when collapsible is true
11611		} else if ( options.active === false ) {
11612			this._activate( 0 );
11613		// was active, but active panel is gone
11614		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11615			// all remaining panel are disabled
11616			if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
11617				options.active = false;
11618				this.active = $();
11619			// activate previous panel
11620			} else {
11621				this._activate( Math.max( 0, options.active - 1 ) );
11622			}
11623		// was active, active panel still exists
11624		} else {
11625			// make sure active index is correct
11626			options.active = this.headers.index( this.active );
11627		}
11628
11629		this._destroyIcons();
11630
11631		this._refresh();
11632	},
11633
11634	_processPanels: function() {
11635		var prevHeaders = this.headers,
11636			prevPanels = this.panels;
11637
11638		this.headers = this.element.find( this.options.header )
11639			.addClass( "ui-accordion-header ui-state-default ui-corner-all" );
11640
11641		this.panels = this.headers.next()
11642			.addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
11643			.filter( ":not(.ui-accordion-content-active)" )
11644			.hide();
11645
11646		// Avoid memory leaks (#10056)
11647		if ( prevPanels ) {
11648			this._off( prevHeaders.not( this.headers ) );
11649			this._off( prevPanels.not( this.panels ) );
11650		}
11651	},
11652
11653	_refresh: function() {
11654		var maxHeight,
11655			options = this.options,
11656			heightStyle = options.heightStyle,
11657			parent = this.element.parent();
11658
11659		this.active = this._findActive( options.active )
11660			.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
11661			.removeClass( "ui-corner-all" );
11662		this.active.next()
11663			.addClass( "ui-accordion-content-active" )
11664			.show();
11665
11666		this.headers
11667			.attr( "role", "tab" )
11668			.each(function() {
11669				var header = $( this ),
11670					headerId = header.uniqueId().attr( "id" ),
11671					panel = header.next(),
11672					panelId = panel.uniqueId().attr( "id" );
11673				header.attr( "aria-controls", panelId );
11674				panel.attr( "aria-labelledby", headerId );
11675			})
11676			.next()
11677				.attr( "role", "tabpanel" );
11678
11679		this.headers
11680			.not( this.active )
11681			.attr({
11682				"aria-selected": "false",
11683				"aria-expanded": "false",
11684				tabIndex: -1
11685			})
11686			.next()
11687				.attr({
11688					"aria-hidden": "true"
11689				})
11690				.hide();
11691
11692		// make sure at least one header is in the tab order
11693		if ( !this.active.length ) {
11694			this.headers.eq( 0 ).attr( "tabIndex", 0 );
11695		} else {
11696			this.active.attr({
11697				"aria-selected": "true",
11698				"aria-expanded": "true",
11699				tabIndex: 0
11700			})
11701			.next()
11702				.attr({
11703					"aria-hidden": "false"
11704				});
11705		}
11706
11707		this._createIcons();
11708
11709		this._setupEvents( options.event );
11710
11711		if ( heightStyle === "fill" ) {
11712			maxHeight = parent.height();
11713			this.element.siblings( ":visible" ).each(function() {
11714				var elem = $( this ),
11715					position = elem.css( "position" );
11716
11717				if ( position === "absolute" || position === "fixed" ) {
11718					return;
11719				}
11720				maxHeight -= elem.outerHeight( true );
11721			});
11722
11723			this.headers.each(function() {
11724				maxHeight -= $( this ).outerHeight( true );
11725			});
11726
11727			this.headers.next()
11728				.each(function() {
11729					$( this ).height( Math.max( 0, maxHeight -
11730						$( this ).innerHeight() + $( this ).height() ) );
11731				})
11732				.css( "overflow", "auto" );
11733		} else if ( heightStyle === "auto" ) {
11734			maxHeight = 0;
11735			this.headers.next()
11736				.each(function() {
11737					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
11738				})
11739				.height( maxHeight );
11740		}
11741	},
11742
11743	_activate: function( index ) {
11744		var active = this._findActive( index )[ 0 ];
11745
11746		// trying to activate the already active panel
11747		if ( active === this.active[ 0 ] ) {
11748			return;
11749		}
11750
11751		// trying to collapse, simulate a click on the currently active header
11752		active = active || this.active[ 0 ];
11753
11754		this._eventHandler({
11755			target: active,
11756			currentTarget: active,
11757			preventDefault: $.noop
11758		});
11759	},
11760
11761	_findActive: function( selector ) {
11762		return typeof selector === "number" ? this.headers.eq( selector ) : $();
11763	},
11764
11765	_setupEvents: function( event ) {
11766		var events = {
11767			keydown: "_keydown"
11768		};
11769		if ( event ) {
11770			$.each( event.split( " " ), function( index, eventName ) {
11771				events[ eventName ] = "_eventHandler";
11772			});
11773		}
11774
11775		this._off( this.headers.add( this.headers.next() ) );
11776		this._on( this.headers, events );
11777		this._on( this.headers.next(), { keydown: "_panelKeyDown" });
11778		this._hoverable( this.headers );
11779		this._focusable( this.headers );
11780	},
11781
11782	_eventHandler: function( event ) {
11783		var options = this.options,
11784			active = this.active,
11785			clicked = $( event.currentTarget ),
11786			clickedIsActive = clicked[ 0 ] === active[ 0 ],
11787			collapsing = clickedIsActive && options.collapsible,
11788			toShow = collapsing ? $() : clicked.next(),
11789			toHide = active.next(),
11790			eventData = {
11791				oldHeader: active,
11792				oldPanel: toHide,
11793				newHeader: collapsing ? $() : clicked,
11794				newPanel: toShow
11795			};
11796
11797		event.preventDefault();
11798
11799		if (
11800				// click on active header, but not collapsible
11801				( clickedIsActive && !options.collapsible ) ||
11802				// allow canceling activation
11803				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
11804			return;
11805		}
11806
11807		options.active = collapsing ? false : this.headers.index( clicked );
11808
11809		// when the call to ._toggle() comes after the class changes
11810		// it causes a very odd bug in IE 8 (see #6720)
11811		this.active = clickedIsActive ? $() : clicked;
11812		this._toggle( eventData );
11813
11814		// switch classes
11815		// corner classes on the previously active header stay after the animation
11816		active.removeClass( "ui-accordion-header-active ui-state-active" );
11817		if ( options.icons ) {
11818			active.children( ".ui-accordion-header-icon" )
11819				.removeClass( options.icons.activeHeader )
11820				.addClass( options.icons.header );
11821		}
11822
11823		if ( !clickedIsActive ) {
11824			clicked
11825				.removeClass( "ui-corner-all" )
11826				.addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
11827			if ( options.icons ) {
11828				clicked.children( ".ui-accordion-header-icon" )
11829					.removeClass( options.icons.header )
11830					.addClass( options.icons.activeHeader );
11831			}
11832
11833			clicked
11834				.next()
11835				.addClass( "ui-accordion-content-active" );
11836		}
11837	},
11838
11839	_toggle: function( data ) {
11840		var toShow = data.newPanel,
11841			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
11842
11843		// handle activating a panel during the animation for another activation
11844		this.prevShow.add( this.prevHide ).stop( true, true );
11845		this.prevShow = toShow;
11846		this.prevHide = toHide;
11847
11848		if ( this.options.animate ) {
11849			this._animate( toShow, toHide, data );
11850		} else {
11851			toHide.hide();
11852			toShow.show();
11853			this._toggleComplete( data );
11854		}
11855
11856		toHide.attr({
11857			"aria-hidden": "true"
11858		});
11859		toHide.prev().attr({
11860			"aria-selected": "false",
11861			"aria-expanded": "false"
11862		});
11863		// if we're switching panels, remove the old header from the tab order
11864		// if we're opening from collapsed state, remove the previous header from the tab order
11865		// if we're collapsing, then keep the collapsing header in the tab order
11866		if ( toShow.length && toHide.length ) {
11867			toHide.prev().attr({
11868				"tabIndex": -1,
11869				"aria-expanded": "false"
11870			});
11871		} else if ( toShow.length ) {
11872			this.headers.filter(function() {
11873				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
11874			})
11875			.attr( "tabIndex", -1 );
11876		}
11877
11878		toShow
11879			.attr( "aria-hidden", "false" )
11880			.prev()
11881				.attr({
11882					"aria-selected": "true",
11883					"aria-expanded": "true",
11884					tabIndex: 0
11885				});
11886	},
11887
11888	_animate: function( toShow, toHide, data ) {
11889		var total, easing, duration,
11890			that = this,
11891			adjust = 0,
11892			boxSizing = toShow.css( "box-sizing" ),
11893			down = toShow.length &&
11894				( !toHide.length || ( toShow.index() < toHide.index() ) ),
11895			animate = this.options.animate || {},
11896			options = down && animate.down || animate,
11897			complete = function() {
11898				that._toggleComplete( data );
11899			};
11900
11901		if ( typeof options === "number" ) {
11902			duration = options;
11903		}
11904		if ( typeof options === "string" ) {
11905			easing = options;
11906		}
11907		// fall back from options to animation in case of partial down settings
11908		easing = easing || options.easing || animate.easing;
11909		duration = duration || options.duration || animate.duration;
11910
11911		if ( !toHide.length ) {
11912			return toShow.animate( this.showProps, duration, easing, complete );
11913		}
11914		if ( !toShow.length ) {
11915			return toHide.animate( this.hideProps, duration, easing, complete );
11916		}
11917
11918		total = toShow.show().outerHeight();
11919		toHide.animate( this.hideProps, {
11920			duration: duration,
11921			easing: easing,
11922			step: function( now, fx ) {
11923				fx.now = Math.round( now );
11924			}
11925		});
11926		toShow
11927			.hide()
11928			.animate( this.showProps, {
11929				duration: duration,
11930				easing: easing,
11931				complete: complete,
11932				step: function( now, fx ) {
11933					fx.now = Math.round( now );
11934					if ( fx.prop !== "height" ) {
11935						if ( boxSizing === "content-box" ) {
11936							adjust += fx.now;
11937						}
11938					} else if ( that.options.heightStyle !== "content" ) {
11939						fx.now = Math.round( total - toHide.outerHeight() - adjust );
11940						adjust = 0;
11941					}
11942				}
11943			});
11944	},
11945
11946	_toggleComplete: function( data ) {
11947		var toHide = data.oldPanel;
11948
11949		toHide
11950			.removeClass( "ui-accordion-content-active" )
11951			.prev()
11952				.removeClass( "ui-corner-top" )
11953				.addClass( "ui-corner-all" );
11954
11955		// Work around for rendering bug in IE (#5421)
11956		if ( toHide.length ) {
11957			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
11958		}
11959		this._trigger( "activate", null, data );
11960	}
11961});
11962
11963
11964/*!
11965 * jQuery UI Menu 1.11.4
11966 * http://jqueryui.com
11967 *
11968 * Copyright jQuery Foundation and other contributors
11969 * Released under the MIT license.
11970 * http://jquery.org/license
11971 *
11972 * http://api.jqueryui.com/menu/
11973 */
11974
11975
11976var menu = $.widget( "ui.menu", {
11977	version: "1.11.4",
11978	defaultElement: "<ul>",
11979	delay: 300,
11980	options: {
11981		icons: {
11982			submenu: "ui-icon-carat-1-e"
11983		},
11984		items: "> *",
11985		menus: "ul",
11986		position: {
11987			my: "left-1 top",
11988			at: "right top"
11989		},
11990		role: "menu",
11991
11992		// callbacks
11993		blur: null,
11994		focus: null,
11995		select: null
11996	},
11997
11998	_create: function() {
11999		this.activeMenu = this.element;
12000
12001		// Flag used to prevent firing of the click handler
12002		// as the event bubbles up through nested menus
12003		this.mouseHandled = false;
12004		this.element
12005			.uniqueId()
12006			.addClass( "ui-menu ui-widget ui-widget-content" )
12007			.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
12008			.attr({
12009				role: this.options.role,
12010				tabIndex: 0
12011			});
12012
12013		if ( this.options.disabled ) {
12014			this.element
12015				.addClass( "ui-state-disabled" )
12016				.attr( "aria-disabled", "true" );
12017		}
12018
12019		this._on({
12020			// Prevent focus from sticking to links inside menu after clicking
12021			// them (focus should always stay on UL during navigation).
12022			"mousedown .ui-menu-item": function( event ) {
12023				event.preventDefault();
12024			},
12025			"click .ui-menu-item": function( event ) {
12026				var target = $( event.target );
12027				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
12028					this.select( event );
12029
12030					// Only set the mouseHandled flag if the event will bubble, see #9469.
12031					if ( !event.isPropagationStopped() ) {
12032						this.mouseHandled = true;
12033					}
12034
12035					// Open submenu on click
12036					if ( target.has( ".ui-menu" ).length ) {
12037						this.expand( event );
12038					} else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
12039
12040						// Redirect focus to the menu
12041						this.element.trigger( "focus", [ true ] );
12042
12043						// If the active item is on the top level, let it stay active.
12044						// Otherwise, blur the active item since it is no longer visible.
12045						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
12046							clearTimeout( this.timer );
12047						}
12048					}
12049				}
12050			},
12051			"mouseenter .ui-menu-item": function( event ) {
12052				// Ignore mouse events while typeahead is active, see #10458.
12053				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
12054				// is over an item in the menu
12055				if ( this.previousFilter ) {
12056					return;
12057				}
12058				var target = $( event.currentTarget );
12059				// Remove ui-state-active class from siblings of the newly focused menu item
12060				// to avoid a jump caused by adjacent elements both having a class with a border
12061				target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
12062				this.focus( event, target );
12063			},
12064			mouseleave: "collapseAll",
12065			"mouseleave .ui-menu": "collapseAll",
12066			focus: function( event, keepActiveItem ) {
12067				// If there's already an active item, keep it active
12068				// If not, activate the first item
12069				var item = this.active || this.element.find( this.options.items ).eq( 0 );
12070
12071				if ( !keepActiveItem ) {
12072					this.focus( event, item );
12073				}
12074			},
12075			blur: function( event ) {
12076				this._delay(function() {
12077					if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
12078						this.collapseAll( event );
12079					}
12080				});
12081			},
12082			keydown: "_keydown"
12083		});
12084
12085		this.refresh();
12086
12087		// Clicks outside of a menu collapse any open menus
12088		this._on( this.document, {
12089			click: function( event ) {
12090				if ( this._closeOnDocumentClick( event ) ) {
12091					this.collapseAll( event );
12092				}
12093
12094				// Reset the mouseHandled flag
12095				this.mouseHandled = false;
12096			}
12097		});
12098	},
12099
12100	_destroy: function() {
12101		// Destroy (sub)menus
12102		this.element
12103			.removeAttr( "aria-activedescendant" )
12104			.find( ".ui-menu" ).addBack()
12105				.removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
12106				.removeAttr( "role" )
12107				.removeAttr( "tabIndex" )
12108				.removeAttr( "aria-labelledby" )
12109				.removeAttr( "aria-expanded" )
12110				.removeAttr( "aria-hidden" )
12111				.removeAttr( "aria-disabled" )
12112				.removeUniqueId()
12113				.show();
12114
12115		// Destroy menu items
12116		this.element.find( ".ui-menu-item" )
12117			.removeClass( "ui-menu-item" )
12118			.removeAttr( "role" )
12119			.removeAttr( "aria-disabled" )
12120			.removeUniqueId()
12121			.removeClass( "ui-state-hover" )
12122			.removeAttr( "tabIndex" )
12123			.removeAttr( "role" )
12124			.removeAttr( "aria-haspopup" )
12125			.children().each( function() {
12126				var elem = $( this );
12127				if ( elem.data( "ui-menu-submenu-carat" ) ) {
12128					elem.remove();
12129				}
12130			});
12131
12132		// Destroy menu dividers
12133		this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
12134	},
12135
12136	_keydown: function( event ) {
12137		var match, prev, character, skip,
12138			preventDefault = true;
12139
12140		switch ( event.keyCode ) {
12141		case $.ui.keyCode.PAGE_UP:
12142			this.previousPage( event );
12143			break;
12144		case $.ui.keyCode.PAGE_DOWN:
12145			this.nextPage( event );
12146			break;
12147		case $.ui.keyCode.HOME:
12148			this._move( "first", "first", event );
12149			break;
12150		case $.ui.keyCode.END:
12151			this._move( "last", "last", event );
12152			break;
12153		case $.ui.keyCode.UP:
12154			this.previous( event );
12155			break;
12156		case $.ui.keyCode.DOWN:
12157			this.next( event );
12158			break;
12159		case $.ui.keyCode.LEFT:
12160			this.collapse( event );
12161			break;
12162		case $.ui.keyCode.RIGHT:
12163			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
12164				this.expand( event );
12165			}
12166			break;
12167		case $.ui.keyCode.ENTER:
12168		case $.ui.keyCode.SPACE:
12169			this._activate( event );
12170			break;
12171		case $.ui.keyCode.ESCAPE:
12172			this.collapse( event );
12173			break;
12174		default:
12175			preventDefault = false;
12176			prev = this.previousFilter || "";
12177			character = String.fromCharCode( event.keyCode );
12178			skip = false;
12179
12180			clearTimeout( this.filterTimer );
12181
12182			if ( character === prev ) {
12183				skip = true;
12184			} else {
12185				character = prev + character;
12186			}
12187
12188			match = this._filterMenuItems( character );
12189			match = skip && match.index( this.active.next() ) !== -1 ?
12190				this.active.nextAll( ".ui-menu-item" ) :
12191				match;
12192
12193			// If no matches on the current filter, reset to the last character pressed
12194			// to move down the menu to the first item that starts with that character
12195			if ( !match.length ) {
12196				character = String.fromCharCode( event.keyCode );
12197				match = this._filterMenuItems( character );
12198			}
12199
12200			if ( match.length ) {
12201				this.focus( event, match );
12202				this.previousFilter = character;
12203				this.filterTimer = this._delay(function() {
12204					delete this.previousFilter;
12205				}, 1000 );
12206			} else {
12207				delete this.previousFilter;
12208			}
12209		}
12210
12211		if ( preventDefault ) {
12212			event.preventDefault();
12213		}
12214	},
12215
12216	_activate: function( event ) {
12217		if ( !this.active.is( ".ui-state-disabled" ) ) {
12218			if ( this.active.is( "[aria-haspopup='true']" ) ) {
12219				this.expand( event );
12220			} else {
12221				this.select( event );
12222			}
12223		}
12224	},
12225
12226	refresh: function() {
12227		var menus, items,
12228			that = this,
12229			icon = this.options.icons.submenu,
12230			submenus = this.element.find( this.options.menus );
12231
12232		this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
12233
12234		// Initialize nested menus
12235		submenus.filter( ":not(.ui-menu)" )
12236			.addClass( "ui-menu ui-widget ui-widget-content ui-front" )
12237			.hide()
12238			.attr({
12239				role: this.options.role,
12240				"aria-hidden": "true",
12241				"aria-expanded": "false"
12242			})
12243			.each(function() {
12244				var menu = $( this ),
12245					item = menu.parent(),
12246					submenuCarat = $( "<span>" )
12247						.addClass( "ui-menu-icon ui-icon " + icon )
12248						.data( "ui-menu-submenu-carat", true );
12249
12250				item
12251					.attr( "aria-haspopup", "true" )
12252					.prepend( submenuCarat );
12253				menu.attr( "aria-labelledby", item.attr( "id" ) );
12254			});
12255
12256		menus = submenus.add( this.element );
12257		items = menus.find( this.options.items );
12258
vendor: 4,109 bytes, lines 12259-12410
12259		// Initialize menu-items containing spaces and/or dashes only as dividers
12260		items.not( ".ui-menu-item" ).each(function() {
12261			var item = $( this );
12262			if ( that._isDivider( item ) ) {
12263				item.addClass( "ui-widget-content ui-menu-divider" );
12264			}
12265		});
12266
12267		// Don't refresh list items that are already adapted
12268		items.not( ".ui-menu-item, .ui-menu-divider" )
12269			.addClass( "ui-menu-item" )
12270			.uniqueId()
12271			.attr({
12272				tabIndex: -1,
12273				role: this._itemRole()
12274			});
12275
12276		// Add aria-disabled attribute to any disabled menu item
12277		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
12278
12279		// If the active item has been removed, blur the menu
12280		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
12281			this.blur();
12282		}
12283	},
12284
12285	_itemRole: function() {
12286		return {
12287			menu: "menuitem",
12288			listbox: "option"
12289		}[ this.options.role ];
12290	},
12291
12292	_setOption: function( key, value ) {
12293		if ( key === "icons" ) {
12294			this.element.find( ".ui-menu-icon" )
12295				.removeClass( this.options.icons.submenu )
12296				.addClass( value.submenu );
12297		}
12298		if ( key === "disabled" ) {
12299			this.element
12300				.toggleClass( "ui-state-disabled", !!value )
12301				.attr( "aria-disabled", value );
12302		}
12303		this._super( key, value );
12304	},
12305
12306	focus: function( event, item ) {
12307		var nested, focused;
12308		this.blur( event, event && event.type === "focus" );
12309
12310		this._scrollIntoView( item );
12311
12312		this.active = item.first();
12313		focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
12314		// Only update aria-activedescendant if there's a role
12315		// otherwise we assume focus is managed elsewhere
12316		if ( this.options.role ) {
12317			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
12318		}
12319
12320		// Highlight active parent menu item, if any
12321		this.active
12322			.parent()
12323			.closest( ".ui-menu-item" )
12324			.addClass( "ui-state-active" );
12325
12326		if ( event && event.type === "keydown" ) {
12327			this._close();
12328		} else {
12329			this.timer = this._delay(function() {
12330				this._close();
12331			}, this.delay );
12332		}
12333
12334		nested = item.children( ".ui-menu" );
12335		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
12336			this._startOpening(nested);
12337		}
12338		this.activeMenu = item.parent();
12339
12340		this._trigger( "focus", event, { item: item } );
12341	},
12342
12343	_scrollIntoView: function( item ) {
12344		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
12345		if ( this._hasScroll() ) {
12346			borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
12347			paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
12348			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
12349			scroll = this.activeMenu.scrollTop();
12350			elementHeight = this.activeMenu.height();
12351			itemHeight = item.outerHeight();
12352
12353			if ( offset < 0 ) {
12354				this.activeMenu.scrollTop( scroll + offset );
12355			} else if ( offset + itemHeight > elementHeight ) {
12356				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
12357			}
12358		}
12359	},
12360
12361	blur: function( event, fromFocus ) {
12362		if ( !fromFocus ) {
12363			clearTimeout( this.timer );
12364		}
12365
12366		if ( !this.active ) {
12367			return;
12368		}
12369
12370		this.active.removeClass( "ui-state-focus" );
12371		this.active = null;
12372
12373		this._trigger( "blur", event, { item: this.active } );
12374	},
12375
12376	_startOpening: function( submenu ) {
12377		clearTimeout( this.timer );
12378
12379		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
12380		// shift in the submenu position when mousing over the carat icon
12381		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
12382			return;
12383		}
12384
12385		this.timer = this._delay(function() {
12386			this._close();
12387			this._open( submenu );
12388		}, this.delay );
12389	},
12390
12391	_open: function( submenu ) {
12392		var position = $.extend({
12393			of: this.active
12394		}, this.options.position );
12395
12396		clearTimeout( this.timer );
12397		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
12398			.hide()
12399			.attr( "aria-hidden", "true" );
12400
12401		submenu
12402			.show()
12403			.removeAttr( "aria-hidden" )
12404			.attr( "aria-expanded", "true" )
12405			.position( position );
12406	},
12407
12408	collapseAll: function( event, all ) {
12409		clearTimeout( this.timer );
12410		this.timer = this._delay(function() {
vendor: 11,138 bytes, lines 12411-12827
12411			// If we were passed an event, look for the submenu that contains the event
12412			var currentMenu = all ? this.element :
12413				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
12414
12415			// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
12416			if ( !currentMenu.length ) {
12417				currentMenu = this.element;
12418			}
12419
12420			this._close( currentMenu );
12421
12422			this.blur( event );
12423			this.activeMenu = currentMenu;
12424		}, this.delay );
12425	},
12426
12427	// With no arguments, closes the currently active menu - if nothing is active
12428	// it closes all menus.  If passed an argument, it will search for menus BELOW
12429	_close: function( startMenu ) {
12430		if ( !startMenu ) {
12431			startMenu = this.active ? this.active.parent() : this.element;
12432		}
12433
12434		startMenu
12435			.find( ".ui-menu" )
12436				.hide()
12437				.attr( "aria-hidden", "true" )
12438				.attr( "aria-expanded", "false" )
12439			.end()
12440			.find( ".ui-state-active" ).not( ".ui-state-focus" )
12441				.removeClass( "ui-state-active" );
12442	},
12443
12444	_closeOnDocumentClick: function( event ) {
12445		return !$( event.target ).closest( ".ui-menu" ).length;
12446	},
12447
12448	_isDivider: function( item ) {
12449
12450		// Match hyphen, em dash, en dash
12451		return !/[^\-\u2014\u2013\s]/.test( item.text() );
12452	},
12453
12454	collapse: function( event ) {
12455		var newItem = this.active &&
12456			this.active.parent().closest( ".ui-menu-item", this.element );
12457		if ( newItem && newItem.length ) {
12458			this._close();
12459			this.focus( event, newItem );
12460		}
12461	},
12462
12463	expand: function( event ) {
12464		var newItem = this.active &&
12465			this.active
12466				.children( ".ui-menu " )
12467				.find( this.options.items )
12468				.first();
12469
12470		if ( newItem && newItem.length ) {
12471			this._open( newItem.parent() );
12472
12473			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
12474			this._delay(function() {
12475				this.focus( event, newItem );
12476			});
12477		}
12478	},
12479
12480	next: function( event ) {
12481		this._move( "next", "first", event );
12482	},
12483
12484	previous: function( event ) {
12485		this._move( "prev", "last", event );
12486	},
12487
12488	isFirstItem: function() {
12489		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
12490	},
12491
12492	isLastItem: function() {
12493		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
12494	},
12495
12496	_move: function( direction, filter, event ) {
12497		var next;
12498		if ( this.active ) {
12499			if ( direction === "first" || direction === "last" ) {
12500				next = this.active
12501					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
12502					.eq( -1 );
12503			} else {
12504				next = this.active
12505					[ direction + "All" ]( ".ui-menu-item" )
12506					.eq( 0 );
12507			}
12508		}
12509		if ( !next || !next.length || !this.active ) {
12510			next = this.activeMenu.find( this.options.items )[ filter ]();
12511		}
12512
12513		this.focus( event, next );
12514	},
12515
12516	nextPage: function( event ) {
12517		var item, base, height;
12518
12519		if ( !this.active ) {
12520			this.next( event );
12521			return;
12522		}
12523		if ( this.isLastItem() ) {
12524			return;
12525		}
12526		if ( this._hasScroll() ) {
12527			base = this.active.offset().top;
12528			height = this.element.height();
12529			this.active.nextAll( ".ui-menu-item" ).each(function() {
12530				item = $( this );
12531				return item.offset().top - base - height < 0;
12532			});
12533
12534			this.focus( event, item );
12535		} else {
12536			this.focus( event, this.activeMenu.find( this.options.items )
12537				[ !this.active ? "first" : "last" ]() );
12538		}
12539	},
12540
12541	previousPage: function( event ) {
12542		var item, base, height;
12543		if ( !this.active ) {
12544			this.next( event );
12545			return;
12546		}
12547		if ( this.isFirstItem() ) {
12548			return;
12549		}
12550		if ( this._hasScroll() ) {
12551			base = this.active.offset().top;
12552			height = this.element.height();
12553			this.active.prevAll( ".ui-menu-item" ).each(function() {
12554				item = $( this );
12555				return item.offset().top - base + height > 0;
12556			});
12557
12558			this.focus( event, item );
12559		} else {
12560			this.focus( event, this.activeMenu.find( this.options.items ).first() );
12561		}
12562	},
12563
12564	_hasScroll: function() {
12565		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12566	},
12567
12568	select: function( event ) {
12569		// TODO: It should never be possible to not have an active item at this
12570		// point, but the tests don't trigger mouseenter before click.
12571		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12572		var ui = { item: this.active };
12573		if ( !this.active.has( ".ui-menu" ).length ) {
12574			this.collapseAll( event, true );
12575		}
12576		this._trigger( "select", event, ui );
12577	},
12578
12579	_filterMenuItems: function(character) {
12580		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
12581			regex = new RegExp( "^" + escapedCharacter, "i" );
12582
12583		return this.activeMenu
12584			.find( this.options.items )
12585
12586			// Only match on items, not dividers or other content (#10571)
12587			.filter( ".ui-menu-item" )
12588			.filter(function() {
12589				return regex.test( $.trim( $( this ).text() ) );
12590			});
12591	}
12592});
12593
12594
12595/*!
12596 * jQuery UI Autocomplete 1.11.4
12597 * http://jqueryui.com
12598 *
12599 * Copyright jQuery Foundation and other contributors
12600 * Released under the MIT license.
12601 * http://jquery.org/license
12602 *
12603 * http://api.jqueryui.com/autocomplete/
12604 */
12605
12606
12607$.widget( "ui.autocomplete", {
12608	version: "1.11.4",
12609	defaultElement: "<input>",
12610	options: {
12611		appendTo: null,
12612		autoFocus: false,
12613		delay: 300,
12614		minLength: 1,
12615		position: {
12616			my: "left top",
12617			at: "left bottom",
12618			collision: "none"
12619		},
12620		source: null,
12621
12622		// callbacks
12623		change: null,
12624		close: null,
12625		focus: null,
12626		open: null,
12627		response: null,
12628		search: null,
12629		select: null
12630	},
12631
12632	requestIndex: 0,
12633	pending: 0,
12634
12635	_create: function() {
12636		// Some browsers only repeat keydown events, not keypress events,
12637		// so we use the suppressKeyPress flag to determine if we've already
12638		// handled the keydown event. #7269
12639		// Unfortunately the code for & in keypress is the same as the up arrow,
12640		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
12641		// events when we know the keydown event was used to modify the
12642		// search term. #7799
12643		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
12644			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
12645			isTextarea = nodeName === "textarea",
12646			isInput = nodeName === "input";
12647
12648		this.isMultiLine =
12649			// Textareas are always multi-line
12650			isTextarea ? true :
12651			// Inputs are always single-line, even if inside a contentEditable element
12652			// IE also treats inputs as contentEditable
12653			isInput ? false :
12654			// All other element types are determined by whether or not they're contentEditable
12655			this.element.prop( "isContentEditable" );
12656
12657		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
12658		this.isNewMenu = true;
12659
12660		this.element
12661			.addClass( "ui-autocomplete-input" )
12662			.attr( "autocomplete", "off" );
12663
12664		this._on( this.element, {
12665			keydown: function( event ) {
12666				if ( this.element.prop( "readOnly" ) ) {
12667					suppressKeyPress = true;
12668					suppressInput = true;
12669					suppressKeyPressRepeat = true;
12670					return;
12671				}
12672
12673				suppressKeyPress = false;
12674				suppressInput = false;
12675				suppressKeyPressRepeat = false;
12676				var keyCode = $.ui.keyCode;
12677				switch ( event.keyCode ) {
12678				case keyCode.PAGE_UP:
12679					suppressKeyPress = true;
12680					this._move( "previousPage", event );
12681					break;
12682				case keyCode.PAGE_DOWN:
12683					suppressKeyPress = true;
12684					this._move( "nextPage", event );
12685					break;
12686				case keyCode.UP:
12687					suppressKeyPress = true;
12688					this._keyEvent( "previous", event );
12689					break;
12690				case keyCode.DOWN:
12691					suppressKeyPress = true;
12692					this._keyEvent( "next", event );
12693					break;
12694				case keyCode.ENTER:
12695					// when menu is open and has focus
12696					if ( this.menu.active ) {
12697						// #6055 - Opera still allows the keypress to occur
12698						// which causes forms to submit
12699						suppressKeyPress = true;
12700						event.preventDefault();
12701						this.menu.select( event );
12702					}
12703					break;
12704				case keyCode.TAB:
12705					if ( this.menu.active ) {
12706						this.menu.select( event );
12707					}
12708					break;
12709				case keyCode.ESCAPE:
12710					if ( this.menu.element.is( ":visible" ) ) {
12711						if ( !this.isMultiLine ) {
12712							this._value( this.term );
12713						}
12714						this.close( event );
12715						// Different browsers have different default behavior for escape
12716						// Single press can mean undo or clear
12717						// Double press in IE means clear the whole form
12718						event.preventDefault();
12719					}
12720					break;
12721				default:
12722					suppressKeyPressRepeat = true;
12723					// search timeout should be triggered before the input value is changed
12724					this._searchTimeout( event );
12725					break;
12726				}
12727			},
12728			keypress: function( event ) {
12729				if ( suppressKeyPress ) {
12730					suppressKeyPress = false;
12731					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
12732						event.preventDefault();
12733					}
12734					return;
12735				}
12736				if ( suppressKeyPressRepeat ) {
12737					return;
12738				}
12739
12740				// replicate some key handlers to allow them to repeat in Firefox and Opera
12741				var keyCode = $.ui.keyCode;
12742				switch ( event.keyCode ) {
12743				case keyCode.PAGE_UP:
12744					this._move( "previousPage", event );
12745					break;
12746				case keyCode.PAGE_DOWN:
12747					this._move( "nextPage", event );
12748					break;
12749				case keyCode.UP:
12750					this._keyEvent( "previous", event );
12751					break;
12752				case keyCode.DOWN:
12753					this._keyEvent( "next", event );
12754					break;
12755				}
12756			},
12757			input: function( event ) {
12758				if ( suppressInput ) {
12759					suppressInput = false;
12760					event.preventDefault();
12761					return;
12762				}
12763				this._searchTimeout( event );
12764			},
12765			focus: function() {
12766				this.selectedItem = null;
12767				this.previous = this._value();
12768			},
12769			blur: function( event ) {
12770				if ( this.cancelBlur ) {
12771					delete this.cancelBlur;
12772					return;
12773				}
12774
12775				clearTimeout( this.searching );
12776				this.close( event );
12777				this._change( event );
12778			}
12779		});
12780
12781		this._initSource();
12782		this.menu = $( "<ul>" )
12783			.addClass( "ui-autocomplete ui-front" )
12784			.appendTo( this._appendTo() )
12785			.menu({
12786				// disable ARIA support, the live region takes care of that
12787				role: null
12788			})
12789			.hide()
12790			.menu( "instance" );
12791
12792		this._on( this.menu.element, {
12793			mousedown: function( event ) {
12794				// prevent moving focus out of the text field
12795				event.preventDefault();
12796
12797				// IE doesn't prevent moving focus even with event.preventDefault()
12798				// so we set a flag to know when we should ignore the blur event
12799				this.cancelBlur = true;
12800				this._delay(function() {
12801					delete this.cancelBlur;
12802				});
12803
12804				// clicking on the scrollbar causes focus to shift to the body
12805				// but we can't detect a mouseup or a click immediately afterward
12806				// so we have to track the next mousedown and close the menu if
12807				// the user clicks somewhere outside of the autocomplete
12808				var menuElement = this.menu.element[ 0 ];
12809				if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
12810					this._delay(function() {
12811						var that = this;
12812						this.document.one( "mousedown", function( event ) {
12813							if ( event.target !== that.element[ 0 ] &&
12814									event.target !== menuElement &&
12815									!$.contains( menuElement, event.target ) ) {
12816								that.close();
12817							}
12818						});
12819					});
12820				}
12821			},
12822			menufocus: function( event, ui ) {
12823				var label, item;
12824				// support: Firefox
12825				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
12826				if ( this.isNewMenu ) {
12827					this.isNewMenu = false;
vendor: 4,086 bytes, lines 12828-12978
12828					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
12829						this.menu.blur();
12830
12831						this.document.one( "mousemove", function() {
12832							$( event.target ).trigger( event.originalEvent );
12833						});
12834
12835						return;
12836					}
12837				}
12838
12839				item = ui.item.data( "ui-autocomplete-item" );
12840				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
12841					// use value to match what will end up in the input, if it was a key event
12842					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
12843						this._value( item.value );
12844					}
12845				}
12846
12847				// Announce the value in the liveRegion
12848				label = ui.item.attr( "aria-label" ) || item.value;
12849				if ( label && $.trim( label ).length ) {
12850					this.liveRegion.children().hide();
12851					$( "<div>" ).text( label ).appendTo( this.liveRegion );
12852				}
12853			},
12854			menuselect: function( event, ui ) {
12855				var item = ui.item.data( "ui-autocomplete-item" ),
12856					previous = this.previous;
12857
12858				// only trigger when focus was lost (click on menu)
12859				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
12860					this.element.focus();
12861					this.previous = previous;
12862					// #6109 - IE triggers two focus events and the second
12863					// is asynchronous, so we need to reset the previous
12864					// term synchronously and asynchronously :-(
12865					this._delay(function() {
12866						this.previous = previous;
12867						this.selectedItem = item;
12868					});
12869				}
12870
12871				if ( false !== this._trigger( "select", event, { item: item } ) ) {
12872					this._value( item.value );
12873				}
12874				// reset the term after the select event
12875				// this allows custom select handling to work properly
12876				this.term = this._value();
12877
12878				this.close( event );
12879				this.selectedItem = item;
12880			}
12881		});
12882
12883		this.liveRegion = $( "<span>", {
12884				role: "status",
12885				"aria-live": "assertive",
12886				"aria-relevant": "additions"
12887			})
12888			.addClass( "ui-helper-hidden-accessible" )
12889			.appendTo( this.document[ 0 ].body );
12890
12891		// turning off autocomplete prevents the browser from remembering the
12892		// value when navigating through history, so we re-enable autocomplete
12893		// if the page is unloaded before the widget is destroyed. #7790
12894		this._on( this.window, {
12895			beforeunload: function() {
12896				this.element.removeAttr( "autocomplete" );
12897			}
12898		});
12899	},
12900
12901	_destroy: function() {
12902		clearTimeout( this.searching );
12903		this.element
12904			.removeClass( "ui-autocomplete-input" )
12905			.removeAttr( "autocomplete" );
12906		this.menu.element.remove();
12907		this.liveRegion.remove();
12908	},
12909
12910	_setOption: function( key, value ) {
12911		this._super( key, value );
12912		if ( key === "source" ) {
12913			this._initSource();
12914		}
12915		if ( key === "appendTo" ) {
12916			this.menu.element.appendTo( this._appendTo() );
12917		}
12918		if ( key === "disabled" && value && this.xhr ) {
12919			this.xhr.abort();
12920		}
12921	},
12922
12923	_appendTo: function() {
12924		var element = this.options.appendTo;
12925
12926		if ( element ) {
12927			element = element.jquery || element.nodeType ?
12928				$( element ) :
12929				this.document.find( element ).eq( 0 );
12930		}
12931
12932		if ( !element || !element[ 0 ] ) {
12933			element = this.element.closest( ".ui-front" );
12934		}
12935
12936		if ( !element.length ) {
12937			element = this.document[ 0 ].body;
12938		}
12939
12940		return element;
12941	},
12942
12943	_initSource: function() {
12944		var array, url,
12945			that = this;
12946		if ( $.isArray( this.options.source ) ) {
12947			array = this.options.source;
12948			this.source = function( request, response ) {
12949				response( $.ui.autocomplete.filter( array, request.term ) );
12950			};
12951		} else if ( typeof this.options.source === "string" ) {
12952			url = this.options.source;
12953			this.source = function( request, response ) {
12954				if ( that.xhr ) {
12955					that.xhr.abort();
12956				}
12957				that.xhr = $.ajax({
12958					url: url,
12959					data: request,
12960					dataType: "json",
12961					success: function( data ) {
12962						response( data );
12963					},
12964					error: function() {
12965						response([]);
12966					}
12967				});
12968			};
12969		} else {
12970			this.source = this.options.source;
12971		}
12972	},
12973
12974	_searchTimeout: function( event ) {
12975		clearTimeout( this.searching );
12976		this.searching = this._delay(function() {
12977
12978			// Search if the value has changed, or if the user retypes the same value (see #7434)
vendor: 8,850 bytes, lines 12979-13327
12979			var equalValues = this.term === this._value(),
12980				menuVisible = this.menu.element.is( ":visible" ),
12981				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
12982
12983			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
12984				this.selectedItem = null;
12985				this.search( null, event );
12986			}
12987		}, this.options.delay );
12988	},
12989
12990	search: function( value, event ) {
12991		value = value != null ? value : this._value();
12992
12993		// always save the actual value, not the one passed as an argument
12994		this.term = this._value();
12995
12996		if ( value.length < this.options.minLength ) {
12997			return this.close( event );
12998		}
12999
13000		if ( this._trigger( "search", event ) === false ) {
13001			return;
13002		}
13003
13004		return this._search( value );
13005	},
13006
13007	_search: function( value ) {
13008		this.pending++;
13009		this.element.addClass( "ui-autocomplete-loading" );
13010		this.cancelSearch = false;
13011
13012		this.source( { term: value }, this._response() );
13013	},
13014
13015	_response: function() {
13016		var index = ++this.requestIndex;
13017
13018		return $.proxy(function( content ) {
13019			if ( index === this.requestIndex ) {
13020				this.__response( content );
13021			}
13022
13023			this.pending--;
13024			if ( !this.pending ) {
13025				this.element.removeClass( "ui-autocomplete-loading" );
13026			}
13027		}, this );
13028	},
13029
13030	__response: function( content ) {
13031		if ( content ) {
13032			content = this._normalize( content );
13033		}
13034		this._trigger( "response", null, { content: content } );
13035		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
13036			this._suggest( content );
13037			this._trigger( "open" );
13038		} else {
13039			// use ._close() instead of .close() so we don't cancel future searches
13040			this._close();
13041		}
13042	},
13043
13044	close: function( event ) {
13045		this.cancelSearch = true;
13046		this._close( event );
13047	},
13048
13049	_close: function( event ) {
13050		if ( this.menu.element.is( ":visible" ) ) {
13051			this.menu.element.hide();
13052			this.menu.blur();
13053			this.isNewMenu = true;
13054			this._trigger( "close", event );
13055		}
13056	},
13057
13058	_change: function( event ) {
13059		if ( this.previous !== this._value() ) {
13060			this._trigger( "change", event, { item: this.selectedItem } );
13061		}
13062	},
13063
13064	_normalize: function( items ) {
13065		// assume all items have the right format when the first item is complete
13066		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
13067			return items;
13068		}
13069		return $.map( items, function( item ) {
13070			if ( typeof item === "string" ) {
13071				return {
13072					label: item,
13073					value: item
13074				};
13075			}
13076			return $.extend( {}, item, {
13077				label: item.label || item.value,
13078				value: item.value || item.label
13079			});
13080		});
13081	},
13082
13083	_suggest: function( items ) {
13084		var ul = this.menu.element.empty();
13085		this._renderMenu( ul, items );
13086		this.isNewMenu = true;
13087		this.menu.refresh();
13088
13089		// size and position menu
13090		ul.show();
13091		this._resizeMenu();
13092		ul.position( $.extend({
13093			of: this.element
13094		}, this.options.position ) );
13095
13096		if ( this.options.autoFocus ) {
13097			this.menu.next();
13098		}
13099	},
13100
13101	_resizeMenu: function() {
13102		var ul = this.menu.element;
13103		ul.outerWidth( Math.max(
13104			// Firefox wraps long text (possibly a rounding bug)
13105			// so we add 1px to avoid the wrapping (#7513)
13106			ul.width( "" ).outerWidth() + 1,
13107			this.element.outerWidth()
13108		) );
13109	},
13110
13111	_renderMenu: function( ul, items ) {
13112		var that = this;
13113		$.each( items, function( index, item ) {
13114			that._renderItemData( ul, item );
13115		});
13116	},
13117
13118	_renderItemData: function( ul, item ) {
13119		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
13120	},
13121
13122	_renderItem: function( ul, item ) {
13123		return $( "<li>" ).text( item.label ).appendTo( ul );
13124	},
13125
13126	_move: function( direction, event ) {
13127		if ( !this.menu.element.is( ":visible" ) ) {
13128			this.search( null, event );
13129			return;
13130		}
13131		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
13132				this.menu.isLastItem() && /^next/.test( direction ) ) {
13133
13134			if ( !this.isMultiLine ) {
13135				this._value( this.term );
13136			}
13137
13138			this.menu.blur();
13139			return;
13140		}
13141		this.menu[ direction ]( event );
13142	},
13143
13144	widget: function() {
13145		return this.menu.element;
13146	},
13147
13148	_value: function() {
13149		return this.valueMethod.apply( this.element, arguments );
13150	},
13151
13152	_keyEvent: function( keyEvent, event ) {
13153		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
13154			this._move( keyEvent, event );
13155
13156			// prevents moving cursor to beginning/end of the text field in some browsers
13157			event.preventDefault();
13158		}
13159	}
13160});
13161
13162$.extend( $.ui.autocomplete, {
13163	escapeRegex: function( value ) {
13164		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
13165	},
13166	filter: function( array, term ) {
13167		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
13168		return $.grep( array, function( value ) {
13169			return matcher.test( value.label || value.value || value );
13170		});
13171	}
13172});
13173
13174// live region extension, adding a `messages` option
13175// NOTE: This is an experimental API. We are still investigating
13176// a full solution for string manipulation and internationalization.
13177$.widget( "ui.autocomplete", $.ui.autocomplete, {
13178	options: {
13179		messages: {
13180			noResults: "No search results.",
13181			results: function( amount ) {
13182				return amount + ( amount > 1 ? " results are" : " result is" ) +
13183					" available, use up and down arrow keys to navigate.";
13184			}
13185		}
13186	},
13187
13188	__response: function( content ) {
13189		var message;
13190		this._superApply( arguments );
13191		if ( this.options.disabled || this.cancelSearch ) {
13192			return;
13193		}
13194		if ( content && content.length ) {
13195			message = this.options.messages.results( content.length );
13196		} else {
13197			message = this.options.messages.noResults;
13198		}
13199		this.liveRegion.children().hide();
13200		$( "<div>" ).text( message ).appendTo( this.liveRegion );
13201	}
13202});
13203
13204var autocomplete = $.ui.autocomplete;
13205
13206
13207/*!
13208 * jQuery UI Button 1.11.4
13209 * http://jqueryui.com
13210 *
13211 * Copyright jQuery Foundation and other contributors
13212 * Released under the MIT license.
13213 * http://jquery.org/license
13214 *
13215 * http://api.jqueryui.com/button/
13216 */
13217
13218
13219var lastActive,
13220	baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
13221	typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
13222	formResetHandler = function() {
13223		var form = $( this );
13224		setTimeout(function() {
13225			form.find( ":ui-button" ).button( "refresh" );
13226		}, 1 );
13227	},
13228	radioGroup = function( radio ) {
13229		var name = radio.name,
13230			form = radio.form,
13231			radios = $( [] );
13232		if ( name ) {
13233			name = name.replace( /'/g, "\\'" );
13234			if ( form ) {
13235				radios = $( form ).find( "[name='" + name + "'][type=radio]" );
13236			} else {
13237				radios = $( "[name='" + name + "'][type=radio]", radio.ownerDocument )
13238					.filter(function() {
13239						return !this.form;
13240					});
13241			}
13242		}
13243		return radios;
13244	};
13245
13246$.widget( "ui.button", {
13247	version: "1.11.4",
13248	defaultElement: "<button>",
13249	options: {
13250		disabled: null,
13251		text: true,
13252		label: null,
13253		icons: {
13254			primary: null,
13255			secondary: null
13256		}
13257	},
13258	_create: function() {
13259		this.element.closest( "form" )
13260			.unbind( "reset" + this.eventNamespace )
13261			.bind( "reset" + this.eventNamespace, formResetHandler );
13262
13263		if ( typeof this.options.disabled !== "boolean" ) {
13264			this.options.disabled = !!this.element.prop( "disabled" );
13265		} else {
13266			this.element.prop( "disabled", this.options.disabled );
13267		}
13268
13269		this._determineButtonType();
13270		this.hasTitle = !!this.buttonElement.attr( "title" );
13271
13272		var that = this,
13273			options = this.options,
13274			toggleButton = this.type === "checkbox" || this.type === "radio",
13275			activeClass = !toggleButton ? "ui-state-active" : "";
13276
13277		if ( options.label === null ) {
13278			options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
13279		}
13280
13281		this._hoverable( this.buttonElement );
13282
13283		this.buttonElement
13284			.addClass( baseClasses )
13285			.attr( "role", "button" )
13286			.bind( "mouseenter" + this.eventNamespace, function() {
13287				if ( options.disabled ) {
13288					return;
13289				}
13290				if ( this === lastActive ) {
13291					$( this ).addClass( "ui-state-active" );
13292				}
13293			})
13294			.bind( "mouseleave" + this.eventNamespace, function() {
13295				if ( options.disabled ) {
13296					return;
13297				}
13298				$( this ).removeClass( activeClass );
13299			})
13300			.bind( "click" + this.eventNamespace, function( event ) {
13301				if ( options.disabled ) {
13302					event.preventDefault();
13303					event.stopImmediatePropagation();
13304				}
13305			});
13306
13307		// Can't use _focusable() because the element that receives focus
13308		// and the element that gets the ui-state-focus class are different
13309		this._on({
13310			focus: function() {
13311				this.buttonElement.addClass( "ui-state-focus" );
13312			},
13313			blur: function() {
13314				this.buttonElement.removeClass( "ui-state-focus" );
13315			}
13316		});
13317
13318		if ( toggleButton ) {
13319			this.element.bind( "change" + this.eventNamespace, function() {
13320				that.refresh();
13321			});
13322		}
13323
13324		if ( this.type === "checkbox" ) {
13325			this.buttonElement.bind( "click" + this.eventNamespace, function() {
13326				if ( options.disabled ) {
13327					return false;
vendor: 5,528 bytes, lines 13328-13512
13328				}
13329			});
13330		} else if ( this.type === "radio" ) {
13331			this.buttonElement.bind( "click" + this.eventNamespace, function() {
13332				if ( options.disabled ) {
13333					return false;
13334				}
13335				$( this ).addClass( "ui-state-active" );
13336				that.buttonElement.attr( "aria-pressed", "true" );
13337
13338				var radio = that.element[ 0 ];
13339				radioGroup( radio )
13340					.not( radio )
13341					.map(function() {
13342						return $( this ).button( "widget" )[ 0 ];
13343					})
13344					.removeClass( "ui-state-active" )
13345					.attr( "aria-pressed", "false" );
13346			});
13347		} else {
13348			this.buttonElement
13349				.bind( "mousedown" + this.eventNamespace, function() {
13350					if ( options.disabled ) {
13351						return false;
13352					}
13353					$( this ).addClass( "ui-state-active" );
13354					lastActive = this;
13355					that.document.one( "mouseup", function() {
13356						lastActive = null;
13357					});
13358				})
13359				.bind( "mouseup" + this.eventNamespace, function() {
13360					if ( options.disabled ) {
13361						return false;
13362					}
13363					$( this ).removeClass( "ui-state-active" );
13364				})
13365				.bind( "keydown" + this.eventNamespace, function(event) {
13366					if ( options.disabled ) {
13367						return false;
13368					}
13369					if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
13370						$( this ).addClass( "ui-state-active" );
13371					}
13372				})
13373				// see #8559, we bind to blur here in case the button element loses
13374				// focus between keydown and keyup, it would be left in an "active" state
13375				.bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
13376					$( this ).removeClass( "ui-state-active" );
13377				});
13378
13379			if ( this.buttonElement.is("a") ) {
13380				this.buttonElement.keyup(function(event) {
13381					if ( event.keyCode === $.ui.keyCode.SPACE ) {
13382						// TODO pass through original event correctly (just as 2nd argument doesn't work)
13383						$( this ).click();
13384					}
13385				});
13386			}
13387		}
13388
13389		this._setOption( "disabled", options.disabled );
13390		this._resetButton();
13391	},
13392
13393	_determineButtonType: function() {
13394		var ancestor, labelSelector, checked;
13395
13396		if ( this.element.is("[type=checkbox]") ) {
13397			this.type = "checkbox";
13398		} else if ( this.element.is("[type=radio]") ) {
13399			this.type = "radio";
13400		} else if ( this.element.is("input") ) {
13401			this.type = "input";
13402		} else {
13403			this.type = "button";
13404		}
13405
13406		if ( this.type === "checkbox" || this.type === "radio" ) {
13407			// we don't search against the document in case the element
13408			// is disconnected from the DOM
13409			ancestor = this.element.parents().last();
13410			labelSelector = "label[for='" + this.element.attr("id") + "']";
13411			this.buttonElement = ancestor.find( labelSelector );
13412			if ( !this.buttonElement.length ) {
13413				ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
13414				this.buttonElement = ancestor.filter( labelSelector );
13415				if ( !this.buttonElement.length ) {
13416					this.buttonElement = ancestor.find( labelSelector );
13417				}
13418			}
13419			this.element.addClass( "ui-helper-hidden-accessible" );
13420
13421			checked = this.element.is( ":checked" );
13422			if ( checked ) {
13423				this.buttonElement.addClass( "ui-state-active" );
13424			}
13425			this.buttonElement.prop( "aria-pressed", checked );
13426		} else {
13427			this.buttonElement = this.element;
13428		}
13429	},
13430
13431	widget: function() {
13432		return this.buttonElement;
13433	},
13434
13435	_destroy: function() {
13436		this.element
13437			.removeClass( "ui-helper-hidden-accessible" );
13438		this.buttonElement
13439			.removeClass( baseClasses + " ui-state-active " + typeClasses )
13440			.removeAttr( "role" )
13441			.removeAttr( "aria-pressed" )
13442			.html( this.buttonElement.find(".ui-button-text").html() );
13443
13444		if ( !this.hasTitle ) {
13445			this.buttonElement.removeAttr( "title" );
13446		}
13447	},
13448
13449	_setOption: function( key, value ) {
13450		this._super( key, value );
13451		if ( key === "disabled" ) {
13452			this.widget().toggleClass( "ui-state-disabled", !!value );
13453			this.element.prop( "disabled", !!value );
13454			if ( value ) {
13455				if ( this.type === "checkbox" || this.type === "radio" ) {
13456					this.buttonElement.removeClass( "ui-state-focus" );
13457				} else {
13458					this.buttonElement.removeClass( "ui-state-focus ui-state-active" );
13459				}
13460			}
13461			return;
13462		}
13463		this._resetButton();
13464	},
13465
13466	refresh: function() {
13467		//See #8237 & #8828
13468		var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
13469
13470		if ( isDisabled !== this.options.disabled ) {
13471			this._setOption( "disabled", isDisabled );
13472		}
13473		if ( this.type === "radio" ) {
13474			radioGroup( this.element[0] ).each(function() {
13475				if ( $( this ).is( ":checked" ) ) {
13476					$( this ).button( "widget" )
13477						.addClass( "ui-state-active" )
13478						.attr( "aria-pressed", "true" );
13479				} else {
13480					$( this ).button( "widget" )
13481						.removeClass( "ui-state-active" )
13482						.attr( "aria-pressed", "false" );
13483				}
13484			});
13485		} else if ( this.type === "checkbox" ) {
13486			if ( this.element.is( ":checked" ) ) {
13487				this.buttonElement
13488					.addClass( "ui-state-active" )
13489					.attr( "aria-pressed", "true" );
13490			} else {
13491				this.buttonElement
13492					.removeClass( "ui-state-active" )
13493					.attr( "aria-pressed", "false" );
13494			}
13495		}
13496	},
13497
13498	_resetButton: function() {
13499		if ( this.type === "input" ) {
13500			if ( this.options.label ) {
13501				this.element.val( this.options.label );
13502			}
13503			return;
13504		}
13505		var buttonElement = this.buttonElement.removeClass( typeClasses ),
13506			buttonText = $( "<span></span>", this.document[0] )
13507				.addClass( "ui-button-text" )
13508				.html( this.options.label )
13509				.appendTo( buttonElement.empty() )
13510				.text(),
13511			icons = this.options.icons,
13512			multipleIcons = icons.primary && icons.secondary,
vendor: 6,515 bytes, lines 13513-13683
13513			buttonClasses = [];
13514
13515		if ( icons.primary || icons.secondary ) {
13516			if ( this.options.text ) {
13517				buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
13518			}
13519
13520			if ( icons.primary ) {
13521				buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
13522			}
13523
13524			if ( icons.secondary ) {
13525				buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
13526			}
13527
13528			if ( !this.options.text ) {
13529				buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
13530
13531				if ( !this.hasTitle ) {
13532					buttonElement.attr( "title", $.trim( buttonText ) );
13533				}
13534			}
13535		} else {
13536			buttonClasses.push( "ui-button-text-only" );
13537		}
13538		buttonElement.addClass( buttonClasses.join( " " ) );
13539	}
13540});
13541
13542$.widget( "ui.buttonset", {
13543	version: "1.11.4",
13544	options: {
13545		items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
13546	},
13547
13548	_create: function() {
13549		this.element.addClass( "ui-buttonset" );
13550	},
13551
13552	_init: function() {
13553		this.refresh();
13554	},
13555
13556	_setOption: function( key, value ) {
13557		if ( key === "disabled" ) {
13558			this.buttons.button( "option", key, value );
13559		}
13560
13561		this._super( key, value );
13562	},
13563
13564	refresh: function() {
13565		var rtl = this.element.css( "direction" ) === "rtl",
13566			allButtons = this.element.find( this.options.items ),
13567			existingButtons = allButtons.filter( ":ui-button" );
13568
13569		// Initialize new buttons
13570		allButtons.not( ":ui-button" ).button();
13571
13572		// Refresh existing buttons
13573		existingButtons.button( "refresh" );
13574
13575		this.buttons = allButtons
13576			.map(function() {
13577				return $( this ).button( "widget" )[ 0 ];
13578			})
13579				.removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
13580				.filter( ":first" )
13581					.addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
13582				.end()
13583				.filter( ":last" )
13584					.addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
13585				.end()
13586			.end();
13587	},
13588
13589	_destroy: function() {
13590		this.element.removeClass( "ui-buttonset" );
13591		this.buttons
13592			.map(function() {
13593				return $( this ).button( "widget" )[ 0 ];
13594			})
13595				.removeClass( "ui-corner-left ui-corner-right" )
13596			.end()
13597			.button( "destroy" );
13598	}
13599});
13600
13601var button = $.ui.button;
13602
13603
13604/*!
13605 * jQuery UI Datepicker 1.11.4
13606 * http://jqueryui.com
13607 *
13608 * Copyright jQuery Foundation and other contributors
13609 * Released under the MIT license.
13610 * http://jquery.org/license
13611 *
13612 * http://api.jqueryui.com/datepicker/
13613 */
13614
13615
13616$.extend($.ui, { datepicker: { version: "1.11.4" } });
13617
13618var datepicker_instActive;
13619
13620function datepicker_getZindex( elem ) {
13621	var position, value;
13622	while ( elem.length && elem[ 0 ] !== document ) {
13623		// Ignore z-index if position is set to a value where z-index is ignored by the browser
13624		// This makes behavior of this function consistent across browsers
13625		// WebKit always returns auto if the element is positioned
13626		position = elem.css( "position" );
13627		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
13628			// IE returns 0 when zIndex is not specified
13629			// other browsers return a string
13630			// we ignore the case of nested elements with an explicit value of 0
13631			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
13632			value = parseInt( elem.css( "zIndex" ), 10 );
13633			if ( !isNaN( value ) && value !== 0 ) {
13634				return value;
13635			}
13636		}
13637		elem = elem.parent();
13638	}
13639
13640	return 0;
13641}
13642/* Date picker manager.
13643   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
13644   Settings for (groups of) date pickers are maintained in an instance object,
13645   allowing multiple different settings on the same page. */
13646
13647function Datepicker() {
13648	this._curInst = null; // The current instance in use
13649	this._keyEvent = false; // If the last event was a key event
13650	this._disabledInputs = []; // List of date picker inputs that have been disabled
13651	this._datepickerShowing = false; // True if the popup picker is showing , false if not
13652	this._inDialog = false; // True if showing within a "dialog", false if not
13653	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
13654	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
13655	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
13656	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
13657	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
13658	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
13659	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
13660	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
13661	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
13662	this.regional = []; // Available regional settings, indexed by language code
13663	this.regional[""] = { // Default regional settings
13664		closeText: "Done", // Display text for close link
13665		prevText: "Prev", // Display text for previous month link
13666		nextText: "Next", // Display text for next month link
13667		currentText: "Today", // Display text for current month link
13668		monthNames: ["January","February","March","April","May","June",
13669			"July","August","September","October","November","December"], // Names of months for drop-down and formatting
13670		monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
13671		dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
13672		dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
13673		dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
13674		weekHeader: "Wk", // Column header for week of the year
13675		dateFormat: "mm/dd/yy", // See format options on parseDate
13676		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
13677		isRTL: false, // True if right-to-left language, false if left-to-right
13678		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
13679		yearSuffix: "" // Additional text to append to the year in the month headers
13680	};
13681	this._defaults = { // Global defaults for all the date picker instances
13682		showOn: "focus", // "focus" for popup on focus,
13683			// "button" for trigger button, or "both" for either
vendor: 19,263 bytes, lines 13684-14183
13684		showAnim: "fadeIn", // Name of jQuery animation for popup
13685		showOptions: {}, // Options for enhanced animations
13686		defaultDate: null, // Used when field is blank: actual date,
13687			// +/-number for offset from today, null for today
13688		appendText: "", // Display text following the input box, e.g. showing the format
13689		buttonText: "...", // Text for trigger button
13690		buttonImage: "", // URL for trigger button image
13691		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
13692		hideIfNoPrevNext: false, // True to hide next/previous month links
13693			// if not applicable, false to just disable them
13694		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
13695		gotoCurrent: false, // True if today link goes back to current selection instead
13696		changeMonth: false, // True if month can be selected directly, false if only prev/next
13697		changeYear: false, // True if year can be selected directly, false if only prev/next
13698		yearRange: "c-10:c+10", // Range of years to display in drop-down,
13699			// either relative to today's year (-nn:+nn), relative to currently displayed year
13700			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
13701		showOtherMonths: false, // True to show dates in other months, false to leave blank
13702		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
13703		showWeek: false, // True to show week of the year, false to not show it
13704		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
13705			// takes a Date and returns the number of the week for it
13706		shortYearCutoff: "+10", // Short year values < this are in the current century,
13707			// > this are in the previous century,
13708			// string value starting with "+" for current year + value
13709		minDate: null, // The earliest selectable date, or null for no limit
13710		maxDate: null, // The latest selectable date, or null for no limit
13711		duration: "fast", // Duration of display/closure
13712		beforeShowDay: null, // Function that takes a date and returns an array with
13713			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
13714			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
13715		beforeShow: null, // Function that takes an input field and
13716			// returns a set of custom settings for the date picker
13717		onSelect: null, // Define a callback function when a date is selected
13718		onChangeMonthYear: null, // Define a callback function when the month or year is changed
13719		onClose: null, // Define a callback function when the datepicker is closed
13720		numberOfMonths: 1, // Number of months to show at a time
13721		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
13722		stepMonths: 1, // Number of months to step back/forward
13723		stepBigMonths: 12, // Number of months to step back/forward for the big links
13724		altField: "", // Selector for an alternate field to store selected dates into
13725		altFormat: "", // The date format to use for the alternate field
13726		constrainInput: true, // The input is constrained by the current date format
13727		showButtonPanel: false, // True to show button panel, false to not show it
13728		autoSize: false, // True to size the input for the date format, false to leave as is
13729		disabled: false // The initial disabled state
13730	};
13731	$.extend(this._defaults, this.regional[""]);
13732	this.regional.en = $.extend( true, {}, this.regional[ "" ]);
13733	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
13734	this.dpDiv = datepicker_bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
13735}
13736
13737$.extend(Datepicker.prototype, {
13738	/* Class name added to elements to indicate already configured with a date picker. */
13739	markerClassName: "hasDatepicker",
13740
13741	//Keep track of the maximum number of rows displayed (see #7043)
13742	maxRows: 4,
13743
13744	// TODO rename to "widget" when switching to widget factory
13745	_widgetDatepicker: function() {
13746		return this.dpDiv;
13747	},
13748
13749	/* Override the default settings for all instances of the date picker.
13750	 * @param  settings  object - the new settings to use as defaults (anonymous object)
13751	 * @return the manager object
13752	 */
13753	setDefaults: function(settings) {
13754		datepicker_extendRemove(this._defaults, settings || {});
13755		return this;
13756	},
13757
13758	/* Attach the date picker to a jQuery selection.
13759	 * @param  target	element - the target input field or division or span
13760	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
13761	 */
13762	_attachDatepicker: function(target, settings) {
13763		var nodeName, inline, inst;
13764		nodeName = target.nodeName.toLowerCase();
13765		inline = (nodeName === "div" || nodeName === "span");
13766		if (!target.id) {
13767			this.uuid += 1;
13768			target.id = "dp" + this.uuid;
13769		}
13770		inst = this._newInst($(target), inline);
13771		inst.settings = $.extend({}, settings || {});
13772		if (nodeName === "input") {
13773			this._connectDatepicker(target, inst);
13774		} else if (inline) {
13775			this._inlineDatepicker(target, inst);
13776		}
13777	},
13778
13779	/* Create a new instance object. */
13780	_newInst: function(target, inline) {
13781		var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
13782		return {id: id, input: target, // associated target
13783			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
13784			drawMonth: 0, drawYear: 0, // month being drawn
13785			inline: inline, // is datepicker inline or not
13786			dpDiv: (!inline ? this.dpDiv : // presentation div
13787			datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
13788	},
13789
13790	/* Attach the date picker to an input field. */
13791	_connectDatepicker: function(target, inst) {
13792		var input = $(target);
13793		inst.append = $([]);
13794		inst.trigger = $([]);
13795		if (input.hasClass(this.markerClassName)) {
13796			return;
13797		}
13798		this._attachments(input, inst);
13799		input.addClass(this.markerClassName).keydown(this._doKeyDown).
13800			keypress(this._doKeyPress).keyup(this._doKeyUp);
13801		this._autoSize(inst);
13802		$.data(target, "datepicker", inst);
13803		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
13804		if( inst.settings.disabled ) {
13805			this._disableDatepicker( target );
13806		}
13807	},
13808
13809	/* Make attachments based on settings. */
13810	_attachments: function(input, inst) {
13811		var showOn, buttonText, buttonImage,
13812			appendText = this._get(inst, "appendText"),
13813			isRTL = this._get(inst, "isRTL");
13814
13815		if (inst.append) {
13816			inst.append.remove();
13817		}
13818		if (appendText) {
13819			inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
13820			input[isRTL ? "before" : "after"](inst.append);
13821		}
13822
13823		input.unbind("focus", this._showDatepicker);
13824
13825		if (inst.trigger) {
13826			inst.trigger.remove();
13827		}
13828
13829		showOn = this._get(inst, "showOn");
13830		if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
13831			input.focus(this._showDatepicker);
13832		}
13833		if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
13834			buttonText = this._get(inst, "buttonText");
13835			buttonImage = this._get(inst, "buttonImage");
13836			inst.trigger = $(this._get(inst, "buttonImageOnly") ?
13837				$("<img/>").addClass(this._triggerClass).
13838					attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
13839				$("<button type='button'></button>").addClass(this._triggerClass).
13840					html(!buttonImage ? buttonText : $("<img/>").attr(
13841					{ src:buttonImage, alt:buttonText, title:buttonText })));
13842			input[isRTL ? "before" : "after"](inst.trigger);
13843			inst.trigger.click(function() {
13844				if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
13845					$.datepicker._hideDatepicker();
13846				} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
13847					$.datepicker._hideDatepicker();
13848					$.datepicker._showDatepicker(input[0]);
13849				} else {
13850					$.datepicker._showDatepicker(input[0]);
13851				}
13852				return false;
13853			});
13854		}
13855	},
13856
13857	/* Apply the maximum length for the date format. */
13858	_autoSize: function(inst) {
13859		if (this._get(inst, "autoSize") && !inst.inline) {
13860			var findMax, max, maxI, i,
13861				date = new Date(2009, 12 - 1, 20), // Ensure double digits
13862				dateFormat = this._get(inst, "dateFormat");
13863
13864			if (dateFormat.match(/[DM]/)) {
13865				findMax = function(names) {
13866					max = 0;
13867					maxI = 0;
13868					for (i = 0; i < names.length; i++) {
13869						if (names[i].length > max) {
13870							max = names[i].length;
13871							maxI = i;
13872						}
13873					}
13874					return maxI;
13875				};
13876				date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
13877					"monthNames" : "monthNamesShort"))));
13878				date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
13879					"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
13880			}
13881			inst.input.attr("size", this._formatDate(inst, date).length);
13882		}
13883	},
13884
13885	/* Attach an inline date picker to a div. */
13886	_inlineDatepicker: function(target, inst) {
13887		var divSpan = $(target);
13888		if (divSpan.hasClass(this.markerClassName)) {
13889			return;
13890		}
13891		divSpan.addClass(this.markerClassName).append(inst.dpDiv);
13892		$.data(target, "datepicker", inst);
13893		this._setDate(inst, this._getDefaultDate(inst), true);
13894		this._updateDatepicker(inst);
13895		this._updateAlternate(inst);
13896		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
13897		if( inst.settings.disabled ) {
13898			this._disableDatepicker( target );
13899		}
13900		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
13901		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
13902		inst.dpDiv.css( "display", "block" );
13903	},
13904
13905	/* Pop-up the date picker in a "dialog" box.
13906	 * @param  input element - ignored
13907	 * @param  date	string or Date - the initial date to display
13908	 * @param  onSelect  function - the function to call when a date is selected
13909	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
13910	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
13911	 *					event - with x/y coordinates or
13912	 *					leave empty for default (screen centre)
13913	 * @return the manager object
13914	 */
13915	_dialogDatepicker: function(input, date, onSelect, settings, pos) {
13916		var id, browserWidth, browserHeight, scrollX, scrollY,
13917			inst = this._dialogInst; // internal instance
13918
13919		if (!inst) {
13920			this.uuid += 1;
13921			id = "dp" + this.uuid;
13922			this._dialogInput = $("<input type='text' id='" + id +
13923				"' style='position: absolute; top: -100px; width: 0px;'/>");
13924			this._dialogInput.keydown(this._doKeyDown);
13925			$("body").append(this._dialogInput);
13926			inst = this._dialogInst = this._newInst(this._dialogInput, false);
13927			inst.settings = {};
13928			$.data(this._dialogInput[0], "datepicker", inst);
13929		}
13930		datepicker_extendRemove(inst.settings, settings || {});
13931		date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
13932		this._dialogInput.val(date);
13933
13934		this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
13935		if (!this._pos) {
13936			browserWidth = document.documentElement.clientWidth;
13937			browserHeight = document.documentElement.clientHeight;
13938			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
13939			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
13940			this._pos = // should use actual width/height below
13941				[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
13942		}
13943
13944		// move input on screen for focus, but hidden behind dialog
13945		this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
13946		inst.settings.onSelect = onSelect;
13947		this._inDialog = true;
13948		this.dpDiv.addClass(this._dialogClass);
13949		this._showDatepicker(this._dialogInput[0]);
13950		if ($.blockUI) {
13951			$.blockUI(this.dpDiv);
13952		}
13953		$.data(this._dialogInput[0], "datepicker", inst);
13954		return this;
13955	},
13956
13957	/* Detach a datepicker from its control.
13958	 * @param  target	element - the target input field or division or span
13959	 */
13960	_destroyDatepicker: function(target) {
13961		var nodeName,
13962			$target = $(target),
13963			inst = $.data(target, "datepicker");
13964
13965		if (!$target.hasClass(this.markerClassName)) {
13966			return;
13967		}
13968
13969		nodeName = target.nodeName.toLowerCase();
13970		$.removeData(target, "datepicker");
13971		if (nodeName === "input") {
13972			inst.append.remove();
13973			inst.trigger.remove();
13974			$target.removeClass(this.markerClassName).
13975				unbind("focus", this._showDatepicker).
13976				unbind("keydown", this._doKeyDown).
13977				unbind("keypress", this._doKeyPress).
13978				unbind("keyup", this._doKeyUp);
13979		} else if (nodeName === "div" || nodeName === "span") {
13980			$target.removeClass(this.markerClassName).empty();
13981		}
13982
13983		if ( datepicker_instActive === inst ) {
13984			datepicker_instActive = null;
13985		}
13986	},
13987
13988	/* Enable the date picker to a jQuery selection.
13989	 * @param  target	element - the target input field or division or span
13990	 */
13991	_enableDatepicker: function(target) {
13992		var nodeName, inline,
13993			$target = $(target),
13994			inst = $.data(target, "datepicker");
13995
13996		if (!$target.hasClass(this.markerClassName)) {
13997			return;
13998		}
13999
14000		nodeName = target.nodeName.toLowerCase();
14001		if (nodeName === "input") {
14002			target.disabled = false;
14003			inst.trigger.filter("button").
14004				each(function() { this.disabled = false; }).end().
14005				filter("img").css({opacity: "1.0", cursor: ""});
14006		} else if (nodeName === "div" || nodeName === "span") {
14007			inline = $target.children("." + this._inlineClass);
14008			inline.children().removeClass("ui-state-disabled");
14009			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
14010				prop("disabled", false);
14011		}
14012		this._disabledInputs = $.map(this._disabledInputs,
14013			function(value) { return (value === target ? null : value); }); // delete entry
14014	},
14015
14016	/* Disable the date picker to a jQuery selection.
14017	 * @param  target	element - the target input field or division or span
14018	 */
14019	_disableDatepicker: function(target) {
14020		var nodeName, inline,
14021			$target = $(target),
14022			inst = $.data(target, "datepicker");
14023
14024		if (!$target.hasClass(this.markerClassName)) {
14025			return;
14026		}
14027
14028		nodeName = target.nodeName.toLowerCase();
14029		if (nodeName === "input") {
14030			target.disabled = true;
14031			inst.trigger.filter("button").
14032				each(function() { this.disabled = true; }).end().
14033				filter("img").css({opacity: "0.5", cursor: "default"});
14034		} else if (nodeName === "div" || nodeName === "span") {
14035			inline = $target.children("." + this._inlineClass);
14036			inline.children().addClass("ui-state-disabled");
14037			inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
14038				prop("disabled", true);
14039		}
14040		this._disabledInputs = $.map(this._disabledInputs,
14041			function(value) { return (value === target ? null : value); }); // delete entry
14042		this._disabledInputs[this._disabledInputs.length] = target;
14043	},
14044
14045	/* Is the first field in a jQuery collection disabled as a datepicker?
14046	 * @param  target	element - the target input field or division or span
14047	 * @return boolean - true if disabled, false if enabled
14048	 */
14049	_isDisabledDatepicker: function(target) {
14050		if (!target) {
14051			return false;
14052		}
14053		for (var i = 0; i < this._disabledInputs.length; i++) {
14054			if (this._disabledInputs[i] === target) {
14055				return true;
14056			}
14057		}
14058		return false;
14059	},
14060
14061	/* Retrieve the instance data for the target control.
14062	 * @param  target  element - the target input field or division or span
14063	 * @return  object - the associated instance data
14064	 * @throws  error if a jQuery problem getting data
14065	 */
14066	_getInst: function(target) {
14067		try {
14068			return $.data(target, "datepicker");
14069		}
14070		catch (err) {
14071			throw "Missing instance data for this datepicker";
14072		}
14073	},
14074
14075	/* Update or retrieve the settings for a date picker attached to an input field or division.
14076	 * @param  target  element - the target input field or division or span
14077	 * @param  name	object - the new settings to update or
14078	 *				string - the name of the setting to change or retrieve,
14079	 *				when retrieving also "all" for all instance settings or
14080	 *				"defaults" for all global defaults
14081	 * @param  value   any - the new value for the setting
14082	 *				(omit if above is an object or to retrieve a value)
14083	 */
14084	_optionDatepicker: function(target, name, value) {
14085		var settings, date, minDate, maxDate,
14086			inst = this._getInst(target);
14087
14088		if (arguments.length === 2 && typeof name === "string") {
14089			return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
14090				(inst ? (name === "all" ? $.extend({}, inst.settings) :
14091				this._get(inst, name)) : null));
14092		}
14093
14094		settings = name || {};
14095		if (typeof name === "string") {
14096			settings = {};
14097			settings[name] = value;
14098		}
14099
14100		if (inst) {
14101			if (this._curInst === inst) {
14102				this._hideDatepicker();
14103			}
14104
14105			date = this._getDateDatepicker(target, true);
14106			minDate = this._getMinMaxDate(inst, "min");
14107			maxDate = this._getMinMaxDate(inst, "max");
14108			datepicker_extendRemove(inst.settings, settings);
14109			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
14110			if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
14111				inst.settings.minDate = this._formatDate(inst, minDate);
14112			}
14113			if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
14114				inst.settings.maxDate = this._formatDate(inst, maxDate);
14115			}
14116			if ( "disabled" in settings ) {
14117				if ( settings.disabled ) {
14118					this._disableDatepicker(target);
14119				} else {
14120					this._enableDatepicker(target);
14121				}
14122			}
14123			this._attachments($(target), inst);
14124			this._autoSize(inst);
14125			this._setDate(inst, date);
14126			this._updateAlternate(inst);
14127			this._updateDatepicker(inst);
14128		}
14129	},
14130
14131	// change method deprecated
14132	_changeDatepicker: function(target, name, value) {
14133		this._optionDatepicker(target, name, value);
14134	},
14135
14136	/* Redraw the date picker attached to an input field or division.
14137	 * @param  target  element - the target input field or division or span
14138	 */
14139	_refreshDatepicker: function(target) {
14140		var inst = this._getInst(target);
14141		if (inst) {
14142			this._updateDatepicker(inst);
14143		}
14144	},
14145
14146	/* Set the dates for a jQuery selection.
14147	 * @param  target element - the target input field or division or span
14148	 * @param  date	Date - the new date
14149	 */
14150	_setDateDatepicker: function(target, date) {
14151		var inst = this._getInst(target);
14152		if (inst) {
14153			this._setDate(inst, date);
14154			this._updateDatepicker(inst);
14155			this._updateAlternate(inst);
14156		}
14157	},
14158
14159	/* Get the date(s) for the first entry in a jQuery selection.
14160	 * @param  target element - the target input field or division or span
14161	 * @param  noDefault boolean - true if no default date is to be used
14162	 * @return Date - the current date
14163	 */
14164	_getDateDatepicker: function(target, noDefault) {
14165		var inst = this._getInst(target);
14166		if (inst && !inst.inline) {
14167			this._setDateFromField(inst, noDefault);
14168		}
14169		return (inst ? this._getDate(inst) : null);
14170	},
14171
14172	/* Handle keystrokes. */
14173	_doKeyDown: function(event) {
14174		var onSelect, dateStr, sel,
14175			inst = $.datepicker._getInst(event.target),
14176			handled = true,
14177			isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
14178
14179		inst._keyEvent = true;
14180		if ($.datepicker._datepickerShowing) {
14181			switch (event.keyCode) {
14182				case 9: $.datepicker._hideDatepicker();
14183						handled = false;
vendor: 4,495 bytes, lines 14184-14307
14184						break; // hide on tab out
14185				case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
14186									$.datepicker._currentClass + ")", inst.dpDiv);
14187						if (sel[0]) {
14188							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
14189						}
14190
14191						onSelect = $.datepicker._get(inst, "onSelect");
14192						if (onSelect) {
14193							dateStr = $.datepicker._formatDate(inst);
14194
14195							// trigger custom callback
14196							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
14197						} else {
14198							$.datepicker._hideDatepicker();
14199						}
14200
14201						return false; // don't submit the form
14202				case 27: $.datepicker._hideDatepicker();
14203						break; // hide on escape
14204				case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
14205							-$.datepicker._get(inst, "stepBigMonths") :
14206							-$.datepicker._get(inst, "stepMonths")), "M");
14207						break; // previous month/year on page up/+ ctrl
14208				case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
14209							+$.datepicker._get(inst, "stepBigMonths") :
14210							+$.datepicker._get(inst, "stepMonths")), "M");
14211						break; // next month/year on page down/+ ctrl
14212				case 35: if (event.ctrlKey || event.metaKey) {
14213							$.datepicker._clearDate(event.target);
14214						}
14215						handled = event.ctrlKey || event.metaKey;
14216						break; // clear on ctrl or command +end
14217				case 36: if (event.ctrlKey || event.metaKey) {
14218							$.datepicker._gotoToday(event.target);
14219						}
14220						handled = event.ctrlKey || event.metaKey;
14221						break; // current on ctrl or command +home
14222				case 37: if (event.ctrlKey || event.metaKey) {
14223							$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
14224						}
14225						handled = event.ctrlKey || event.metaKey;
14226						// -1 day on ctrl or command +left
14227						if (event.originalEvent.altKey) {
14228							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
14229								-$.datepicker._get(inst, "stepBigMonths") :
14230								-$.datepicker._get(inst, "stepMonths")), "M");
14231						}
14232						// next month/year on alt +left on Mac
14233						break;
14234				case 38: if (event.ctrlKey || event.metaKey) {
14235							$.datepicker._adjustDate(event.target, -7, "D");
14236						}
14237						handled = event.ctrlKey || event.metaKey;
14238						break; // -1 week on ctrl or command +up
14239				case 39: if (event.ctrlKey || event.metaKey) {
14240							$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
14241						}
14242						handled = event.ctrlKey || event.metaKey;
14243						// +1 day on ctrl or command +right
14244						if (event.originalEvent.altKey) {
14245							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
14246								+$.datepicker._get(inst, "stepBigMonths") :
14247								+$.datepicker._get(inst, "stepMonths")), "M");
14248						}
14249						// next month/year on alt +right
14250						break;
14251				case 40: if (event.ctrlKey || event.metaKey) {
14252							$.datepicker._adjustDate(event.target, +7, "D");
14253						}
14254						handled = event.ctrlKey || event.metaKey;
14255						break; // +1 week on ctrl or command +down
14256				default: handled = false;
14257			}
14258		} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
14259			$.datepicker._showDatepicker(this);
14260		} else {
14261			handled = false;
14262		}
14263
14264		if (handled) {
14265			event.preventDefault();
14266			event.stopPropagation();
14267		}
14268	},
14269
14270	/* Filter entered characters - based on date format. */
14271	_doKeyPress: function(event) {
14272		var chars, chr,
14273			inst = $.datepicker._getInst(event.target);
14274
14275		if ($.datepicker._get(inst, "constrainInput")) {
14276			chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
14277			chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
14278			return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
14279		}
14280	},
14281
14282	/* Synchronise manual entry and field/alternate field. */
14283	_doKeyUp: function(event) {
14284		var date,
14285			inst = $.datepicker._getInst(event.target);
14286
14287		if (inst.input.val() !== inst.lastVal) {
14288			try {
14289				date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
14290					(inst.input ? inst.input.val() : null),
14291					$.datepicker._getFormatConfig(inst));
14292
14293				if (date) { // only if valid
14294					$.datepicker._setDateFromField(inst);
14295					$.datepicker._updateAlternate(inst);
14296					$.datepicker._updateDatepicker(inst);
14297				}
14298			}
14299			catch (err) {
14300			}
14301		}
14302		return true;
14303	},
14304
14305	/* Pop-up the date picker for a given input field.
14306	 * If false returned from beforeShow event handler do not show.
14307	 * @param  input  element - the input field attached to the date picker or
vendor: 9,398 bytes, lines 14308-14582
14308	 *					event - if triggered by focus
14309	 */
14310	_showDatepicker: function(input) {
14311		input = input.target || input;
14312		if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
14313			input = $("input", input.parentNode)[0];
14314		}
14315
14316		if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
14317			return;
14318		}
14319
14320		var inst, beforeShow, beforeShowSettings, isFixed,
14321			offset, showAnim, duration;
14322
14323		inst = $.datepicker._getInst(input);
14324		if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
14325			$.datepicker._curInst.dpDiv.stop(true, true);
14326			if ( inst && $.datepicker._datepickerShowing ) {
14327				$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
14328			}
14329		}
14330
14331		beforeShow = $.datepicker._get(inst, "beforeShow");
14332		beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
14333		if(beforeShowSettings === false){
14334			return;
14335		}
14336		datepicker_extendRemove(inst.settings, beforeShowSettings);
14337
14338		inst.lastVal = null;
14339		$.datepicker._lastInput = input;
14340		$.datepicker._setDateFromField(inst);
14341
14342		if ($.datepicker._inDialog) { // hide cursor
14343			input.value = "";
14344		}
14345		if (!$.datepicker._pos) { // position below input
14346			$.datepicker._pos = $.datepicker._findPos(input);
14347			$.datepicker._pos[1] += input.offsetHeight; // add the height
14348		}
14349
14350		isFixed = false;
14351		$(input).parents().each(function() {
14352			isFixed |= $(this).css("position") === "fixed";
14353			return !isFixed;
14354		});
14355
14356		offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
14357		$.datepicker._pos = null;
14358		//to avoid flashes on Firefox
14359		inst.dpDiv.empty();
14360		// determine sizing offscreen
14361		inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
14362		$.datepicker._updateDatepicker(inst);
14363		// fix width for dynamic number of date pickers
14364		// and adjust position before showing
14365		offset = $.datepicker._checkOffset(inst, offset, isFixed);
14366		inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
14367			"static" : (isFixed ? "fixed" : "absolute")), display: "none",
14368			left: offset.left + "px", top: offset.top + "px"});
14369
14370		if (!inst.inline) {
14371			showAnim = $.datepicker._get(inst, "showAnim");
14372			duration = $.datepicker._get(inst, "duration");
14373			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
14374			$.datepicker._datepickerShowing = true;
14375
14376			if ( $.effects && $.effects.effect[ showAnim ] ) {
14377				inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
14378			} else {
14379				inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
14380			}
14381
14382			if ( $.datepicker._shouldFocusInput( inst ) ) {
14383				inst.input.focus();
14384			}
14385
14386			$.datepicker._curInst = inst;
14387		}
14388	},
14389
14390	/* Generate the date picker content. */
14391	_updateDatepicker: function(inst) {
14392		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
14393		datepicker_instActive = inst; // for delegate hover events
14394		inst.dpDiv.empty().append(this._generateHTML(inst));
14395		this._attachHandlers(inst);
14396
14397		var origyearshtml,
14398			numMonths = this._getNumberOfMonths(inst),
14399			cols = numMonths[1],
14400			width = 17,
14401			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
14402
14403		if ( activeCell.length > 0 ) {
14404			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
14405		}
14406
14407		inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
14408		if (cols > 1) {
14409			inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
14410		}
14411		inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
14412			"Class"]("ui-datepicker-multi");
14413		inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
14414			"Class"]("ui-datepicker-rtl");
14415
14416		if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
14417			inst.input.focus();
14418		}
14419
14420		// deffered render of the years select (to avoid flashes on Firefox)
14421		if( inst.yearshtml ){
14422			origyearshtml = inst.yearshtml;
14423			setTimeout(function(){
14424				//assure that inst.yearshtml didn't change.
14425				if( origyearshtml === inst.yearshtml && inst.yearshtml ){
14426					inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
14427				}
14428				origyearshtml = inst.yearshtml = null;
14429			}, 0);
14430		}
14431	},
14432
14433	// #6694 - don't focus the input if it's already focused
14434	// this breaks the change event in IE
14435	// Support: IE and jQuery <1.9
14436	_shouldFocusInput: function( inst ) {
14437		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
14438	},
14439
14440	/* Check positioning to remain on screen. */
14441	_checkOffset: function(inst, offset, isFixed) {
14442		var dpWidth = inst.dpDiv.outerWidth(),
14443			dpHeight = inst.dpDiv.outerHeight(),
14444			inputWidth = inst.input ? inst.input.outerWidth() : 0,
14445			inputHeight = inst.input ? inst.input.outerHeight() : 0,
14446			viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
14447			viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
14448
14449		offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
14450		offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
14451		offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
14452
14453		// now check if datepicker is showing outside window viewport - move to a better place if so.
14454		offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
14455			Math.abs(offset.left + dpWidth - viewWidth) : 0);
14456		offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
14457			Math.abs(dpHeight + inputHeight) : 0);
14458
14459		return offset;
14460	},
14461
14462	/* Find an object's position on the screen. */
14463	_findPos: function(obj) {
14464		var position,
14465			inst = this._getInst(obj),
14466			isRTL = this._get(inst, "isRTL");
14467
14468		while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
14469			obj = obj[isRTL ? "previousSibling" : "nextSibling"];
14470		}
14471
14472		position = $(obj).offset();
14473		return [position.left, position.top];
14474	},
14475
14476	/* Hide the date picker from view.
14477	 * @param  input  element - the input field attached to the date picker
14478	 */
14479	_hideDatepicker: function(input) {
14480		var showAnim, duration, postProcess, onClose,
14481			inst = this._curInst;
14482
14483		if (!inst || (input && inst !== $.data(input, "datepicker"))) {
14484			return;
14485		}
14486
14487		if (this._datepickerShowing) {
14488			showAnim = this._get(inst, "showAnim");
14489			duration = this._get(inst, "duration");
14490			postProcess = function() {
14491				$.datepicker._tidyDialog(inst);
14492			};
14493
14494			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
14495			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
14496				inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
14497			} else {
14498				inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
14499					(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
14500			}
14501
14502			if (!showAnim) {
14503				postProcess();
14504			}
14505			this._datepickerShowing = false;
14506
14507			onClose = this._get(inst, "onClose");
14508			if (onClose) {
14509				onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
14510			}
14511
14512			this._lastInput = null;
14513			if (this._inDialog) {
14514				this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
14515				if ($.blockUI) {
14516					$.unblockUI();
14517					$("body").append(this.dpDiv);
14518				}
14519			}
14520			this._inDialog = false;
14521		}
14522	},
14523
14524	/* Tidy up after a dialog display. */
14525	_tidyDialog: function(inst) {
14526		inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
14527	},
14528
14529	/* Close date picker if clicked elsewhere. */
14530	_checkExternalClick: function(event) {
14531		if (!$.datepicker._curInst) {
14532			return;
14533		}
14534
14535		var $target = $(event.target),
14536			inst = $.datepicker._getInst($target[0]);
14537
14538		if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
14539				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
14540				!$target.hasClass($.datepicker.markerClassName) &&
14541				!$target.closest("." + $.datepicker._triggerClass).length &&
14542				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
14543			( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
14544				$.datepicker._hideDatepicker();
14545		}
14546	},
14547
14548	/* Adjust one of the date sub-fields. */
14549	_adjustDate: function(id, offset, period) {
14550		var target = $(id),
14551			inst = this._getInst(target[0]);
14552
14553		if (this._isDisabledDatepicker(target[0])) {
14554			return;
14555		}
14556		this._adjustInstDate(inst, offset +
14557			(period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
14558			period);
14559		this._updateDatepicker(inst);
14560	},
14561
14562	/* Action for current link. */
14563	_gotoToday: function(id) {
14564		var date,
14565			target = $(id),
14566			inst = this._getInst(target[0]);
14567
14568		if (this._get(inst, "gotoCurrent") && inst.currentDay) {
14569			inst.selectedDay = inst.currentDay;
14570			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
14571			inst.drawYear = inst.selectedYear = inst.currentYear;
14572		} else {
14573			date = new Date();
14574			inst.selectedDay = date.getDate();
14575			inst.drawMonth = inst.selectedMonth = date.getMonth();
14576			inst.drawYear = inst.selectedYear = date.getFullYear();
14577		}
14578		this._notifyChange(inst);
14579		this._adjustDate(target);
14580	},
14581
14582	/* Action for selecting a new month/year. */
vendor: 4,436 bytes, lines 14583-14714
14583	_selectMonthYear: function(id, select, period) {
14584		var target = $(id),
14585			inst = this._getInst(target[0]);
14586
14587		inst["selected" + (period === "M" ? "Month" : "Year")] =
14588		inst["draw" + (period === "M" ? "Month" : "Year")] =
14589			parseInt(select.options[select.selectedIndex].value,10);
14590
14591		this._notifyChange(inst);
14592		this._adjustDate(target);
14593	},
14594
14595	/* Action for selecting a day. */
14596	_selectDay: function(id, month, year, td) {
14597		var inst,
14598			target = $(id);
14599
14600		if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
14601			return;
14602		}
14603
14604		inst = this._getInst(target[0]);
14605		inst.selectedDay = inst.currentDay = $("a", td).html();
14606		inst.selectedMonth = inst.currentMonth = month;
14607		inst.selectedYear = inst.currentYear = year;
14608		this._selectDate(id, this._formatDate(inst,
14609			inst.currentDay, inst.currentMonth, inst.currentYear));
14610	},
14611
14612	/* Erase the input field and hide the date picker. */
14613	_clearDate: function(id) {
14614		var target = $(id);
14615		this._selectDate(target, "");
14616	},
14617
14618	/* Update the input field with the selected date. */
14619	_selectDate: function(id, dateStr) {
14620		var onSelect,
14621			target = $(id),
14622			inst = this._getInst(target[0]);
14623
14624		dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
14625		if (inst.input) {
14626			inst.input.val(dateStr);
14627		}
14628		this._updateAlternate(inst);
14629
14630		onSelect = this._get(inst, "onSelect");
14631		if (onSelect) {
14632			onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
14633		} else if (inst.input) {
14634			inst.input.trigger("change"); // fire the change event
14635		}
14636
14637		if (inst.inline){
14638			this._updateDatepicker(inst);
14639		} else {
14640			this._hideDatepicker();
14641			this._lastInput = inst.input[0];
14642			if (typeof(inst.input[0]) !== "object") {
14643				inst.input.focus(); // restore focus
14644			}
14645			this._lastInput = null;
14646		}
14647	},
14648
14649	/* Update any alternate field to synchronise with the main field. */
14650	_updateAlternate: function(inst) {
14651		var altFormat, date, dateStr,
14652			altField = this._get(inst, "altField");
14653
14654		if (altField) { // update alternate field too
14655			altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
14656			date = this._getDate(inst);
14657			dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
14658			$(altField).each(function() { $(this).val(dateStr); });
14659		}
14660	},
14661
14662	/* Set as beforeShowDay function to prevent selection of weekends.
14663	 * @param  date  Date - the date to customise
14664	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
14665	 */
14666	noWeekends: function(date) {
14667		var day = date.getDay();
14668		return [(day > 0 && day < 6), ""];
14669	},
14670
14671	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
14672	 * @param  date  Date - the date to get the week for
14673	 * @return  number - the number of the week within the year that contains this date
14674	 */
14675	iso8601Week: function(date) {
14676		var time,
14677			checkDate = new Date(date.getTime());
14678
14679		// Find Thursday of this week starting on Monday
14680		checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
14681
14682		time = checkDate.getTime();
14683		checkDate.setMonth(0); // Compare with Jan 1
14684		checkDate.setDate(1);
14685		return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
14686	},
14687
14688	/* Parse a string value into a date object.
14689	 * See formatDate below for the possible formats.
14690	 *
14691	 * @param  format string - the expected format of the date
14692	 * @param  value string - the date in the above format
14693	 * @param  settings Object - attributes include:
14694	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
14695	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
14696	 *					dayNames		string[7] - names of the days from Sunday (optional)
14697	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
14698	 *					monthNames		string[12] - names of the months (optional)
14699	 * @return  Date - the extracted date value or null if value is blank
14700	 */
14701	parseDate: function (format, value, settings) {
14702		if (format == null || value == null) {
14703			throw "Invalid arguments";
14704		}
14705
14706		value = (typeof value === "object" ? value.toString() : value + "");
14707		if (value === "") {
14708			return null;
14709		}
14710
14711		var iFormat, dim, extra,
14712			iValue = 0,
14713			shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
14714			shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,261 bytes, lines 14714-14900
14714:
14715				new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
14716			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
14717			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
14718			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
14719			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
14720			year = -1,
14721			month = -1,
14722			day = -1,
14723			doy = -1,
14724			literal = false,
14725			date,
14726			// Check whether a format character is doubled
14727			lookAhead = function(match) {
14728				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
14729				if (matches) {
14730					iFormat++;
14731				}
14732				return matches;
14733			},
14734			// Extract a number from the string value
14735			getNumber = function(match) {
14736				var isDoubled = lookAhead(match),
14737					size = (match === "@" ? 14 : (match === "!" ? 20 :
14738					(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
14739					minSize = (match === "y" ? size : 1),
14740					digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
14741					num = value.substring(iValue).match(digits);
14742				if (!num) {
14743					throw "Missing number at position " + iValue;
14744				}
14745				iValue += num[0].length;
14746				return parseInt(num[0], 10);
14747			},
14748			// Extract a name from the string value and convert to an index
14749			getName = function(match, shortNames, longNames) {
14750				var index = -1,
14751					names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
14752						return [ [k, v] ];
14753					}).sort(function (a, b) {
14754						return -(a[1].length - b[1].length);
14755					});
14756
14757				$.each(names, function (i, pair) {
14758					var name = pair[1];
14759					if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
14760						index = pair[0];
14761						iValue += name.length;
14762						return false;
14763					}
14764				});
14765				if (index !== -1) {
14766					return index + 1;
14767				} else {
14768					throw "Unknown name at position " + iValue;
14769				}
14770			},
14771			// Confirm that a literal character matches the string value
14772			checkLiteral = function() {
14773				if (value.charAt(iValue) !== format.charAt(iFormat)) {
14774					throw "Unexpected literal at position " + iValue;
14775				}
14776				iValue++;
14777			};
14778
14779		for (iFormat = 0; iFormat < format.length; iFormat++) {
14780			if (literal) {
14781				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
14782					literal = false;
14783				} else {
14784					checkLiteral();
14785				}
14786			} else {
14787				switch (format.charAt(iFormat)) {
14788					case "d":
14789						day = getNumber("d");
14790						break;
14791					case "D":
14792						getName("D", dayNamesShort, dayNames);
14793						break;
14794					case "o":
14795						doy = getNumber("o");
14796						break;
14797					case "m":
14798						month = getNumber("m");
14799						break;
14800					case "M":
14801						month = getName("M", monthNamesShort, monthNames);
14802						break;
14803					case "y":
14804						year = getNumber("y");
14805						break;
14806					case "@":
14807						date = new Date(getNumber("@"));
14808						year = date.getFullYear();
14809						month = date.getMonth() + 1;
14810						day = date.getDate();
14811						break;
14812					case "!":
14813						date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
14814						year = date.getFullYear();
14815						month = date.getMonth() + 1;
14816						day = date.getDate();
14817						break;
14818					case "'":
14819						if (lookAhead("'")){
14820							checkLiteral();
14821						} else {
14822							literal = true;
14823						}
14824						break;
14825					default:
14826						checkLiteral();
14827				}
14828			}
14829		}
14830
14831		if (iValue < value.length){
14832			extra = value.substr(iValue);
14833			if (!/^\s+/.test(extra)) {
14834				throw "Extra/unparsed characters found in date: " + extra;
14835			}
14836		}
14837
14838		if (year === -1) {
14839			year = new Date().getFullYear();
14840		} else if (year < 100) {
14841			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
14842				(year <= shortYearCutoff ? 0 : -100);
14843		}
14844
14845		if (doy > -1) {
14846			month = 1;
14847			day = doy;
14848			do {
14849				dim = this._getDaysInMonth(year, month - 1);
14850				if (day <= dim) {
14851					break;
14852				}
14853				month++;
14854				day -= dim;
14855			} while (true);
14856		}
14857
14858		date = this._daylightSavingAdjust(new Date(year, month - 1, day));
14859		if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
14860			throw "Invalid date"; // E.g. 31/02/00
14861		}
14862		return date;
14863	},
14864
14865	/* Standard date formats. */
14866	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
14867	COOKIE: "D, dd M yy",
14868	ISO_8601: "yy-mm-dd",
14869	RFC_822: "D, d M y",
14870	RFC_850: "DD, dd-M-y",
14871	RFC_1036: "D, d M y",
14872	RFC_1123: "D, d M yy",
14873	RFC_2822: "D, d M yy",
14874	RSS: "D, d M y", // RFC 822
14875	TICKS: "!",
14876	TIMESTAMP: "@",
14877	W3C: "yy-mm-dd", // ISO 8601
14878
14879	_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
14880		Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
14881
14882	/* Format a date object into a string value.
14883	 * The format can be combinations of the following:
14884	 * d  - day of month (no leading zero)
14885	 * dd - day of month (two digit)
14886	 * o  - day of year (no leading zeros)
14887	 * oo - day of year (three digit)
14888	 * D  - day name short
14889	 * DD - day name long
14890	 * m  - month of year (no leading zero)
14891	 * mm - month of year (two digit)
14892	 * M  - month name short
14893	 * MM - month name long
14894	 * y  - year (two digit)
14895	 * yy - year (four digit)
14896	 * @ - Unix timestamp (ms since 01/01/1970)
14897	 * ! - Windows ticks (100ns since 01/01/0001)
14898	 * "..." - literal text
14899	 * '' - single quote
14900	 *
vendor: 11,157 bytes, lines 14901-15234
14901	 * @param  format string - the desired format of the date
14902	 * @param  date Date - the date value to format
14903	 * @param  settings Object - attributes include:
14904	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
14905	 *					dayNames		string[7] - names of the days from Sunday (optional)
14906	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
14907	 *					monthNames		string[12] - names of the months (optional)
14908	 * @return  string - the date in the above format
14909	 */
14910	formatDate: function (format, date, settings) {
14911		if (!date) {
14912			return "";
14913		}
14914
14915		var iFormat,
14916			dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
14917			dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
14918			monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
14919			monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
14920			// Check whether a format character is doubled
14921			lookAhead = function(match) {
14922				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
14923				if (matches) {
14924					iFormat++;
14925				}
14926				return matches;
14927			},
14928			// Format a number, with leading zero if necessary
14929			formatNumber = function(match, value, len) {
14930				var num = "" + value;
14931				if (lookAhead(match)) {
14932					while (num.length < len) {
14933						num = "0" + num;
14934					}
14935				}
14936				return num;
14937			},
14938			// Format a name, short or long as requested
14939			formatName = function(match, value, shortNames, longNames) {
14940				return (lookAhead(match) ? longNames[value] : shortNames[value]);
14941			},
14942			output = "",
14943			literal = false;
14944
14945		if (date) {
14946			for (iFormat = 0; iFormat < format.length; iFormat++) {
14947				if (literal) {
14948					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
14949						literal = false;
14950					} else {
14951						output += format.charAt(iFormat);
14952					}
14953				} else {
14954					switch (format.charAt(iFormat)) {
14955						case "d":
14956							output += formatNumber("d", date.getDate(), 2);
14957							break;
14958						case "D":
14959							output += formatName("D", date.getDay(), dayNamesShort, dayNames);
14960							break;
14961						case "o":
14962							output += formatNumber("o",
14963								Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
14964							break;
14965						case "m":
14966							output += formatNumber("m", date.getMonth() + 1, 2);
14967							break;
14968						case "M":
14969							output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
14970							break;
14971						case "y":
14972							output += (lookAhead("y") ? date.getFullYear() :
14973								(date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
14974							break;
14975						case "@":
14976							output += date.getTime();
14977							break;
14978						case "!":
14979							output += date.getTime() * 10000 + this._ticksTo1970;
14980							break;
14981						case "'":
14982							if (lookAhead("'")) {
14983								output += "'";
14984							} else {
14985								literal = true;
14986							}
14987							break;
14988						default:
14989							output += format.charAt(iFormat);
14990					}
14991				}
14992			}
14993		}
14994		return output;
14995	},
14996
14997	/* Extract all possible characters from the date format. */
14998	_possibleChars: function (format) {
14999		var iFormat,
15000			chars = "",
15001			literal = false,
15002			// Check whether a format character is doubled
15003			lookAhead = function(match) {
15004				var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
15005				if (matches) {
15006					iFormat++;
15007				}
15008				return matches;
15009			};
15010
15011		for (iFormat = 0; iFormat < format.length; iFormat++) {
15012			if (literal) {
15013				if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
15014					literal = false;
15015				} else {
15016					chars += format.charAt(iFormat);
15017				}
15018			} else {
15019				switch (format.charAt(iFormat)) {
15020					case "d": case "m": case "y": case "@":
15021						chars += "0123456789";
15022						break;
15023					case "D": case "M":
15024						return null; // Accept anything
15025					case "'":
15026						if (lookAhead("'")) {
15027							chars += "'";
15028						} else {
15029							literal = true;
15030						}
15031						break;
15032					default:
15033						chars += format.charAt(iFormat);
15034				}
15035			}
15036		}
15037		return chars;
15038	},
15039
15040	/* Get a setting value, defaulting if necessary. */
15041	_get: function(inst, name) {
15042		return inst.settings[name] !== undefined ?
15043			inst.settings[name] : this._defaults[name];
15044	},
15045
15046	/* Parse existing date and initialise date picker. */
15047	_setDateFromField: function(inst, noDefault) {
15048		if (inst.input.val() === inst.lastVal) {
15049			return;
15050		}
15051
15052		var dateFormat = this._get(inst, "dateFormat"),
15053			dates = inst.lastVal = inst.input ? inst.input.val() : null,
15054			defaultDate = this._getDefaultDate(inst),
15055			date = defaultDate,
15056			settings = this._getFormatConfig(inst);
15057
15058		try {
15059			date = this.parseDate(dateFormat, dates, settings) || defaultDate;
15060		} catch (event) {
15061			dates = (noDefault ? "" : dates);
15062		}
15063		inst.selectedDay = date.getDate();
15064		inst.drawMonth = inst.selectedMonth = date.getMonth();
15065		inst.drawYear = inst.selectedYear = date.getFullYear();
15066		inst.currentDay = (dates ? date.getDate() : 0);
15067		inst.currentMonth = (dates ? date.getMonth() : 0);
15068		inst.currentYear = (dates ? date.getFullYear() : 0);
15069		this._adjustInstDate(inst);
15070	},
15071
15072	/* Retrieve the default date shown on opening. */
15073	_getDefaultDate: function(inst) {
15074		return this._restrictMinMax(inst,
15075			this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
15076	},
15077
15078	/* A date may be specified as an exact value or a relative one. */
15079	_determineDate: function(inst, date, defaultDate) {
15080		var offsetNumeric = function(offset) {
15081				var date = new Date();
15082				date.setDate(date.getDate() + offset);
15083				return date;
15084			},
15085			offsetString = function(offset) {
15086				try {
15087					return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
15088						offset, $.datepicker._getFormatConfig(inst));
15089				}
15090				catch (e) {
15091					// Ignore
15092				}
15093
15094				var date = (offset.toLowerCase().match(/^c/) ?
15095					$.datepicker._getDate(inst) : null) || new Date(),
15096					year = date.getFullYear(),
15097					month = date.getMonth(),
15098					day = date.getDate(),
15099					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
15100					matches = pattern.exec(offset);
15101
15102				while (matches) {
15103					switch (matches[2] || "d") {
15104						case "d" : case "D" :
15105							day += parseInt(matches[1],10); break;
15106						case "w" : case "W" :
15107							day += parseInt(matches[1],10) * 7; break;
15108						case "m" : case "M" :
15109							month += parseInt(matches[1],10);
15110							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
15111							break;
15112						case "y": case "Y" :
15113							year += parseInt(matches[1],10);
15114							day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
15115							break;
15116					}
15117					matches = pattern.exec(offset);
15118				}
15119				return new Date(year, month, day);
15120			},
15121			newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
15122				(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
15123
15124		newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
15125		if (newDate) {
15126			newDate.setHours(0);
15127			newDate.setMinutes(0);
15128			newDate.setSeconds(0);
15129			newDate.setMilliseconds(0);
15130		}
15131		return this._daylightSavingAdjust(newDate);
15132	},
15133
15134	/* Handle switch to/from daylight saving.
15135	 * Hours may be non-zero on daylight saving cut-over:
15136	 * > 12 when midnight changeover, but then cannot generate
15137	 * midnight datetime, so jump to 1AM, otherwise reset.
15138	 * @param  date  (Date) the date to check
15139	 * @return  (Date) the corrected date
15140	 */
15141	_daylightSavingAdjust: function(date) {
15142		if (!date) {
15143			return null;
15144		}
15145		date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
15146		return date;
15147	},
15148
15149	/* Set the date(s) directly. */
15150	_setDate: function(inst, date, noChange) {
15151		var clear = !date,
15152			origMonth = inst.selectedMonth,
15153			origYear = inst.selectedYear,
15154			newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
15155
15156		inst.selectedDay = inst.currentDay = newDate.getDate();
15157		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
15158		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
15159		if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
15160			this._notifyChange(inst);
15161		}
15162		this._adjustInstDate(inst);
15163		if (inst.input) {
15164			inst.input.val(clear ? "" : this._formatDate(inst));
15165		}
15166	},
15167
15168	/* Retrieve the date(s) directly. */
15169	_getDate: function(inst) {
15170		var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
15171			this._daylightSavingAdjust(new Date(
15172			inst.currentYear, inst.currentMonth, inst.currentDay)));
15173			return startDate;
15174	},
15175
15176	/* Attach the onxxx handlers.  These are declared statically so
15177	 * they work with static code transformers like Caja.
15178	 */
15179	_attachHandlers: function(inst) {
15180		var stepMonths = this._get(inst, "stepMonths"),
15181			id = "#" + inst.id.replace( /\\\\/g, "\\" );
15182		inst.dpDiv.find("[data-handler]").map(function () {
15183			var handler = {
15184				prev: function () {
15185					$.datepicker._adjustDate(id, -stepMonths, "M");
15186				},
15187				next: function () {
15188					$.datepicker._adjustDate(id, +stepMonths, "M");
15189				},
15190				hide: function () {
15191					$.datepicker._hideDatepicker();
15192				},
15193				today: function () {
15194					$.datepicker._gotoToday(id);
15195				},
15196				selectDay: function () {
15197					$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
15198					return false;
15199				},
15200				selectMonth: function () {
15201					$.datepicker._selectMonthYear(id, this, "M");
15202					return false;
15203				},
15204				selectYear: function () {
15205					$.datepicker._selectMonthYear(id, this, "Y");
15206					return false;
15207				}
15208			};
15209			$(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
15210		});
15211	},
15212
15213	/* Generate the HTML for the current state of the date picker. */
15214	_generateHTML: function(inst) {
15215		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
15216			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
15217			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
15218			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
15219			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
15220			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
15221			tempDate = new Date(),
15222			today = this._daylightSavingAdjust(
15223				new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
15224			isRTL = this._get(inst, "isRTL"),
15225			showButtonPanel = this._get(inst, "showButtonPanel"),
15226			hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
15227			navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
15228			numMonths = this._getNumberOfMonths(inst),
15229			showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
15230			stepMonths = this._get(inst, "stepMonths"),
15231			isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
15232			currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
15233				new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
15234			minDate = this._getMinMaxDate(inst, "min"),
vendor: 9,139 bytes, lines 15235-15393
15235			maxDate = this._getMinMaxDate(inst, "max"),
15236			drawMonth = inst.drawMonth - showCurrentAtPos,
15237			drawYear = inst.drawYear;
15238
15239		if (drawMonth < 0) {
15240			drawMonth += 12;
15241			drawYear--;
15242		}
15243		if (maxDate) {
15244			maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
15245				maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
15246			maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
15247			while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
15248				drawMonth--;
15249				if (drawMonth < 0) {
15250					drawMonth = 11;
15251					drawYear--;
15252				}
15253			}
15254		}
15255		inst.drawMonth = drawMonth;
15256		inst.drawYear = drawYear;
15257
15258		prevText = this._get(inst, "prevText");
15259		prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
15260			this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
15261			this._getFormatConfig(inst)));
15262
15263		prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
15264			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
15265			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
15266			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
15267
15268		nextText = this._get(inst, "nextText");
15269		nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
15270			this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
15271			this._getFormatConfig(inst)));
15272
15273		next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
15274			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
15275			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
15276			(hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
15277
15278		currentText = this._get(inst, "currentText");
15279		gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
15280		currentText = (!navigationAsDateFormat ? currentText :
15281			this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
15282
15283		controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
15284			this._get(inst, "closeText") + "</button>" : "");
15285
15286		buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
15287			(this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
15288			">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
15289
15290		firstDay = parseInt(this._get(inst, "firstDay"),10);
15291		firstDay = (isNaN(firstDay) ? 0 : firstDay);
15292
15293		showWeek = this._get(inst, "showWeek");
15294		dayNames = this._get(inst, "dayNames");
15295		dayNamesMin = this._get(inst, "dayNamesMin");
15296		monthNames = this._get(inst, "monthNames");
15297		monthNamesShort = this._get(inst, "monthNamesShort");
15298		beforeShowDay = this._get(inst, "beforeShowDay");
15299		showOtherMonths = this._get(inst, "showOtherMonths");
15300		selectOtherMonths = this._get(inst, "selectOtherMonths");
15301		defaultDate = this._getDefaultDate(inst);
15302		html = "";
15303		dow;
15304		for (row = 0; row < numMonths[0]; row++) {
15305			group = "";
15306			this.maxRows = 4;
15307			for (col = 0; col < numMonths[1]; col++) {
15308				selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
15309				cornerClass = " ui-corner-all";
15310				calender = "";
15311				if (isMultiMonth) {
15312					calender += "<div class='ui-datepicker-group";
15313					if (numMonths[1] > 1) {
15314						switch (col) {
15315							case 0: calender += " ui-datepicker-group-first";
15316								cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
15317							case numMonths[1]-1: calender += " ui-datepicker-group-last";
15318								cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
15319							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
15320						}
15321					}
15322					calender += "'>";
15323				}
15324				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
15325					(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
15326					(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
15327					this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
15328					row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
15329					"</div><table class='ui-datepicker-calendar'><thead>" +
15330					"<tr>";
15331				thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
15332				for (dow = 0; dow < 7; dow++) { // days of the week
15333					day = (dow + firstDay) % 7;
15334					thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
15335						"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
15336				}
15337				calender += thead + "</tr></thead><tbody>";
15338				daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
15339				if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
15340					inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
15341				}
15342				leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
15343				curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
15344				numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
15345				this.maxRows = numRows;
15346				printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
15347				for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
15348					calender += "<tr>";
15349					tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
15350						this._get(inst, "calculateWeek")(printDate) + "</td>");
15351					for (dow = 0; dow < 7; dow++) { // create date picker days
15352						daySettings = (beforeShowDay ?
15353							beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
15354						otherMonth = (printDate.getMonth() !== drawMonth);
15355						unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
15356							(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
15357						tbody += "<td class='" +
15358							((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
15359							(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
15360							((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
15361							(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
15362							// or defaultDate is current printedDate and defaultDate is selectedDate
15363							" " + this._dayOverClass : "") + // highlight selected day
15364							(unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") +  // highlight unselectable days
15365							(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
15366							(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
15367							(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
15368							((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
15369							(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
15370							(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
15371							(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
15372							(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
15373							(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
15374							(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
15375							"' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
15376						printDate.setDate(printDate.getDate() + 1);
15377						printDate = this._daylightSavingAdjust(printDate);
15378					}
15379					calender += tbody + "</tr>";
15380				}
15381				drawMonth++;
15382				if (drawMonth > 11) {
15383					drawMonth = 0;
15384					drawYear++;
15385				}
15386				calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
15387							((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
15388				group += calender;
15389			}
15390			html += group;
15391		}
15392		html += buttonPanel;
15393		inst._keyEvent = false;
vendor: 5,431 bytes, lines 15394-15537
15394		return html;
15395	},
15396
15397	/* Generate the month and year header. */
15398	_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
15399			secondary, monthNames, monthNamesShort) {
15400
15401		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
15402			changeMonth = this._get(inst, "changeMonth"),
15403			changeYear = this._get(inst, "changeYear"),
15404			showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
15405			html = "<div class='ui-datepicker-title'>",
15406			monthHtml = "";
15407
15408		// month selection
15409		if (secondary || !changeMonth) {
15410			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
15411		} else {
15412			inMinYear = (minDate && minDate.getFullYear() === drawYear);
15413			inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
15414			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
15415			for ( month = 0; month < 12; month++) {
15416				if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
15417					monthHtml += "<option value='" + month + "'" +
15418						(month === drawMonth ? " selected='selected'" : "") +
15419						">" + monthNamesShort[month] + "</option>";
15420				}
15421			}
15422			monthHtml += "</select>";
15423		}
15424
15425		if (!showMonthAfterYear) {
15426			html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
15427		}
15428
15429		// year selection
15430		if ( !inst.yearshtml ) {
15431			inst.yearshtml = "";
15432			if (secondary || !changeYear) {
15433				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
15434			} else {
15435				// determine range of years to display
15436				years = this._get(inst, "yearRange").split(":");
15437				thisYear = new Date().getFullYear();
15438				determineYear = function(value) {
15439					var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
15440						(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
15441						parseInt(value, 10)));
15442					return (isNaN(year) ? thisYear : year);
15443				};
15444				year = determineYear(years[0]);
15445				endYear = Math.max(year, determineYear(years[1] || ""));
15446				year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
15447				endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
15448				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
15449				for (; year <= endYear; year++) {
15450					inst.yearshtml += "<option value='" + year + "'" +
15451						(year === drawYear ? " selected='selected'" : "") +
15452						">" + year + "</option>";
15453				}
15454				inst.yearshtml += "</select>";
15455
15456				html += inst.yearshtml;
15457				inst.yearshtml = null;
15458			}
15459		}
15460
15461		html += this._get(inst, "yearSuffix");
15462		if (showMonthAfterYear) {
15463			html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
15464		}
15465		html += "</div>"; // Close datepicker_header
15466		return html;
15467	},
15468
15469	/* Adjust one of the date sub-fields. */
15470	_adjustInstDate: function(inst, offset, period) {
15471		var year = inst.drawYear + (period === "Y" ? offset : 0),
15472			month = inst.drawMonth + (period === "M" ? offset : 0),
15473			day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
15474			date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
15475
15476		inst.selectedDay = date.getDate();
15477		inst.drawMonth = inst.selectedMonth = date.getMonth();
15478		inst.drawYear = inst.selectedYear = date.getFullYear();
15479		if (period === "M" || period === "Y") {
15480			this._notifyChange(inst);
15481		}
15482	},
15483
15484	/* Ensure a date is within any min/max bounds. */
15485	_restrictMinMax: function(inst, date) {
15486		var minDate = this._getMinMaxDate(inst, "min"),
15487			maxDate = this._getMinMaxDate(inst, "max"),
15488			newDate = (minDate && date < minDate ? minDate : date);
15489		return (maxDate && newDate > maxDate ? maxDate : newDate);
15490	},
15491
15492	/* Notify change of month/year. */
15493	_notifyChange: function(inst) {
15494		var onChange = this._get(inst, "onChangeMonthYear");
15495		if (onChange) {
15496			onChange.apply((inst.input ? inst.input[0] : null),
15497				[inst.selectedYear, inst.selectedMonth + 1, inst]);
15498		}
15499	},
15500
15501	/* Determine the number of months to show. */
15502	_getNumberOfMonths: function(inst) {
15503		var numMonths = this._get(inst, "numberOfMonths");
15504		return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
15505	},
15506
15507	/* Determine the current maximum date - ensure no time components are set. */
15508	_getMinMaxDate: function(inst, minMax) {
15509		return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
15510	},
15511
15512	/* Find the number of days in a given month. */
15513	_getDaysInMonth: function(year, month) {
15514		return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
15515	},
15516
15517	/* Find the day of the week of the first of a month. */
15518	_getFirstDayOfMonth: function(year, month) {
15519		return new Date(year, month, 1).getDay();
15520	},
15521
15522	/* Determines if we should allow a "next/prev" month display change. */
15523	_canAdjustMonth: function(inst, offset, curYear, curMonth) {
15524		var numMonths = this._getNumberOfMonths(inst),
15525			date = this._daylightSavingAdjust(new Date(curYear,
15526			curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
15527
15528		if (offset < 0) {
15529			date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
15530		}
15531		return this._isInRange(inst, date);
15532	},
15533
15534	/* Is the given date in the accepted range? */
15535	_isInRange: function(inst, date) {
15536		var yearSplit, currentYear,
15537			minDate = this._getMinMaxDate(inst, "min"),
vendor: 4,850 bytes, lines 15538-15668
15538			maxDate = this._getMinMaxDate(inst, "max"),
15539			minYear = null,
15540			maxYear = null,
15541			years = this._get(inst, "yearRange");
15542			if (years){
15543				yearSplit = years.split(":");
15544				currentYear = new Date().getFullYear();
15545				minYear = parseInt(yearSplit[0], 10);
15546				maxYear = parseInt(yearSplit[1], 10);
15547				if ( yearSplit[0].match(/[+\-].*/) ) {
15548					minYear += currentYear;
15549				}
15550				if ( yearSplit[1].match(/[+\-].*/) ) {
15551					maxYear += currentYear;
15552				}
15553			}
15554
15555		return ((!minDate || date.getTime() >= minDate.getTime()) &&
15556			(!maxDate || date.getTime() <= maxDate.getTime()) &&
15557			(!minYear || date.getFullYear() >= minYear) &&
15558			(!maxYear || date.getFullYear() <= maxYear));
15559	},
15560
15561	/* Provide the configuration settings for formatting/parsing. */
15562	_getFormatConfig: function(inst) {
15563		var shortYearCutoff = this._get(inst, "shortYearCutoff");
15564		shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
15565			new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
15566		return {shortYearCutoff: shortYearCutoff,
15567			dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
15568			monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
15569	},
15570
15571	/* Format the given date for display. */
15572	_formatDate: function(inst, day, month, year) {
15573		if (!day) {
15574			inst.currentDay = inst.selectedDay;
15575			inst.currentMonth = inst.selectedMonth;
15576			inst.currentYear = inst.selectedYear;
15577		}
15578		var date = (day ? (typeof day === "object" ? day :
15579			this._daylightSavingAdjust(new Date(year, month, day))) :
15580			this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
15581		return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
15582	}
15583});
15584
15585/*
15586 * Bind hover events for datepicker elements.
15587 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
15588 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
15589 */
15590function datepicker_bindHover(dpDiv) {
15591	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
15592	return dpDiv.delegate(selector, "mouseout", function() {
15593			$(this).removeClass("ui-state-hover");
15594			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
15595				$(this).removeClass("ui-datepicker-prev-hover");
15596			}
15597			if (this.className.indexOf("ui-datepicker-next") !== -1) {
15598				$(this).removeClass("ui-datepicker-next-hover");
15599			}
15600		})
15601		.delegate( selector, "mouseover", datepicker_handleMouseover );
15602}
15603
15604function datepicker_handleMouseover() {
15605	if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
15606		$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
15607		$(this).addClass("ui-state-hover");
15608		if (this.className.indexOf("ui-datepicker-prev") !== -1) {
15609			$(this).addClass("ui-datepicker-prev-hover");
15610		}
15611		if (this.className.indexOf("ui-datepicker-next") !== -1) {
15612			$(this).addClass("ui-datepicker-next-hover");
15613		}
15614	}
15615}
15616
15617/* jQuery extend now ignores nulls! */
15618function datepicker_extendRemove(target, props) {
15619	$.extend(target, props);
15620	for (var name in props) {
15621		if (props[name] == null) {
15622			target[name] = props[name];
15623		}
15624	}
15625	return target;
15626}
15627
15628/* Invoke the datepicker functionality.
15629   @param  options  string - a command, optionally followed by additional parameters or
15630					Object - settings for attaching new datepicker functionality
15631   @return  jQuery object */
15632$.fn.datepicker = function(options){
15633
15634	/* Verify an empty collection wasn't passed - Fixes #6976 */
15635	if ( !this.length ) {
15636		return this;
15637	}
15638
15639	/* Initialise the date picker. */
15640	if (!$.datepicker.initialized) {
15641		$(document).mousedown($.datepicker._checkExternalClick);
15642		$.datepicker.initialized = true;
15643	}
15644
15645	/* Append datepicker main container to body if not exist. */
15646	if ($("#"+$.datepicker._mainDivId).length === 0) {
15647		$("body").append($.datepicker.dpDiv);
15648	}
15649
15650	var otherArgs = Array.prototype.slice.call(arguments, 1);
15651	if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
15652		return $.datepicker["_" + options + "Datepicker"].
15653			apply($.datepicker, [this[0]].concat(otherArgs));
15654	}
15655	if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
15656		return $.datepicker["_" + options + "Datepicker"].
15657			apply($.datepicker, [this[0]].concat(otherArgs));
15658	}
15659	return this.each(function() {
15660		typeof options === "string" ?
15661			$.datepicker["_" + options + "Datepicker"].
15662				apply($.datepicker, [this].concat(otherArgs)) :
15663			$.datepicker._attachDatepicker(this, options);
15664	});
15665};
15666
15667$.datepicker = new Datepicker(); // singleton instance
15668$.datepicker.initialized = false;
vendor: 44,343 bytes, lines 15669-17189
15669$.datepicker.uuid = new Date().getTime();
15670$.datepicker.version = "1.11.4";
15671
15672var datepicker = $.datepicker;
15673
15674
15675/*!
15676 * jQuery UI Draggable 1.11.4
15677 * http://jqueryui.com
15678 *
15679 * Copyright jQuery Foundation and other contributors
15680 * Released under the MIT license.
15681 * http://jquery.org/license
15682 *
15683 * http://api.jqueryui.com/draggable/
15684 */
15685
15686
15687$.widget("ui.draggable", $.ui.mouse, {
15688	version: "1.11.4",
15689	widgetEventPrefix: "drag",
15690	options: {
15691		addClasses: true,
15692		appendTo: "parent",
15693		axis: false,
15694		connectToSortable: false,
15695		containment: false,
15696		cursor: "auto",
15697		cursorAt: false,
15698		grid: false,
15699		handle: false,
15700		helper: "original",
15701		iframeFix: false,
15702		opacity: false,
15703		refreshPositions: false,
15704		revert: false,
15705		revertDuration: 500,
15706		scope: "default",
15707		scroll: true,
15708		scrollSensitivity: 20,
15709		scrollSpeed: 20,
15710		snap: false,
15711		snapMode: "both",
15712		snapTolerance: 20,
15713		stack: false,
15714		zIndex: false,
15715
15716		// callbacks
15717		drag: null,
15718		start: null,
15719		stop: null
15720	},
15721	_create: function() {
15722
15723		if ( this.options.helper === "original" ) {
15724			this._setPositionRelative();
15725		}
15726		if (this.options.addClasses){
15727			this.element.addClass("ui-draggable");
15728		}
15729		if (this.options.disabled){
15730			this.element.addClass("ui-draggable-disabled");
15731		}
15732		this._setHandleClassName();
15733
15734		this._mouseInit();
15735	},
15736
15737	_setOption: function( key, value ) {
15738		this._super( key, value );
15739		if ( key === "handle" ) {
15740			this._removeHandleClassName();
15741			this._setHandleClassName();
15742		}
15743	},
15744
15745	_destroy: function() {
15746		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
15747			this.destroyOnClear = true;
15748			return;
15749		}
15750		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
15751		this._removeHandleClassName();
15752		this._mouseDestroy();
15753	},
15754
15755	_mouseCapture: function(event) {
15756		var o = this.options;
15757
15758		this._blurActiveElement( event );
15759
15760		// among others, prevent a drag on a resizable-handle
15761		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
15762			return false;
15763		}
15764
15765		//Quit if we're not on a valid handle
15766		this.handle = this._getHandle(event);
15767		if (!this.handle) {
15768			return false;
15769		}
15770
15771		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
15772
15773		return true;
15774
15775	},
15776
15777	_blockFrames: function( selector ) {
15778		this.iframeBlocks = this.document.find( selector ).map(function() {
15779			var iframe = $( this );
15780
15781			return $( "<div>" )
15782				.css( "position", "absolute" )
15783				.appendTo( iframe.parent() )
15784				.outerWidth( iframe.outerWidth() )
15785				.outerHeight( iframe.outerHeight() )
15786				.offset( iframe.offset() )[ 0 ];
15787		});
15788	},
15789
15790	_unblockFrames: function() {
15791		if ( this.iframeBlocks ) {
15792			this.iframeBlocks.remove();
15793			delete this.iframeBlocks;
15794		}
15795	},
15796
15797	_blurActiveElement: function( event ) {
15798		var document = this.document[ 0 ];
15799
15800		// Only need to blur if the event occurred on the draggable itself, see #10527
15801		if ( !this.handleElement.is( event.target ) ) {
15802			return;
15803		}
15804
15805		// support: IE9
15806		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
15807		try {
15808
15809			// Support: IE9, IE10
15810			// If the <body> is blurred, IE will switch windows, see #9520
15811			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {
15812
15813				// Blur any element that currently has focus, see #4261
15814				$( document.activeElement ).blur();
15815			}
15816		} catch ( error ) {}
15817	},
15818
15819	_mouseStart: function(event) {
15820
15821		var o = this.options;
15822
15823		//Create and append the visible helper
15824		this.helper = this._createHelper(event);
15825
15826		this.helper.addClass("ui-draggable-dragging");
15827
15828		//Cache the helper size
15829		this._cacheHelperProportions();
15830
15831		//If ddmanager is used for droppables, set the global draggable
15832		if ($.ui.ddmanager) {
15833			$.ui.ddmanager.current = this;
15834		}
15835
15836		/*
15837		 * - Position generation -
15838		 * This block generates everything position related - it's the core of draggables.
15839		 */
15840
15841		//Cache the margins of the original element
15842		this._cacheMargins();
15843
15844		//Store the helper's css position
15845		this.cssPosition = this.helper.css( "position" );
15846		this.scrollParent = this.helper.scrollParent( true );
15847		this.offsetParent = this.helper.offsetParent();
15848		this.hasFixedAncestor = this.helper.parents().filter(function() {
15849				return $( this ).css( "position" ) === "fixed";
15850			}).length > 0;
15851
15852		//The element's absolute position on the page minus margins
15853		this.positionAbs = this.element.offset();
15854		this._refreshOffsets( event );
15855
15856		//Generate the original position
15857		this.originalPosition = this.position = this._generatePosition( event, false );
15858		this.originalPageX = event.pageX;
15859		this.originalPageY = event.pageY;
15860
15861		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15862		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
15863
15864		//Set a containment if given in the options
15865		this._setContainment();
15866
15867		//Trigger event + callbacks
15868		if (this._trigger("start", event) === false) {
15869			this._clear();
15870			return false;
15871		}
15872
15873		//Recache the helper size
15874		this._cacheHelperProportions();
15875
15876		//Prepare the droppable offsets
15877		if ($.ui.ddmanager && !o.dropBehaviour) {
15878			$.ui.ddmanager.prepareOffsets(this, event);
15879		}
15880
15881		// Reset helper's right/bottom css if they're set and set explicit width/height instead
15882		// as this prevents resizing of elements with right/bottom set (see #7772)
15883		this._normalizeRightBottom();
15884
15885		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
15886
15887		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
15888		if ( $.ui.ddmanager ) {
15889			$.ui.ddmanager.dragStart(this, event);
15890		}
15891
15892		return true;
15893	},
15894
15895	_refreshOffsets: function( event ) {
15896		this.offset = {
15897			top: this.positionAbs.top - this.margins.top,
15898			left: this.positionAbs.left - this.margins.left,
15899			scroll: false,
15900			parent: this._getParentOffset(),
15901			relative: this._getRelativeOffset()
15902		};
15903
15904		this.offset.click = {
15905			left: event.pageX - this.offset.left,
15906			top: event.pageY - this.offset.top
15907		};
15908	},
15909
15910	_mouseDrag: function(event, noPropagation) {
15911		// reset any necessary cached properties (see #5009)
15912		if ( this.hasFixedAncestor ) {
15913			this.offset.parent = this._getParentOffset();
15914		}
15915
15916		//Compute the helpers position
15917		this.position = this._generatePosition( event, true );
15918		this.positionAbs = this._convertPositionTo("absolute");
15919
15920		//Call plugins and callbacks and use the resulting position if something is returned
15921		if (!noPropagation) {
15922			var ui = this._uiHash();
15923			if (this._trigger("drag", event, ui) === false) {
15924				this._mouseUp({});
15925				return false;
15926			}
15927			this.position = ui.position;
15928		}
15929
15930		this.helper[ 0 ].style.left = this.position.left + "px";
15931		this.helper[ 0 ].style.top = this.position.top + "px";
15932
15933		if ($.ui.ddmanager) {
15934			$.ui.ddmanager.drag(this, event);
15935		}
15936
15937		return false;
15938	},
15939
15940	_mouseStop: function(event) {
15941
15942		//If we are using droppables, inform the manager about the drop
15943		var that = this,
15944			dropped = false;
15945		if ($.ui.ddmanager && !this.options.dropBehaviour) {
15946			dropped = $.ui.ddmanager.drop(this, event);
15947		}
15948
15949		//if a drop comes from outside (a sortable)
15950		if (this.dropped) {
15951			dropped = this.dropped;
15952			this.dropped = false;
15953		}
15954
15955		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
15956			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
15957				if (that._trigger("stop", event) !== false) {
15958					that._clear();
15959				}
15960			});
15961		} else {
15962			if (this._trigger("stop", event) !== false) {
15963				this._clear();
15964			}
15965		}
15966
15967		return false;
15968	},
15969
15970	_mouseUp: function( event ) {
15971		this._unblockFrames();
15972
15973		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
15974		if ( $.ui.ddmanager ) {
15975			$.ui.ddmanager.dragStop(this, event);
15976		}
15977
15978		// Only need to focus if the event occurred on the draggable itself, see #10527
15979		if ( this.handleElement.is( event.target ) ) {
15980			// The interaction is over; whether or not the click resulted in a drag, focus the element
15981			this.element.focus();
15982		}
15983
15984		return $.ui.mouse.prototype._mouseUp.call(this, event);
15985	},
15986
15987	cancel: function() {
15988
15989		if (this.helper.is(".ui-draggable-dragging")) {
15990			this._mouseUp({});
15991		} else {
15992			this._clear();
15993		}
15994
15995		return this;
15996
15997	},
15998
15999	_getHandle: function(event) {
16000		return this.options.handle ?
16001			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
16002			true;
16003	},
16004
16005	_setHandleClassName: function() {
16006		this.handleElement = this.options.handle ?
16007			this.element.find( this.options.handle ) : this.element;
16008		this.handleElement.addClass( "ui-draggable-handle" );
16009	},
16010
16011	_removeHandleClassName: function() {
16012		this.handleElement.removeClass( "ui-draggable-handle" );
16013	},
16014
16015	_createHelper: function(event) {
16016
16017		var o = this.options,
16018			helperIsFunction = $.isFunction( o.helper ),
16019			helper = helperIsFunction ?
16020				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
16021				( o.helper === "clone" ?
16022					this.element.clone().removeAttr( "id" ) :
16023					this.element );
16024
16025		if (!helper.parents("body").length) {
16026			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
16027		}
16028
16029		// http://bugs.jqueryui.com/ticket/9446
16030		// a helper function can return the original element
16031		// which wouldn't have been set to relative in _create
16032		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
16033			this._setPositionRelative();
16034		}
16035
16036		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
16037			helper.css("position", "absolute");
16038		}
16039
16040		return helper;
16041
16042	},
16043
16044	_setPositionRelative: function() {
16045		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
16046			this.element[ 0 ].style.position = "relative";
16047		}
16048	},
16049
16050	_adjustOffsetFromHelper: function(obj) {
16051		if (typeof obj === "string") {
16052			obj = obj.split(" ");
16053		}
16054		if ($.isArray(obj)) {
16055			obj = { left: +obj[0], top: +obj[1] || 0 };
16056		}
16057		if ("left" in obj) {
16058			this.offset.click.left = obj.left + this.margins.left;
16059		}
16060		if ("right" in obj) {
16061			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16062		}
16063		if ("top" in obj) {
16064			this.offset.click.top = obj.top + this.margins.top;
16065		}
16066		if ("bottom" in obj) {
16067			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16068		}
16069	},
16070
16071	_isRootNode: function( element ) {
16072		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
16073	},
16074
16075	_getParentOffset: function() {
16076
16077		//Get the offsetParent and cache its position
16078		var po = this.offsetParent.offset(),
16079			document = this.document[ 0 ];
16080
16081		// This is a special case where we need to modify a offset calculated on start, since the following happened:
16082		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
16083		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
16084		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
16085		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
16086			po.left += this.scrollParent.scrollLeft();
16087			po.top += this.scrollParent.scrollTop();
16088		}
16089
16090		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
16091			po = { top: 0, left: 0 };
16092		}
16093
16094		return {
16095			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
16096			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
16097		};
16098
16099	},
16100
16101	_getRelativeOffset: function() {
16102		if ( this.cssPosition !== "relative" ) {
16103			return { top: 0, left: 0 };
16104		}
16105
16106		var p = this.element.position(),
16107			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
16108
16109		return {
16110			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
16111			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
16112		};
16113
16114	},
16115
16116	_cacheMargins: function() {
16117		this.margins = {
16118			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
16119			top: (parseInt(this.element.css("marginTop"), 10) || 0),
16120			right: (parseInt(this.element.css("marginRight"), 10) || 0),
16121			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
16122		};
16123	},
16124
16125	_cacheHelperProportions: function() {
16126		this.helperProportions = {
16127			width: this.helper.outerWidth(),
16128			height: this.helper.outerHeight()
16129		};
16130	},
16131
16132	_setContainment: function() {
16133
16134		var isUserScrollable, c, ce,
16135			o = this.options,
16136			document = this.document[ 0 ];
16137
16138		this.relativeContainer = null;
16139
16140		if ( !o.containment ) {
16141			this.containment = null;
16142			return;
16143		}
16144
16145		if ( o.containment === "window" ) {
16146			this.containment = [
16147				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
16148				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
16149				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
16150				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
16151			];
16152			return;
16153		}
16154
16155		if ( o.containment === "document") {
16156			this.containment = [
16157				0,
16158				0,
16159				$( document ).width() - this.helperProportions.width - this.margins.left,
16160				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
16161			];
16162			return;
16163		}
16164
16165		if ( o.containment.constructor === Array ) {
16166			this.containment = o.containment;
16167			return;
16168		}
16169
16170		if ( o.containment === "parent" ) {
16171			o.containment = this.helper[ 0 ].parentNode;
16172		}
16173
16174		c = $( o.containment );
16175		ce = c[ 0 ];
16176
16177		if ( !ce ) {
16178			return;
16179		}
16180
16181		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
16182
16183		this.containment = [
16184			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
16185			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
16186			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16187				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
16188				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
16189				this.helperProportions.width -
16190				this.margins.left -
16191				this.margins.right,
16192			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16193				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
16194				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
16195				this.helperProportions.height -
16196				this.margins.top -
16197				this.margins.bottom
16198		];
16199		this.relativeContainer = c;
16200	},
16201
16202	_convertPositionTo: function(d, pos) {
16203
16204		if (!pos) {
16205			pos = this.position;
16206		}
16207
16208		var mod = d === "absolute" ? 1 : -1,
16209			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
16210
16211		return {
16212			top: (
16213				pos.top	+																// The absolute mouse position
16214				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
16215				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
16216				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
16217			),
16218			left: (
16219				pos.left +																// The absolute mouse position
16220				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
16221				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
16222				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
16223			)
16224		};
16225
16226	},
16227
16228	_generatePosition: function( event, constrainPosition ) {
16229
16230		var containment, co, top, left,
16231			o = this.options,
16232			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
16233			pageX = event.pageX,
16234			pageY = event.pageY;
16235
16236		// Cache the scroll
16237		if ( !scrollIsRootNode || !this.offset.scroll ) {
16238			this.offset.scroll = {
16239				top: this.scrollParent.scrollTop(),
16240				left: this.scrollParent.scrollLeft()
16241			};
16242		}
16243
16244		/*
16245		 * - Position constraining -
16246		 * Constrain the position to a mix of grid, containment.
16247		 */
16248
16249		// If we are not dragging yet, we won't check for options
16250		if ( constrainPosition ) {
16251			if ( this.containment ) {
16252				if ( this.relativeContainer ){
16253					co = this.relativeContainer.offset();
16254					containment = [
16255						this.containment[ 0 ] + co.left,
16256						this.containment[ 1 ] + co.top,
16257						this.containment[ 2 ] + co.left,
16258						this.containment[ 3 ] + co.top
16259					];
16260				} else {
16261					containment = this.containment;
16262				}
16263
16264				if (event.pageX - this.offset.click.left < containment[0]) {
16265					pageX = containment[0] + this.offset.click.left;
16266				}
16267				if (event.pageY - this.offset.click.top < containment[1]) {
16268					pageY = containment[1] + this.offset.click.top;
16269				}
16270				if (event.pageX - this.offset.click.left > containment[2]) {
16271					pageX = containment[2] + this.offset.click.left;
16272				}
16273				if (event.pageY - this.offset.click.top > containment[3]) {
16274					pageY = containment[3] + this.offset.click.top;
16275				}
16276			}
16277
16278			if (o.grid) {
16279				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
16280				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
16281				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
16282
16283				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
16284				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
16285			}
16286
16287			if ( o.axis === "y" ) {
16288				pageX = this.originalPageX;
16289			}
16290
16291			if ( o.axis === "x" ) {
16292				pageY = this.originalPageY;
16293			}
16294		}
16295
16296		return {
16297			top: (
16298				pageY -																	// The absolute mouse position
16299				this.offset.click.top	-												// Click offset (relative to the element)
16300				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
16301				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
16302				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
16303			),
16304			left: (
16305				pageX -																	// The absolute mouse position
16306				this.offset.click.left -												// Click offset (relative to the element)
16307				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
16308				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
16309				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
16310			)
16311		};
16312
16313	},
16314
16315	_clear: function() {
16316		this.helper.removeClass("ui-draggable-dragging");
16317		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
16318			this.helper.remove();
16319		}
16320		this.helper = null;
16321		this.cancelHelperRemoval = false;
16322		if ( this.destroyOnClear ) {
16323			this.destroy();
16324		}
16325	},
16326
16327	_normalizeRightBottom: function() {
16328		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
16329			this.helper.width( this.helper.width() );
16330			this.helper.css( "right", "auto" );
16331		}
16332		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
16333			this.helper.height( this.helper.height() );
16334			this.helper.css( "bottom", "auto" );
16335		}
16336	},
16337
16338	// From now on bulk stuff - mainly helpers
16339
16340	_trigger: function( type, event, ui ) {
16341		ui = ui || this._uiHash();
16342		$.ui.plugin.call( this, type, [ event, ui, this ], true );
16343
16344		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
16345		if ( /^(drag|start|stop)/.test( type ) ) {
16346			this.positionAbs = this._convertPositionTo( "absolute" );
16347			ui.offset = this.positionAbs;
16348		}
16349		return $.Widget.prototype._trigger.call( this, type, event, ui );
16350	},
16351
16352	plugins: {},
16353
16354	_uiHash: function() {
16355		return {
16356			helper: this.helper,
16357			position: this.position,
16358			originalPosition: this.originalPosition,
16359			offset: this.positionAbs
16360		};
16361	}
16362
16363});
16364
16365$.ui.plugin.add( "draggable", "connectToSortable", {
16366	start: function( event, ui, draggable ) {
16367		var uiSortable = $.extend( {}, ui, {
16368			item: draggable.element
16369		});
16370
16371		draggable.sortables = [];
16372		$( draggable.options.connectToSortable ).each(function() {
16373			var sortable = $( this ).sortable( "instance" );
16374
16375			if ( sortable && !sortable.options.disabled ) {
16376				draggable.sortables.push( sortable );
16377
16378				// refreshPositions is called at drag start to refresh the containerCache
16379				// which is used in drag. This ensures it's initialized and synchronized
16380				// with any changes that might have happened on the page since initialization.
16381				sortable.refreshPositions();
16382				sortable._trigger("activate", event, uiSortable);
16383			}
16384		});
16385	},
16386	stop: function( event, ui, draggable ) {
16387		var uiSortable = $.extend( {}, ui, {
16388			item: draggable.element
16389		});
16390
16391		draggable.cancelHelperRemoval = false;
16392
16393		$.each( draggable.sortables, function() {
16394			var sortable = this;
16395
16396			if ( sortable.isOver ) {
16397				sortable.isOver = 0;
16398
16399				// Allow this sortable to handle removing the helper
16400				draggable.cancelHelperRemoval = true;
16401				sortable.cancelHelperRemoval = false;
16402
16403				// Use _storedCSS To restore properties in the sortable,
16404				// as this also handles revert (#9675) since the draggable
16405				// may have modified them in unexpected ways (#8809)
16406				sortable._storedCSS = {
16407					position: sortable.placeholder.css( "position" ),
16408					top: sortable.placeholder.css( "top" ),
16409					left: sortable.placeholder.css( "left" )
16410				};
16411
16412				sortable._mouseStop(event);
16413
16414				// Once drag has ended, the sortable should return to using
16415				// its original helper, not the shared helper from draggable
16416				sortable.options.helper = sortable.options._helper;
16417			} else {
16418				// Prevent this Sortable from removing the helper.
16419				// However, don't set the draggable to remove the helper
16420				// either as another connected Sortable may yet handle the removal.
16421				sortable.cancelHelperRemoval = true;
16422
16423				sortable._trigger( "deactivate", event, uiSortable );
16424			}
16425		});
16426	},
16427	drag: function( event, ui, draggable ) {
16428		$.each( draggable.sortables, function() {
16429			var innermostIntersecting = false,
16430				sortable = this;
16431
16432			// Copy over variables that sortable's _intersectsWith uses
16433			sortable.positionAbs = draggable.positionAbs;
16434			sortable.helperProportions = draggable.helperProportions;
16435			sortable.offset.click = draggable.offset.click;
16436
16437			if ( sortable._intersectsWith( sortable.containerCache ) ) {
16438				innermostIntersecting = true;
16439
16440				$.each( draggable.sortables, function() {
16441					// Copy over variables that sortable's _intersectsWith uses
16442					this.positionAbs = draggable.positionAbs;
16443					this.helperProportions = draggable.helperProportions;
16444					this.offset.click = draggable.offset.click;
16445
16446					if ( this !== sortable &&
16447							this._intersectsWith( this.containerCache ) &&
16448							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
16449						innermostIntersecting = false;
16450					}
16451
16452					return innermostIntersecting;
16453				});
16454			}
16455
16456			if ( innermostIntersecting ) {
16457				// If it intersects, we use a little isOver variable and set it once,
16458				// so that the move-in stuff gets fired only once.
16459				if ( !sortable.isOver ) {
16460					sortable.isOver = 1;
16461
16462					// Store draggable's parent in case we need to reappend to it later.
16463					draggable._parent = ui.helper.parent();
16464
16465					sortable.currentItem = ui.helper
16466						.appendTo( sortable.element )
16467						.data( "ui-sortable-item", true );
16468
16469					// Store helper option to later restore it
16470					sortable.options._helper = sortable.options.helper;
16471
16472					sortable.options.helper = function() {
16473						return ui.helper[ 0 ];
16474					};
16475
16476					// Fire the start events of the sortable with our passed browser event,
16477					// and our own helper (so it doesn't create a new one)
16478					event.target = sortable.currentItem[ 0 ];
16479					sortable._mouseCapture( event, true );
16480					sortable._mouseStart( event, true, true );
16481
16482					// Because the browser event is way off the new appended portlet,
16483					// modify necessary variables to reflect the changes
16484					sortable.offset.click.top = draggable.offset.click.top;
16485					sortable.offset.click.left = draggable.offset.click.left;
16486					sortable.offset.parent.left -= draggable.offset.parent.left -
16487						sortable.offset.parent.left;
16488					sortable.offset.parent.top -= draggable.offset.parent.top -
16489						sortable.offset.parent.top;
16490
16491					draggable._trigger( "toSortable", event );
16492
16493					// Inform draggable that the helper is in a valid drop zone,
16494					// used solely in the revert option to handle "valid/invalid".
16495					draggable.dropped = sortable.element;
16496
16497					// Need to refreshPositions of all sortables in the case that
16498					// adding to one sortable changes the location of the other sortables (#9675)
16499					$.each( draggable.sortables, function() {
16500						this.refreshPositions();
16501					});
16502
16503					// hack so receive/update callbacks work (mostly)
16504					draggable.currentItem = draggable.element;
16505					sortable.fromOutside = draggable;
16506				}
16507
16508				if ( sortable.currentItem ) {
16509					sortable._mouseDrag( event );
16510					// Copy the sortable's position because the draggable's can potentially reflect
16511					// a relative position, while sortable is always absolute, which the dragged
16512					// element has now become. (#8809)
16513					ui.position = sortable.position;
16514				}
16515			} else {
16516				// If it doesn't intersect with the sortable, and it intersected before,
16517				// we fake the drag stop of the sortable, but make sure it doesn't remove
16518				// the helper by using cancelHelperRemoval.
16519				if ( sortable.isOver ) {
16520
16521					sortable.isOver = 0;
16522					sortable.cancelHelperRemoval = true;
16523
16524					// Calling sortable's mouseStop would trigger a revert,
16525					// so revert must be temporarily false until after mouseStop is called.
16526					sortable.options._revert = sortable.options.revert;
16527					sortable.options.revert = false;
16528
16529					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
16530					sortable._mouseStop( event, true );
16531
16532					// restore sortable behaviors that were modfied
16533					// when the draggable entered the sortable area (#9481)
16534					sortable.options.revert = sortable.options._revert;
16535					sortable.options.helper = sortable.options._helper;
16536
16537					if ( sortable.placeholder ) {
16538						sortable.placeholder.remove();
16539					}
16540
16541					// Restore and recalculate the draggable's offset considering the sortable
16542					// may have modified them in unexpected ways. (#8809, #10669)
16543					ui.helper.appendTo( draggable._parent );
16544					draggable._refreshOffsets( event );
16545					ui.position = draggable._generatePosition( event, true );
16546
16547					draggable._trigger( "fromSortable", event );
16548
16549					// Inform draggable that the helper is no longer in a valid drop zone
16550					draggable.dropped = false;
16551
16552					// Need to refreshPositions of all sortables just in case removing
16553					// from one sortable changes the location of other sortables (#9675)
16554					$.each( draggable.sortables, function() {
16555						this.refreshPositions();
16556					});
16557				}
16558			}
16559		});
16560	}
16561});
16562
16563$.ui.plugin.add("draggable", "cursor", {
16564	start: function( event, ui, instance ) {
16565		var t = $( "body" ),
16566			o = instance.options;
16567
16568		if (t.css("cursor")) {
16569			o._cursor = t.css("cursor");
16570		}
16571		t.css("cursor", o.cursor);
16572	},
16573	stop: function( event, ui, instance ) {
16574		var o = instance.options;
16575		if (o._cursor) {
16576			$("body").css("cursor", o._cursor);
16577		}
16578	}
16579});
16580
16581$.ui.plugin.add("draggable", "opacity", {
16582	start: function( event, ui, instance ) {
16583		var t = $( ui.helper ),
16584			o = instance.options;
16585		if (t.css("opacity")) {
16586			o._opacity = t.css("opacity");
16587		}
16588		t.css("opacity", o.opacity);
16589	},
16590	stop: function( event, ui, instance ) {
16591		var o = instance.options;
16592		if (o._opacity) {
16593			$(ui.helper).css("opacity", o._opacity);
16594		}
16595	}
16596});
16597
16598$.ui.plugin.add("draggable", "scroll", {
16599	start: function( event, ui, i ) {
16600		if ( !i.scrollParentNotHidden ) {
16601			i.scrollParentNotHidden = i.helper.scrollParent( false );
16602		}
16603
16604		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
16605			i.overflowOffset = i.scrollParentNotHidden.offset();
16606		}
16607	},
16608	drag: function( event, ui, i  ) {
16609
16610		var o = i.options,
16611			scrolled = false,
16612			scrollParent = i.scrollParentNotHidden[ 0 ],
16613			document = i.document[ 0 ];
16614
16615		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
16616			if ( !o.axis || o.axis !== "x" ) {
16617				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
16618					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
16619				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
16620					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
16621				}
16622			}
16623
16624			if ( !o.axis || o.axis !== "y" ) {
16625				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
16626					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
16627				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
16628					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
16629				}
16630			}
16631
16632		} else {
16633
16634			if (!o.axis || o.axis !== "x") {
16635				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
16636					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
16637				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
16638					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
16639				}
16640			}
16641
16642			if (!o.axis || o.axis !== "y") {
16643				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
16644					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
16645				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
16646					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
16647				}
16648			}
16649
16650		}
16651
16652		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
16653			$.ui.ddmanager.prepareOffsets(i, event);
16654		}
16655
16656	}
16657});
16658
16659$.ui.plugin.add("draggable", "snap", {
16660	start: function( event, ui, i ) {
16661
16662		var o = i.options;
16663
16664		i.snapElements = [];
16665
16666		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
16667			var $t = $(this),
16668				$o = $t.offset();
16669			if (this !== i.element[0]) {
16670				i.snapElements.push({
16671					item: this,
16672					width: $t.outerWidth(), height: $t.outerHeight(),
16673					top: $o.top, left: $o.left
16674				});
16675			}
16676		});
16677
16678	},
16679	drag: function( event, ui, inst ) {
16680
16681		var ts, bs, ls, rs, l, r, t, b, i, first,
16682			o = inst.options,
16683			d = o.snapTolerance,
16684			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
16685			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
16686
16687		for (i = inst.snapElements.length - 1; i >= 0; i--){
16688
16689			l = inst.snapElements[i].left - inst.margins.left;
16690			r = l + inst.snapElements[i].width;
16691			t = inst.snapElements[i].top - inst.margins.top;
16692			b = t + inst.snapElements[i].height;
16693
16694			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
16695				if (inst.snapElements[i].snapping) {
16696					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
16697				}
16698				inst.snapElements[i].snapping = false;
16699				continue;
16700			}
16701
16702			if (o.snapMode !== "inner") {
16703				ts = Math.abs(t - y2) <= d;
16704				bs = Math.abs(b - y1) <= d;
16705				ls = Math.abs(l - x2) <= d;
16706				rs = Math.abs(r - x1) <= d;
16707				if (ts) {
16708					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
16709				}
16710				if (bs) {
16711					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
16712				}
16713				if (ls) {
16714					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
16715				}
16716				if (rs) {
16717					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
16718				}
16719			}
16720
16721			first = (ts || bs || ls || rs);
16722
16723			if (o.snapMode !== "outer") {
16724				ts = Math.abs(t - y1) <= d;
16725				bs = Math.abs(b - y2) <= d;
16726				ls = Math.abs(l - x1) <= d;
16727				rs = Math.abs(r - x2) <= d;
16728				if (ts) {
16729					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
16730				}
16731				if (bs) {
16732					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
16733				}
16734				if (ls) {
16735					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
16736				}
16737				if (rs) {
16738					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
16739				}
16740			}
16741
16742			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
16743				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
16744			}
16745			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
16746
16747		}
16748
16749	}
16750});
16751
16752$.ui.plugin.add("draggable", "stack", {
16753	start: function( event, ui, instance ) {
16754		var min,
16755			o = instance.options,
16756			group = $.makeArray($(o.stack)).sort(function(a, b) {
16757				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
16758			});
16759
16760		if (!group.length) { return; }
16761
16762		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
16763		$(group).each(function(i) {
16764			$(this).css("zIndex", min + i);
16765		});
16766		this.css("zIndex", (min + group.length));
16767	}
16768});
16769
16770$.ui.plugin.add("draggable", "zIndex", {
16771	start: function( event, ui, instance ) {
16772		var t = $( ui.helper ),
16773			o = instance.options;
16774
16775		if (t.css("zIndex")) {
16776			o._zIndex = t.css("zIndex");
16777		}
16778		t.css("zIndex", o.zIndex);
16779	},
16780	stop: function( event, ui, instance ) {
16781		var o = instance.options;
16782
16783		if (o._zIndex) {
16784			$(ui.helper).css("zIndex", o._zIndex);
16785		}
16786	}
16787});
16788
16789var draggable = $.ui.draggable;
16790
16791
16792/*!
16793 * jQuery UI Resizable 1.11.4
16794 * http://jqueryui.com
16795 *
16796 * Copyright jQuery Foundation and other contributors
16797 * Released under the MIT license.
16798 * http://jquery.org/license
16799 *
16800 * http://api.jqueryui.com/resizable/
16801 */
16802
16803
16804$.widget("ui.resizable", $.ui.mouse, {
16805	version: "1.11.4",
16806	widgetEventPrefix: "resize",
16807	options: {
16808		alsoResize: false,
16809		animate: false,
16810		animateDuration: "slow",
16811		animateEasing: "swing",
16812		aspectRatio: false,
16813		autoHide: false,
16814		containment: false,
16815		ghost: false,
16816		grid: false,
16817		handles: "e,s,se",
16818		helper: false,
16819		maxHeight: null,
16820		maxWidth: null,
16821		minHeight: 10,
16822		minWidth: 10,
16823		// See #7960
16824		zIndex: 90,
16825
16826		// callbacks
16827		resize: null,
16828		start: null,
16829		stop: null
16830	},
16831
16832	_num: function( value ) {
16833		return parseInt( value, 10 ) || 0;
16834	},
16835
16836	_isNumber: function( value ) {
16837		return !isNaN( parseInt( value, 10 ) );
16838	},
16839
16840	_hasScroll: function( el, a ) {
16841
16842		if ( $( el ).css( "overflow" ) === "hidden") {
16843			return false;
16844		}
16845
16846		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
16847			has = false;
16848
16849		if ( el[ scroll ] > 0 ) {
16850			return true;
16851		}
16852
16853		// TODO: determine which cases actually cause this to happen
16854		// if the element doesn't have the scroll set, see if it's possible to
16855		// set the scroll
16856		el[ scroll ] = 1;
16857		has = ( el[ scroll ] > 0 );
16858		el[ scroll ] = 0;
16859		return has;
16860	},
16861
16862	_create: function() {
16863
16864		var n, i, handle, axis, hname,
16865			that = this,
16866			o = this.options;
16867		this.element.addClass("ui-resizable");
16868
16869		$.extend(this, {
16870			_aspectRatio: !!(o.aspectRatio),
16871			aspectRatio: o.aspectRatio,
16872			originalElement: this.element,
16873			_proportionallyResizeElements: [],
16874			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
16875		});
16876
16877		// Wrap the element if it cannot hold child nodes
16878		if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
16879
16880			this.element.wrap(
16881				$("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
16882					position: this.element.css("position"),
16883					width: this.element.outerWidth(),
16884					height: this.element.outerHeight(),
16885					top: this.element.css("top"),
16886					left: this.element.css("left")
16887				})
16888			);
16889
16890			this.element = this.element.parent().data(
16891				"ui-resizable", this.element.resizable( "instance" )
16892			);
16893
16894			this.elementIsWrapper = true;
16895
16896			this.element.css({
16897				marginLeft: this.originalElement.css("marginLeft"),
16898				marginTop: this.originalElement.css("marginTop"),
16899				marginRight: this.originalElement.css("marginRight"),
16900				marginBottom: this.originalElement.css("marginBottom")
16901			});
16902			this.originalElement.css({
16903				marginLeft: 0,
16904				marginTop: 0,
16905				marginRight: 0,
16906				marginBottom: 0
16907			});
16908			// support: Safari
16909			// Prevent Safari textarea resize
16910			this.originalResizeStyle = this.originalElement.css("resize");
16911			this.originalElement.css("resize", "none");
16912
16913			this._proportionallyResizeElements.push( this.originalElement.css({
16914				position: "static",
16915				zoom: 1,
16916				display: "block"
16917			}) );
16918
16919			// support: IE9
16920			// avoid IE jump (hard set the margin)
16921			this.originalElement.css({ margin: this.originalElement.css("margin") });
16922
16923			this._proportionallyResize();
16924		}
16925
16926		this.handles = o.handles ||
16927			( !$(".ui-resizable-handle", this.element).length ?
16928				"e,s,se" : {
16929					n: ".ui-resizable-n",
16930					e: ".ui-resizable-e",
16931					s: ".ui-resizable-s",
16932					w: ".ui-resizable-w",
16933					se: ".ui-resizable-se",
16934					sw: ".ui-resizable-sw",
16935					ne: ".ui-resizable-ne",
16936					nw: ".ui-resizable-nw"
16937				} );
16938
16939		this._handles = $();
16940		if ( this.handles.constructor === String ) {
16941
16942			if ( this.handles === "all") {
16943				this.handles = "n,e,s,w,se,sw,ne,nw";
16944			}
16945
16946			n = this.handles.split(",");
16947			this.handles = {};
16948
16949			for (i = 0; i < n.length; i++) {
16950
16951				handle = $.trim(n[i]);
16952				hname = "ui-resizable-" + handle;
16953				axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
16954
16955				axis.css({ zIndex: o.zIndex });
16956
16957				// TODO : What's going on here?
16958				if ("se" === handle) {
16959					axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
16960				}
16961
16962				this.handles[handle] = ".ui-resizable-" + handle;
16963				this.element.append(axis);
16964			}
16965
16966		}
16967
16968		this._renderAxis = function(target) {
16969
16970			var i, axis, padPos, padWrapper;
16971
16972			target = target || this.element;
16973
16974			for (i in this.handles) {
16975
16976				if (this.handles[i].constructor === String) {
16977					this.handles[i] = this.element.children( this.handles[ i ] ).first().show();
16978				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
16979					this.handles[ i ] = $( this.handles[ i ] );
16980					this._on( this.handles[ i ], { "mousedown": that._mouseDown });
16981				}
16982
16983				if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {
16984
16985					axis = $(this.handles[i], this.element);
16986
16987					padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
16988
16989					padPos = [ "padding",
16990						/ne|nw|n/.test(i) ? "Top" :
16991						/se|sw|s/.test(i) ? "Bottom" :
16992						/^e$/.test(i) ? "Right" : "Left" ].join("");
16993
16994					target.css(padPos, padWrapper);
16995
16996					this._proportionallyResize();
16997				}
16998
16999				this._handles = this._handles.add( this.handles[ i ] );
17000			}
17001		};
17002
17003		// TODO: make renderAxis a prototype function
17004		this._renderAxis(this.element);
17005
17006		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
17007		this._handles.disableSelection();
17008
17009		this._handles.mouseover(function() {
17010			if (!that.resizing) {
17011				if (this.className) {
17012					axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
17013				}
17014				that.axis = axis && axis[1] ? axis[1] : "se";
17015			}
17016		});
17017
17018		if (o.autoHide) {
17019			this._handles.hide();
17020			$(this.element)
17021				.addClass("ui-resizable-autohide")
17022				.mouseenter(function() {
17023					if (o.disabled) {
17024						return;
17025					}
17026					$(this).removeClass("ui-resizable-autohide");
17027					that._handles.show();
17028				})
17029				.mouseleave(function() {
17030					if (o.disabled) {
17031						return;
17032					}
17033					if (!that.resizing) {
17034						$(this).addClass("ui-resizable-autohide");
17035						that._handles.hide();
17036					}
17037				});
17038		}
17039
17040		this._mouseInit();
17041	},
17042
17043	_destroy: function() {
17044
17045		this._mouseDestroy();
17046
17047		var wrapper,
17048			_destroy = function(exp) {
17049				$(exp)
17050					.removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
17051					.removeData("resizable")
17052					.removeData("ui-resizable")
17053					.unbind(".resizable")
17054					.find(".ui-resizable-handle")
17055						.remove();
17056			};
17057
17058		// TODO: Unwrap at same DOM position
17059		if (this.elementIsWrapper) {
17060			_destroy(this.element);
17061			wrapper = this.element;
17062			this.originalElement.css({
17063				position: wrapper.css("position"),
17064				width: wrapper.outerWidth(),
17065				height: wrapper.outerHeight(),
17066				top: wrapper.css("top"),
17067				left: wrapper.css("left")
17068			}).insertAfter( wrapper );
17069			wrapper.remove();
17070		}
17071
17072		this.originalElement.css("resize", this.originalResizeStyle);
17073		_destroy(this.originalElement);
17074
17075		return this;
17076	},
17077
17078	_mouseCapture: function(event) {
17079		var i, handle,
17080			capture = false;
17081
17082		for (i in this.handles) {
17083			handle = $(this.handles[i])[0];
17084			if (handle === event.target || $.contains(handle, event.target)) {
17085				capture = true;
17086			}
17087		}
17088
17089		return !this.options.disabled && capture;
17090	},
17091
17092	_mouseStart: function(event) {
17093
17094		var curleft, curtop, cursor,
17095			o = this.options,
17096			el = this.element;
17097
17098		this.resizing = true;
17099
17100		this._renderProxy();
17101
17102		curleft = this._num(this.helper.css("left"));
17103		curtop = this._num(this.helper.css("top"));
17104
17105		if (o.containment) {
17106			curleft += $(o.containment).scrollLeft() || 0;
17107			curtop += $(o.containment).scrollTop() || 0;
17108		}
17109
17110		this.offset = this.helper.offset();
17111		this.position = { left: curleft, top: curtop };
17112
17113		this.size = this._helper ? {
17114				width: this.helper.width(),
17115				height: this.helper.height()
17116			} : {
17117				width: el.width(),
17118				height: el.height()
17119			};
17120
17121		this.originalSize = this._helper ? {
17122				width: el.outerWidth(),
17123				height: el.outerHeight()
17124			} : {
17125				width: el.width(),
17126				height: el.height()
17127			};
17128
17129		this.sizeDiff = {
17130			width: el.outerWidth() - el.width(),
17131			height: el.outerHeight() - el.height()
17132		};
17133
17134		this.originalPosition = { left: curleft, top: curtop };
17135		this.originalMousePosition = { left: event.pageX, top: event.pageY };
17136
17137		this.aspectRatio = (typeof o.aspectRatio === "number") ?
17138			o.aspectRatio :
17139			((this.originalSize.width / this.originalSize.height) || 1);
17140
17141		cursor = $(".ui-resizable-" + this.axis).css("cursor");
17142		$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
17143
17144		el.addClass("ui-resizable-resizing");
17145		this._propagate("start", event);
17146		return true;
17147	},
17148
17149	_mouseDrag: function(event) {
17150
17151		var data, props,
17152			smp = this.originalMousePosition,
17153			a = this.axis,
17154			dx = (event.pageX - smp.left) || 0,
17155			dy = (event.pageY - smp.top) || 0,
17156			trigger = this._change[a];
17157
17158		this._updatePrevProperties();
17159
17160		if (!trigger) {
17161			return false;
17162		}
17163
17164		data = trigger.apply(this, [ event, dx, dy ]);
17165
17166		this._updateVirtualBoundaries(event.shiftKey);
17167		if (this._aspectRatio || event.shiftKey) {
17168			data = this._updateRatio(data, event);
17169		}
17170
17171		data = this._respectSize(data, event);
17172
17173		this._updateCache(data);
17174
17175		this._propagate("resize", event);
17176
17177		props = this._applyChanges();
17178
17179		if ( !this._helper && this._proportionallyResizeElements.length ) {
17180			this._proportionallyResize();
17181		}
17182
17183		if ( !$.isEmptyObject( props ) ) {
17184			this._updatePrevProperties();
17185			this._trigger( "resize", event, this.ui() );
17186			this._applyChanges();
17187		}
17188
17189		return false;
vendor: 10,889 bytes, lines 17190-17619
17190	},
17191
17192	_mouseStop: function(event) {
17193
17194		this.resizing = false;
17195		var pr, ista, soffseth, soffsetw, s, left, top,
17196			o = this.options, that = this;
17197
17198		if (this._helper) {
17199
17200			pr = this._proportionallyResizeElements;
17201			ista = pr.length && (/textarea/i).test(pr[0].nodeName);
17202			soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
17203			soffsetw = ista ? 0 : that.sizeDiff.width;
17204
17205			s = {
17206				width: (that.helper.width()  - soffsetw),
17207				height: (that.helper.height() - soffseth)
17208			};
17209			left = (parseInt(that.element.css("left"), 10) +
17210				(that.position.left - that.originalPosition.left)) || null;
17211			top = (parseInt(that.element.css("top"), 10) +
17212				(that.position.top - that.originalPosition.top)) || null;
17213
17214			if (!o.animate) {
17215				this.element.css($.extend(s, { top: top, left: left }));
17216			}
17217
17218			that.helper.height(that.size.height);
17219			that.helper.width(that.size.width);
17220
17221			if (this._helper && !o.animate) {
17222				this._proportionallyResize();
17223			}
17224		}
17225
17226		$("body").css("cursor", "auto");
17227
17228		this.element.removeClass("ui-resizable-resizing");
17229
17230		this._propagate("stop", event);
17231
17232		if (this._helper) {
17233			this.helper.remove();
17234		}
17235
17236		return false;
17237
17238	},
17239
17240	_updatePrevProperties: function() {
17241		this.prevPosition = {
17242			top: this.position.top,
17243			left: this.position.left
17244		};
17245		this.prevSize = {
17246			width: this.size.width,
17247			height: this.size.height
17248		};
17249	},
17250
17251	_applyChanges: function() {
17252		var props = {};
17253
17254		if ( this.position.top !== this.prevPosition.top ) {
17255			props.top = this.position.top + "px";
17256		}
17257		if ( this.position.left !== this.prevPosition.left ) {
17258			props.left = this.position.left + "px";
17259		}
17260		if ( this.size.width !== this.prevSize.width ) {
17261			props.width = this.size.width + "px";
17262		}
17263		if ( this.size.height !== this.prevSize.height ) {
17264			props.height = this.size.height + "px";
17265		}
17266
17267		this.helper.css( props );
17268
17269		return props;
17270	},
17271
17272	_updateVirtualBoundaries: function(forceAspectRatio) {
17273		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
17274			o = this.options;
17275
17276		b = {
17277			minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
17278			maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
17279			minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
17280			maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
17281		};
17282
17283		if (this._aspectRatio || forceAspectRatio) {
17284			pMinWidth = b.minHeight * this.aspectRatio;
17285			pMinHeight = b.minWidth / this.aspectRatio;
17286			pMaxWidth = b.maxHeight * this.aspectRatio;
17287			pMaxHeight = b.maxWidth / this.aspectRatio;
17288
17289			if (pMinWidth > b.minWidth) {
17290				b.minWidth = pMinWidth;
17291			}
17292			if (pMinHeight > b.minHeight) {
17293				b.minHeight = pMinHeight;
17294			}
17295			if (pMaxWidth < b.maxWidth) {
17296				b.maxWidth = pMaxWidth;
17297			}
17298			if (pMaxHeight < b.maxHeight) {
17299				b.maxHeight = pMaxHeight;
17300			}
17301		}
17302		this._vBoundaries = b;
17303	},
17304
17305	_updateCache: function(data) {
17306		this.offset = this.helper.offset();
17307		if (this._isNumber(data.left)) {
17308			this.position.left = data.left;
17309		}
17310		if (this._isNumber(data.top)) {
17311			this.position.top = data.top;
17312		}
17313		if (this._isNumber(data.height)) {
17314			this.size.height = data.height;
17315		}
17316		if (this._isNumber(data.width)) {
17317			this.size.width = data.width;
17318		}
17319	},
17320
17321	_updateRatio: function( data ) {
17322
17323		var cpos = this.position,
17324			csize = this.size,
17325			a = this.axis;
17326
17327		if (this._isNumber(data.height)) {
17328			data.width = (data.height * this.aspectRatio);
17329		} else if (this._isNumber(data.width)) {
17330			data.height = (data.width / this.aspectRatio);
17331		}
17332
17333		if (a === "sw") {
17334			data.left = cpos.left + (csize.width - data.width);
17335			data.top = null;
17336		}
17337		if (a === "nw") {
17338			data.top = cpos.top + (csize.height - data.height);
17339			data.left = cpos.left + (csize.width - data.width);
17340		}
17341
17342		return data;
17343	},
17344
17345	_respectSize: function( data ) {
17346
17347		var o = this._vBoundaries,
17348			a = this.axis,
17349			ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
17350			ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
17351			isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
17352			isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
17353			dw = this.originalPosition.left + this.originalSize.width,
17354			dh = this.position.top + this.size.height,
17355			cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
17356		if (isminw) {
17357			data.width = o.minWidth;
17358		}
17359		if (isminh) {
17360			data.height = o.minHeight;
17361		}
17362		if (ismaxw) {
17363			data.width = o.maxWidth;
17364		}
17365		if (ismaxh) {
17366			data.height = o.maxHeight;
17367		}
17368
17369		if (isminw && cw) {
17370			data.left = dw - o.minWidth;
17371		}
17372		if (ismaxw && cw) {
17373			data.left = dw - o.maxWidth;
17374		}
17375		if (isminh && ch) {
17376			data.top = dh - o.minHeight;
17377		}
17378		if (ismaxh && ch) {
17379			data.top = dh - o.maxHeight;
17380		}
17381
17382		// Fixing jump error on top/left - bug #2330
17383		if (!data.width && !data.height && !data.left && data.top) {
17384			data.top = null;
17385		} else if (!data.width && !data.height && !data.top && data.left) {
17386			data.left = null;
17387		}
17388
17389		return data;
17390	},
17391
17392	_getPaddingPlusBorderDimensions: function( element ) {
17393		var i = 0,
17394			widths = [],
17395			borders = [
17396				element.css( "borderTopWidth" ),
17397				element.css( "borderRightWidth" ),
17398				element.css( "borderBottomWidth" ),
17399				element.css( "borderLeftWidth" )
17400			],
17401			paddings = [
17402				element.css( "paddingTop" ),
17403				element.css( "paddingRight" ),
17404				element.css( "paddingBottom" ),
17405				element.css( "paddingLeft" )
17406			];
17407
17408		for ( ; i < 4; i++ ) {
17409			widths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );
17410			widths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );
17411		}
17412
17413		return {
17414			height: widths[ 0 ] + widths[ 2 ],
17415			width: widths[ 1 ] + widths[ 3 ]
17416		};
17417	},
17418
17419	_proportionallyResize: function() {
17420
17421		if (!this._proportionallyResizeElements.length) {
17422			return;
17423		}
17424
17425		var prel,
17426			i = 0,
17427			element = this.helper || this.element;
17428
17429		for ( ; i < this._proportionallyResizeElements.length; i++) {
17430
17431			prel = this._proportionallyResizeElements[i];
17432
17433			// TODO: Seems like a bug to cache this.outerDimensions
17434			// considering that we are in a loop.
17435			if (!this.outerDimensions) {
17436				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
17437			}
17438
17439			prel.css({
17440				height: (element.height() - this.outerDimensions.height) || 0,
17441				width: (element.width() - this.outerDimensions.width) || 0
17442			});
17443
17444		}
17445
17446	},
17447
17448	_renderProxy: function() {
17449
17450		var el = this.element, o = this.options;
17451		this.elementOffset = el.offset();
17452
17453		if (this._helper) {
17454
17455			this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
17456
17457			this.helper.addClass(this._helper).css({
17458				width: this.element.outerWidth() - 1,
17459				height: this.element.outerHeight() - 1,
17460				position: "absolute",
17461				left: this.elementOffset.left + "px",
17462				top: this.elementOffset.top + "px",
17463				zIndex: ++o.zIndex //TODO: Don't modify option
17464			});
17465
17466			this.helper
17467				.appendTo("body")
17468				.disableSelection();
17469
17470		} else {
17471			this.helper = this.element;
17472		}
17473
17474	},
17475
17476	_change: {
17477		e: function(event, dx) {
17478			return { width: this.originalSize.width + dx };
17479		},
17480		w: function(event, dx) {
17481			var cs = this.originalSize, sp = this.originalPosition;
17482			return { left: sp.left + dx, width: cs.width - dx };
17483		},
17484		n: function(event, dx, dy) {
17485			var cs = this.originalSize, sp = this.originalPosition;
17486			return { top: sp.top + dy, height: cs.height - dy };
17487		},
17488		s: function(event, dx, dy) {
17489			return { height: this.originalSize.height + dy };
17490		},
17491		se: function(event, dx, dy) {
17492			return $.extend(this._change.s.apply(this, arguments),
17493				this._change.e.apply(this, [ event, dx, dy ]));
17494		},
17495		sw: function(event, dx, dy) {
17496			return $.extend(this._change.s.apply(this, arguments),
17497				this._change.w.apply(this, [ event, dx, dy ]));
17498		},
17499		ne: function(event, dx, dy) {
17500			return $.extend(this._change.n.apply(this, arguments),
17501				this._change.e.apply(this, [ event, dx, dy ]));
17502		},
17503		nw: function(event, dx, dy) {
17504			return $.extend(this._change.n.apply(this, arguments),
17505				this._change.w.apply(this, [ event, dx, dy ]));
17506		}
17507	},
17508
17509	_propagate: function(n, event) {
17510		$.ui.plugin.call(this, n, [ event, this.ui() ]);
17511		(n !== "resize" && this._trigger(n, event, this.ui()));
17512	},
17513
17514	plugins: {},
17515
17516	ui: function() {
17517		return {
17518			originalElement: this.originalElement,
17519			element: this.element,
17520			helper: this.helper,
17521			position: this.position,
17522			size: this.size,
17523			originalSize: this.originalSize,
17524			originalPosition: this.originalPosition
17525		};
17526	}
17527
17528});
17529
17530/*
17531 * Resizable Extensions
17532 */
17533
17534$.ui.plugin.add("resizable", "animate", {
17535
17536	stop: function( event ) {
17537		var that = $(this).resizable( "instance" ),
17538			o = that.options,
17539			pr = that._proportionallyResizeElements,
17540			ista = pr.length && (/textarea/i).test(pr[0].nodeName),
17541			soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
17542			soffsetw = ista ? 0 : that.sizeDiff.width,
17543			style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
17544			left = (parseInt(that.element.css("left"), 10) +
17545				(that.position.left - that.originalPosition.left)) || null,
17546			top = (parseInt(that.element.css("top"), 10) +
17547				(that.position.top - that.originalPosition.top)) || null;
17548
17549		that.element.animate(
17550			$.extend(style, top && left ? { top: top, left: left } : {}), {
17551				duration: o.animateDuration,
17552				easing: o.animateEasing,
17553				step: function() {
17554
17555					var data = {
17556						width: parseInt(that.element.css("width"), 10),
17557						height: parseInt(that.element.css("height"), 10),
17558						top: parseInt(that.element.css("top"), 10),
17559						left: parseInt(that.element.css("left"), 10)
17560					};
17561
17562					if (pr && pr.length) {
17563						$(pr[0]).css({ width: data.width, height: data.height });
17564					}
17565
17566					// propagating resize, and updating values for each animation step
17567					that._updateCache(data);
17568					that._propagate("resize", event);
17569
17570				}
17571			}
17572		);
17573	}
17574
17575});
17576
17577$.ui.plugin.add( "resizable", "containment", {
17578
17579	start: function() {
17580		var element, p, co, ch, cw, width, height,
17581			that = $( this ).resizable( "instance" ),
17582			o = that.options,
17583			el = that.element,
17584			oc = o.containment,
17585			ce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
17586
17587		if ( !ce ) {
17588			return;
17589		}
17590
17591		that.containerElement = $( ce );
17592
17593		if ( /document/.test( oc ) || oc === document ) {
17594			that.containerOffset = {
17595				left: 0,
17596				top: 0
17597			};
17598			that.containerPosition = {
17599				left: 0,
17600				top: 0
17601			};
17602
17603			that.parentData = {
17604				element: $( document ),
17605				left: 0,
17606				top: 0,
17607				width: $( document ).width(),
17608				height: $( document ).height() || document.body.parentNode.scrollHeight
17609			};
17610		} else {
17611			element = $( ce );
17612			p = [];
17613			$([ "Top", "Right", "Left", "Bottom" ]).each(function( i, name ) {
17614				p[ i ] = that._num( element.css( "padding" + name ) );
17615			});
17616
17617			that.containerOffset = element.offset();
17618			that.containerPosition = element.position();
17619			that.containerSize = {
vendor: 43,899 bytes, lines 17620-19313
17620				height: ( element.innerHeight() - p[ 3 ] ),
17621				width: ( element.innerWidth() - p[ 1 ] )
17622			};
17623
17624			co = that.containerOffset;
17625			ch = that.containerSize.height;
17626			cw = that.containerSize.width;
17627			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
17628			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
17629
17630			that.parentData = {
17631				element: ce,
17632				left: co.left,
17633				top: co.top,
17634				width: width,
17635				height: height
17636			};
17637		}
17638	},
17639
17640	resize: function( event ) {
17641		var woset, hoset, isParent, isOffsetRelative,
17642			that = $( this ).resizable( "instance" ),
17643			o = that.options,
17644			co = that.containerOffset,
17645			cp = that.position,
17646			pRatio = that._aspectRatio || event.shiftKey,
17647			cop = {
17648				top: 0,
17649				left: 0
17650			},
17651			ce = that.containerElement,
17652			continueResize = true;
17653
17654		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
17655			cop = co;
17656		}
17657
17658		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
17659			that.size.width = that.size.width +
17660				( that._helper ?
17661					( that.position.left - co.left ) :
17662					( that.position.left - cop.left ) );
17663
17664			if ( pRatio ) {
17665				that.size.height = that.size.width / that.aspectRatio;
17666				continueResize = false;
17667			}
17668			that.position.left = o.helper ? co.left : 0;
17669		}
17670
17671		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
17672			that.size.height = that.size.height +
17673				( that._helper ?
17674					( that.position.top - co.top ) :
17675					that.position.top );
17676
17677			if ( pRatio ) {
17678				that.size.width = that.size.height * that.aspectRatio;
17679				continueResize = false;
17680			}
17681			that.position.top = that._helper ? co.top : 0;
17682		}
17683
17684		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
17685		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
17686
17687		if ( isParent && isOffsetRelative ) {
17688			that.offset.left = that.parentData.left + that.position.left;
17689			that.offset.top = that.parentData.top + that.position.top;
17690		} else {
17691			that.offset.left = that.element.offset().left;
17692			that.offset.top = that.element.offset().top;
17693		}
17694
17695		woset = Math.abs( that.sizeDiff.width +
17696			(that._helper ?
17697				that.offset.left - cop.left :
17698				(that.offset.left - co.left)) );
17699
17700		hoset = Math.abs( that.sizeDiff.height +
17701			(that._helper ?
17702				that.offset.top - cop.top :
17703				(that.offset.top - co.top)) );
17704
17705		if ( woset + that.size.width >= that.parentData.width ) {
17706			that.size.width = that.parentData.width - woset;
17707			if ( pRatio ) {
17708				that.size.height = that.size.width / that.aspectRatio;
17709				continueResize = false;
17710			}
17711		}
17712
17713		if ( hoset + that.size.height >= that.parentData.height ) {
17714			that.size.height = that.parentData.height - hoset;
17715			if ( pRatio ) {
17716				that.size.width = that.size.height * that.aspectRatio;
17717				continueResize = false;
17718			}
17719		}
17720
17721		if ( !continueResize ) {
17722			that.position.left = that.prevPosition.left;
17723			that.position.top = that.prevPosition.top;
17724			that.size.width = that.prevSize.width;
17725			that.size.height = that.prevSize.height;
17726		}
17727	},
17728
17729	stop: function() {
17730		var that = $( this ).resizable( "instance" ),
17731			o = that.options,
17732			co = that.containerOffset,
17733			cop = that.containerPosition,
17734			ce = that.containerElement,
17735			helper = $( that.helper ),
17736			ho = helper.offset(),
17737			w = helper.outerWidth() - that.sizeDiff.width,
17738			h = helper.outerHeight() - that.sizeDiff.height;
17739
17740		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
17741			$( this ).css({
17742				left: ho.left - cop.left - co.left,
17743				width: w,
17744				height: h
17745			});
17746		}
17747
17748		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
17749			$( this ).css({
17750				left: ho.left - cop.left - co.left,
17751				width: w,
17752				height: h
17753			});
17754		}
17755	}
17756});
17757
17758$.ui.plugin.add("resizable", "alsoResize", {
17759
17760	start: function() {
17761		var that = $(this).resizable( "instance" ),
17762			o = that.options;
17763
17764		$(o.alsoResize).each(function() {
17765			var el = $(this);
17766			el.data("ui-resizable-alsoresize", {
17767				width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
17768				left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
17769			});
17770		});
17771	},
17772
17773	resize: function(event, ui) {
17774		var that = $(this).resizable( "instance" ),
17775			o = that.options,
17776			os = that.originalSize,
17777			op = that.originalPosition,
17778			delta = {
17779				height: (that.size.height - os.height) || 0,
17780				width: (that.size.width - os.width) || 0,
17781				top: (that.position.top - op.top) || 0,
17782				left: (that.position.left - op.left) || 0
17783			};
17784
17785			$(o.alsoResize).each(function() {
17786				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
17787					css = el.parents(ui.originalElement[0]).length ?
17788							[ "width", "height" ] :
17789							[ "width", "height", "top", "left" ];
17790
17791				$.each(css, function(i, prop) {
17792					var sum = (start[prop] || 0) + (delta[prop] || 0);
17793					if (sum && sum >= 0) {
17794						style[prop] = sum || null;
17795					}
17796				});
17797
17798				el.css(style);
17799			});
17800	},
17801
17802	stop: function() {
17803		$(this).removeData("resizable-alsoresize");
17804	}
17805});
17806
17807$.ui.plugin.add("resizable", "ghost", {
17808
17809	start: function() {
17810
17811		var that = $(this).resizable( "instance" ), o = that.options, cs = that.size;
17812
17813		that.ghost = that.originalElement.clone();
17814		that.ghost
17815			.css({
17816				opacity: 0.25,
17817				display: "block",
17818				position: "relative",
17819				height: cs.height,
17820				width: cs.width,
17821				margin: 0,
17822				left: 0,
17823				top: 0
17824			})
17825			.addClass("ui-resizable-ghost")
17826			.addClass(typeof o.ghost === "string" ? o.ghost : "");
17827
17828		that.ghost.appendTo(that.helper);
17829
17830	},
17831
17832	resize: function() {
17833		var that = $(this).resizable( "instance" );
17834		if (that.ghost) {
17835			that.ghost.css({
17836				position: "relative",
17837				height: that.size.height,
17838				width: that.size.width
17839			});
17840		}
17841	},
17842
17843	stop: function() {
17844		var that = $(this).resizable( "instance" );
17845		if (that.ghost && that.helper) {
17846			that.helper.get(0).removeChild(that.ghost.get(0));
17847		}
17848	}
17849
17850});
17851
17852$.ui.plugin.add("resizable", "grid", {
17853
17854	resize: function() {
17855		var outerDimensions,
17856			that = $(this).resizable( "instance" ),
17857			o = that.options,
17858			cs = that.size,
17859			os = that.originalSize,
17860			op = that.originalPosition,
17861			a = that.axis,
17862			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
17863			gridX = (grid[0] || 1),
17864			gridY = (grid[1] || 1),
17865			ox = Math.round((cs.width - os.width) / gridX) * gridX,
17866			oy = Math.round((cs.height - os.height) / gridY) * gridY,
17867			newWidth = os.width + ox,
17868			newHeight = os.height + oy,
17869			isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
17870			isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
17871			isMinWidth = o.minWidth && (o.minWidth > newWidth),
17872			isMinHeight = o.minHeight && (o.minHeight > newHeight);
17873
17874		o.grid = grid;
17875
17876		if (isMinWidth) {
17877			newWidth += gridX;
17878		}
17879		if (isMinHeight) {
17880			newHeight += gridY;
17881		}
17882		if (isMaxWidth) {
17883			newWidth -= gridX;
17884		}
17885		if (isMaxHeight) {
17886			newHeight -= gridY;
17887		}
17888
17889		if (/^(se|s|e)$/.test(a)) {
17890			that.size.width = newWidth;
17891			that.size.height = newHeight;
17892		} else if (/^(ne)$/.test(a)) {
17893			that.size.width = newWidth;
17894			that.size.height = newHeight;
17895			that.position.top = op.top - oy;
17896		} else if (/^(sw)$/.test(a)) {
17897			that.size.width = newWidth;
17898			that.size.height = newHeight;
17899			that.position.left = op.left - ox;
17900		} else {
17901			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {
17902				outerDimensions = that._getPaddingPlusBorderDimensions( this );
17903			}
17904
17905			if ( newHeight - gridY > 0 ) {
17906				that.size.height = newHeight;
17907				that.position.top = op.top - oy;
17908			} else {
17909				newHeight = gridY - outerDimensions.height;
17910				that.size.height = newHeight;
17911				that.position.top = op.top + os.height - newHeight;
17912			}
17913			if ( newWidth - gridX > 0 ) {
17914				that.size.width = newWidth;
17915				that.position.left = op.left - ox;
17916			} else {
17917				newWidth = gridX - outerDimensions.width;
17918				that.size.width = newWidth;
17919				that.position.left = op.left + os.width - newWidth;
17920			}
17921		}
17922	}
17923
17924});
17925
17926var resizable = $.ui.resizable;
17927
17928
17929/*!
17930 * jQuery UI Dialog 1.11.4
17931 * http://jqueryui.com
17932 *
17933 * Copyright jQuery Foundation and other contributors
17934 * Released under the MIT license.
17935 * http://jquery.org/license
17936 *
17937 * http://api.jqueryui.com/dialog/
17938 */
17939
17940
17941var dialog = $.widget( "ui.dialog", {
17942	version: "1.11.4",
17943	options: {
17944		appendTo: "body",
17945		autoOpen: true,
17946		buttons: [],
17947		closeOnEscape: true,
17948		closeText: "Close",
17949		dialogClass: "",
17950		draggable: true,
17951		hide: null,
17952		height: "auto",
17953		maxHeight: null,
17954		maxWidth: null,
17955		minHeight: 150,
17956		minWidth: 150,
17957		modal: false,
17958		position: {
17959			my: "center",
17960			at: "center",
17961			of: window,
17962			collision: "fit",
17963			// Ensure the titlebar is always visible
17964			using: function( pos ) {
17965				var topOffset = $( this ).css( pos ).offset().top;
17966				if ( topOffset < 0 ) {
17967					$( this ).css( "top", pos.top - topOffset );
17968				}
17969			}
17970		},
17971		resizable: true,
17972		show: null,
17973		title: null,
17974		width: 300,
17975
17976		// callbacks
17977		beforeClose: null,
17978		close: null,
17979		drag: null,
17980		dragStart: null,
17981		dragStop: null,
17982		focus: null,
17983		open: null,
17984		resize: null,
17985		resizeStart: null,
17986		resizeStop: null
17987	},
17988
17989	sizeRelatedOptions: {
17990		buttons: true,
17991		height: true,
17992		maxHeight: true,
17993		maxWidth: true,
17994		minHeight: true,
17995		minWidth: true,
17996		width: true
17997	},
17998
17999	resizableRelatedOptions: {
18000		maxHeight: true,
18001		maxWidth: true,
18002		minHeight: true,
18003		minWidth: true
18004	},
18005
18006	_create: function() {
18007		this.originalCss = {
18008			display: this.element[ 0 ].style.display,
18009			width: this.element[ 0 ].style.width,
18010			minHeight: this.element[ 0 ].style.minHeight,
18011			maxHeight: this.element[ 0 ].style.maxHeight,
18012			height: this.element[ 0 ].style.height
18013		};
18014		this.originalPosition = {
18015			parent: this.element.parent(),
18016			index: this.element.parent().children().index( this.element )
18017		};
18018		this.originalTitle = this.element.attr( "title" );
18019		this.options.title = this.options.title || this.originalTitle;
18020
18021		this._createWrapper();
18022
18023		this.element
18024			.show()
18025			.removeAttr( "title" )
18026			.addClass( "ui-dialog-content ui-widget-content" )
18027			.appendTo( this.uiDialog );
18028
18029		this._createTitlebar();
18030		this._createButtonPane();
18031
18032		if ( this.options.draggable && $.fn.draggable ) {
18033			this._makeDraggable();
18034		}
18035		if ( this.options.resizable && $.fn.resizable ) {
18036			this._makeResizable();
18037		}
18038
18039		this._isOpen = false;
18040
18041		this._trackFocus();
18042	},
18043
18044	_init: function() {
18045		if ( this.options.autoOpen ) {
18046			this.open();
18047		}
18048	},
18049
18050	_appendTo: function() {
18051		var element = this.options.appendTo;
18052		if ( element && (element.jquery || element.nodeType) ) {
18053			return $( element );
18054		}
18055		return this.document.find( element || "body" ).eq( 0 );
18056	},
18057
18058	_destroy: function() {
18059		var next,
18060			originalPosition = this.originalPosition;
18061
18062		this._untrackInstance();
18063		this._destroyOverlay();
18064
18065		this.element
18066			.removeUniqueId()
18067			.removeClass( "ui-dialog-content ui-widget-content" )
18068			.css( this.originalCss )
18069			// Without detaching first, the following becomes really slow
18070			.detach();
18071
18072		this.uiDialog.stop( true, true ).remove();
18073
18074		if ( this.originalTitle ) {
18075			this.element.attr( "title", this.originalTitle );
18076		}
18077
18078		next = originalPosition.parent.children().eq( originalPosition.index );
18079		// Don't try to place the dialog next to itself (#8613)
18080		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
18081			next.before( this.element );
18082		} else {
18083			originalPosition.parent.append( this.element );
18084		}
18085	},
18086
18087	widget: function() {
18088		return this.uiDialog;
18089	},
18090
18091	disable: $.noop,
18092	enable: $.noop,
18093
18094	close: function( event ) {
18095		var activeElement,
18096			that = this;
18097
18098		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
18099			return;
18100		}
18101
18102		this._isOpen = false;
18103		this._focusedElement = null;
18104		this._destroyOverlay();
18105		this._untrackInstance();
18106
18107		if ( !this.opener.filter( ":focusable" ).focus().length ) {
18108
18109			// support: IE9
18110			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
18111			try {
18112				activeElement = this.document[ 0 ].activeElement;
18113
18114				// Support: IE9, IE10
18115				// If the <body> is blurred, IE will switch windows, see #4520
18116				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
18117
18118					// Hiding a focused element doesn't trigger blur in WebKit
18119					// so in case we have nothing to focus on, explicitly blur the active element
18120					// https://bugs.webkit.org/show_bug.cgi?id=47182
18121					$( activeElement ).blur();
18122				}
18123			} catch ( error ) {}
18124		}
18125
18126		this._hide( this.uiDialog, this.options.hide, function() {
18127			that._trigger( "close", event );
18128		});
18129	},
18130
18131	isOpen: function() {
18132		return this._isOpen;
18133	},
18134
18135	moveToTop: function() {
18136		this._moveToTop();
18137	},
18138
18139	_moveToTop: function( event, silent ) {
18140		var moved = false,
18141			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
18142				return +$( this ).css( "z-index" );
18143			}).get(),
18144			zIndexMax = Math.max.apply( null, zIndices );
18145
18146		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
18147			this.uiDialog.css( "z-index", zIndexMax + 1 );
18148			moved = true;
18149		}
18150
18151		if ( moved && !silent ) {
18152			this._trigger( "focus", event );
18153		}
18154		return moved;
18155	},
18156
18157	open: function() {
18158		var that = this;
18159		if ( this._isOpen ) {
18160			if ( this._moveToTop() ) {
18161				this._focusTabbable();
18162			}
18163			return;
18164		}
18165
18166		this._isOpen = true;
18167		this.opener = $( this.document[ 0 ].activeElement );
18168
18169		this._size();
18170		this._position();
18171		this._createOverlay();
18172		this._moveToTop( null, true );
18173
18174		// Ensure the overlay is moved to the top with the dialog, but only when
18175		// opening. The overlay shouldn't move after the dialog is open so that
18176		// modeless dialogs opened after the modal dialog stack properly.
18177		if ( this.overlay ) {
18178			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
18179		}
18180
18181		this._show( this.uiDialog, this.options.show, function() {
18182			that._focusTabbable();
18183			that._trigger( "focus" );
18184		});
18185
18186		// Track the dialog immediately upon openening in case a focus event
18187		// somehow occurs outside of the dialog before an element inside the
18188		// dialog is focused (#10152)
18189		this._makeFocusTarget();
18190
18191		this._trigger( "open" );
18192	},
18193
18194	_focusTabbable: function() {
18195		// Set focus to the first match:
18196		// 1. An element that was focused previously
18197		// 2. First element inside the dialog matching [autofocus]
18198		// 3. Tabbable element inside the content element
18199		// 4. Tabbable element inside the buttonpane
18200		// 5. The close button
18201		// 6. The dialog itself
18202		var hasFocus = this._focusedElement;
18203		if ( !hasFocus ) {
18204			hasFocus = this.element.find( "[autofocus]" );
18205		}
18206		if ( !hasFocus.length ) {
18207			hasFocus = this.element.find( ":tabbable" );
18208		}
18209		if ( !hasFocus.length ) {
18210			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
18211		}
18212		if ( !hasFocus.length ) {
18213			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
18214		}
18215		if ( !hasFocus.length ) {
18216			hasFocus = this.uiDialog;
18217		}
18218		hasFocus.eq( 0 ).focus();
18219	},
18220
18221	_keepFocus: function( event ) {
18222		function checkFocus() {
18223			var activeElement = this.document[0].activeElement,
18224				isActive = this.uiDialog[0] === activeElement ||
18225					$.contains( this.uiDialog[0], activeElement );
18226			if ( !isActive ) {
18227				this._focusTabbable();
18228			}
18229		}
18230		event.preventDefault();
18231		checkFocus.call( this );
18232		// support: IE
18233		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
18234		// so we check again later
18235		this._delay( checkFocus );
18236	},
18237
18238	_createWrapper: function() {
18239		this.uiDialog = $("<div>")
18240			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
18241				this.options.dialogClass )
18242			.hide()
18243			.attr({
18244				// Setting tabIndex makes the div focusable
18245				tabIndex: -1,
18246				role: "dialog"
18247			})
18248			.appendTo( this._appendTo() );
18249
18250		this._on( this.uiDialog, {
18251			keydown: function( event ) {
18252				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
18253						event.keyCode === $.ui.keyCode.ESCAPE ) {
18254					event.preventDefault();
18255					this.close( event );
18256					return;
18257				}
18258
18259				// prevent tabbing out of dialogs
18260				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
18261					return;
18262				}
18263				var tabbables = this.uiDialog.find( ":tabbable" ),
18264					first = tabbables.filter( ":first" ),
18265					last = tabbables.filter( ":last" );
18266
18267				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
18268					this._delay(function() {
18269						first.focus();
18270					});
18271					event.preventDefault();
18272				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
18273					this._delay(function() {
18274						last.focus();
18275					});
18276					event.preventDefault();
18277				}
18278			},
18279			mousedown: function( event ) {
18280				if ( this._moveToTop( event ) ) {
18281					this._focusTabbable();
18282				}
18283			}
18284		});
18285
18286		// We assume that any existing aria-describedby attribute means
18287		// that the dialog content is marked up properly
18288		// otherwise we brute force the content as the description
18289		if ( !this.element.find( "[aria-describedby]" ).length ) {
18290			this.uiDialog.attr({
18291				"aria-describedby": this.element.uniqueId().attr( "id" )
18292			});
18293		}
18294	},
18295
18296	_createTitlebar: function() {
18297		var uiDialogTitle;
18298
18299		this.uiDialogTitlebar = $( "<div>" )
18300			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
18301			.prependTo( this.uiDialog );
18302		this._on( this.uiDialogTitlebar, {
18303			mousedown: function( event ) {
18304				// Don't prevent click on close button (#8838)
18305				// Focusing a dialog that is partially scrolled out of view
18306				// causes the browser to scroll it into view, preventing the click event
18307				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
18308					// Dialog isn't getting focus when dragging (#8063)
18309					this.uiDialog.focus();
18310				}
18311			}
18312		});
18313
18314		// support: IE
18315		// Use type="button" to prevent enter keypresses in textboxes from closing the
18316		// dialog in IE (#9312)
18317		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
18318			.button({
18319				label: this.options.closeText,
18320				icons: {
18321					primary: "ui-icon-closethick"
18322				},
18323				text: false
18324			})
18325			.addClass( "ui-dialog-titlebar-close" )
18326			.appendTo( this.uiDialogTitlebar );
18327		this._on( this.uiDialogTitlebarClose, {
18328			click: function( event ) {
18329				event.preventDefault();
18330				this.close( event );
18331			}
18332		});
18333
18334		uiDialogTitle = $( "<span>" )
18335			.uniqueId()
18336			.addClass( "ui-dialog-title" )
18337			.prependTo( this.uiDialogTitlebar );
18338		this._title( uiDialogTitle );
18339
18340		this.uiDialog.attr({
18341			"aria-labelledby": uiDialogTitle.attr( "id" )
18342		});
18343	},
18344
18345	_title: function( title ) {
18346		if ( !this.options.title ) {
18347			title.html( "&#160;" );
18348		}
18349		title.text( this.options.title );
18350	},
18351
18352	_createButtonPane: function() {
18353		this.uiDialogButtonPane = $( "<div>" )
18354			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );
18355
18356		this.uiButtonSet = $( "<div>" )
18357			.addClass( "ui-dialog-buttonset" )
18358			.appendTo( this.uiDialogButtonPane );
18359
18360		this._createButtons();
18361	},
18362
18363	_createButtons: function() {
18364		var that = this,
18365			buttons = this.options.buttons;
18366
18367		// if we already have a button pane, remove it
18368		this.uiDialogButtonPane.remove();
18369		this.uiButtonSet.empty();
18370
18371		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
18372			this.uiDialog.removeClass( "ui-dialog-buttons" );
18373			return;
18374		}
18375
18376		$.each( buttons, function( name, props ) {
18377			var click, buttonOptions;
18378			props = $.isFunction( props ) ?
18379				{ click: props, text: name } :
18380				props;
18381			// Default to a non-submitting button
18382			props = $.extend( { type: "button" }, props );
18383			// Change the context for the click callback to be the main element
18384			click = props.click;
18385			props.click = function() {
18386				click.apply( that.element[ 0 ], arguments );
18387			};
18388			buttonOptions = {
18389				icons: props.icons,
18390				text: props.showText
18391			};
18392			delete props.icons;
18393			delete props.showText;
18394			$( "<button></button>", props )
18395				.button( buttonOptions )
18396				.appendTo( that.uiButtonSet );
18397		});
18398		this.uiDialog.addClass( "ui-dialog-buttons" );
18399		this.uiDialogButtonPane.appendTo( this.uiDialog );
18400	},
18401
18402	_makeDraggable: function() {
18403		var that = this,
18404			options = this.options;
18405
18406		function filteredUi( ui ) {
18407			return {
18408				position: ui.position,
18409				offset: ui.offset
18410			};
18411		}
18412
18413		this.uiDialog.draggable({
18414			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
18415			handle: ".ui-dialog-titlebar",
18416			containment: "document",
18417			start: function( event, ui ) {
18418				$( this ).addClass( "ui-dialog-dragging" );
18419				that._blockFrames();
18420				that._trigger( "dragStart", event, filteredUi( ui ) );
18421			},
18422			drag: function( event, ui ) {
18423				that._trigger( "drag", event, filteredUi( ui ) );
18424			},
18425			stop: function( event, ui ) {
18426				var left = ui.offset.left - that.document.scrollLeft(),
18427					top = ui.offset.top - that.document.scrollTop();
18428
18429				options.position = {
18430					my: "left top",
18431					at: "left" + (left >= 0 ? "+" : "") + left + " " +
18432						"top" + (top >= 0 ? "+" : "") + top,
18433					of: that.window
18434				};
18435				$( this ).removeClass( "ui-dialog-dragging" );
18436				that._unblockFrames();
18437				that._trigger( "dragStop", event, filteredUi( ui ) );
18438			}
18439		});
18440	},
18441
18442	_makeResizable: function() {
18443		var that = this,
18444			options = this.options,
18445			handles = options.resizable,
18446			// .ui-resizable has position: relative defined in the stylesheet
18447			// but dialogs have to use absolute or fixed positioning
18448			position = this.uiDialog.css("position"),
18449			resizeHandles = typeof handles === "string" ?
18450				handles	:
18451				"n,e,s,w,se,sw,ne,nw";
18452
18453		function filteredUi( ui ) {
18454			return {
18455				originalPosition: ui.originalPosition,
18456				originalSize: ui.originalSize,
18457				position: ui.position,
18458				size: ui.size
18459			};
18460		}
18461
18462		this.uiDialog.resizable({
18463			cancel: ".ui-dialog-content",
18464			containment: "document",
18465			alsoResize: this.element,
18466			maxWidth: options.maxWidth,
18467			maxHeight: options.maxHeight,
18468			minWidth: options.minWidth,
18469			minHeight: this._minHeight(),
18470			handles: resizeHandles,
18471			start: function( event, ui ) {
18472				$( this ).addClass( "ui-dialog-resizing" );
18473				that._blockFrames();
18474				that._trigger( "resizeStart", event, filteredUi( ui ) );
18475			},
18476			resize: function( event, ui ) {
18477				that._trigger( "resize", event, filteredUi( ui ) );
18478			},
18479			stop: function( event, ui ) {
18480				var offset = that.uiDialog.offset(),
18481					left = offset.left - that.document.scrollLeft(),
18482					top = offset.top - that.document.scrollTop();
18483
18484				options.height = that.uiDialog.height();
18485				options.width = that.uiDialog.width();
18486				options.position = {
18487					my: "left top",
18488					at: "left" + (left >= 0 ? "+" : "") + left + " " +
18489						"top" + (top >= 0 ? "+" : "") + top,
18490					of: that.window
18491				};
18492				$( this ).removeClass( "ui-dialog-resizing" );
18493				that._unblockFrames();
18494				that._trigger( "resizeStop", event, filteredUi( ui ) );
18495			}
18496		})
18497		.css( "position", position );
18498	},
18499
18500	_trackFocus: function() {
18501		this._on( this.widget(), {
18502			focusin: function( event ) {
18503				this._makeFocusTarget();
18504				this._focusedElement = $( event.target );
18505			}
18506		});
18507	},
18508
18509	_makeFocusTarget: function() {
18510		this._untrackInstance();
18511		this._trackingInstances().unshift( this );
18512	},
18513
18514	_untrackInstance: function() {
18515		var instances = this._trackingInstances(),
18516			exists = $.inArray( this, instances );
18517		if ( exists !== -1 ) {
18518			instances.splice( exists, 1 );
18519		}
18520	},
18521
18522	_trackingInstances: function() {
18523		var instances = this.document.data( "ui-dialog-instances" );
18524		if ( !instances ) {
18525			instances = [];
18526			this.document.data( "ui-dialog-instances", instances );
18527		}
18528		return instances;
18529	},
18530
18531	_minHeight: function() {
18532		var options = this.options;
18533
18534		return options.height === "auto" ?
18535			options.minHeight :
18536			Math.min( options.minHeight, options.height );
18537	},
18538
18539	_position: function() {
18540		// Need to show the dialog to get the actual offset in the position plugin
18541		var isVisible = this.uiDialog.is( ":visible" );
18542		if ( !isVisible ) {
18543			this.uiDialog.show();
18544		}
18545		this.uiDialog.position( this.options.position );
18546		if ( !isVisible ) {
18547			this.uiDialog.hide();
18548		}
18549	},
18550
18551	_setOptions: function( options ) {
18552		var that = this,
18553			resize = false,
18554			resizableOptions = {};
18555
18556		$.each( options, function( key, value ) {
18557			that._setOption( key, value );
18558
18559			if ( key in that.sizeRelatedOptions ) {
18560				resize = true;
18561			}
18562			if ( key in that.resizableRelatedOptions ) {
18563				resizableOptions[ key ] = value;
18564			}
18565		});
18566
18567		if ( resize ) {
18568			this._size();
18569			this._position();
18570		}
18571		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
18572			this.uiDialog.resizable( "option", resizableOptions );
18573		}
18574	},
18575
18576	_setOption: function( key, value ) {
18577		var isDraggable, isResizable,
18578			uiDialog = this.uiDialog;
18579
18580		if ( key === "dialogClass" ) {
18581			uiDialog
18582				.removeClass( this.options.dialogClass )
18583				.addClass( value );
18584		}
18585
18586		if ( key === "disabled" ) {
18587			return;
18588		}
18589
18590		this._super( key, value );
18591
18592		if ( key === "appendTo" ) {
18593			this.uiDialog.appendTo( this._appendTo() );
18594		}
18595
18596		if ( key === "buttons" ) {
18597			this._createButtons();
18598		}
18599
18600		if ( key === "closeText" ) {
18601			this.uiDialogTitlebarClose.button({
18602				// Ensure that we always pass a string
18603				label: "" + value
18604			});
18605		}
18606
18607		if ( key === "draggable" ) {
18608			isDraggable = uiDialog.is( ":data(ui-draggable)" );
18609			if ( isDraggable && !value ) {
18610				uiDialog.draggable( "destroy" );
18611			}
18612
18613			if ( !isDraggable && value ) {
18614				this._makeDraggable();
18615			}
18616		}
18617
18618		if ( key === "position" ) {
18619			this._position();
18620		}
18621
18622		if ( key === "resizable" ) {
18623			// currently resizable, becoming non-resizable
18624			isResizable = uiDialog.is( ":data(ui-resizable)" );
18625			if ( isResizable && !value ) {
18626				uiDialog.resizable( "destroy" );
18627			}
18628
18629			// currently resizable, changing handles
18630			if ( isResizable && typeof value === "string" ) {
18631				uiDialog.resizable( "option", "handles", value );
18632			}
18633
18634			// currently non-resizable, becoming resizable
18635			if ( !isResizable && value !== false ) {
18636				this._makeResizable();
18637			}
18638		}
18639
18640		if ( key === "title" ) {
18641			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
18642		}
18643	},
18644
18645	_size: function() {
18646		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
18647		// divs will both have width and height set, so we need to reset them
18648		var nonContentHeight, minContentHeight, maxContentHeight,
18649			options = this.options;
18650
18651		// Reset content sizing
18652		this.element.show().css({
18653			width: "auto",
18654			minHeight: 0,
18655			maxHeight: "none",
18656			height: 0
18657		});
18658
18659		if ( options.minWidth > options.width ) {
18660			options.width = options.minWidth;
18661		}
18662
18663		// reset wrapper sizing
18664		// determine the height of all the non-content elements
18665		nonContentHeight = this.uiDialog.css({
18666				height: "auto",
18667				width: options.width
18668			})
18669			.outerHeight();
18670		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
18671		maxContentHeight = typeof options.maxHeight === "number" ?
18672			Math.max( 0, options.maxHeight - nonContentHeight ) :
18673			"none";
18674
18675		if ( options.height === "auto" ) {
18676			this.element.css({
18677				minHeight: minContentHeight,
18678				maxHeight: maxContentHeight,
18679				height: "auto"
18680			});
18681		} else {
18682			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
18683		}
18684
18685		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
18686			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
18687		}
18688	},
18689
18690	_blockFrames: function() {
18691		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
18692			var iframe = $( this );
18693
18694			return $( "<div>" )
18695				.css({
18696					position: "absolute",
18697					width: iframe.outerWidth(),
18698					height: iframe.outerHeight()
18699				})
18700				.appendTo( iframe.parent() )
18701				.offset( iframe.offset() )[0];
18702		});
18703	},
18704
18705	_unblockFrames: function() {
18706		if ( this.iframeBlocks ) {
18707			this.iframeBlocks.remove();
18708			delete this.iframeBlocks;
18709		}
18710	},
18711
18712	_allowInteraction: function( event ) {
18713		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
18714			return true;
18715		}
18716
18717		// TODO: Remove hack when datepicker implements
18718		// the .ui-front logic (#8989)
18719		return !!$( event.target ).closest( ".ui-datepicker" ).length;
18720	},
18721
18722	_createOverlay: function() {
18723		if ( !this.options.modal ) {
18724			return;
18725		}
18726
18727		// We use a delay in case the overlay is created from an
18728		// event that we're going to be cancelling (#2804)
18729		var isOpening = true;
18730		this._delay(function() {
18731			isOpening = false;
18732		});
18733
18734		if ( !this.document.data( "ui-dialog-overlays" ) ) {
18735
18736			// Prevent use of anchors and inputs
18737			// Using _on() for an event handler shared across many instances is
18738			// safe because the dialogs stack and must be closed in reverse order
18739			this._on( this.document, {
18740				focusin: function( event ) {
18741					if ( isOpening ) {
18742						return;
18743					}
18744
18745					if ( !this._allowInteraction( event ) ) {
18746						event.preventDefault();
18747						this._trackingInstances()[ 0 ]._focusTabbable();
18748					}
18749				}
18750			});
18751		}
18752
18753		this.overlay = $( "<div>" )
18754			.addClass( "ui-widget-overlay ui-front" )
18755			.appendTo( this._appendTo() );
18756		this._on( this.overlay, {
18757			mousedown: "_keepFocus"
18758		});
18759		this.document.data( "ui-dialog-overlays",
18760			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
18761	},
18762
18763	_destroyOverlay: function() {
18764		if ( !this.options.modal ) {
18765			return;
18766		}
18767
18768		if ( this.overlay ) {
18769			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
18770
18771			if ( !overlays ) {
18772				this.document
18773					.unbind( "focusin" )
18774					.removeData( "ui-dialog-overlays" );
18775			} else {
18776				this.document.data( "ui-dialog-overlays", overlays );
18777			}
18778
18779			this.overlay.remove();
18780			this.overlay = null;
18781		}
18782	}
18783});
18784
18785
18786/*!
18787 * jQuery UI Droppable 1.11.4
18788 * http://jqueryui.com
18789 *
18790 * Copyright jQuery Foundation and other contributors
18791 * Released under the MIT license.
18792 * http://jquery.org/license
18793 *
18794 * http://api.jqueryui.com/droppable/
18795 */
18796
18797
18798$.widget( "ui.droppable", {
18799	version: "1.11.4",
18800	widgetEventPrefix: "drop",
18801	options: {
18802		accept: "*",
18803		activeClass: false,
18804		addClasses: true,
18805		greedy: false,
18806		hoverClass: false,
18807		scope: "default",
18808		tolerance: "intersect",
18809
18810		// callbacks
18811		activate: null,
18812		deactivate: null,
18813		drop: null,
18814		out: null,
18815		over: null
18816	},
18817	_create: function() {
18818
18819		var proportions,
18820			o = this.options,
18821			accept = o.accept;
18822
18823		this.isover = false;
18824		this.isout = true;
18825
18826		this.accept = $.isFunction( accept ) ? accept : function( d ) {
18827			return d.is( accept );
18828		};
18829
18830		this.proportions = function( /* valueToWrite */ ) {
18831			if ( arguments.length ) {
18832				// Store the droppable's proportions
18833				proportions = arguments[ 0 ];
18834			} else {
18835				// Retrieve or derive the droppable's proportions
18836				return proportions ?
18837					proportions :
18838					proportions = {
18839						width: this.element[ 0 ].offsetWidth,
18840						height: this.element[ 0 ].offsetHeight
18841					};
18842			}
18843		};
18844
18845		this._addToManager( o.scope );
18846
18847		o.addClasses && this.element.addClass( "ui-droppable" );
18848
18849	},
18850
18851	_addToManager: function( scope ) {
18852		// Add the reference and positions to the manager
18853		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
18854		$.ui.ddmanager.droppables[ scope ].push( this );
18855	},
18856
18857	_splice: function( drop ) {
18858		var i = 0;
18859		for ( ; i < drop.length; i++ ) {
18860			if ( drop[ i ] === this ) {
18861				drop.splice( i, 1 );
18862			}
18863		}
18864	},
18865
18866	_destroy: function() {
18867		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
18868
18869		this._splice( drop );
18870
18871		this.element.removeClass( "ui-droppable ui-droppable-disabled" );
18872	},
18873
18874	_setOption: function( key, value ) {
18875
18876		if ( key === "accept" ) {
18877			this.accept = $.isFunction( value ) ? value : function( d ) {
18878				return d.is( value );
18879			};
18880		} else if ( key === "scope" ) {
18881			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
18882
18883			this._splice( drop );
18884			this._addToManager( value );
18885		}
18886
18887		this._super( key, value );
18888	},
18889
18890	_activate: function( event ) {
18891		var draggable = $.ui.ddmanager.current;
18892		if ( this.options.activeClass ) {
18893			this.element.addClass( this.options.activeClass );
18894		}
18895		if ( draggable ){
18896			this._trigger( "activate", event, this.ui( draggable ) );
18897		}
18898	},
18899
18900	_deactivate: function( event ) {
18901		var draggable = $.ui.ddmanager.current;
18902		if ( this.options.activeClass ) {
18903			this.element.removeClass( this.options.activeClass );
18904		}
18905		if ( draggable ){
18906			this._trigger( "deactivate", event, this.ui( draggable ) );
18907		}
18908	},
18909
18910	_over: function( event ) {
18911
18912		var draggable = $.ui.ddmanager.current;
18913
18914		// Bail if draggable and droppable are same element
18915		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
18916			return;
18917		}
18918
18919		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
18920			if ( this.options.hoverClass ) {
18921				this.element.addClass( this.options.hoverClass );
18922			}
18923			this._trigger( "over", event, this.ui( draggable ) );
18924		}
18925
18926	},
18927
18928	_out: function( event ) {
18929
18930		var draggable = $.ui.ddmanager.current;
18931
18932		// Bail if draggable and droppable are same element
18933		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
18934			return;
18935		}
18936
18937		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
18938			if ( this.options.hoverClass ) {
18939				this.element.removeClass( this.options.hoverClass );
18940			}
18941			this._trigger( "out", event, this.ui( draggable ) );
18942		}
18943
18944	},
18945
18946	_drop: function( event, custom ) {
18947
18948		var draggable = custom || $.ui.ddmanager.current,
18949			childrenIntersection = false;
18950
18951		// Bail if draggable and droppable are same element
18952		if ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {
18953			return false;
18954		}
18955
18956		this.element.find( ":data(ui-droppable)" ).not( ".ui-draggable-dragging" ).each(function() {
18957			var inst = $( this ).droppable( "instance" );
18958			if (
18959				inst.options.greedy &&
18960				!inst.options.disabled &&
18961				inst.options.scope === draggable.options.scope &&
18962				inst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&
18963				$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )
18964			) { childrenIntersection = true; return false; }
18965		});
18966		if ( childrenIntersection ) {
18967			return false;
18968		}
18969
18970		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
18971			if ( this.options.activeClass ) {
18972				this.element.removeClass( this.options.activeClass );
18973			}
18974			if ( this.options.hoverClass ) {
18975				this.element.removeClass( this.options.hoverClass );
18976			}
18977			this._trigger( "drop", event, this.ui( draggable ) );
18978			return this.element;
18979		}
18980
18981		return false;
18982
18983	},
18984
18985	ui: function( c ) {
18986		return {
18987			draggable: ( c.currentItem || c.element ),
18988			helper: c.helper,
18989			position: c.position,
18990			offset: c.positionAbs
18991		};
18992	}
18993
18994});
18995
18996$.ui.intersect = (function() {
18997	function isOverAxis( x, reference, size ) {
18998		return ( x >= reference ) && ( x < ( reference + size ) );
18999	}
19000
19001	return function( draggable, droppable, toleranceMode, event ) {
19002
19003		if ( !droppable.offset ) {
19004			return false;
19005		}
19006
19007		var x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,
19008			y1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,
19009			x2 = x1 + draggable.helperProportions.width,
19010			y2 = y1 + draggable.helperProportions.height,
19011			l = droppable.offset.left,
19012			t = droppable.offset.top,
19013			r = l + droppable.proportions().width,
19014			b = t + droppable.proportions().height;
19015
19016		switch ( toleranceMode ) {
19017		case "fit":
19018			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
19019		case "intersect":
19020			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
19021				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
19022				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
19023				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
19024		case "pointer":
19025			return isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );
19026		case "touch":
19027			return (
19028				( y1 >= t && y1 <= b ) || // Top edge touching
19029				( y2 >= t && y2 <= b ) || // Bottom edge touching
19030				( y1 < t && y2 > b ) // Surrounded vertically
19031			) && (
19032				( x1 >= l && x1 <= r ) || // Left edge touching
19033				( x2 >= l && x2 <= r ) || // Right edge touching
19034				( x1 < l && x2 > r ) // Surrounded horizontally
19035			);
19036		default:
19037			return false;
19038		}
19039	};
19040})();
19041
19042/*
19043	This manager tracks offsets of draggables and droppables
19044*/
19045$.ui.ddmanager = {
19046	current: null,
19047	droppables: { "default": [] },
19048	prepareOffsets: function( t, event ) {
19049
19050		var i, j,
19051			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
19052			type = event ? event.type : null, // workaround for #2317
19053			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
19054
19055		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
19056
19057			// No disabled and non-accepted
19058			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {
19059				continue;
19060			}
19061
19062			// Filter out elements in the current dragged item
19063			for ( j = 0; j < list.length; j++ ) {
19064				if ( list[ j ] === m[ i ].element[ 0 ] ) {
19065					m[ i ].proportions().height = 0;
19066					continue droppablesLoop;
19067				}
19068			}
19069
19070			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
19071			if ( !m[ i ].visible ) {
19072				continue;
19073			}
19074
19075			// Activate the droppable if used directly from draggables
19076			if ( type === "mousedown" ) {
19077				m[ i ]._activate.call( m[ i ], event );
19078			}
19079
19080			m[ i ].offset = m[ i ].element.offset();
19081			m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
19082
19083		}
19084
19085	},
19086	drop: function( draggable, event ) {
19087
19088		var dropped = false;
19089		// Create a copy of the droppables in case the list changes during the drop (#9116)
19090		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
19091
19092			if ( !this.options ) {
19093				return;
19094			}
19095			if ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
19096				dropped = this._drop.call( this, event ) || dropped;
19097			}
19098
19099			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {
19100				this.isout = true;
19101				this.isover = false;
19102				this._deactivate.call( this, event );
19103			}
19104
19105		});
19106		return dropped;
19107
19108	},
19109	dragStart: function( draggable, event ) {
19110		// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
19111		draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
19112			if ( !draggable.options.refreshPositions ) {
19113				$.ui.ddmanager.prepareOffsets( draggable, event );
19114			}
19115		});
19116	},
19117	drag: function( draggable, event ) {
19118
19119		// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
19120		if ( draggable.options.refreshPositions ) {
19121			$.ui.ddmanager.prepareOffsets( draggable, event );
19122		}
19123
19124		// Run through all droppables and check their positions based on specific tolerance options
19125		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
19126
19127			if ( this.options.disabled || this.greedyChild || !this.visible ) {
19128				return;
19129			}
19130
19131			var parentInstance, scope, parent,
19132				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
19133				c = !intersects && this.isover ? "isout" : ( intersects && !this.isover ? "isover" : null );
19134			if ( !c ) {
19135				return;
19136			}
19137
19138			if ( this.options.greedy ) {
19139				// find droppable parents with same scope
19140				scope = this.options.scope;
19141				parent = this.element.parents( ":data(ui-droppable)" ).filter(function() {
19142					return $( this ).droppable( "instance" ).options.scope === scope;
19143				});
19144
19145				if ( parent.length ) {
19146					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
19147					parentInstance.greedyChild = ( c === "isover" );
19148				}
19149			}
19150
19151			// we just moved into a greedy child
19152			if ( parentInstance && c === "isover" ) {
19153				parentInstance.isover = false;
19154				parentInstance.isout = true;
19155				parentInstance._out.call( parentInstance, event );
19156			}
19157
19158			this[ c ] = true;
19159			this[c === "isout" ? "isover" : "isout"] = false;
19160			this[c === "isover" ? "_over" : "_out"].call( this, event );
19161
19162			// we just moved out of a greedy child
19163			if ( parentInstance && c === "isout" ) {
19164				parentInstance.isout = false;
19165				parentInstance.isover = true;
19166				parentInstance._over.call( parentInstance, event );
19167			}
19168		});
19169
19170	},
19171	dragStop: function( draggable, event ) {
19172		draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
19173		// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
19174		if ( !draggable.options.refreshPositions ) {
19175			$.ui.ddmanager.prepareOffsets( draggable, event );
19176		}
19177	}
19178};
19179
19180var droppable = $.ui.droppable;
19181
19182
19183/*!
19184 * jQuery UI Effects 1.11.4
19185 * http://jqueryui.com
19186 *
19187 * Copyright jQuery Foundation and other contributors
19188 * Released under the MIT license.
19189 * http://jquery.org/license
19190 *
19191 * http://api.jqueryui.com/category/effects-core/
19192 */
19193
19194
19195var dataSpace = "ui-effects-",
19196
19197	// Create a local jQuery because jQuery Color relies on it and the
19198	// global may not exist with AMD and a custom build (#10199)
19199	jQuery = $;
19200
19201$.effects = {
19202	effect: {}
19203};
19204
19205/*!
19206 * jQuery Color Animations v2.1.2
19207 * https://github.com/jquery/jquery-color
19208 *
19209 * Copyright 2014 jQuery Foundation and other contributors
19210 * Released under the MIT license.
19211 * http://jquery.org/license
19212 *
19213 * Date: Wed Jan 16 08:47:09 2013 -0600
19214 */
19215(function( jQuery, undefined ) {
19216
19217	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
19218
19219	// plusequals test for += 100 -= 100
19220	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
19221	// a set of RE's that can match strings and generate color tuples.
19222	stringParsers = [ {
19223			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
19224			parse: function( execResult ) {
19225				return [
19226					execResult[ 1 ],
19227					execResult[ 2 ],
19228					execResult[ 3 ],
19229					execResult[ 4 ]
19230				];
19231			}
19232		}, {
19233			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
19234			parse: function( execResult ) {
19235				return [
19236					execResult[ 1 ] * 2.55,
19237					execResult[ 2 ] * 2.55,
19238					execResult[ 3 ] * 2.55,
19239					execResult[ 4 ]
19240				];
19241			}
19242		}, {
19243			// this regex ignores A-F because it's compared against an already lowercased string
19244			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
19245			parse: function( execResult ) {
19246				return [
19247					parseInt( execResult[ 1 ], 16 ),
19248					parseInt( execResult[ 2 ], 16 ),
19249					parseInt( execResult[ 3 ], 16 )
19250				];
19251			}
19252		}, {
19253			// this regex ignores A-F because it's compared against an already lowercased string
19254			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
19255			parse: function( execResult ) {
19256				return [
19257					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
19258					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
19259					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
19260				];
19261			}
19262		}, {
19263			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
19264			space: "hsla",
19265			parse: function( execResult ) {
19266				return [
19267					execResult[ 1 ],
19268					execResult[ 2 ] / 100,
19269					execResult[ 3 ] / 100,
19270					execResult[ 4 ]
19271				];
19272			}
19273		} ],
19274
19275	// jQuery.Color( )
19276	color = jQuery.Color = function( color, green, blue, alpha ) {
19277		return new jQuery.Color.fn.parse( color, green, blue, alpha );
19278	},
19279	spaces = {
19280		rgba: {
19281			props: {
19282				red: {
19283					idx: 0,
19284					type: "byte"
19285				},
19286				green: {
19287					idx: 1,
19288					type: "byte"
19289				},
19290				blue: {
19291					idx: 2,
19292					type: "byte"
19293				}
19294			}
19295		},
19296
19297		hsla: {
19298			props: {
19299				hue: {
19300					idx: 0,
19301					type: "degrees"
19302				},
19303				saturation: {
19304					idx: 1,
19305					type: "percent"
19306				},
19307				lightness: {
19308					idx: 2,
19309					type: "percent"
19310				}
19311			}
19312		}
19313	},
vendor: 9,998 bytes, lines 19314-19721
19314	propTypes = {
19315		"byte": {
19316			floor: true,
19317			max: 255
19318		},
19319		"percent": {
19320			max: 1
19321		},
19322		"degrees": {
19323			mod: 360,
19324			floor: true
19325		}
19326	},
19327	support = color.support = {},
19328
19329	// element for support tests
19330	supportElem = jQuery( "<p>" )[ 0 ],
19331
19332	// colors = jQuery.Color.names
19333	colors,
19334
19335	// local aliases of functions called often
19336	each = jQuery.each;
19337
19338// determine rgba support immediately
19339supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
19340support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
19341
19342// define cache name and alpha properties
19343// for rgba and hsla spaces
19344each( spaces, function( spaceName, space ) {
19345	space.cache = "_" + spaceName;
19346	space.props.alpha = {
19347		idx: 3,
19348		type: "percent",
19349		def: 1
19350	};
19351});
19352
19353function clamp( value, prop, allowEmpty ) {
19354	var type = propTypes[ prop.type ] || {};
19355
19356	if ( value == null ) {
19357		return (allowEmpty || !prop.def) ? null : prop.def;
19358	}
19359
19360	// ~~ is an short way of doing floor for positive numbers
19361	value = type.floor ? ~~value : parseFloat( value );
19362
19363	// IE will pass in empty strings as value for alpha,
19364	// which will hit this case
19365	if ( isNaN( value ) ) {
19366		return prop.def;
19367	}
19368
19369	if ( type.mod ) {
19370		// we add mod before modding to make sure that negatives values
19371		// get converted properly: -10 -> 350
19372		return (value + type.mod) % type.mod;
19373	}
19374
19375	// for now all property types without mod have min and max
19376	return 0 > value ? 0 : type.max < value ? type.max : value;
19377}
19378
19379function stringParse( string ) {
19380	var inst = color(),
19381		rgba = inst._rgba = [];
19382
19383	string = string.toLowerCase();
19384
19385	each( stringParsers, function( i, parser ) {
19386		var parsed,
19387			match = parser.re.exec( string ),
19388			values = match && parser.parse( match ),
19389			spaceName = parser.space || "rgba";
19390
19391		if ( values ) {
19392			parsed = inst[ spaceName ]( values );
19393
19394			// if this was an rgba parse the assignment might happen twice
19395			// oh well....
19396			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
19397			rgba = inst._rgba = parsed._rgba;
19398
19399			// exit each( stringParsers ) here because we matched
19400			return false;
19401		}
19402	});
19403
19404	// Found a stringParser that handled it
19405	if ( rgba.length ) {
19406
19407		// if this came from a parsed string, force "transparent" when alpha is 0
19408		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
19409		if ( rgba.join() === "0,0,0,0" ) {
19410			jQuery.extend( rgba, colors.transparent );
19411		}
19412		return inst;
19413	}
19414
19415	// named colors
19416	return colors[ string ];
19417}
19418
19419color.fn = jQuery.extend( color.prototype, {
19420	parse: function( red, green, blue, alpha ) {
19421		if ( red === undefined ) {
19422			this._rgba = [ null, null, null, null ];
19423			return this;
19424		}
19425		if ( red.jquery || red.nodeType ) {
19426			red = jQuery( red ).css( green );
19427			green = undefined;
19428		}
19429
19430		var inst = this,
19431			type = jQuery.type( red ),
19432			rgba = this._rgba = [];
19433
19434		// more than 1 argument specified - assume ( red, green, blue, alpha )
19435		if ( green !== undefined ) {
19436			red = [ red, green, blue, alpha ];
19437			type = "array";
19438		}
19439
19440		if ( type === "string" ) {
19441			return this.parse( stringParse( red ) || colors._default );
19442		}
19443
19444		if ( type === "array" ) {
19445			each( spaces.rgba.props, function( key, prop ) {
19446				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
19447			});
19448			return this;
19449		}
19450
19451		if ( type === "object" ) {
19452			if ( red instanceof color ) {
19453				each( spaces, function( spaceName, space ) {
19454					if ( red[ space.cache ] ) {
19455						inst[ space.cache ] = red[ space.cache ].slice();
19456					}
19457				});
19458			} else {
19459				each( spaces, function( spaceName, space ) {
19460					var cache = space.cache;
19461					each( space.props, function( key, prop ) {
19462
19463						// if the cache doesn't exist, and we know how to convert
19464						if ( !inst[ cache ] && space.to ) {
19465
19466							// if the value was null, we don't need to copy it
19467							// if the key was alpha, we don't need to copy it either
19468							if ( key === "alpha" || red[ key ] == null ) {
19469								return;
19470							}
19471							inst[ cache ] = space.to( inst._rgba );
19472						}
19473
19474						// this is the only case where we allow nulls for ALL properties.
19475						// call clamp with alwaysAllowEmpty
19476						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
19477					});
19478
19479					// everything defined but alpha?
19480					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
19481						// use the default of 1
19482						inst[ cache ][ 3 ] = 1;
19483						if ( space.from ) {
19484							inst._rgba = space.from( inst[ cache ] );
19485						}
19486					}
19487				});
19488			}
19489			return this;
19490		}
19491	},
19492	is: function( compare ) {
19493		var is = color( compare ),
19494			same = true,
19495			inst = this;
19496
19497		each( spaces, function( _, space ) {
19498			var localCache,
19499				isCache = is[ space.cache ];
19500			if (isCache) {
19501				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
19502				each( space.props, function( _, prop ) {
19503					if ( isCache[ prop.idx ] != null ) {
19504						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
19505						return same;
19506					}
19507				});
19508			}
19509			return same;
19510		});
19511		return same;
19512	},
19513	_space: function() {
19514		var used = [],
19515			inst = this;
19516		each( spaces, function( spaceName, space ) {
19517			if ( inst[ space.cache ] ) {
19518				used.push( spaceName );
19519			}
19520		});
19521		return used.pop();
19522	},
19523	transition: function( other, distance ) {
19524		var end = color( other ),
19525			spaceName = end._space(),
19526			space = spaces[ spaceName ],
19527			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
19528			start = startColor[ space.cache ] || space.to( startColor._rgba ),
19529			result = start.slice();
19530
19531		end = end[ space.cache ];
19532		each( space.props, function( key, prop ) {
19533			var index = prop.idx,
19534				startValue = start[ index ],
19535				endValue = end[ index ],
19536				type = propTypes[ prop.type ] || {};
19537
19538			// if null, don't override start value
19539			if ( endValue === null ) {
19540				return;
19541			}
19542			// if null - use end
19543			if ( startValue === null ) {
19544				result[ index ] = endValue;
19545			} else {
19546				if ( type.mod ) {
19547					if ( endValue - startValue > type.mod / 2 ) {
19548						startValue += type.mod;
19549					} else if ( startValue - endValue > type.mod / 2 ) {
19550						startValue -= type.mod;
19551					}
19552				}
19553				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
19554			}
19555		});
19556		return this[ spaceName ]( result );
19557	},
19558	blend: function( opaque ) {
19559		// if we are already opaque - return ourself
19560		if ( this._rgba[ 3 ] === 1 ) {
19561			return this;
19562		}
19563
19564		var rgb = this._rgba.slice(),
19565			a = rgb.pop(),
19566			blend = color( opaque )._rgba;
19567
19568		return color( jQuery.map( rgb, function( v, i ) {
19569			return ( 1 - a ) * blend[ i ] + a * v;
19570		}));
19571	},
19572	toRgbaString: function() {
19573		var prefix = "rgba(",
19574			rgba = jQuery.map( this._rgba, function( v, i ) {
19575				return v == null ? ( i > 2 ? 1 : 0 ) : v;
19576			});
19577
19578		if ( rgba[ 3 ] === 1 ) {
19579			rgba.pop();
19580			prefix = "rgb(";
19581		}
19582
19583		return prefix + rgba.join() + ")";
19584	},
19585	toHslaString: function() {
19586		var prefix = "hsla(",
19587			hsla = jQuery.map( this.hsla(), function( v, i ) {
19588				if ( v == null ) {
19589					v = i > 2 ? 1 : 0;
19590				}
19591
19592				// catch 1 and 2
19593				if ( i && i < 3 ) {
19594					v = Math.round( v * 100 ) + "%";
19595				}
19596				return v;
19597			});
19598
19599		if ( hsla[ 3 ] === 1 ) {
19600			hsla.pop();
19601			prefix = "hsl(";
19602		}
19603		return prefix + hsla.join() + ")";
19604	},
19605	toHexString: function( includeAlpha ) {
19606		var rgba = this._rgba.slice(),
19607			alpha = rgba.pop();
19608
19609		if ( includeAlpha ) {
19610			rgba.push( ~~( alpha * 255 ) );
19611		}
19612
19613		return "#" + jQuery.map( rgba, function( v ) {
19614
19615			// default to 0 when nulls exist
19616			v = ( v || 0 ).toString( 16 );
19617			return v.length === 1 ? "0" + v : v;
19618		}).join("");
19619	},
19620	toString: function() {
19621		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
19622	}
19623});
19624color.fn.parse.prototype = color.fn;
19625
19626// hsla conversions adapted from:
19627// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
19628
19629function hue2rgb( p, q, h ) {
19630	h = ( h + 1 ) % 1;
19631	if ( h * 6 < 1 ) {
19632		return p + ( q - p ) * h * 6;
19633	}
19634	if ( h * 2 < 1) {
19635		return q;
19636	}
19637	if ( h * 3 < 2 ) {
19638		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
19639	}
19640	return p;
19641}
19642
19643spaces.hsla.to = function( rgba ) {
19644	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
19645		return [ null, null, null, rgba[ 3 ] ];
19646	}
19647	var r = rgba[ 0 ] / 255,
19648		g = rgba[ 1 ] / 255,
19649		b = rgba[ 2 ] / 255,
19650		a = rgba[ 3 ],
19651		max = Math.max( r, g, b ),
19652		min = Math.min( r, g, b ),
19653		diff = max - min,
19654		add = max + min,
19655		l = add * 0.5,
19656		h, s;
19657
19658	if ( min === max ) {
19659		h = 0;
19660	} else if ( r === max ) {
19661		h = ( 60 * ( g - b ) / diff ) + 360;
19662	} else if ( g === max ) {
19663		h = ( 60 * ( b - r ) / diff ) + 120;
19664	} else {
19665		h = ( 60 * ( r - g ) / diff ) + 240;
19666	}
19667
19668	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
19669	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
19670	if ( diff === 0 ) {
19671		s = 0;
19672	} else if ( l <= 0.5 ) {
19673		s = diff / add;
19674	} else {
19675		s = diff / ( 2 - add );
19676	}
19677	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
19678};
19679
19680spaces.hsla.from = function( hsla ) {
19681	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
19682		return [ null, null, null, hsla[ 3 ] ];
19683	}
19684	var h = hsla[ 0 ] / 360,
19685		s = hsla[ 1 ],
19686		l = hsla[ 2 ],
19687		a = hsla[ 3 ],
19688		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
19689		p = 2 * l - q;
19690
19691	return [
19692		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
19693		Math.round( hue2rgb( p, q, h ) * 255 ),
19694		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
19695		a
19696	];
19697};
19698
19699each( spaces, function( spaceName, space ) {
19700	var props = space.props,
19701		cache = space.cache,
19702		to = space.to,
19703		from = space.from;
19704
19705	// makes rgba() and hsla()
19706	color.fn[ spaceName ] = function( value ) {
19707
19708		// generate a cache for this space if it doesn't exist
19709		if ( to && !this[ cache ] ) {
19710			this[ cache ] = to( this._rgba );
19711		}
19712		if ( value === undefined ) {
19713			return this[ cache ].slice();
19714		}
19715
19716		var ret,
19717			type = jQuery.type( value ),
19718			arr = ( type === "array" || type === "object" ) ? value : arguments,
19719			local = this[ cache ].slice();
19720
19721		each( props, function( key, prop ) {
vendor: 50,293 bytes, lines 19722-21785
19722			var val = arr[ type === "object" ? key : prop.idx ];
19723			if ( val == null ) {
19724				val = local[ prop.idx ];
19725			}
19726			local[ prop.idx ] = clamp( val, prop );
19727		});
19728
19729		if ( from ) {
19730			ret = color( from( local ) );
19731			ret[ cache ] = local;
19732			return ret;
19733		} else {
19734			return color( local );
19735		}
19736	};
19737
19738	// makes red() green() blue() alpha() hue() saturation() lightness()
19739	each( props, function( key, prop ) {
19740		// alpha is included in more than one space
19741		if ( color.fn[ key ] ) {
19742			return;
19743		}
19744		color.fn[ key ] = function( value ) {
19745			var vtype = jQuery.type( value ),
19746				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
19747				local = this[ fn ](),
19748				cur = local[ prop.idx ],
19749				match;
19750
19751			if ( vtype === "undefined" ) {
19752				return cur;
19753			}
19754
19755			if ( vtype === "function" ) {
19756				value = value.call( this, cur );
19757				vtype = jQuery.type( value );
19758			}
19759			if ( value == null && prop.empty ) {
19760				return this;
19761			}
19762			if ( vtype === "string" ) {
19763				match = rplusequals.exec( value );
19764				if ( match ) {
19765					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
19766				}
19767			}
19768			local[ prop.idx ] = value;
19769			return this[ fn ]( local );
19770		};
19771	});
19772});
19773
19774// add cssHook and .fx.step function for each named hook.
19775// accept a space separated string of properties
19776color.hook = function( hook ) {
19777	var hooks = hook.split( " " );
19778	each( hooks, function( i, hook ) {
19779		jQuery.cssHooks[ hook ] = {
19780			set: function( elem, value ) {
19781				var parsed, curElem,
19782					backgroundColor = "";
19783
19784				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
19785					value = color( parsed || value );
19786					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
19787						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
19788						while (
19789							(backgroundColor === "" || backgroundColor === "transparent") &&
19790							curElem && curElem.style
19791						) {
19792							try {
19793								backgroundColor = jQuery.css( curElem, "backgroundColor" );
19794								curElem = curElem.parentNode;
19795							} catch ( e ) {
19796							}
19797						}
19798
19799						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
19800							backgroundColor :
19801							"_default" );
19802					}
19803
19804					value = value.toRgbaString();
19805				}
19806				try {
19807					elem.style[ hook ] = value;
19808				} catch ( e ) {
19809					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
19810				}
19811			}
19812		};
19813		jQuery.fx.step[ hook ] = function( fx ) {
19814			if ( !fx.colorInit ) {
19815				fx.start = color( fx.elem, hook );
19816				fx.end = color( fx.end );
19817				fx.colorInit = true;
19818			}
19819			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
19820		};
19821	});
19822
19823};
19824
19825color.hook( stepHooks );
19826
19827jQuery.cssHooks.borderColor = {
19828	expand: function( value ) {
19829		var expanded = {};
19830
19831		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
19832			expanded[ "border" + part + "Color" ] = value;
19833		});
19834		return expanded;
19835	}
19836};
19837
19838// Basic color names only.
19839// Usage of any of the other color names requires adding yourself or including
19840// jquery.color.svg-names.js.
19841colors = jQuery.Color.names = {
19842	// 4.1. Basic color keywords
19843	aqua: "#00ffff",
19844	black: "#000000",
19845	blue: "#0000ff",
19846	fuchsia: "#ff00ff",
19847	gray: "#808080",
19848	green: "#008000",
19849	lime: "#00ff00",
19850	maroon: "#800000",
19851	navy: "#000080",
19852	olive: "#808000",
19853	purple: "#800080",
19854	red: "#ff0000",
19855	silver: "#c0c0c0",
19856	teal: "#008080",
19857	white: "#ffffff",
19858	yellow: "#ffff00",
19859
19860	// 4.2.3. "transparent" color keyword
19861	transparent: [ null, null, null, 0 ],
19862
19863	_default: "#ffffff"
19864};
19865
19866})( jQuery );
19867
19868/******************************************************************************/
19869/****************************** CLASS ANIMATIONS ******************************/
19870/******************************************************************************/
19871(function() {
19872
19873var classAnimationActions = [ "add", "remove", "toggle" ],
19874	shorthandStyles = {
19875		border: 1,
19876		borderBottom: 1,
19877		borderColor: 1,
19878		borderLeft: 1,
19879		borderRight: 1,
19880		borderTop: 1,
19881		borderWidth: 1,
19882		margin: 1,
19883		padding: 1
19884	};
19885
19886$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
19887	$.fx.step[ prop ] = function( fx ) {
19888		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
19889			jQuery.style( fx.elem, prop, fx.end );
19890			fx.setAttr = true;
19891		}
19892	};
19893});
19894
19895function getElementStyles( elem ) {
19896	var key, len,
19897		style = elem.ownerDocument.defaultView ?
19898			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
19899			elem.currentStyle,
19900		styles = {};
19901
19902	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
19903		len = style.length;
19904		while ( len-- ) {
19905			key = style[ len ];
19906			if ( typeof style[ key ] === "string" ) {
19907				styles[ $.camelCase( key ) ] = style[ key ];
19908			}
19909		}
19910	// support: Opera, IE <9
19911	} else {
19912		for ( key in style ) {
19913			if ( typeof style[ key ] === "string" ) {
19914				styles[ key ] = style[ key ];
19915			}
19916		}
19917	}
19918
19919	return styles;
19920}
19921
19922function styleDifference( oldStyle, newStyle ) {
19923	var diff = {},
19924		name, value;
19925
19926	for ( name in newStyle ) {
19927		value = newStyle[ name ];
19928		if ( oldStyle[ name ] !== value ) {
19929			if ( !shorthandStyles[ name ] ) {
19930				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
19931					diff[ name ] = value;
19932				}
19933			}
19934		}
19935	}
19936
19937	return diff;
19938}
19939
19940// support: jQuery <1.8
19941if ( !$.fn.addBack ) {
19942	$.fn.addBack = function( selector ) {
19943		return this.add( selector == null ?
19944			this.prevObject : this.prevObject.filter( selector )
19945		);
19946	};
19947}
19948
19949$.effects.animateClass = function( value, duration, easing, callback ) {
19950	var o = $.speed( duration, easing, callback );
19951
19952	return this.queue( function() {
19953		var animated = $( this ),
19954			baseClass = animated.attr( "class" ) || "",
19955			applyClassChange,
19956			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
19957
19958		// map the animated objects to store the original styles.
19959		allAnimations = allAnimations.map(function() {
19960			var el = $( this );
19961			return {
19962				el: el,
19963				start: getElementStyles( this )
19964			};
19965		});
19966
19967		// apply class change
19968		applyClassChange = function() {
19969			$.each( classAnimationActions, function(i, action) {
19970				if ( value[ action ] ) {
19971					animated[ action + "Class" ]( value[ action ] );
19972				}
19973			});
19974		};
19975		applyClassChange();
19976
19977		// map all animated objects again - calculate new styles and diff
19978		allAnimations = allAnimations.map(function() {
19979			this.end = getElementStyles( this.el[ 0 ] );
19980			this.diff = styleDifference( this.start, this.end );
19981			return this;
19982		});
19983
19984		// apply original class
19985		animated.attr( "class", baseClass );
19986
19987		// map all animated objects again - this time collecting a promise
19988		allAnimations = allAnimations.map(function() {
19989			var styleInfo = this,
19990				dfd = $.Deferred(),
19991				opts = $.extend({}, o, {
19992					queue: false,
19993					complete: function() {
19994						dfd.resolve( styleInfo );
19995					}
19996				});
19997
19998			this.el.animate( this.diff, opts );
19999			return dfd.promise();
20000		});
20001
20002		// once all animations have completed:
20003		$.when.apply( $, allAnimations.get() ).done(function() {
20004
20005			// set the final class
20006			applyClassChange();
20007
20008			// for each animated element,
20009			// clear all css properties that were animated
20010			$.each( arguments, function() {
20011				var el = this.el;
20012				$.each( this.diff, function(key) {
20013					el.css( key, "" );
20014				});
20015			});
20016
20017			// this is guarnteed to be there if you use jQuery.speed()
20018			// it also handles dequeuing the next anim...
20019			o.complete.call( animated[ 0 ] );
20020		});
20021	});
20022};
20023
20024$.fn.extend({
20025	addClass: (function( orig ) {
20026		return function( classNames, speed, easing, callback ) {
20027			return speed ?
20028				$.effects.animateClass.call( this,
20029					{ add: classNames }, speed, easing, callback ) :
20030				orig.apply( this, arguments );
20031		};
20032	})( $.fn.addClass ),
20033
20034	removeClass: (function( orig ) {
20035		return function( classNames, speed, easing, callback ) {
20036			return arguments.length > 1 ?
20037				$.effects.animateClass.call( this,
20038					{ remove: classNames }, speed, easing, callback ) :
20039				orig.apply( this, arguments );
20040		};
20041	})( $.fn.removeClass ),
20042
20043	toggleClass: (function( orig ) {
20044		return function( classNames, force, speed, easing, callback ) {
20045			if ( typeof force === "boolean" || force === undefined ) {
20046				if ( !speed ) {
20047					// without speed parameter
20048					return orig.apply( this, arguments );
20049				} else {
20050					return $.effects.animateClass.call( this,
20051						(force ? { add: classNames } : { remove: classNames }),
20052						speed, easing, callback );
20053				}
20054			} else {
20055				// without force parameter
20056				return $.effects.animateClass.call( this,
20057					{ toggle: classNames }, force, speed, easing );
20058			}
20059		};
20060	})( $.fn.toggleClass ),
20061
20062	switchClass: function( remove, add, speed, easing, callback) {
20063		return $.effects.animateClass.call( this, {
20064			add: add,
20065			remove: remove
20066		}, speed, easing, callback );
20067	}
20068});
20069
20070})();
20071
20072/******************************************************************************/
20073/*********************************** EFFECTS **********************************/
20074/******************************************************************************/
20075
20076(function() {
20077
20078$.extend( $.effects, {
20079	version: "1.11.4",
20080
20081	// Saves a set of properties in a data storage
20082	save: function( element, set ) {
20083		for ( var i = 0; i < set.length; i++ ) {
20084			if ( set[ i ] !== null ) {
20085				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
20086			}
20087		}
20088	},
20089
20090	// Restores a set of previously saved properties from a data storage
20091	restore: function( element, set ) {
20092		var val, i;
20093		for ( i = 0; i < set.length; i++ ) {
20094			if ( set[ i ] !== null ) {
20095				val = element.data( dataSpace + set[ i ] );
20096				// support: jQuery 1.6.2
20097				// http://bugs.jquery.com/ticket/9917
20098				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
20099				// We can't differentiate between "" and 0 here, so we just assume
20100				// empty string since it's likely to be a more common value...
20101				if ( val === undefined ) {
20102					val = "";
20103				}
20104				element.css( set[ i ], val );
20105			}
20106		}
20107	},
20108
20109	setMode: function( el, mode ) {
20110		if (mode === "toggle") {
20111			mode = el.is( ":hidden" ) ? "show" : "hide";
20112		}
20113		return mode;
20114	},
20115
20116	// Translates a [top,left] array into a baseline value
20117	// this should be a little more flexible in the future to handle a string & hash
20118	getBaseline: function( origin, original ) {
20119		var y, x;
20120		switch ( origin[ 0 ] ) {
20121			case "top": y = 0; break;
20122			case "middle": y = 0.5; break;
20123			case "bottom": y = 1; break;
20124			default: y = origin[ 0 ] / original.height;
20125		}
20126		switch ( origin[ 1 ] ) {
20127			case "left": x = 0; break;
20128			case "center": x = 0.5; break;
20129			case "right": x = 1; break;
20130			default: x = origin[ 1 ] / original.width;
20131		}
20132		return {
20133			x: x,
20134			y: y
20135		};
20136	},
20137
20138	// Wraps the element around a wrapper that copies position properties
20139	createWrapper: function( element ) {
20140
20141		// if the element is already wrapped, return it
20142		if ( element.parent().is( ".ui-effects-wrapper" )) {
20143			return element.parent();
20144		}
20145
20146		// wrap the element
20147		var props = {
20148				width: element.outerWidth(true),
20149				height: element.outerHeight(true),
20150				"float": element.css( "float" )
20151			},
20152			wrapper = $( "<div></div>" )
20153				.addClass( "ui-effects-wrapper" )
20154				.css({
20155					fontSize: "100%",
20156					background: "transparent",
20157					border: "none",
20158					margin: 0,
20159					padding: 0
20160				}),
20161			// Store the size in case width/height are defined in % - Fixes #5245
20162			size = {
20163				width: element.width(),
20164				height: element.height()
20165			},
20166			active = document.activeElement;
20167
20168		// support: Firefox
20169		// Firefox incorrectly exposes anonymous content
20170		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
20171		try {
20172			active.id;
20173		} catch ( e ) {
20174			active = document.body;
20175		}
20176
20177		element.wrap( wrapper );
20178
20179		// Fixes #7595 - Elements lose focus when wrapped.
20180		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
20181			$( active ).focus();
20182		}
20183
20184		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
20185
20186		// transfer positioning properties to the wrapper
20187		if ( element.css( "position" ) === "static" ) {
20188			wrapper.css({ position: "relative" });
20189			element.css({ position: "relative" });
20190		} else {
20191			$.extend( props, {
20192				position: element.css( "position" ),
20193				zIndex: element.css( "z-index" )
20194			});
20195			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
20196				props[ pos ] = element.css( pos );
20197				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
20198					props[ pos ] = "auto";
20199				}
20200			});
20201			element.css({
20202				position: "relative",
20203				top: 0,
20204				left: 0,
20205				right: "auto",
20206				bottom: "auto"
20207			});
20208		}
20209		element.css(size);
20210
20211		return wrapper.css( props ).show();
20212	},
20213
20214	removeWrapper: function( element ) {
20215		var active = document.activeElement;
20216
20217		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
20218			element.parent().replaceWith( element );
20219
20220			// Fixes #7595 - Elements lose focus when wrapped.
20221			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
20222				$( active ).focus();
20223			}
20224		}
20225
20226		return element;
20227	},
20228
20229	setTransition: function( element, list, factor, value ) {
20230		value = value || {};
20231		$.each( list, function( i, x ) {
20232			var unit = element.cssUnit( x );
20233			if ( unit[ 0 ] > 0 ) {
20234				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
20235			}
20236		});
20237		return value;
20238	}
20239});
20240
20241// return an effect options object for the given parameters:
20242function _normalizeArguments( effect, options, speed, callback ) {
20243
20244	// allow passing all options as the first parameter
20245	if ( $.isPlainObject( effect ) ) {
20246		options = effect;
20247		effect = effect.effect;
20248	}
20249
20250	// convert to an object
20251	effect = { effect: effect };
20252
20253	// catch (effect, null, ...)
20254	if ( options == null ) {
20255		options = {};
20256	}
20257
20258	// catch (effect, callback)
20259	if ( $.isFunction( options ) ) {
20260		callback = options;
20261		speed = null;
20262		options = {};
20263	}
20264
20265	// catch (effect, speed, ?)
20266	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
20267		callback = speed;
20268		speed = options;
20269		options = {};
20270	}
20271
20272	// catch (effect, options, callback)
20273	if ( $.isFunction( speed ) ) {
20274		callback = speed;
20275		speed = null;
20276	}
20277
20278	// add options to effect
20279	if ( options ) {
20280		$.extend( effect, options );
20281	}
20282
20283	speed = speed || options.duration;
20284	effect.duration = $.fx.off ? 0 :
20285		typeof speed === "number" ? speed :
20286		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
20287		$.fx.speeds._default;
20288
20289	effect.complete = callback || options.complete;
20290
20291	return effect;
20292}
20293
20294function standardAnimationOption( option ) {
20295	// Valid standard speeds (nothing, number, named speed)
20296	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
20297		return true;
20298	}
20299
20300	// Invalid strings - treat as "normal" speed
20301	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
20302		return true;
20303	}
20304
20305	// Complete callback
20306	if ( $.isFunction( option ) ) {
20307		return true;
20308	}
20309
20310	// Options hash (but not naming an effect)
20311	if ( typeof option === "object" && !option.effect ) {
20312		return true;
20313	}
20314
20315	// Didn't match any standard API
20316	return false;
20317}
20318
20319$.fn.extend({
20320	effect: function( /* effect, options, speed, callback */ ) {
20321		var args = _normalizeArguments.apply( this, arguments ),
20322			mode = args.mode,
20323			queue = args.queue,
20324			effectMethod = $.effects.effect[ args.effect ];
20325
20326		if ( $.fx.off || !effectMethod ) {
20327			// delegate to the original method (e.g., .show()) if possible
20328			if ( mode ) {
20329				return this[ mode ]( args.duration, args.complete );
20330			} else {
20331				return this.each( function() {
20332					if ( args.complete ) {
20333						args.complete.call( this );
20334					}
20335				});
20336			}
20337		}
20338
20339		function run( next ) {
20340			var elem = $( this ),
20341				complete = args.complete,
20342				mode = args.mode;
20343
20344			function done() {
20345				if ( $.isFunction( complete ) ) {
20346					complete.call( elem[0] );
20347				}
20348				if ( $.isFunction( next ) ) {
20349					next();
20350				}
20351			}
20352
20353			// If the element already has the correct final state, delegate to
20354			// the core methods so the internal tracking of "olddisplay" works.
20355			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
20356				elem[ mode ]();
20357				done();
20358			} else {
20359				effectMethod.call( elem[0], args, done );
20360			}
20361		}
20362
20363		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
20364	},
20365
20366	show: (function( orig ) {
20367		return function( option ) {
20368			if ( standardAnimationOption( option ) ) {
20369				return orig.apply( this, arguments );
20370			} else {
20371				var args = _normalizeArguments.apply( this, arguments );
20372				args.mode = "show";
20373				return this.effect.call( this, args );
20374			}
20375		};
20376	})( $.fn.show ),
20377
20378	hide: (function( orig ) {
20379		return function( option ) {
20380			if ( standardAnimationOption( option ) ) {
20381				return orig.apply( this, arguments );
20382			} else {
20383				var args = _normalizeArguments.apply( this, arguments );
20384				args.mode = "hide";
20385				return this.effect.call( this, args );
20386			}
20387		};
20388	})( $.fn.hide ),
20389
20390	toggle: (function( orig ) {
20391		return function( option ) {
20392			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
20393				return orig.apply( this, arguments );
20394			} else {
20395				var args = _normalizeArguments.apply( this, arguments );
20396				args.mode = "toggle";
20397				return this.effect.call( this, args );
20398			}
20399		};
20400	})( $.fn.toggle ),
20401
20402	// helper functions
20403	cssUnit: function(key) {
20404		var style = this.css( key ),
20405			val = [];
20406
20407		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
20408			if ( style.indexOf( unit ) > 0 ) {
20409				val = [ parseFloat( style ), unit ];
20410			}
20411		});
20412		return val;
20413	}
20414});
20415
20416})();
20417
20418/******************************************************************************/
20419/*********************************** EASING ***********************************/
20420/******************************************************************************/
20421
20422(function() {
20423
20424// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
20425
20426var baseEasings = {};
20427
20428$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
20429	baseEasings[ name ] = function( p ) {
20430		return Math.pow( p, i + 2 );
20431	};
20432});
20433
20434$.extend( baseEasings, {
20435	Sine: function( p ) {
20436		return 1 - Math.cos( p * Math.PI / 2 );
20437	},
20438	Circ: function( p ) {
20439		return 1 - Math.sqrt( 1 - p * p );
20440	},
20441	Elastic: function( p ) {
20442		return p === 0 || p === 1 ? p :
20443			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
20444	},
20445	Back: function( p ) {
20446		return p * p * ( 3 * p - 2 );
20447	},
20448	Bounce: function( p ) {
20449		var pow2,
20450			bounce = 4;
20451
20452		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
20453		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
20454	}
20455});
20456
20457$.each( baseEasings, function( name, easeIn ) {
20458	$.easing[ "easeIn" + name ] = easeIn;
20459	$.easing[ "easeOut" + name ] = function( p ) {
20460		return 1 - easeIn( 1 - p );
20461	};
20462	$.easing[ "easeInOut" + name ] = function( p ) {
20463		return p < 0.5 ?
20464			easeIn( p * 2 ) / 2 :
20465			1 - easeIn( p * -2 + 2 ) / 2;
20466	};
20467});
20468
20469})();
20470
20471var effect = $.effects;
20472
20473
20474/*!
20475 * jQuery UI Effects Blind 1.11.4
20476 * http://jqueryui.com
20477 *
20478 * Copyright jQuery Foundation and other contributors
20479 * Released under the MIT license.
20480 * http://jquery.org/license
20481 *
20482 * http://api.jqueryui.com/blind-effect/
20483 */
20484
20485
20486var effectBlind = $.effects.effect.blind = function( o, done ) {
20487	// Create element
20488	var el = $( this ),
20489		rvertical = /up|down|vertical/,
20490		rpositivemotion = /up|left|vertical|horizontal/,
20491		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
20492		mode = $.effects.setMode( el, o.mode || "hide" ),
20493		direction = o.direction || "up",
20494		vertical = rvertical.test( direction ),
20495		ref = vertical ? "height" : "width",
20496		ref2 = vertical ? "top" : "left",
20497		motion = rpositivemotion.test( direction ),
20498		animation = {},
20499		show = mode === "show",
20500		wrapper, distance, margin;
20501
20502	// if already wrapped, the wrapper's properties are my property. #6245
20503	if ( el.parent().is( ".ui-effects-wrapper" ) ) {
20504		$.effects.save( el.parent(), props );
20505	} else {
20506		$.effects.save( el, props );
20507	}
20508	el.show();
20509	wrapper = $.effects.createWrapper( el ).css({
20510		overflow: "hidden"
20511	});
20512
20513	distance = wrapper[ ref ]();
20514	margin = parseFloat( wrapper.css( ref2 ) ) || 0;
20515
20516	animation[ ref ] = show ? distance : 0;
20517	if ( !motion ) {
20518		el
20519			.css( vertical ? "bottom" : "right", 0 )
20520			.css( vertical ? "top" : "left", "auto" )
20521			.css({ position: "absolute" });
20522
20523		animation[ ref2 ] = show ? margin : distance + margin;
20524	}
20525
20526	// start at 0 if we are showing
20527	if ( show ) {
20528		wrapper.css( ref, 0 );
20529		if ( !motion ) {
20530			wrapper.css( ref2, margin + distance );
20531		}
20532	}
20533
20534	// Animate
20535	wrapper.animate( animation, {
20536		duration: o.duration,
20537		easing: o.easing,
20538		queue: false,
20539		complete: function() {
20540			if ( mode === "hide" ) {
20541				el.hide();
20542			}
20543			$.effects.restore( el, props );
20544			$.effects.removeWrapper( el );
20545			done();
20546		}
20547	});
20548};
20549
20550
20551/*!
20552 * jQuery UI Effects Bounce 1.11.4
20553 * http://jqueryui.com
20554 *
20555 * Copyright jQuery Foundation and other contributors
20556 * Released under the MIT license.
20557 * http://jquery.org/license
20558 *
20559 * http://api.jqueryui.com/bounce-effect/
20560 */
20561
20562
20563var effectBounce = $.effects.effect.bounce = function( o, done ) {
20564	var el = $( this ),
20565		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
20566
20567		// defaults:
20568		mode = $.effects.setMode( el, o.mode || "effect" ),
20569		hide = mode === "hide",
20570		show = mode === "show",
20571		direction = o.direction || "up",
20572		distance = o.distance,
20573		times = o.times || 5,
20574
20575		// number of internal animations
20576		anims = times * 2 + ( show || hide ? 1 : 0 ),
20577		speed = o.duration / anims,
20578		easing = o.easing,
20579
20580		// utility:
20581		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
20582		motion = ( direction === "up" || direction === "left" ),
20583		i,
20584		upAnim,
20585		downAnim,
20586
20587		// we will need to re-assemble the queue to stack our animations in place
20588		queue = el.queue(),
20589		queuelen = queue.length;
20590
20591	// Avoid touching opacity to prevent clearType and PNG issues in IE
20592	if ( show || hide ) {
20593		props.push( "opacity" );
20594	}
20595
20596	$.effects.save( el, props );
20597	el.show();
20598	$.effects.createWrapper( el ); // Create Wrapper
20599
20600	// default distance for the BIGGEST bounce is the outer Distance / 3
20601	if ( !distance ) {
20602		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
20603	}
20604
20605	if ( show ) {
20606		downAnim = { opacity: 1 };
20607		downAnim[ ref ] = 0;
20608
20609		// if we are showing, force opacity 0 and set the initial position
20610		// then do the "first" animation
20611		el.css( "opacity", 0 )
20612			.css( ref, motion ? -distance * 2 : distance * 2 )
20613			.animate( downAnim, speed, easing );
20614	}
20615
20616	// start at the smallest distance if we are hiding
20617	if ( hide ) {
20618		distance = distance / Math.pow( 2, times - 1 );
20619	}
20620
20621	downAnim = {};
20622	downAnim[ ref ] = 0;
20623	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
20624	for ( i = 0; i < times; i++ ) {
20625		upAnim = {};
20626		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
20627
20628		el.animate( upAnim, speed, easing )
20629			.animate( downAnim, speed, easing );
20630
20631		distance = hide ? distance * 2 : distance / 2;
20632	}
20633
20634	// Last Bounce when Hiding
20635	if ( hide ) {
20636		upAnim = { opacity: 0 };
20637		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
20638
20639		el.animate( upAnim, speed, easing );
20640	}
20641
20642	el.queue(function() {
20643		if ( hide ) {
20644			el.hide();
20645		}
20646		$.effects.restore( el, props );
20647		$.effects.removeWrapper( el );
20648		done();
20649	});
20650
20651	// inject all the animations we just queued to be first in line (after "inprogress")
20652	if ( queuelen > 1) {
20653		queue.splice.apply( queue,
20654			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
20655	}
20656	el.dequeue();
20657
20658};
20659
20660
20661/*!
20662 * jQuery UI Effects Clip 1.11.4
20663 * http://jqueryui.com
20664 *
20665 * Copyright jQuery Foundation and other contributors
20666 * Released under the MIT license.
20667 * http://jquery.org/license
20668 *
20669 * http://api.jqueryui.com/clip-effect/
20670 */
20671
20672
20673var effectClip = $.effects.effect.clip = function( o, done ) {
20674	// Create element
20675	var el = $( this ),
20676		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
20677		mode = $.effects.setMode( el, o.mode || "hide" ),
20678		show = mode === "show",
20679		direction = o.direction || "vertical",
20680		vert = direction === "vertical",
20681		size = vert ? "height" : "width",
20682		position = vert ? "top" : "left",
20683		animation = {},
20684		wrapper, animate, distance;
20685
20686	// Save & Show
20687	$.effects.save( el, props );
20688	el.show();
20689
20690	// Create Wrapper
20691	wrapper = $.effects.createWrapper( el ).css({
20692		overflow: "hidden"
20693	});
20694	animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
20695	distance = animate[ size ]();
20696
20697	// Shift
20698	if ( show ) {
20699		animate.css( size, 0 );
20700		animate.css( position, distance / 2 );
20701	}
20702
20703	// Create Animation Object:
20704	animation[ size ] = show ? distance : 0;
20705	animation[ position ] = show ? 0 : distance / 2;
20706
20707	// Animate
20708	animate.animate( animation, {
20709		queue: false,
20710		duration: o.duration,
20711		easing: o.easing,
20712		complete: function() {
20713			if ( !show ) {
20714				el.hide();
20715			}
20716			$.effects.restore( el, props );
20717			$.effects.removeWrapper( el );
20718			done();
20719		}
20720	});
20721
20722};
20723
20724
20725/*!
20726 * jQuery UI Effects Drop 1.11.4
20727 * http://jqueryui.com
20728 *
20729 * Copyright jQuery Foundation and other contributors
20730 * Released under the MIT license.
20731 * http://jquery.org/license
20732 *
20733 * http://api.jqueryui.com/drop-effect/
20734 */
20735
20736
20737var effectDrop = $.effects.effect.drop = function( o, done ) {
20738
20739	var el = $( this ),
20740		props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
20741		mode = $.effects.setMode( el, o.mode || "hide" ),
20742		show = mode === "show",
20743		direction = o.direction || "left",
20744		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
20745		motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
20746		animation = {
20747			opacity: show ? 1 : 0
20748		},
20749		distance;
20750
20751	// Adjust
20752	$.effects.save( el, props );
20753	el.show();
20754	$.effects.createWrapper( el );
20755
20756	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
20757
20758	if ( show ) {
20759		el
20760			.css( "opacity", 0 )
20761			.css( ref, motion === "pos" ? -distance : distance );
20762	}
20763
20764	// Animation
20765	animation[ ref ] = ( show ?
20766		( motion === "pos" ? "+=" : "-=" ) :
20767		( motion === "pos" ? "-=" : "+=" ) ) +
20768		distance;
20769
20770	// Animate
20771	el.animate( animation, {
20772		queue: false,
20773		duration: o.duration,
20774		easing: o.easing,
20775		complete: function() {
20776			if ( mode === "hide" ) {
20777				el.hide();
20778			}
20779			$.effects.restore( el, props );
20780			$.effects.removeWrapper( el );
20781			done();
20782		}
20783	});
20784};
20785
20786
20787/*!
20788 * jQuery UI Effects Explode 1.11.4
20789 * http://jqueryui.com
20790 *
20791 * Copyright jQuery Foundation and other contributors
20792 * Released under the MIT license.
20793 * http://jquery.org/license
20794 *
20795 * http://api.jqueryui.com/explode-effect/
20796 */
20797
20798
20799var effectExplode = $.effects.effect.explode = function( o, done ) {
20800
20801	var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
20802		cells = rows,
20803		el = $( this ),
20804		mode = $.effects.setMode( el, o.mode || "hide" ),
20805		show = mode === "show",
20806
20807		// show and then visibility:hidden the element before calculating offset
20808		offset = el.show().css( "visibility", "hidden" ).offset(),
20809
20810		// width and height of a piece
20811		width = Math.ceil( el.outerWidth() / cells ),
20812		height = Math.ceil( el.outerHeight() / rows ),
20813		pieces = [],
20814
20815		// loop
20816		i, j, left, top, mx, my;
20817
20818	// children animate complete:
20819	function childComplete() {
20820		pieces.push( this );
20821		if ( pieces.length === rows * cells ) {
20822			animComplete();
20823		}
20824	}
20825
20826	// clone the element for each row and cell.
20827	for ( i = 0; i < rows ; i++ ) { // ===>
20828		top = offset.top + i * height;
20829		my = i - ( rows - 1 ) / 2 ;
20830
20831		for ( j = 0; j < cells ; j++ ) { // |||
20832			left = offset.left + j * width;
20833			mx = j - ( cells - 1 ) / 2 ;
20834
20835			// Create a clone of the now hidden main element that will be absolute positioned
20836			// within a wrapper div off the -left and -top equal to size of our pieces
20837			el
20838				.clone()
20839				.appendTo( "body" )
20840				.wrap( "<div></div>" )
20841				.css({
20842					position: "absolute",
20843					visibility: "visible",
20844					left: -j * width,
20845					top: -i * height
20846				})
20847
20848			// select the wrapper - make it overflow: hidden and absolute positioned based on
20849			// where the original was located +left and +top equal to the size of pieces
20850				.parent()
20851				.addClass( "ui-effects-explode" )
20852				.css({
20853					position: "absolute",
20854					overflow: "hidden",
20855					width: width,
20856					height: height,
20857					left: left + ( show ? mx * width : 0 ),
20858					top: top + ( show ? my * height : 0 ),
20859					opacity: show ? 0 : 1
20860				}).animate({
20861					left: left + ( show ? 0 : mx * width ),
20862					top: top + ( show ? 0 : my * height ),
20863					opacity: show ? 1 : 0
20864				}, o.duration || 500, o.easing, childComplete );
20865		}
20866	}
20867
20868	function animComplete() {
20869		el.css({
20870			visibility: "visible"
20871		});
20872		$( pieces ).remove();
20873		if ( !show ) {
20874			el.hide();
20875		}
20876		done();
20877	}
20878};
20879
20880
20881/*!
20882 * jQuery UI Effects Fade 1.11.4
20883 * http://jqueryui.com
20884 *
20885 * Copyright jQuery Foundation and other contributors
20886 * Released under the MIT license.
20887 * http://jquery.org/license
20888 *
20889 * http://api.jqueryui.com/fade-effect/
20890 */
20891
20892
20893var effectFade = $.effects.effect.fade = function( o, done ) {
20894	var el = $( this ),
20895		mode = $.effects.setMode( el, o.mode || "toggle" );
20896
20897	el.animate({
20898		opacity: mode
20899	}, {
20900		queue: false,
20901		duration: o.duration,
20902		easing: o.easing,
20903		complete: done
20904	});
20905};
20906
20907
20908/*!
20909 * jQuery UI Effects Fold 1.11.4
20910 * http://jqueryui.com
20911 *
20912 * Copyright jQuery Foundation and other contributors
20913 * Released under the MIT license.
20914 * http://jquery.org/license
20915 *
20916 * http://api.jqueryui.com/fold-effect/
20917 */
20918
20919
20920var effectFold = $.effects.effect.fold = function( o, done ) {
20921
20922	// Create element
20923	var el = $( this ),
20924		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
20925		mode = $.effects.setMode( el, o.mode || "hide" ),
20926		show = mode === "show",
20927		hide = mode === "hide",
20928		size = o.size || 15,
20929		percent = /([0-9]+)%/.exec( size ),
20930		horizFirst = !!o.horizFirst,
20931		widthFirst = show !== horizFirst,
20932		ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
20933		duration = o.duration / 2,
20934		wrapper, distance,
20935		animation1 = {},
20936		animation2 = {};
20937
20938	$.effects.save( el, props );
20939	el.show();
20940
20941	// Create Wrapper
20942	wrapper = $.effects.createWrapper( el ).css({
20943		overflow: "hidden"
20944	});
20945	distance = widthFirst ?
20946		[ wrapper.width(), wrapper.height() ] :
20947		[ wrapper.height(), wrapper.width() ];
20948
20949	if ( percent ) {
20950		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
20951	}
20952	if ( show ) {
20953		wrapper.css( horizFirst ? {
20954			height: 0,
20955			width: size
20956		} : {
20957			height: size,
20958			width: 0
20959		});
20960	}
20961
20962	// Animation
20963	animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
20964	animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
20965
20966	// Animate
20967	wrapper
20968		.animate( animation1, duration, o.easing )
20969		.animate( animation2, duration, o.easing, function() {
20970			if ( hide ) {
20971				el.hide();
20972			}
20973			$.effects.restore( el, props );
20974			$.effects.removeWrapper( el );
20975			done();
20976		});
20977
20978};
20979
20980
20981/*!
20982 * jQuery UI Effects Highlight 1.11.4
20983 * http://jqueryui.com
20984 *
20985 * Copyright jQuery Foundation and other contributors
20986 * Released under the MIT license.
20987 * http://jquery.org/license
20988 *
20989 * http://api.jqueryui.com/highlight-effect/
20990 */
20991
20992
20993var effectHighlight = $.effects.effect.highlight = function( o, done ) {
20994	var elem = $( this ),
20995		props = [ "backgroundImage", "backgroundColor", "opacity" ],
20996		mode = $.effects.setMode( elem, o.mode || "show" ),
20997		animation = {
20998			backgroundColor: elem.css( "backgroundColor" )
20999		};
21000
21001	if (mode === "hide") {
21002		animation.opacity = 0;
21003	}
21004
21005	$.effects.save( elem, props );
21006
21007	elem
21008		.show()
21009		.css({
21010			backgroundImage: "none",
21011			backgroundColor: o.color || "#ffff99"
21012		})
21013		.animate( animation, {
21014			queue: false,
21015			duration: o.duration,
21016			easing: o.easing,
21017			complete: function() {
21018				if ( mode === "hide" ) {
21019					elem.hide();
21020				}
21021				$.effects.restore( elem, props );
21022				done();
21023			}
21024		});
21025};
21026
21027
21028/*!
21029 * jQuery UI Effects Size 1.11.4
21030 * http://jqueryui.com
21031 *
21032 * Copyright jQuery Foundation and other contributors
21033 * Released under the MIT license.
21034 * http://jquery.org/license
21035 *
21036 * http://api.jqueryui.com/size-effect/
21037 */
21038
21039
21040var effectSize = $.effects.effect.size = function( o, done ) {
21041
21042	// Create element
21043	var original, baseline, factor,
21044		el = $( this ),
21045		props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
21046
21047		// Always restore
21048		props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
21049
21050		// Copy for children
21051		props2 = [ "width", "height", "overflow" ],
21052		cProps = [ "fontSize" ],
21053		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
21054		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
21055
21056		// Set options
21057		mode = $.effects.setMode( el, o.mode || "effect" ),
21058		restore = o.restore || mode !== "effect",
21059		scale = o.scale || "both",
21060		origin = o.origin || [ "middle", "center" ],
21061		position = el.css( "position" ),
21062		props = restore ? props0 : props1,
21063		zero = {
21064			height: 0,
21065			width: 0,
21066			outerHeight: 0,
21067			outerWidth: 0
21068		};
21069
21070	if ( mode === "show" ) {
21071		el.show();
21072	}
21073	original = {
21074		height: el.height(),
21075		width: el.width(),
21076		outerHeight: el.outerHeight(),
21077		outerWidth: el.outerWidth()
21078	};
21079
21080	if ( o.mode === "toggle" && mode === "show" ) {
21081		el.from = o.to || zero;
21082		el.to = o.from || original;
21083	} else {
21084		el.from = o.from || ( mode === "show" ? zero : original );
21085		el.to = o.to || ( mode === "hide" ? zero : original );
21086	}
21087
21088	// Set scaling factor
21089	factor = {
21090		from: {
21091			y: el.from.height / original.height,
21092			x: el.from.width / original.width
21093		},
21094		to: {
21095			y: el.to.height / original.height,
21096			x: el.to.width / original.width
21097		}
21098	};
21099
21100	// Scale the css box
21101	if ( scale === "box" || scale === "both" ) {
21102
21103		// Vertical props scaling
21104		if ( factor.from.y !== factor.to.y ) {
21105			props = props.concat( vProps );
21106			el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
21107			el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
21108		}
21109
21110		// Horizontal props scaling
21111		if ( factor.from.x !== factor.to.x ) {
21112			props = props.concat( hProps );
21113			el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
21114			el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
21115		}
21116	}
21117
21118	// Scale the content
21119	if ( scale === "content" || scale === "both" ) {
21120
21121		// Vertical props scaling
21122		if ( factor.from.y !== factor.to.y ) {
21123			props = props.concat( cProps ).concat( props2 );
21124			el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
21125			el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
21126		}
21127	}
21128
21129	$.effects.save( el, props );
21130	el.show();
21131	$.effects.createWrapper( el );
21132	el.css( "overflow", "hidden" ).css( el.from );
21133
21134	// Adjust
21135	if (origin) { // Calculate baseline shifts
21136		baseline = $.effects.getBaseline( origin, original );
21137		el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
21138		el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
21139		el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
21140		el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
21141	}
21142	el.css( el.from ); // set top & left
21143
21144	// Animate
21145	if ( scale === "content" || scale === "both" ) { // Scale the children
21146
21147		// Add margins/font-size
21148		vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
21149		hProps = hProps.concat([ "marginLeft", "marginRight" ]);
21150		props2 = props0.concat(vProps).concat(hProps);
21151
21152		el.find( "*[width]" ).each( function() {
21153			var child = $( this ),
21154				c_original = {
21155					height: child.height(),
21156					width: child.width(),
21157					outerHeight: child.outerHeight(),
21158					outerWidth: child.outerWidth()
21159				};
21160			if (restore) {
21161				$.effects.save(child, props2);
21162			}
21163
21164			child.from = {
21165				height: c_original.height * factor.from.y,
21166				width: c_original.width * factor.from.x,
21167				outerHeight: c_original.outerHeight * factor.from.y,
21168				outerWidth: c_original.outerWidth * factor.from.x
21169			};
21170			child.to = {
21171				height: c_original.height * factor.to.y,
21172				width: c_original.width * factor.to.x,
21173				outerHeight: c_original.height * factor.to.y,
21174				outerWidth: c_original.width * factor.to.x
21175			};
21176
21177			// Vertical props scaling
21178			if ( factor.from.y !== factor.to.y ) {
21179				child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
21180				child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
21181			}
21182
21183			// Horizontal props scaling
21184			if ( factor.from.x !== factor.to.x ) {
21185				child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
21186				child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
21187			}
21188
21189			// Animate children
21190			child.css( child.from );
21191			child.animate( child.to, o.duration, o.easing, function() {
21192
21193				// Restore children
21194				if ( restore ) {
21195					$.effects.restore( child, props2 );
21196				}
21197			});
21198		});
21199	}
21200
21201	// Animate
21202	el.animate( el.to, {
21203		queue: false,
21204		duration: o.duration,
21205		easing: o.easing,
21206		complete: function() {
21207			if ( el.to.opacity === 0 ) {
21208				el.css( "opacity", el.from.opacity );
21209			}
21210			if ( mode === "hide" ) {
21211				el.hide();
21212			}
21213			$.effects.restore( el, props );
21214			if ( !restore ) {
21215
21216				// we need to calculate our new positioning based on the scaling
21217				if ( position === "static" ) {
21218					el.css({
21219						position: "relative",
21220						top: el.to.top,
21221						left: el.to.left
21222					});
21223				} else {
21224					$.each([ "top", "left" ], function( idx, pos ) {
21225						el.css( pos, function( _, str ) {
21226							var val = parseInt( str, 10 ),
21227								toRef = idx ? el.to.left : el.to.top;
21228
21229							// if original was "auto", recalculate the new value from wrapper
21230							if ( str === "auto" ) {
21231								return toRef + "px";
21232							}
21233
21234							return val + toRef + "px";
21235						});
21236					});
21237				}
21238			}
21239
21240			$.effects.removeWrapper( el );
21241			done();
21242		}
21243	});
21244
21245};
21246
21247
21248/*!
21249 * jQuery UI Effects Scale 1.11.4
21250 * http://jqueryui.com
21251 *
21252 * Copyright jQuery Foundation and other contributors
21253 * Released under the MIT license.
21254 * http://jquery.org/license
21255 *
21256 * http://api.jqueryui.com/scale-effect/
21257 */
21258
21259
21260var effectScale = $.effects.effect.scale = function( o, done ) {
21261
21262	// Create element
21263	var el = $( this ),
21264		options = $.extend( true, {}, o ),
21265		mode = $.effects.setMode( el, o.mode || "effect" ),
21266		percent = parseInt( o.percent, 10 ) ||
21267			( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
21268		direction = o.direction || "both",
21269		origin = o.origin,
21270		original = {
21271			height: el.height(),
21272			width: el.width(),
21273			outerHeight: el.outerHeight(),
21274			outerWidth: el.outerWidth()
21275		},
21276		factor = {
21277			y: direction !== "horizontal" ? (percent / 100) : 1,
21278			x: direction !== "vertical" ? (percent / 100) : 1
21279		};
21280
21281	// We are going to pass this effect to the size effect:
21282	options.effect = "size";
21283	options.queue = false;
21284	options.complete = done;
21285
21286	// Set default origin and restore for show/hide
21287	if ( mode !== "effect" ) {
21288		options.origin = origin || [ "middle", "center" ];
21289		options.restore = true;
21290	}
21291
21292	options.from = o.from || ( mode === "show" ? {
21293		height: 0,
21294		width: 0,
21295		outerHeight: 0,
21296		outerWidth: 0
21297	} : original );
21298	options.to = {
21299		height: original.height * factor.y,
21300		width: original.width * factor.x,
21301		outerHeight: original.outerHeight * factor.y,
21302		outerWidth: original.outerWidth * factor.x
21303	};
21304
21305	// Fade option to support puff
21306	if ( options.fade ) {
21307		if ( mode === "show" ) {
21308			options.from.opacity = 0;
21309			options.to.opacity = 1;
21310		}
21311		if ( mode === "hide" ) {
21312			options.from.opacity = 1;
21313			options.to.opacity = 0;
21314		}
21315	}
21316
21317	// Animate
21318	el.effect( options );
21319
21320};
21321
21322
21323/*!
21324 * jQuery UI Effects Puff 1.11.4
21325 * http://jqueryui.com
21326 *
21327 * Copyright jQuery Foundation and other contributors
21328 * Released under the MIT license.
21329 * http://jquery.org/license
21330 *
21331 * http://api.jqueryui.com/puff-effect/
21332 */
21333
21334
21335var effectPuff = $.effects.effect.puff = function( o, done ) {
21336	var elem = $( this ),
21337		mode = $.effects.setMode( elem, o.mode || "hide" ),
21338		hide = mode === "hide",
21339		percent = parseInt( o.percent, 10 ) || 150,
21340		factor = percent / 100,
21341		original = {
21342			height: elem.height(),
21343			width: elem.width(),
21344			outerHeight: elem.outerHeight(),
21345			outerWidth: elem.outerWidth()
21346		};
21347
21348	$.extend( o, {
21349		effect: "scale",
21350		queue: false,
21351		fade: true,
21352		mode: mode,
21353		complete: done,
21354		percent: hide ? percent : 100,
21355		from: hide ?
21356			original :
21357			{
21358				height: original.height * factor,
21359				width: original.width * factor,
21360				outerHeight: original.outerHeight * factor,
21361				outerWidth: original.outerWidth * factor
21362			}
21363	});
21364
21365	elem.effect( o );
21366};
21367
21368
21369/*!
21370 * jQuery UI Effects Pulsate 1.11.4
21371 * http://jqueryui.com
21372 *
21373 * Copyright jQuery Foundation and other contributors
21374 * Released under the MIT license.
21375 * http://jquery.org/license
21376 *
21377 * http://api.jqueryui.com/pulsate-effect/
21378 */
21379
21380
21381var effectPulsate = $.effects.effect.pulsate = function( o, done ) {
21382	var elem = $( this ),
21383		mode = $.effects.setMode( elem, o.mode || "show" ),
21384		show = mode === "show",
21385		hide = mode === "hide",
21386		showhide = ( show || mode === "hide" ),
21387
21388		// showing or hiding leaves of the "last" animation
21389		anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
21390		duration = o.duration / anims,
21391		animateTo = 0,
21392		queue = elem.queue(),
21393		queuelen = queue.length,
21394		i;
21395
21396	if ( show || !elem.is(":visible")) {
21397		elem.css( "opacity", 0 ).show();
21398		animateTo = 1;
21399	}
21400
21401	// anims - 1 opacity "toggles"
21402	for ( i = 1; i < anims; i++ ) {
21403		elem.animate({
21404			opacity: animateTo
21405		}, duration, o.easing );
21406		animateTo = 1 - animateTo;
21407	}
21408
21409	elem.animate({
21410		opacity: animateTo
21411	}, duration, o.easing);
21412
21413	elem.queue(function() {
21414		if ( hide ) {
21415			elem.hide();
21416		}
21417		done();
21418	});
21419
21420	// We just queued up "anims" animations, we need to put them next in the queue
21421	if ( queuelen > 1 ) {
21422		queue.splice.apply( queue,
21423			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
21424	}
21425	elem.dequeue();
21426};
21427
21428
21429/*!
21430 * jQuery UI Effects Shake 1.11.4
21431 * http://jqueryui.com
21432 *
21433 * Copyright jQuery Foundation and other contributors
21434 * Released under the MIT license.
21435 * http://jquery.org/license
21436 *
21437 * http://api.jqueryui.com/shake-effect/
21438 */
21439
21440
21441var effectShake = $.effects.effect.shake = function( o, done ) {
21442
21443	var el = $( this ),
21444		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
21445		mode = $.effects.setMode( el, o.mode || "effect" ),
21446		direction = o.direction || "left",
21447		distance = o.distance || 20,
21448		times = o.times || 3,
21449		anims = times * 2 + 1,
21450		speed = Math.round( o.duration / anims ),
21451		ref = (direction === "up" || direction === "down") ? "top" : "left",
21452		positiveMotion = (direction === "up" || direction === "left"),
21453		animation = {},
21454		animation1 = {},
21455		animation2 = {},
21456		i,
21457
21458		// we will need to re-assemble the queue to stack our animations in place
21459		queue = el.queue(),
21460		queuelen = queue.length;
21461
21462	$.effects.save( el, props );
21463	el.show();
21464	$.effects.createWrapper( el );
21465
21466	// Animation
21467	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
21468	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
21469	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
21470
21471	// Animate
21472	el.animate( animation, speed, o.easing );
21473
21474	// Shakes
21475	for ( i = 1; i < times; i++ ) {
21476		el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
21477	}
21478	el
21479		.animate( animation1, speed, o.easing )
21480		.animate( animation, speed / 2, o.easing )
21481		.queue(function() {
21482			if ( mode === "hide" ) {
21483				el.hide();
21484			}
21485			$.effects.restore( el, props );
21486			$.effects.removeWrapper( el );
21487			done();
21488		});
21489
21490	// inject all the animations we just queued to be first in line (after "inprogress")
21491	if ( queuelen > 1) {
21492		queue.splice.apply( queue,
21493			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
21494	}
21495	el.dequeue();
21496
21497};
21498
21499
21500/*!
21501 * jQuery UI Effects Slide 1.11.4
21502 * http://jqueryui.com
21503 *
21504 * Copyright jQuery Foundation and other contributors
21505 * Released under the MIT license.
21506 * http://jquery.org/license
21507 *
21508 * http://api.jqueryui.com/slide-effect/
21509 */
21510
21511
21512var effectSlide = $.effects.effect.slide = function( o, done ) {
21513
21514	// Create element
21515	var el = $( this ),
21516		props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
21517		mode = $.effects.setMode( el, o.mode || "show" ),
21518		show = mode === "show",
21519		direction = o.direction || "left",
21520		ref = (direction === "up" || direction === "down") ? "top" : "left",
21521		positiveMotion = (direction === "up" || direction === "left"),
21522		distance,
21523		animation = {};
21524
21525	// Adjust
21526	$.effects.save( el, props );
21527	el.show();
21528	distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
21529
21530	$.effects.createWrapper( el ).css({
21531		overflow: "hidden"
21532	});
21533
21534	if ( show ) {
21535		el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
21536	}
21537
21538	// Animation
21539	animation[ ref ] = ( show ?
21540		( positiveMotion ? "+=" : "-=") :
21541		( positiveMotion ? "-=" : "+=")) +
21542		distance;
21543
21544	// Animate
21545	el.animate( animation, {
21546		queue: false,
21547		duration: o.duration,
21548		easing: o.easing,
21549		complete: function() {
21550			if ( mode === "hide" ) {
21551				el.hide();
21552			}
21553			$.effects.restore( el, props );
21554			$.effects.removeWrapper( el );
21555			done();
21556		}
21557	});
21558};
21559
21560
21561/*!
21562 * jQuery UI Effects Transfer 1.11.4
21563 * http://jqueryui.com
21564 *
21565 * Copyright jQuery Foundation and other contributors
21566 * Released under the MIT license.
21567 * http://jquery.org/license
21568 *
21569 * http://api.jqueryui.com/transfer-effect/
21570 */
21571
21572
21573var effectTransfer = $.effects.effect.transfer = function( o, done ) {
21574	var elem = $( this ),
21575		target = $( o.to ),
21576		targetFixed = target.css( "position" ) === "fixed",
21577		body = $("body"),
21578		fixTop = targetFixed ? body.scrollTop() : 0,
21579		fixLeft = targetFixed ? body.scrollLeft() : 0,
21580		endPosition = target.offset(),
21581		animation = {
21582			top: endPosition.top - fixTop,
21583			left: endPosition.left - fixLeft,
21584			height: target.innerHeight(),
21585			width: target.innerWidth()
21586		},
21587		startPosition = elem.offset(),
21588		transfer = $( "<div class='ui-effects-transfer'></div>" )
21589			.appendTo( document.body )
21590			.addClass( o.className )
21591			.css({
21592				top: startPosition.top - fixTop,
21593				left: startPosition.left - fixLeft,
21594				height: elem.innerHeight(),
21595				width: elem.innerWidth(),
21596				position: targetFixed ? "fixed" : "absolute"
21597			})
21598			.animate( animation, o.duration, o.easing, function() {
21599				transfer.remove();
21600				done();
21601			});
21602};
21603
21604
21605/*!
21606 * jQuery UI Progressbar 1.11.4
21607 * http://jqueryui.com
21608 *
21609 * Copyright jQuery Foundation and other contributors
21610 * Released under the MIT license.
21611 * http://jquery.org/license
21612 *
21613 * http://api.jqueryui.com/progressbar/
21614 */
21615
21616
21617var progressbar = $.widget( "ui.progressbar", {
21618	version: "1.11.4",
21619	options: {
21620		max: 100,
21621		value: 0,
21622
21623		change: null,
21624		complete: null
21625	},
21626
21627	min: 0,
21628
21629	_create: function() {
21630		// Constrain initial value
21631		this.oldValue = this.options.value = this._constrainedValue();
21632
21633		this.element
21634			.addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
21635			.attr({
21636				// Only set static values, aria-valuenow and aria-valuemax are
21637				// set inside _refreshValue()
21638				role: "progressbar",
21639				"aria-valuemin": this.min
21640			});
21641
21642		this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
21643			.appendTo( this.element );
21644
21645		this._refreshValue();
21646	},
21647
21648	_destroy: function() {
21649		this.element
21650			.removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
21651			.removeAttr( "role" )
21652			.removeAttr( "aria-valuemin" )
21653			.removeAttr( "aria-valuemax" )
21654			.removeAttr( "aria-valuenow" );
21655
21656		this.valueDiv.remove();
21657	},
21658
21659	value: function( newValue ) {
21660		if ( newValue === undefined ) {
21661			return this.options.value;
21662		}
21663
21664		this.options.value = this._constrainedValue( newValue );
21665		this._refreshValue();
21666	},
21667
21668	_constrainedValue: function( newValue ) {
21669		if ( newValue === undefined ) {
21670			newValue = this.options.value;
21671		}
21672
21673		this.indeterminate = newValue === false;
21674
21675		// sanitize value
21676		if ( typeof newValue !== "number" ) {
21677			newValue = 0;
21678		}
21679
21680		return this.indeterminate ? false :
21681			Math.min( this.options.max, Math.max( this.min, newValue ) );
21682	},
21683
21684	_setOptions: function( options ) {
21685		// Ensure "value" option is set after other values (like max)
21686		var value = options.value;
21687		delete options.value;
21688
21689		this._super( options );
21690
21691		this.options.value = this._constrainedValue( value );
21692		this._refreshValue();
21693	},
21694
21695	_setOption: function( key, value ) {
21696		if ( key === "max" ) {
21697			// Don't allow a max less than min
21698			value = Math.max( this.min, value );
21699		}
21700		if ( key === "disabled" ) {
21701			this.element
21702				.toggleClass( "ui-state-disabled", !!value )
21703				.attr( "aria-disabled", value );
21704		}
21705		this._super( key, value );
21706	},
21707
21708	_percentage: function() {
21709		return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
21710	},
21711
21712	_refreshValue: function() {
21713		var value = this.options.value,
21714			percentage = this._percentage();
21715
21716		this.valueDiv
21717			.toggle( this.indeterminate || value > this.min )
21718			.toggleClass( "ui-corner-right", value === this.options.max )
21719			.width( percentage.toFixed(0) + "%" );
21720
21721		this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
21722
21723		if ( this.indeterminate ) {
21724			this.element.removeAttr( "aria-valuenow" );
21725			if ( !this.overlayDiv ) {
21726				this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
21727			}
21728		} else {
21729			this.element.attr({
21730				"aria-valuemax": this.options.max,
21731				"aria-valuenow": value
21732			});
21733			if ( this.overlayDiv ) {
21734				this.overlayDiv.remove();
21735				this.overlayDiv = null;
21736			}
21737		}
21738
21739		if ( this.oldValue !== value ) {
21740			this.oldValue = value;
21741			this._trigger( "change" );
21742		}
21743		if ( value === this.options.max ) {
21744			this._trigger( "complete" );
21745		}
21746	}
21747});
21748
21749
21750/*!
21751 * jQuery UI Selectable 1.11.4
21752 * http://jqueryui.com
21753 *
21754 * Copyright jQuery Foundation and other contributors
21755 * Released under the MIT license.
21756 * http://jquery.org/license
21757 *
21758 * http://api.jqueryui.com/selectable/
21759 */
21760
21761
21762var selectable = $.widget("ui.selectable", $.ui.mouse, {
21763	version: "1.11.4",
21764	options: {
21765		appendTo: "body",
21766		autoRefresh: true,
21767		distance: 0,
21768		filter: "*",
21769		tolerance: "touch",
21770
21771		// callbacks
21772		selected: null,
21773		selecting: null,
21774		start: null,
21775		stop: null,
21776		unselected: null,
21777		unselecting: null
21778	},
21779	_create: function() {
21780		var selectees,
21781			that = this;
21782
21783		this.element.addClass("ui-selectable");
21784
21785		this.dragged = false;
vendor: 4,465 bytes, lines 21786-21953
21786
21787		// cache selectee children based on filter
21788		this.refresh = function() {
21789			selectees = $(that.options.filter, that.element[0]);
21790			selectees.addClass("ui-selectee");
21791			selectees.each(function() {
21792				var $this = $(this),
21793					pos = $this.offset();
21794				$.data(this, "selectable-item", {
21795					element: this,
21796					$element: $this,
21797					left: pos.left,
21798					top: pos.top,
21799					right: pos.left + $this.outerWidth(),
21800					bottom: pos.top + $this.outerHeight(),
21801					startselected: false,
21802					selected: $this.hasClass("ui-selected"),
21803					selecting: $this.hasClass("ui-selecting"),
21804					unselecting: $this.hasClass("ui-unselecting")
21805				});
21806			});
21807		};
21808		this.refresh();
21809
21810		this.selectees = selectees.addClass("ui-selectee");
21811
21812		this._mouseInit();
21813
21814		this.helper = $("<div class='ui-selectable-helper'></div>");
21815	},
21816
21817	_destroy: function() {
21818		this.selectees
21819			.removeClass("ui-selectee")
21820			.removeData("selectable-item");
21821		this.element
21822			.removeClass("ui-selectable ui-selectable-disabled");
21823		this._mouseDestroy();
21824	},
21825
21826	_mouseStart: function(event) {
21827		var that = this,
21828			options = this.options;
21829
21830		this.opos = [ event.pageX, event.pageY ];
21831
21832		if (this.options.disabled) {
21833			return;
21834		}
21835
21836		this.selectees = $(options.filter, this.element[0]);
21837
21838		this._trigger("start", event);
21839
21840		$(options.appendTo).append(this.helper);
21841		// position helper (lasso)
21842		this.helper.css({
21843			"left": event.pageX,
21844			"top": event.pageY,
21845			"width": 0,
21846			"height": 0
21847		});
21848
21849		if (options.autoRefresh) {
21850			this.refresh();
21851		}
21852
21853		this.selectees.filter(".ui-selected").each(function() {
21854			var selectee = $.data(this, "selectable-item");
21855			selectee.startselected = true;
21856			if (!event.metaKey && !event.ctrlKey) {
21857				selectee.$element.removeClass("ui-selected");
21858				selectee.selected = false;
21859				selectee.$element.addClass("ui-unselecting");
21860				selectee.unselecting = true;
21861				// selectable UNSELECTING callback
21862				that._trigger("unselecting", event, {
21863					unselecting: selectee.element
21864				});
21865			}
21866		});
21867
21868		$(event.target).parents().addBack().each(function() {
21869			var doSelect,
21870				selectee = $.data(this, "selectable-item");
21871			if (selectee) {
21872				doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
21873				selectee.$element
21874					.removeClass(doSelect ? "ui-unselecting" : "ui-selected")
21875					.addClass(doSelect ? "ui-selecting" : "ui-unselecting");
21876				selectee.unselecting = !doSelect;
21877				selectee.selecting = doSelect;
21878				selectee.selected = doSelect;
21879				// selectable (UN)SELECTING callback
21880				if (doSelect) {
21881					that._trigger("selecting", event, {
21882						selecting: selectee.element
21883					});
21884				} else {
21885					that._trigger("unselecting", event, {
21886						unselecting: selectee.element
21887					});
21888				}
21889				return false;
21890			}
21891		});
21892
21893	},
21894
21895	_mouseDrag: function(event) {
21896
21897		this.dragged = true;
21898
21899		if (this.options.disabled) {
21900			return;
21901		}
21902
21903		var tmp,
21904			that = this,
21905			options = this.options,
21906			x1 = this.opos[0],
21907			y1 = this.opos[1],
21908			x2 = event.pageX,
21909			y2 = event.pageY;
21910
21911		if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
21912		if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
21913		this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
21914
21915		this.selectees.each(function() {
21916			var selectee = $.data(this, "selectable-item"),
21917				hit = false;
21918
21919			//prevent helper from being selected if appendTo: selectable
21920			if (!selectee || selectee.element === that.element[0]) {
21921				return;
21922			}
21923
21924			if (options.tolerance === "touch") {
21925				hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
21926			} else if (options.tolerance === "fit") {
21927				hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
21928			}
21929
21930			if (hit) {
21931				// SELECT
21932				if (selectee.selected) {
21933					selectee.$element.removeClass("ui-selected");
21934					selectee.selected = false;
21935				}
21936				if (selectee.unselecting) {
21937					selectee.$element.removeClass("ui-unselecting");
21938					selectee.unselecting = false;
21939				}
21940				if (!selectee.selecting) {
21941					selectee.$element.addClass("ui-selecting");
21942					selectee.selecting = true;
21943					// selectable SELECTING callback
21944					that._trigger("selecting", event, {
21945						selecting: selectee.element
21946					});
21947				}
21948			} else {
21949				// UNSELECT
21950				if (selectee.selecting) {
21951					if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
21952						selectee.$element.removeClass("ui-selecting");
21953						selectee.selecting = false;
vendor: 20,164 bytes, lines 21954-22822
21954						selectee.$element.addClass("ui-selected");
21955						selectee.selected = true;
21956					} else {
21957						selectee.$element.removeClass("ui-selecting");
21958						selectee.selecting = false;
21959						if (selectee.startselected) {
21960							selectee.$element.addClass("ui-unselecting");
21961							selectee.unselecting = true;
21962						}
21963						// selectable UNSELECTING callback
21964						that._trigger("unselecting", event, {
21965							unselecting: selectee.element
21966						});
21967					}
21968				}
21969				if (selectee.selected) {
21970					if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
21971						selectee.$element.removeClass("ui-selected");
21972						selectee.selected = false;
21973
21974						selectee.$element.addClass("ui-unselecting");
21975						selectee.unselecting = true;
21976						// selectable UNSELECTING callback
21977						that._trigger("unselecting", event, {
21978							unselecting: selectee.element
21979						});
21980					}
21981				}
21982			}
21983		});
21984
21985		return false;
21986	},
21987
21988	_mouseStop: function(event) {
21989		var that = this;
21990
21991		this.dragged = false;
21992
21993		$(".ui-unselecting", this.element[0]).each(function() {
21994			var selectee = $.data(this, "selectable-item");
21995			selectee.$element.removeClass("ui-unselecting");
21996			selectee.unselecting = false;
21997			selectee.startselected = false;
21998			that._trigger("unselected", event, {
21999				unselected: selectee.element
22000			});
22001		});
22002		$(".ui-selecting", this.element[0]).each(function() {
22003			var selectee = $.data(this, "selectable-item");
22004			selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
22005			selectee.selecting = false;
22006			selectee.selected = true;
22007			selectee.startselected = true;
22008			that._trigger("selected", event, {
22009				selected: selectee.element
22010			});
22011		});
22012		this._trigger("stop", event);
22013
22014		this.helper.remove();
22015
22016		return false;
22017	}
22018
22019});
22020
22021
22022/*!
22023 * jQuery UI Selectmenu 1.11.4
22024 * http://jqueryui.com
22025 *
22026 * Copyright jQuery Foundation and other contributors
22027 * Released under the MIT license.
22028 * http://jquery.org/license
22029 *
22030 * http://api.jqueryui.com/selectmenu
22031 */
22032
22033
22034var selectmenu = $.widget( "ui.selectmenu", {
22035	version: "1.11.4",
22036	defaultElement: "<select>",
22037	options: {
22038		appendTo: null,
22039		disabled: null,
22040		icons: {
22041			button: "ui-icon-triangle-1-s"
22042		},
22043		position: {
22044			my: "left top",
22045			at: "left bottom",
22046			collision: "none"
22047		},
22048		width: null,
22049
22050		// callbacks
22051		change: null,
22052		close: null,
22053		focus: null,
22054		open: null,
22055		select: null
22056	},
22057
22058	_create: function() {
22059		var selectmenuId = this.element.uniqueId().attr( "id" );
22060		this.ids = {
22061			element: selectmenuId,
22062			button: selectmenuId + "-button",
22063			menu: selectmenuId + "-menu"
22064		};
22065
22066		this._drawButton();
22067		this._drawMenu();
22068
22069		if ( this.options.disabled ) {
22070			this.disable();
22071		}
22072	},
22073
22074	_drawButton: function() {
22075		var that = this;
22076
22077		// Associate existing label with the new button
22078		this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
22079		this._on( this.label, {
22080			click: function( event ) {
22081				this.button.focus();
22082				event.preventDefault();
22083			}
22084		});
22085
22086		// Hide original select element
22087		this.element.hide();
22088
22089		// Create button
22090		this.button = $( "<span>", {
22091			"class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
22092			tabindex: this.options.disabled ? -1 : 0,
22093			id: this.ids.button,
22094			role: "combobox",
22095			"aria-expanded": "false",
22096			"aria-autocomplete": "list",
22097			"aria-owns": this.ids.menu,
22098			"aria-haspopup": "true"
22099		})
22100			.insertAfter( this.element );
22101
22102		$( "<span>", {
22103			"class": "ui-icon " + this.options.icons.button
22104		})
22105			.prependTo( this.button );
22106
22107		this.buttonText = $( "<span>", {
22108			"class": "ui-selectmenu-text"
22109		})
22110			.appendTo( this.button );
22111
22112		this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
22113		this._resizeButton();
22114
22115		this._on( this.button, this._buttonEvents );
22116		this.button.one( "focusin", function() {
22117
22118			// Delay rendering the menu items until the button receives focus.
22119			// The menu may have already been rendered via a programmatic open.
22120			if ( !that.menuItems ) {
22121				that._refreshMenu();
22122			}
22123		});
22124		this._hoverable( this.button );
22125		this._focusable( this.button );
22126	},
22127
22128	_drawMenu: function() {
22129		var that = this;
22130
22131		// Create menu
22132		this.menu = $( "<ul>", {
22133			"aria-hidden": "true",
22134			"aria-labelledby": this.ids.button,
22135			id: this.ids.menu
22136		});
22137
22138		// Wrap menu
22139		this.menuWrap = $( "<div>", {
22140			"class": "ui-selectmenu-menu ui-front"
22141		})
22142			.append( this.menu )
22143			.appendTo( this._appendTo() );
22144
22145		// Initialize menu widget
22146		this.menuInstance = this.menu
22147			.menu({
22148				role: "listbox",
22149				select: function( event, ui ) {
22150					event.preventDefault();
22151
22152					// support: IE8
22153					// If the item was selected via a click, the text selection
22154					// will be destroyed in IE
22155					that._setSelection();
22156
22157					that._select( ui.item.data( "ui-selectmenu-item" ), event );
22158				},
22159				focus: function( event, ui ) {
22160					var item = ui.item.data( "ui-selectmenu-item" );
22161
22162					// Prevent inital focus from firing and check if its a newly focused item
22163					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
22164						that._trigger( "focus", event, { item: item } );
22165						if ( !that.isOpen ) {
22166							that._select( item, event );
22167						}
22168					}
22169					that.focusIndex = item.index;
22170
22171					that.button.attr( "aria-activedescendant",
22172						that.menuItems.eq( item.index ).attr( "id" ) );
22173				}
22174			})
22175			.menu( "instance" );
22176
22177		// Adjust menu styles to dropdown
22178		this.menu
22179			.addClass( "ui-corner-bottom" )
22180			.removeClass( "ui-corner-all" );
22181
22182		// Don't close the menu on mouseleave
22183		this.menuInstance._off( this.menu, "mouseleave" );
22184
22185		// Cancel the menu's collapseAll on document click
22186		this.menuInstance._closeOnDocumentClick = function() {
22187			return false;
22188		};
22189
22190		// Selects often contain empty items, but never contain dividers
22191		this.menuInstance._isDivider = function() {
22192			return false;
22193		};
22194	},
22195
22196	refresh: function() {
22197		this._refreshMenu();
22198		this._setText( this.buttonText, this._getSelectedItem().text() );
22199		if ( !this.options.width ) {
22200			this._resizeButton();
22201		}
22202	},
22203
22204	_refreshMenu: function() {
22205		this.menu.empty();
22206
22207		var item,
22208			options = this.element.find( "option" );
22209
22210		if ( !options.length ) {
22211			return;
22212		}
22213
22214		this._parseOptions( options );
22215		this._renderMenu( this.menu, this.items );
22216
22217		this.menuInstance.refresh();
22218		this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
22219
22220		item = this._getSelectedItem();
22221
22222		// Update the menu to have the correct item focused
22223		this.menuInstance.focus( null, item );
22224		this._setAria( item.data( "ui-selectmenu-item" ) );
22225
22226		// Set disabled state
22227		this._setOption( "disabled", this.element.prop( "disabled" ) );
22228	},
22229
22230	open: function( event ) {
22231		if ( this.options.disabled ) {
22232			return;
22233		}
22234
22235		// If this is the first time the menu is being opened, render the items
22236		if ( !this.menuItems ) {
22237			this._refreshMenu();
22238		} else {
22239
22240			// Menu clears focus on close, reset focus to selected item
22241			this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
22242			this.menuInstance.focus( null, this._getSelectedItem() );
22243		}
22244
22245		this.isOpen = true;
22246		this._toggleAttr();
22247		this._resizeMenu();
22248		this._position();
22249
22250		this._on( this.document, this._documentClick );
22251
22252		this._trigger( "open", event );
22253	},
22254
22255	_position: function() {
22256		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
22257	},
22258
22259	close: function( event ) {
22260		if ( !this.isOpen ) {
22261			return;
22262		}
22263
22264		this.isOpen = false;
22265		this._toggleAttr();
22266
22267		this.range = null;
22268		this._off( this.document );
22269
22270		this._trigger( "close", event );
22271	},
22272
22273	widget: function() {
22274		return this.button;
22275	},
22276
22277	menuWidget: function() {
22278		return this.menu;
22279	},
22280
22281	_renderMenu: function( ul, items ) {
22282		var that = this,
22283			currentOptgroup = "";
22284
22285		$.each( items, function( index, item ) {
22286			if ( item.optgroup !== currentOptgroup ) {
22287				$( "<li>", {
22288					"class": "ui-selectmenu-optgroup ui-menu-divider" +
22289						( item.element.parent( "optgroup" ).prop( "disabled" ) ?
22290							" ui-state-disabled" :
22291							"" ),
22292					text: item.optgroup
22293				})
22294					.appendTo( ul );
22295
22296				currentOptgroup = item.optgroup;
22297			}
22298
22299			that._renderItemData( ul, item );
22300		});
22301	},
22302
22303	_renderItemData: function( ul, item ) {
22304		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
22305	},
22306
22307	_renderItem: function( ul, item ) {
22308		var li = $( "<li>" );
22309
22310		if ( item.disabled ) {
22311			li.addClass( "ui-state-disabled" );
22312		}
22313		this._setText( li, item.label );
22314
22315		return li.appendTo( ul );
22316	},
22317
22318	_setText: function( element, value ) {
22319		if ( value ) {
22320			element.text( value );
22321		} else {
22322			element.html( "&#160;" );
22323		}
22324	},
22325
22326	_move: function( direction, event ) {
22327		var item, next,
22328			filter = ".ui-menu-item";
22329
22330		if ( this.isOpen ) {
22331			item = this.menuItems.eq( this.focusIndex );
22332		} else {
22333			item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
22334			filter += ":not(.ui-state-disabled)";
22335		}
22336
22337		if ( direction === "first" || direction === "last" ) {
22338			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
22339		} else {
22340			next = item[ direction + "All" ]( filter ).eq( 0 );
22341		}
22342
22343		if ( next.length ) {
22344			this.menuInstance.focus( event, next );
22345		}
22346	},
22347
22348	_getSelectedItem: function() {
22349		return this.menuItems.eq( this.element[ 0 ].selectedIndex );
22350	},
22351
22352	_toggle: function( event ) {
22353		this[ this.isOpen ? "close" : "open" ]( event );
22354	},
22355
22356	_setSelection: function() {
22357		var selection;
22358
22359		if ( !this.range ) {
22360			return;
22361		}
22362
22363		if ( window.getSelection ) {
22364			selection = window.getSelection();
22365			selection.removeAllRanges();
22366			selection.addRange( this.range );
22367
22368		// support: IE8
22369		} else {
22370			this.range.select();
22371		}
22372
22373		// support: IE
22374		// Setting the text selection kills the button focus in IE, but
22375		// restoring the focus doesn't kill the selection.
22376		this.button.focus();
22377	},
22378
22379	_documentClick: {
22380		mousedown: function( event ) {
22381			if ( !this.isOpen ) {
22382				return;
22383			}
22384
22385			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
22386				this.close( event );
22387			}
22388		}
22389	},
22390
22391	_buttonEvents: {
22392
22393		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
22394		mousedown: function() {
22395			var selection;
22396
22397			if ( window.getSelection ) {
22398				selection = window.getSelection();
22399				if ( selection.rangeCount ) {
22400					this.range = selection.getRangeAt( 0 );
22401				}
22402
22403			// support: IE8
22404			} else {
22405				this.range = document.selection.createRange();
22406			}
22407		},
22408
22409		click: function( event ) {
22410			this._setSelection();
22411			this._toggle( event );
22412		},
22413
22414		keydown: function( event ) {
22415			var preventDefault = true;
22416			switch ( event.keyCode ) {
22417				case $.ui.keyCode.TAB:
22418				case $.ui.keyCode.ESCAPE:
22419					this.close( event );
22420					preventDefault = false;
22421					break;
22422				case $.ui.keyCode.ENTER:
22423					if ( this.isOpen ) {
22424						this._selectFocusedItem( event );
22425					}
22426					break;
22427				case $.ui.keyCode.UP:
22428					if ( event.altKey ) {
22429						this._toggle( event );
22430					} else {
22431						this._move( "prev", event );
22432					}
22433					break;
22434				case $.ui.keyCode.DOWN:
22435					if ( event.altKey ) {
22436						this._toggle( event );
22437					} else {
22438						this._move( "next", event );
22439					}
22440					break;
22441				case $.ui.keyCode.SPACE:
22442					if ( this.isOpen ) {
22443						this._selectFocusedItem( event );
22444					} else {
22445						this._toggle( event );
22446					}
22447					break;
22448				case $.ui.keyCode.LEFT:
22449					this._move( "prev", event );
22450					break;
22451				case $.ui.keyCode.RIGHT:
22452					this._move( "next", event );
22453					break;
22454				case $.ui.keyCode.HOME:
22455				case $.ui.keyCode.PAGE_UP:
22456					this._move( "first", event );
22457					break;
22458				case $.ui.keyCode.END:
22459				case $.ui.keyCode.PAGE_DOWN:
22460					this._move( "last", event );
22461					break;
22462				default:
22463					this.menu.trigger( event );
22464					preventDefault = false;
22465			}
22466
22467			if ( preventDefault ) {
22468				event.preventDefault();
22469			}
22470		}
22471	},
22472
22473	_selectFocusedItem: function( event ) {
22474		var item = this.menuItems.eq( this.focusIndex );
22475		if ( !item.hasClass( "ui-state-disabled" ) ) {
22476			this._select( item.data( "ui-selectmenu-item" ), event );
22477		}
22478	},
22479
22480	_select: function( item, event ) {
22481		var oldIndex = this.element[ 0 ].selectedIndex;
22482
22483		// Change native select element
22484		this.element[ 0 ].selectedIndex = item.index;
22485		this._setText( this.buttonText, item.label );
22486		this._setAria( item );
22487		this._trigger( "select", event, { item: item } );
22488
22489		if ( item.index !== oldIndex ) {
22490			this._trigger( "change", event, { item: item } );
22491		}
22492
22493		this.close( event );
22494	},
22495
22496	_setAria: function( item ) {
22497		var id = this.menuItems.eq( item.index ).attr( "id" );
22498
22499		this.button.attr({
22500			"aria-labelledby": id,
22501			"aria-activedescendant": id
22502		});
22503		this.menu.attr( "aria-activedescendant", id );
22504	},
22505
22506	_setOption: function( key, value ) {
22507		if ( key === "icons" ) {
22508			this.button.find( "span.ui-icon" )
22509				.removeClass( this.options.icons.button )
22510				.addClass( value.button );
22511		}
22512
22513		this._super( key, value );
22514
22515		if ( key === "appendTo" ) {
22516			this.menuWrap.appendTo( this._appendTo() );
22517		}
22518
22519		if ( key === "disabled" ) {
22520			this.menuInstance.option( "disabled", value );
22521			this.button
22522				.toggleClass( "ui-state-disabled", value )
22523				.attr( "aria-disabled", value );
22524
22525			this.element.prop( "disabled", value );
22526			if ( value ) {
22527				this.button.attr( "tabindex", -1 );
22528				this.close();
22529			} else {
22530				this.button.attr( "tabindex", 0 );
22531			}
22532		}
22533
22534		if ( key === "width" ) {
22535			this._resizeButton();
22536		}
22537	},
22538
22539	_appendTo: function() {
22540		var element = this.options.appendTo;
22541
22542		if ( element ) {
22543			element = element.jquery || element.nodeType ?
22544				$( element ) :
22545				this.document.find( element ).eq( 0 );
22546		}
22547
22548		if ( !element || !element[ 0 ] ) {
22549			element = this.element.closest( ".ui-front" );
22550		}
22551
22552		if ( !element.length ) {
22553			element = this.document[ 0 ].body;
22554		}
22555
22556		return element;
22557	},
22558
22559	_toggleAttr: function() {
22560		this.button
22561			.toggleClass( "ui-corner-top", this.isOpen )
22562			.toggleClass( "ui-corner-all", !this.isOpen )
22563			.attr( "aria-expanded", this.isOpen );
22564		this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
22565		this.menu.attr( "aria-hidden", !this.isOpen );
22566	},
22567
22568	_resizeButton: function() {
22569		var width = this.options.width;
22570
22571		if ( !width ) {
22572			width = this.element.show().outerWidth();
22573			this.element.hide();
22574		}
22575
22576		this.button.outerWidth( width );
22577	},
22578
22579	_resizeMenu: function() {
22580		this.menu.outerWidth( Math.max(
22581			this.button.outerWidth(),
22582
22583			// support: IE10
22584			// IE10 wraps long text (possibly a rounding bug)
22585			// so we add 1px to avoid the wrapping
22586			this.menu.width( "" ).outerWidth() + 1
22587		) );
22588	},
22589
22590	_getCreateOptions: function() {
22591		return { disabled: this.element.prop( "disabled" ) };
22592	},
22593
22594	_parseOptions: function( options ) {
22595		var data = [];
22596		options.each(function( index, item ) {
22597			var option = $( item ),
22598				optgroup = option.parent( "optgroup" );
22599			data.push({
22600				element: option,
22601				index: index,
22602				value: option.val(),
22603				label: option.text(),
22604				optgroup: optgroup.attr( "label" ) || "",
22605				disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
22606			});
22607		});
22608		this.items = data;
22609	},
22610
22611	_destroy: function() {
22612		this.menuWrap.remove();
22613		this.button.remove();
22614		this.element.show();
22615		this.element.removeUniqueId();
22616		this.label.attr( "for", this.ids.element );
22617	}
22618});
22619
22620
22621/*!
22622 * jQuery UI Slider 1.11.4
22623 * http://jqueryui.com
22624 *
22625 * Copyright jQuery Foundation and other contributors
22626 * Released under the MIT license.
22627 * http://jquery.org/license
22628 *
22629 * http://api.jqueryui.com/slider/
22630 */
22631
22632
22633var slider = $.widget( "ui.slider", $.ui.mouse, {
22634	version: "1.11.4",
22635	widgetEventPrefix: "slide",
22636
22637	options: {
22638		animate: false,
22639		distance: 0,
22640		max: 100,
22641		min: 0,
22642		orientation: "horizontal",
22643		range: false,
22644		step: 1,
22645		value: 0,
22646		values: null,
22647
22648		// callbacks
22649		change: null,
22650		slide: null,
22651		start: null,
22652		stop: null
22653	},
22654
22655	// number of pages in a slider
22656	// (how many times can you page up/down to go through the whole range)
22657	numPages: 5,
22658
22659	_create: function() {
22660		this._keySliding = false;
22661		this._mouseSliding = false;
22662		this._animateOff = true;
22663		this._handleIndex = null;
22664		this._detectOrientation();
22665		this._mouseInit();
22666		this._calculateNewMax();
22667
22668		this.element
22669			.addClass( "ui-slider" +
22670				" ui-slider-" + this.orientation +
22671				" ui-widget" +
22672				" ui-widget-content" +
22673				" ui-corner-all");
22674
22675		this._refresh();
22676		this._setOption( "disabled", this.options.disabled );
22677
22678		this._animateOff = false;
22679	},
22680
22681	_refresh: function() {
22682		this._createRange();
22683		this._createHandles();
22684		this._setupEvents();
22685		this._refreshValue();
22686	},
22687
22688	_createHandles: function() {
22689		var i, handleCount,
22690			options = this.options,
22691			existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
22692			handle = "<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>",
22693			handles = [];
22694
22695		handleCount = ( options.values && options.values.length ) || 1;
22696
22697		if ( existingHandles.length > handleCount ) {
22698			existingHandles.slice( handleCount ).remove();
22699			existingHandles = existingHandles.slice( 0, handleCount );
22700		}
22701
22702		for ( i = existingHandles.length; i < handleCount; i++ ) {
22703			handles.push( handle );
22704		}
22705
22706		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
22707
22708		this.handle = this.handles.eq( 0 );
22709
22710		this.handles.each(function( i ) {
22711			$( this ).data( "ui-slider-handle-index", i );
22712		});
22713	},
22714
22715	_createRange: function() {
22716		var options = this.options,
22717			classes = "";
22718
22719		if ( options.range ) {
22720			if ( options.range === true ) {
22721				if ( !options.values ) {
22722					options.values = [ this._valueMin(), this._valueMin() ];
22723				} else if ( options.values.length && options.values.length !== 2 ) {
22724					options.values = [ options.values[0], options.values[0] ];
22725				} else if ( $.isArray( options.values ) ) {
22726					options.values = options.values.slice(0);
22727				}
22728			}
22729
22730			if ( !this.range || !this.range.length ) {
22731				this.range = $( "<div></div>" )
22732					.appendTo( this.element );
22733
22734				classes = "ui-slider-range" +
22735				// note: this isn't the most fittingly semantic framework class for this element,
22736				// but worked best visually with a variety of themes
22737				" ui-widget-header ui-corner-all";
22738			} else {
22739				this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
22740					// Handle range switching from true to min/max
22741					.css({
22742						"left": "",
22743						"bottom": ""
22744					});
22745			}
22746
22747			this.range.addClass( classes +
22748				( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
22749		} else {
22750			if ( this.range ) {
22751				this.range.remove();
22752			}
22753			this.range = null;
22754		}
22755	},
22756
22757	_setupEvents: function() {
22758		this._off( this.handles );
22759		this._on( this.handles, this._handleEvents );
22760		this._hoverable( this.handles );
22761		this._focusable( this.handles );
22762	},
22763
22764	_destroy: function() {
22765		this.handles.remove();
22766		if ( this.range ) {
22767			this.range.remove();
22768		}
22769
22770		this.element
22771			.removeClass( "ui-slider" +
22772				" ui-slider-horizontal" +
22773				" ui-slider-vertical" +
22774				" ui-widget" +
22775				" ui-widget-content" +
22776				" ui-corner-all" );
22777
22778		this._mouseDestroy();
22779	},
22780
22781	_mouseCapture: function( event ) {
22782		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
22783			that = this,
22784			o = this.options;
22785
22786		if ( o.disabled ) {
22787			return false;
22788		}
22789
22790		this.elementSize = {
22791			width: this.element.outerWidth(),
22792			height: this.element.outerHeight()
22793		};
22794		this.elementOffset = this.element.offset();
22795
22796		position = { x: event.pageX, y: event.pageY };
22797		normValue = this._normValueFromMouse( position );
22798		distance = this._valueMax() - this._valueMin() + 1;
22799		this.handles.each(function( i ) {
22800			var thisDistance = Math.abs( normValue - that.values(i) );
22801			if (( distance > thisDistance ) ||
22802				( distance === thisDistance &&
22803					(i === that._lastChangedValue || that.values(i) === o.min ))) {
22804				distance = thisDistance;
22805				closestHandle = $( this );
22806				index = i;
22807			}
22808		});
22809
22810		allowed = this._start( event, index );
22811		if ( allowed === false ) {
22812			return false;
22813		}
22814		this._mouseSliding = true;
22815
22816		this._handleIndex = index;
22817
22818		closestHandle
22819			.addClass( "ui-state-active" )
22820			.focus();
22821
22822		offset = closestHandle.offset();
vendor: 4,641 bytes, lines 22823-22995
22823		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
22824		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
22825			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
22826			top: event.pageY - offset.top -
22827				( closestHandle.height() / 2 ) -
22828				( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
22829				( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
22830				( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
22831		};
22832
22833		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
22834			this._slide( event, index, normValue );
22835		}
22836		this._animateOff = true;
22837		return true;
22838	},
22839
22840	_mouseStart: function() {
22841		return true;
22842	},
22843
22844	_mouseDrag: function( event ) {
22845		var position = { x: event.pageX, y: event.pageY },
22846			normValue = this._normValueFromMouse( position );
22847
22848		this._slide( event, this._handleIndex, normValue );
22849
22850		return false;
22851	},
22852
22853	_mouseStop: function( event ) {
22854		this.handles.removeClass( "ui-state-active" );
22855		this._mouseSliding = false;
22856
22857		this._stop( event, this._handleIndex );
22858		this._change( event, this._handleIndex );
22859
22860		this._handleIndex = null;
22861		this._clickOffset = null;
22862		this._animateOff = false;
22863
22864		return false;
22865	},
22866
22867	_detectOrientation: function() {
22868		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
22869	},
22870
22871	_normValueFromMouse: function( position ) {
22872		var pixelTotal,
22873			pixelMouse,
22874			percentMouse,
22875			valueTotal,
22876			valueMouse;
22877
22878		if ( this.orientation === "horizontal" ) {
22879			pixelTotal = this.elementSize.width;
22880			pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
22881		} else {
22882			pixelTotal = this.elementSize.height;
22883			pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
22884		}
22885
22886		percentMouse = ( pixelMouse / pixelTotal );
22887		if ( percentMouse > 1 ) {
22888			percentMouse = 1;
22889		}
22890		if ( percentMouse < 0 ) {
22891			percentMouse = 0;
22892		}
22893		if ( this.orientation === "vertical" ) {
22894			percentMouse = 1 - percentMouse;
22895		}
22896
22897		valueTotal = this._valueMax() - this._valueMin();
22898		valueMouse = this._valueMin() + percentMouse * valueTotal;
22899
22900		return this._trimAlignValue( valueMouse );
22901	},
22902
22903	_start: function( event, index ) {
22904		var uiHash = {
22905			handle: this.handles[ index ],
22906			value: this.value()
22907		};
22908		if ( this.options.values && this.options.values.length ) {
22909			uiHash.value = this.values( index );
22910			uiHash.values = this.values();
22911		}
22912		return this._trigger( "start", event, uiHash );
22913	},
22914
22915	_slide: function( event, index, newVal ) {
22916		var otherVal,
22917			newValues,
22918			allowed;
22919
22920		if ( this.options.values && this.options.values.length ) {
22921			otherVal = this.values( index ? 0 : 1 );
22922
22923			if ( ( this.options.values.length === 2 && this.options.range === true ) &&
22924					( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
22925				) {
22926				newVal = otherVal;
22927			}
22928
22929			if ( newVal !== this.values( index ) ) {
22930				newValues = this.values();
22931				newValues[ index ] = newVal;
22932				// A slide can be canceled by returning false from the slide callback
22933				allowed = this._trigger( "slide", event, {
22934					handle: this.handles[ index ],
22935					value: newVal,
22936					values: newValues
22937				} );
22938				otherVal = this.values( index ? 0 : 1 );
22939				if ( allowed !== false ) {
22940					this.values( index, newVal );
22941				}
22942			}
22943		} else {
22944			if ( newVal !== this.value() ) {
22945				// A slide can be canceled by returning false from the slide callback
22946				allowed = this._trigger( "slide", event, {
22947					handle: this.handles[ index ],
22948					value: newVal
22949				} );
22950				if ( allowed !== false ) {
22951					this.value( newVal );
22952				}
22953			}
22954		}
22955	},
22956
22957	_stop: function( event, index ) {
22958		var uiHash = {
22959			handle: this.handles[ index ],
22960			value: this.value()
22961		};
22962		if ( this.options.values && this.options.values.length ) {
22963			uiHash.value = this.values( index );
22964			uiHash.values = this.values();
22965		}
22966
22967		this._trigger( "stop", event, uiHash );
22968	},
22969
22970	_change: function( event, index ) {
22971		if ( !this._keySliding && !this._mouseSliding ) {
22972			var uiHash = {
22973				handle: this.handles[ index ],
22974				value: this.value()
22975			};
22976			if ( this.options.values && this.options.values.length ) {
22977				uiHash.value = this.values( index );
22978				uiHash.values = this.values();
22979			}
22980
22981			//store the last changed value index for reference when handles overlap
22982			this._lastChangedValue = index;
22983
22984			this._trigger( "change", event, uiHash );
22985		}
22986	},
22987
22988	value: function( newValue ) {
22989		if ( arguments.length ) {
22990			this.options.value = this._trimAlignValue( newValue );
22991			this._refreshValue();
22992			this._change( null, 0 );
22993			return;
22994		}
22995
vendor: 56,341 bytes, lines 22996-24774
22996		return this._value();
22997	},
22998
22999	values: function( index, newValue ) {
23000		var vals,
23001			newValues,
23002			i;
23003
23004		if ( arguments.length > 1 ) {
23005			this.options.values[ index ] = this._trimAlignValue( newValue );
23006			this._refreshValue();
23007			this._change( null, index );
23008			return;
23009		}
23010
23011		if ( arguments.length ) {
23012			if ( $.isArray( arguments[ 0 ] ) ) {
23013				vals = this.options.values;
23014				newValues = arguments[ 0 ];
23015				for ( i = 0; i < vals.length; i += 1 ) {
23016					vals[ i ] = this._trimAlignValue( newValues[ i ] );
23017					this._change( null, i );
23018				}
23019				this._refreshValue();
23020			} else {
23021				if ( this.options.values && this.options.values.length ) {
23022					return this._values( index );
23023				} else {
23024					return this.value();
23025				}
23026			}
23027		} else {
23028			return this._values();
23029		}
23030	},
23031
23032	_setOption: function( key, value ) {
23033		var i,
23034			valsLength = 0;
23035
23036		if ( key === "range" && this.options.range === true ) {
23037			if ( value === "min" ) {
23038				this.options.value = this._values( 0 );
23039				this.options.values = null;
23040			} else if ( value === "max" ) {
23041				this.options.value = this._values( this.options.values.length - 1 );
23042				this.options.values = null;
23043			}
23044		}
23045
23046		if ( $.isArray( this.options.values ) ) {
23047			valsLength = this.options.values.length;
23048		}
23049
23050		if ( key === "disabled" ) {
23051			this.element.toggleClass( "ui-state-disabled", !!value );
23052		}
23053
23054		this._super( key, value );
23055
23056		switch ( key ) {
23057			case "orientation":
23058				this._detectOrientation();
23059				this.element
23060					.removeClass( "ui-slider-horizontal ui-slider-vertical" )
23061					.addClass( "ui-slider-" + this.orientation );
23062				this._refreshValue();
23063
23064				// Reset positioning from previous orientation
23065				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
23066				break;
23067			case "value":
23068				this._animateOff = true;
23069				this._refreshValue();
23070				this._change( null, 0 );
23071				this._animateOff = false;
23072				break;
23073			case "values":
23074				this._animateOff = true;
23075				this._refreshValue();
23076				for ( i = 0; i < valsLength; i += 1 ) {
23077					this._change( null, i );
23078				}
23079				this._animateOff = false;
23080				break;
23081			case "step":
23082			case "min":
23083			case "max":
23084				this._animateOff = true;
23085				this._calculateNewMax();
23086				this._refreshValue();
23087				this._animateOff = false;
23088				break;
23089			case "range":
23090				this._animateOff = true;
23091				this._refresh();
23092				this._animateOff = false;
23093				break;
23094		}
23095	},
23096
23097	//internal value getter
23098	// _value() returns value trimmed by min and max, aligned by step
23099	_value: function() {
23100		var val = this.options.value;
23101		val = this._trimAlignValue( val );
23102
23103		return val;
23104	},
23105
23106	//internal values getter
23107	// _values() returns array of values trimmed by min and max, aligned by step
23108	// _values( index ) returns single value trimmed by min and max, aligned by step
23109	_values: function( index ) {
23110		var val,
23111			vals,
23112			i;
23113
23114		if ( arguments.length ) {
23115			val = this.options.values[ index ];
23116			val = this._trimAlignValue( val );
23117
23118			return val;
23119		} else if ( this.options.values && this.options.values.length ) {
23120			// .slice() creates a copy of the array
23121			// this copy gets trimmed by min and max and then returned
23122			vals = this.options.values.slice();
23123			for ( i = 0; i < vals.length; i += 1) {
23124				vals[ i ] = this._trimAlignValue( vals[ i ] );
23125			}
23126
23127			return vals;
23128		} else {
23129			return [];
23130		}
23131	},
23132
23133	// returns the step-aligned value that val is closest to, between (inclusive) min and max
23134	_trimAlignValue: function( val ) {
23135		if ( val <= this._valueMin() ) {
23136			return this._valueMin();
23137		}
23138		if ( val >= this._valueMax() ) {
23139			return this._valueMax();
23140		}
23141		var step = ( this.options.step > 0 ) ? this.options.step : 1,
23142			valModStep = (val - this._valueMin()) % step,
23143			alignValue = val - valModStep;
23144
23145		if ( Math.abs(valModStep) * 2 >= step ) {
23146			alignValue += ( valModStep > 0 ) ? step : ( -step );
23147		}
23148
23149		// Since JavaScript has problems with large floats, round
23150		// the final value to 5 digits after the decimal point (see #4124)
23151		return parseFloat( alignValue.toFixed(5) );
23152	},
23153
23154	_calculateNewMax: function() {
23155		var max = this.options.max,
23156			min = this._valueMin(),
23157			step = this.options.step,
23158			aboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;
23159		max = aboveMin + min;
23160		this.max = parseFloat( max.toFixed( this._precision() ) );
23161	},
23162
23163	_precision: function() {
23164		var precision = this._precisionOf( this.options.step );
23165		if ( this.options.min !== null ) {
23166			precision = Math.max( precision, this._precisionOf( this.options.min ) );
23167		}
23168		return precision;
23169	},
23170
23171	_precisionOf: function( num ) {
23172		var str = num.toString(),
23173			decimal = str.indexOf( "." );
23174		return decimal === -1 ? 0 : str.length - decimal - 1;
23175	},
23176
23177	_valueMin: function() {
23178		return this.options.min;
23179	},
23180
23181	_valueMax: function() {
23182		return this.max;
23183	},
23184
23185	_refreshValue: function() {
23186		var lastValPercent, valPercent, value, valueMin, valueMax,
23187			oRange = this.options.range,
23188			o = this.options,
23189			that = this,
23190			animate = ( !this._animateOff ) ? o.animate : false,
23191			_set = {};
23192
23193		if ( this.options.values && this.options.values.length ) {
23194			this.handles.each(function( i ) {
23195				valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
23196				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
23197				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
23198				if ( that.options.range === true ) {
23199					if ( that.orientation === "horizontal" ) {
23200						if ( i === 0 ) {
23201							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
23202						}
23203						if ( i === 1 ) {
23204							that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
23205						}
23206					} else {
23207						if ( i === 0 ) {
23208							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
23209						}
23210						if ( i === 1 ) {
23211							that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
23212						}
23213					}
23214				}
23215				lastValPercent = valPercent;
23216			});
23217		} else {
23218			value = this.value();
23219			valueMin = this._valueMin();
23220			valueMax = this._valueMax();
23221			valPercent = ( valueMax !== valueMin ) ?
23222					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
23223					0;
23224			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
23225			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
23226
23227			if ( oRange === "min" && this.orientation === "horizontal" ) {
23228				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
23229			}
23230			if ( oRange === "max" && this.orientation === "horizontal" ) {
23231				this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
23232			}
23233			if ( oRange === "min" && this.orientation === "vertical" ) {
23234				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
23235			}
23236			if ( oRange === "max" && this.orientation === "vertical" ) {
23237				this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
23238			}
23239		}
23240	},
23241
23242	_handleEvents: {
23243		keydown: function( event ) {
23244			var allowed, curVal, newVal, step,
23245				index = $( event.target ).data( "ui-slider-handle-index" );
23246
23247			switch ( event.keyCode ) {
23248				case $.ui.keyCode.HOME:
23249				case $.ui.keyCode.END:
23250				case $.ui.keyCode.PAGE_UP:
23251				case $.ui.keyCode.PAGE_DOWN:
23252				case $.ui.keyCode.UP:
23253				case $.ui.keyCode.RIGHT:
23254				case $.ui.keyCode.DOWN:
23255				case $.ui.keyCode.LEFT:
23256					event.preventDefault();
23257					if ( !this._keySliding ) {
23258						this._keySliding = true;
23259						$( event.target ).addClass( "ui-state-active" );
23260						allowed = this._start( event, index );
23261						if ( allowed === false ) {
23262							return;
23263						}
23264					}
23265					break;
23266			}
23267
23268			step = this.options.step;
23269			if ( this.options.values && this.options.values.length ) {
23270				curVal = newVal = this.values( index );
23271			} else {
23272				curVal = newVal = this.value();
23273			}
23274
23275			switch ( event.keyCode ) {
23276				case $.ui.keyCode.HOME:
23277					newVal = this._valueMin();
23278					break;
23279				case $.ui.keyCode.END:
23280					newVal = this._valueMax();
23281					break;
23282				case $.ui.keyCode.PAGE_UP:
23283					newVal = this._trimAlignValue(
23284						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
23285					);
23286					break;
23287				case $.ui.keyCode.PAGE_DOWN:
23288					newVal = this._trimAlignValue(
23289						curVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );
23290					break;
23291				case $.ui.keyCode.UP:
23292				case $.ui.keyCode.RIGHT:
23293					if ( curVal === this._valueMax() ) {
23294						return;
23295					}
23296					newVal = this._trimAlignValue( curVal + step );
23297					break;
23298				case $.ui.keyCode.DOWN:
23299				case $.ui.keyCode.LEFT:
23300					if ( curVal === this._valueMin() ) {
23301						return;
23302					}
23303					newVal = this._trimAlignValue( curVal - step );
23304					break;
23305			}
23306
23307			this._slide( event, index, newVal );
23308		},
23309		keyup: function( event ) {
23310			var index = $( event.target ).data( "ui-slider-handle-index" );
23311
23312			if ( this._keySliding ) {
23313				this._keySliding = false;
23314				this._stop( event, index );
23315				this._change( event, index );
23316				$( event.target ).removeClass( "ui-state-active" );
23317			}
23318		}
23319	}
23320});
23321
23322
23323/*!
23324 * jQuery UI Sortable 1.11.4
23325 * http://jqueryui.com
23326 *
23327 * Copyright jQuery Foundation and other contributors
23328 * Released under the MIT license.
23329 * http://jquery.org/license
23330 *
23331 * http://api.jqueryui.com/sortable/
23332 */
23333
23334
23335var sortable = $.widget("ui.sortable", $.ui.mouse, {
23336	version: "1.11.4",
23337	widgetEventPrefix: "sort",
23338	ready: false,
23339	options: {
23340		appendTo: "parent",
23341		axis: false,
23342		connectWith: false,
23343		containment: false,
23344		cursor: "auto",
23345		cursorAt: false,
23346		dropOnEmpty: true,
23347		forcePlaceholderSize: false,
23348		forceHelperSize: false,
23349		grid: false,
23350		handle: false,
23351		helper: "original",
23352		items: "> *",
23353		opacity: false,
23354		placeholder: false,
23355		revert: false,
23356		scroll: true,
23357		scrollSensitivity: 20,
23358		scrollSpeed: 20,
23359		scope: "default",
23360		tolerance: "intersect",
23361		zIndex: 1000,
23362
23363		// callbacks
23364		activate: null,
23365		beforeStop: null,
23366		change: null,
23367		deactivate: null,
23368		out: null,
23369		over: null,
23370		receive: null,
23371		remove: null,
23372		sort: null,
23373		start: null,
23374		stop: null,
23375		update: null
23376	},
23377
23378	_isOverAxis: function( x, reference, size ) {
23379		return ( x >= reference ) && ( x < ( reference + size ) );
23380	},
23381
23382	_isFloating: function( item ) {
23383		return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
23384	},
23385
23386	_create: function() {
23387		this.containerCache = {};
23388		this.element.addClass("ui-sortable");
23389
23390		//Get the items
23391		this.refresh();
23392
23393		//Let's determine the parent's offset
23394		this.offset = this.element.offset();
23395
23396		//Initialize mouse events for interaction
23397		this._mouseInit();
23398
23399		this._setHandleClassName();
23400
23401		//We're ready to go
23402		this.ready = true;
23403
23404	},
23405
23406	_setOption: function( key, value ) {
23407		this._super( key, value );
23408
23409		if ( key === "handle" ) {
23410			this._setHandleClassName();
23411		}
23412	},
23413
23414	_setHandleClassName: function() {
23415		this.element.find( ".ui-sortable-handle" ).removeClass( "ui-sortable-handle" );
23416		$.each( this.items, function() {
23417			( this.instance.options.handle ?
23418				this.item.find( this.instance.options.handle ) : this.item )
23419				.addClass( "ui-sortable-handle" );
23420		});
23421	},
23422
23423	_destroy: function() {
23424		this.element
23425			.removeClass( "ui-sortable ui-sortable-disabled" )
23426			.find( ".ui-sortable-handle" )
23427				.removeClass( "ui-sortable-handle" );
23428		this._mouseDestroy();
23429
23430		for ( var i = this.items.length - 1; i >= 0; i-- ) {
23431			this.items[i].item.removeData(this.widgetName + "-item");
23432		}
23433
23434		return this;
23435	},
23436
23437	_mouseCapture: function(event, overrideHandle) {
23438		var currentItem = null,
23439			validHandle = false,
23440			that = this;
23441
23442		if (this.reverting) {
23443			return false;
23444		}
23445
23446		if(this.options.disabled || this.options.type === "static") {
23447			return false;
23448		}
23449
23450		//We have to refresh the items data once first
23451		this._refreshItems(event);
23452
23453		//Find out if the clicked node (or one of its parents) is a actual item in this.items
23454		$(event.target).parents().each(function() {
23455			if($.data(this, that.widgetName + "-item") === that) {
23456				currentItem = $(this);
23457				return false;
23458			}
23459		});
23460		if($.data(event.target, that.widgetName + "-item") === that) {
23461			currentItem = $(event.target);
23462		}
23463
23464		if(!currentItem) {
23465			return false;
23466		}
23467		if(this.options.handle && !overrideHandle) {
23468			$(this.options.handle, currentItem).find("*").addBack().each(function() {
23469				if(this === event.target) {
23470					validHandle = true;
23471				}
23472			});
23473			if(!validHandle) {
23474				return false;
23475			}
23476		}
23477
23478		this.currentItem = currentItem;
23479		this._removeCurrentsFromItems();
23480		return true;
23481
23482	},
23483
23484	_mouseStart: function(event, overrideHandle, noActivation) {
23485
23486		var i, body,
23487			o = this.options;
23488
23489		this.currentContainer = this;
23490
23491		//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
23492		this.refreshPositions();
23493
23494		//Create and append the visible helper
23495		this.helper = this._createHelper(event);
23496
23497		//Cache the helper size
23498		this._cacheHelperProportions();
23499
23500		/*
23501		 * - Position generation -
23502		 * This block generates everything position related - it's the core of draggables.
23503		 */
23504
23505		//Cache the margins of the original element
23506		this._cacheMargins();
23507
23508		//Get the next scrolling parent
23509		this.scrollParent = this.helper.scrollParent();
23510
23511		//The element's absolute position on the page minus margins
23512		this.offset = this.currentItem.offset();
23513		this.offset = {
23514			top: this.offset.top - this.margins.top,
23515			left: this.offset.left - this.margins.left
23516		};
23517
23518		$.extend(this.offset, {
23519			click: { //Where the click happened, relative to the element
23520				left: event.pageX - this.offset.left,
23521				top: event.pageY - this.offset.top
23522			},
23523			parent: this._getParentOffset(),
23524			relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
23525		});
23526
23527		// Only after we got the offset, we can change the helper's position to absolute
23528		// TODO: Still need to figure out a way to make relative sorting possible
23529		this.helper.css("position", "absolute");
23530		this.cssPosition = this.helper.css("position");
23531
23532		//Generate the original position
23533		this.originalPosition = this._generatePosition(event);
23534		this.originalPageX = event.pageX;
23535		this.originalPageY = event.pageY;
23536
23537		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
23538		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
23539
23540		//Cache the former DOM position
23541		this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
23542
23543		//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
23544		if(this.helper[0] !== this.currentItem[0]) {
23545			this.currentItem.hide();
23546		}
23547
23548		//Create the placeholder
23549		this._createPlaceholder();
23550
23551		//Set a containment if given in the options
23552		if(o.containment) {
23553			this._setContainment();
23554		}
23555
23556		if( o.cursor && o.cursor !== "auto" ) { // cursor option
23557			body = this.document.find( "body" );
23558
23559			// support: IE
23560			this.storedCursor = body.css( "cursor" );
23561			body.css( "cursor", o.cursor );
23562
23563			this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
23564		}
23565
23566		if(o.opacity) { // opacity option
23567			if (this.helper.css("opacity")) {
23568				this._storedOpacity = this.helper.css("opacity");
23569			}
23570			this.helper.css("opacity", o.opacity);
23571		}
23572
23573		if(o.zIndex) { // zIndex option
23574			if (this.helper.css("zIndex")) {
23575				this._storedZIndex = this.helper.css("zIndex");
23576			}
23577			this.helper.css("zIndex", o.zIndex);
23578		}
23579
23580		//Prepare scrolling
23581		if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
23582			this.overflowOffset = this.scrollParent.offset();
23583		}
23584
23585		//Call callbacks
23586		this._trigger("start", event, this._uiHash());
23587
23588		//Recache the helper size
23589		if(!this._preserveHelperProportions) {
23590			this._cacheHelperProportions();
23591		}
23592
23593
23594		//Post "activate" events to possible containers
23595		if( !noActivation ) {
23596			for ( i = this.containers.length - 1; i >= 0; i-- ) {
23597				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
23598			}
23599		}
23600
23601		//Prepare possible droppables
23602		if($.ui.ddmanager) {
23603			$.ui.ddmanager.current = this;
23604		}
23605
23606		if ($.ui.ddmanager && !o.dropBehaviour) {
23607			$.ui.ddmanager.prepareOffsets(this, event);
23608		}
23609
23610		this.dragging = true;
23611
23612		this.helper.addClass("ui-sortable-helper");
23613		this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
23614		return true;
23615
23616	},
23617
23618	_mouseDrag: function(event) {
23619		var i, item, itemElement, intersection,
23620			o = this.options,
23621			scrolled = false;
23622
23623		//Compute the helpers position
23624		this.position = this._generatePosition(event);
23625		this.positionAbs = this._convertPositionTo("absolute");
23626
23627		if (!this.lastPositionAbs) {
23628			this.lastPositionAbs = this.positionAbs;
23629		}
23630
23631		//Do scrolling
23632		if(this.options.scroll) {
23633			if(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== "HTML") {
23634
23635				if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
23636					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
23637				} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
23638					this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
23639				}
23640
23641				if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
23642					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
23643				} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
23644					this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
23645				}
23646
23647			} else {
23648
23649				if(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
23650					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
23651				} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {
23652					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
23653				}
23654
23655				if(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
23656					scrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);
23657				} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {
23658					scrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);
23659				}
23660
23661			}
23662
23663			if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
23664				$.ui.ddmanager.prepareOffsets(this, event);
23665			}
23666		}
23667
23668		//Regenerate the absolute position used for position checks
23669		this.positionAbs = this._convertPositionTo("absolute");
23670
23671		//Set the helper position
23672		if(!this.options.axis || this.options.axis !== "y") {
23673			this.helper[0].style.left = this.position.left+"px";
23674		}
23675		if(!this.options.axis || this.options.axis !== "x") {
23676			this.helper[0].style.top = this.position.top+"px";
23677		}
23678
23679		//Rearrange
23680		for (i = this.items.length - 1; i >= 0; i--) {
23681
23682			//Cache variables and intersection, continue if no intersection
23683			item = this.items[i];
23684			itemElement = item.item[0];
23685			intersection = this._intersectsWithPointer(item);
23686			if (!intersection) {
23687				continue;
23688			}
23689
23690			// Only put the placeholder inside the current Container, skip all
23691			// items from other containers. This works because when moving
23692			// an item from one container to another the
23693			// currentContainer is switched before the placeholder is moved.
23694			//
23695			// Without this, moving items in "sub-sortables" can cause
23696			// the placeholder to jitter between the outer and inner container.
23697			if (item.instance !== this.currentContainer) {
23698				continue;
23699			}
23700
23701			// cannot intersect with itself
23702			// no useless actions that have been done before
23703			// no action if the item moved is the parent of the item checked
23704			if (itemElement !== this.currentItem[0] &&
23705				this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
23706				!$.contains(this.placeholder[0], itemElement) &&
23707				(this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
23708			) {
23709
23710				this.direction = intersection === 1 ? "down" : "up";
23711
23712				if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
23713					this._rearrange(event, item);
23714				} else {
23715					break;
23716				}
23717
23718				this._trigger("change", event, this._uiHash());
23719				break;
23720			}
23721		}
23722
23723		//Post events to containers
23724		this._contactContainers(event);
23725
23726		//Interconnect with droppables
23727		if($.ui.ddmanager) {
23728			$.ui.ddmanager.drag(this, event);
23729		}
23730
23731		//Call callbacks
23732		this._trigger("sort", event, this._uiHash());
23733
23734		this.lastPositionAbs = this.positionAbs;
23735		return false;
23736
23737	},
23738
23739	_mouseStop: function(event, noPropagation) {
23740
23741		if(!event) {
23742			return;
23743		}
23744
23745		//If we are using droppables, inform the manager about the drop
23746		if ($.ui.ddmanager && !this.options.dropBehaviour) {
23747			$.ui.ddmanager.drop(this, event);
23748		}
23749
23750		if(this.options.revert) {
23751			var that = this,
23752				cur = this.placeholder.offset(),
23753				axis = this.options.axis,
23754				animation = {};
23755
23756			if ( !axis || axis === "x" ) {
23757				animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);
23758			}
23759			if ( !axis || axis === "y" ) {
23760				animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);
23761			}
23762			this.reverting = true;
23763			$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
23764				that._clear(event);
23765			});
23766		} else {
23767			this._clear(event, noPropagation);
23768		}
23769
23770		return false;
23771
23772	},
23773
23774	cancel: function() {
23775
23776		if(this.dragging) {
23777
23778			this._mouseUp({ target: null });
23779
23780			if(this.options.helper === "original") {
23781				this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
23782			} else {
23783				this.currentItem.show();
23784			}
23785
23786			//Post deactivating events to containers
23787			for (var i = this.containers.length - 1; i >= 0; i--){
23788				this.containers[i]._trigger("deactivate", null, this._uiHash(this));
23789				if(this.containers[i].containerCache.over) {
23790					this.containers[i]._trigger("out", null, this._uiHash(this));
23791					this.containers[i].containerCache.over = 0;
23792				}
23793			}
23794
23795		}
23796
23797		if (this.placeholder) {
23798			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
23799			if(this.placeholder[0].parentNode) {
23800				this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
23801			}
23802			if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
23803				this.helper.remove();
23804			}
23805
23806			$.extend(this, {
23807				helper: null,
23808				dragging: false,
23809				reverting: false,
23810				_noFinalSort: null
23811			});
23812
23813			if(this.domPosition.prev) {
23814				$(this.domPosition.prev).after(this.currentItem);
23815			} else {
23816				$(this.domPosition.parent).prepend(this.currentItem);
23817			}
23818		}
23819
23820		return this;
23821
23822	},
23823
23824	serialize: function(o) {
23825
23826		var items = this._getItemsAsjQuery(o && o.connected),
23827			str = [];
23828		o = o || {};
23829
23830		$(items).each(function() {
23831			var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
23832			if (res) {
23833				str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
23834			}
23835		});
23836
23837		if(!str.length && o.key) {
23838			str.push(o.key + "=");
23839		}
23840
23841		return str.join("&");
23842
23843	},
23844
23845	toArray: function(o) {
23846
23847		var items = this._getItemsAsjQuery(o && o.connected),
23848			ret = [];
23849
23850		o = o || {};
23851
23852		items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
23853		return ret;
23854
23855	},
23856
23857	/* Be careful with the following core functions */
23858	_intersectsWith: function(item) {
23859
23860		var x1 = this.positionAbs.left,
23861			x2 = x1 + this.helperProportions.width,
23862			y1 = this.positionAbs.top,
23863			y2 = y1 + this.helperProportions.height,
23864			l = item.left,
23865			r = l + item.width,
23866			t = item.top,
23867			b = t + item.height,
23868			dyClick = this.offset.click.top,
23869			dxClick = this.offset.click.left,
23870			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
23871			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
23872			isOverElement = isOverElementHeight && isOverElementWidth;
23873
23874		if ( this.options.tolerance === "pointer" ||
23875			this.options.forcePointerForContainers ||
23876			(this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
23877		) {
23878			return isOverElement;
23879		} else {
23880
23881			return (l < x1 + (this.helperProportions.width / 2) && // Right Half
23882				x2 - (this.helperProportions.width / 2) < r && // Left Half
23883				t < y1 + (this.helperProportions.height / 2) && // Bottom Half
23884				y2 - (this.helperProportions.height / 2) < b ); // Top Half
23885
23886		}
23887	},
23888
23889	_intersectsWithPointer: function(item) {
23890
23891		var isOverElementHeight = (this.options.axis === "x") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
23892			isOverElementWidth = (this.options.axis === "y") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
23893			isOverElement = isOverElementHeight && isOverElementWidth,
23894			verticalDirection = this._getDragVerticalDirection(),
23895			horizontalDirection = this._getDragHorizontalDirection();
23896
23897		if (!isOverElement) {
23898			return false;
23899		}
23900
23901		return this.floating ?
23902			( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
23903			: ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
23904
23905	},
23906
23907	_intersectsWithSides: function(item) {
23908
23909		var isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
23910			isOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
23911			verticalDirection = this._getDragVerticalDirection(),
23912			horizontalDirection = this._getDragHorizontalDirection();
23913
23914		if (this.floating && horizontalDirection) {
23915			return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
23916		} else {
23917			return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
23918		}
23919
23920	},
23921
23922	_getDragVerticalDirection: function() {
23923		var delta = this.positionAbs.top - this.lastPositionAbs.top;
23924		return delta !== 0 && (delta > 0 ? "down" : "up");
23925	},
23926
23927	_getDragHorizontalDirection: function() {
23928		var delta = this.positionAbs.left - this.lastPositionAbs.left;
23929		return delta !== 0 && (delta > 0 ? "right" : "left");
23930	},
23931
23932	refresh: function(event) {
23933		this._refreshItems(event);
23934		this._setHandleClassName();
23935		this.refreshPositions();
23936		return this;
23937	},
23938
23939	_connectWith: function() {
23940		var options = this.options;
23941		return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
23942	},
23943
23944	_getItemsAsjQuery: function(connected) {
23945
23946		var i, j, cur, inst,
23947			items = [],
23948			queries = [],
23949			connectWith = this._connectWith();
23950
23951		if(connectWith && connected) {
23952			for (i = connectWith.length - 1; i >= 0; i--){
23953				cur = $(connectWith[i], this.document[0]);
23954				for ( j = cur.length - 1; j >= 0; j--){
23955					inst = $.data(cur[j], this.widgetFullName);
23956					if(inst && inst !== this && !inst.options.disabled) {
23957						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
23958					}
23959				}
23960			}
23961		}
23962
23963		queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
23964
23965		function addItems() {
23966			items.push( this );
23967		}
23968		for (i = queries.length - 1; i >= 0; i--){
23969			queries[i][0].each( addItems );
23970		}
23971
23972		return $(items);
23973
23974	},
23975
23976	_removeCurrentsFromItems: function() {
23977
23978		var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
23979
23980		this.items = $.grep(this.items, function (item) {
23981			for (var j=0; j < list.length; j++) {
23982				if(list[j] === item.item[0]) {
23983					return false;
23984				}
23985			}
23986			return true;
23987		});
23988
23989	},
23990
23991	_refreshItems: function(event) {
23992
23993		this.items = [];
23994		this.containers = [this];
23995
23996		var i, j, cur, inst, targetData, _queries, item, queriesLength,
23997			items = this.items,
23998			queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
23999			connectWith = this._connectWith();
24000
24001		if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
24002			for (i = connectWith.length - 1; i >= 0; i--){
24003				cur = $(connectWith[i], this.document[0]);
24004				for (j = cur.length - 1; j >= 0; j--){
24005					inst = $.data(cur[j], this.widgetFullName);
24006					if(inst && inst !== this && !inst.options.disabled) {
24007						queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
24008						this.containers.push(inst);
24009					}
24010				}
24011			}
24012		}
24013
24014		for (i = queries.length - 1; i >= 0; i--) {
24015			targetData = queries[i][1];
24016			_queries = queries[i][0];
24017
24018			for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
24019				item = $(_queries[j]);
24020
24021				item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
24022
24023				items.push({
24024					item: item,
24025					instance: targetData,
24026					width: 0, height: 0,
24027					left: 0, top: 0
24028				});
24029			}
24030		}
24031
24032	},
24033
24034	refreshPositions: function(fast) {
24035
24036		// Determine whether items are being displayed horizontally
24037		this.floating = this.items.length ?
24038			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
24039			false;
24040
24041		//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
24042		if(this.offsetParent && this.helper) {
24043			this.offset.parent = this._getParentOffset();
24044		}
24045
24046		var i, item, t, p;
24047
24048		for (i = this.items.length - 1; i >= 0; i--){
24049			item = this.items[i];
24050
24051			//We ignore calculating positions of all connected containers when we're not over them
24052			if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
24053				continue;
24054			}
24055
24056			t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
24057
24058			if (!fast) {
24059				item.width = t.outerWidth();
24060				item.height = t.outerHeight();
24061			}
24062
24063			p = t.offset();
24064			item.left = p.left;
24065			item.top = p.top;
24066		}
24067
24068		if(this.options.custom && this.options.custom.refreshContainers) {
24069			this.options.custom.refreshContainers.call(this);
24070		} else {
24071			for (i = this.containers.length - 1; i >= 0; i--){
24072				p = this.containers[i].element.offset();
24073				this.containers[i].containerCache.left = p.left;
24074				this.containers[i].containerCache.top = p.top;
24075				this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
24076				this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
24077			}
24078		}
24079
24080		return this;
24081	},
24082
24083	_createPlaceholder: function(that) {
24084		that = that || this;
24085		var className,
24086			o = that.options;
24087
24088		if(!o.placeholder || o.placeholder.constructor === String) {
24089			className = o.placeholder;
24090			o.placeholder = {
24091				element: function() {
24092
24093					var nodeName = that.currentItem[0].nodeName.toLowerCase(),
24094						element = $( "<" + nodeName + ">", that.document[0] )
24095							.addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
24096							.removeClass("ui-sortable-helper");
24097
24098					if ( nodeName === "tbody" ) {
24099						that._createTrPlaceholder(
24100							that.currentItem.find( "tr" ).eq( 0 ),
24101							$( "<tr>", that.document[ 0 ] ).appendTo( element )
24102						);
24103					} else if ( nodeName === "tr" ) {
24104						that._createTrPlaceholder( that.currentItem, element );
24105					} else if ( nodeName === "img" ) {
24106						element.attr( "src", that.currentItem.attr( "src" ) );
24107					}
24108
24109					if ( !className ) {
24110						element.css( "visibility", "hidden" );
24111					}
24112
24113					return element;
24114				},
24115				update: function(container, p) {
24116
24117					// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
24118					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
24119					if(className && !o.forcePlaceholderSize) {
24120						return;
24121					}
24122
24123					//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
24124					if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
24125					if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
24126				}
24127			};
24128		}
24129
24130		//Create the placeholder
24131		that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
24132
24133		//Append it after the actual current item
24134		that.currentItem.after(that.placeholder);
24135
24136		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
24137		o.placeholder.update(that, that.placeholder);
24138
24139	},
24140
24141	_createTrPlaceholder: function( sourceTr, targetTr ) {
24142		var that = this;
24143
24144		sourceTr.children().each(function() {
24145			$( "<td>&#160;</td>", that.document[ 0 ] )
24146				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
24147				.appendTo( targetTr );
24148		});
24149	},
24150
24151	_contactContainers: function(event) {
24152		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,
24153			innermostContainer = null,
24154			innermostIndex = null;
24155
24156		// get innermost container that intersects with item
24157		for (i = this.containers.length - 1; i >= 0; i--) {
24158
24159			// never consider a container that's located within the item itself
24160			if($.contains(this.currentItem[0], this.containers[i].element[0])) {
24161				continue;
24162			}
24163
24164			if(this._intersectsWith(this.containers[i].containerCache)) {
24165
24166				// if we've already found a container and it's more "inner" than this, then continue
24167				if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
24168					continue;
24169				}
24170
24171				innermostContainer = this.containers[i];
24172				innermostIndex = i;
24173
24174			} else {
24175				// container doesn't intersect. trigger "out" event if necessary
24176				if(this.containers[i].containerCache.over) {
24177					this.containers[i]._trigger("out", event, this._uiHash(this));
24178					this.containers[i].containerCache.over = 0;
24179				}
24180			}
24181
24182		}
24183
24184		// if no intersecting containers found, return
24185		if(!innermostContainer) {
24186			return;
24187		}
24188
24189		// move the item into the container if it's not there already
24190		if(this.containers.length === 1) {
24191			if (!this.containers[innermostIndex].containerCache.over) {
24192				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
24193				this.containers[innermostIndex].containerCache.over = 1;
24194			}
24195		} else {
24196
24197			//When entering a new container, we will find the item with the least distance and append our item near it
24198			dist = 10000;
24199			itemWithLeastDistance = null;
24200			floating = innermostContainer.floating || this._isFloating(this.currentItem);
24201			posProperty = floating ? "left" : "top";
24202			sizeProperty = floating ? "width" : "height";
24203			axis = floating ? "clientX" : "clientY";
24204
24205			for (j = this.items.length - 1; j >= 0; j--) {
24206				if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
24207					continue;
24208				}
24209				if(this.items[j].item[0] === this.currentItem[0]) {
24210					continue;
24211				}
24212
24213				cur = this.items[j].item.offset()[posProperty];
24214				nearBottom = false;
24215				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
24216					nearBottom = true;
24217				}
24218
24219				if ( Math.abs( event[ axis ] - cur ) < dist ) {
24220					dist = Math.abs( event[ axis ] - cur );
24221					itemWithLeastDistance = this.items[ j ];
24222					this.direction = nearBottom ? "up": "down";
24223				}
24224			}
24225
24226			//Check if dropOnEmpty is enabled
24227			if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
24228				return;
24229			}
24230
24231			if(this.currentContainer === this.containers[innermostIndex]) {
24232				if ( !this.currentContainer.containerCache.over ) {
24233					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
24234					this.currentContainer.containerCache.over = 1;
24235				}
24236				return;
24237			}
24238
24239			itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
24240			this._trigger("change", event, this._uiHash());
24241			this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
24242			this.currentContainer = this.containers[innermostIndex];
24243
24244			//Update the placeholder
24245			this.options.placeholder.update(this.currentContainer, this.placeholder);
24246
24247			this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
24248			this.containers[innermostIndex].containerCache.over = 1;
24249		}
24250
24251
24252	},
24253
24254	_createHelper: function(event) {
24255
24256		var o = this.options,
24257			helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
24258
24259		//Add the helper to the DOM if that didn't happen already
24260		if(!helper.parents("body").length) {
24261			$(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
24262		}
24263
24264		if(helper[0] === this.currentItem[0]) {
24265			this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
24266		}
24267
24268		if(!helper[0].style.width || o.forceHelperSize) {
24269			helper.width(this.currentItem.width());
24270		}
24271		if(!helper[0].style.height || o.forceHelperSize) {
24272			helper.height(this.currentItem.height());
24273		}
24274
24275		return helper;
24276
24277	},
24278
24279	_adjustOffsetFromHelper: function(obj) {
24280		if (typeof obj === "string") {
24281			obj = obj.split(" ");
24282		}
24283		if ($.isArray(obj)) {
24284			obj = {left: +obj[0], top: +obj[1] || 0};
24285		}
24286		if ("left" in obj) {
24287			this.offset.click.left = obj.left + this.margins.left;
24288		}
24289		if ("right" in obj) {
24290			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
24291		}
24292		if ("top" in obj) {
24293			this.offset.click.top = obj.top + this.margins.top;
24294		}
24295		if ("bottom" in obj) {
24296			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
24297		}
24298	},
24299
24300	_getParentOffset: function() {
24301
24302
24303		//Get the offsetParent and cache its position
24304		this.offsetParent = this.helper.offsetParent();
24305		var po = this.offsetParent.offset();
24306
24307		// This is a special case where we need to modify a offset calculated on start, since the following happened:
24308		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
24309		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
24310		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
24311		if(this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {
24312			po.left += this.scrollParent.scrollLeft();
24313			po.top += this.scrollParent.scrollTop();
24314		}
24315
24316		// This needs to be actually done for all browsers, since pageX/pageY includes this information
24317		// with an ugly IE fix
24318		if( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
24319			po = { top: 0, left: 0 };
24320		}
24321
24322		return {
24323			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
24324			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
24325		};
24326
24327	},
24328
24329	_getRelativeOffset: function() {
24330
24331		if(this.cssPosition === "relative") {
24332			var p = this.currentItem.position();
24333			return {
24334				top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
24335				left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
24336			};
24337		} else {
24338			return { top: 0, left: 0 };
24339		}
24340
24341	},
24342
24343	_cacheMargins: function() {
24344		this.margins = {
24345			left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
24346			top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
24347		};
24348	},
24349
24350	_cacheHelperProportions: function() {
24351		this.helperProportions = {
24352			width: this.helper.outerWidth(),
24353			height: this.helper.outerHeight()
24354		};
24355	},
24356
24357	_setContainment: function() {
24358
24359		var ce, co, over,
24360			o = this.options;
24361		if(o.containment === "parent") {
24362			o.containment = this.helper[0].parentNode;
24363		}
24364		if(o.containment === "document" || o.containment === "window") {
24365			this.containment = [
24366				0 - this.offset.relative.left - this.offset.parent.left,
24367				0 - this.offset.relative.top - this.offset.parent.top,
24368				o.containment === "document" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,
24369				(o.containment === "document" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
24370			];
24371		}
24372
24373		if(!(/^(document|window|parent)$/).test(o.containment)) {
24374			ce = $(o.containment)[0];
24375			co = $(o.containment).offset();
24376			over = ($(ce).css("overflow") !== "hidden");
24377
24378			this.containment = [
24379				co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
24380				co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
24381				co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
24382				co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
24383			];
24384		}
24385
24386	},
24387
24388	_convertPositionTo: function(d, pos) {
24389
24390		if(!pos) {
24391			pos = this.position;
24392		}
24393		var mod = d === "absolute" ? 1 : -1,
24394			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
24395			scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
24396
24397		return {
24398			top: (
24399				pos.top	+																// The absolute mouse position
24400				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
24401				this.offset.parent.top * mod -											// The offsetParent's offset without borders (offset + border)
24402				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
24403			),
24404			left: (
24405				pos.left +																// The absolute mouse position
24406				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
24407				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
24408				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
24409			)
24410		};
24411
24412	},
24413
24414	_generatePosition: function(event) {
24415
24416		var top, left,
24417			o = this.options,
24418			pageX = event.pageX,
24419			pageY = event.pageY,
24420			scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
24421
24422		// This is another very weird special case that only happens for relative elements:
24423		// 1. If the css position is relative
24424		// 2. and the scroll parent is the document or similar to the offset parent
24425		// we have to refresh the relative offset during the scroll so there are no jumps
24426		if(this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {
24427			this.offset.relative = this._getRelativeOffset();
24428		}
24429
24430		/*
24431		 * - Position constraining -
24432		 * Constrain the position to a mix of grid, containment.
24433		 */
24434
24435		if(this.originalPosition) { //If we are not dragging yet, we won't check for options
24436
24437			if(this.containment) {
24438				if(event.pageX - this.offset.click.left < this.containment[0]) {
24439					pageX = this.containment[0] + this.offset.click.left;
24440				}
24441				if(event.pageY - this.offset.click.top < this.containment[1]) {
24442					pageY = this.containment[1] + this.offset.click.top;
24443				}
24444				if(event.pageX - this.offset.click.left > this.containment[2]) {
24445					pageX = this.containment[2] + this.offset.click.left;
24446				}
24447				if(event.pageY - this.offset.click.top > this.containment[3]) {
24448					pageY = this.containment[3] + this.offset.click.top;
24449				}
24450			}
24451
24452			if(o.grid) {
24453				top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
24454				pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
24455
24456				left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
24457				pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
24458			}
24459
24460		}
24461
24462		return {
24463			top: (
24464				pageY -																// The absolute mouse position
24465				this.offset.click.top -													// Click offset (relative to the element)
24466				this.offset.relative.top	-											// Only for relative positioned nodes: Relative offset from element to offset parent
24467				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
24468				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
24469			),
24470			left: (
24471				pageX -																// The absolute mouse position
24472				this.offset.click.left -												// Click offset (relative to the element)
24473				this.offset.relative.left	-											// Only for relative positioned nodes: Relative offset from element to offset parent
24474				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
24475				( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
24476			)
24477		};
24478
24479	},
24480
24481	_rearrange: function(event, i, a, hardRefresh) {
24482
24483		a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
24484
24485		//Various things done here to improve the performance:
24486		// 1. we create a setTimeout, that calls refreshPositions
24487		// 2. on the instance, we have a counter variable, that get's higher after every append
24488		// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
24489		// 4. this lets only the last addition to the timeout stack through
24490		this.counter = this.counter ? ++this.counter : 1;
24491		var counter = this.counter;
24492
24493		this._delay(function() {
24494			if(counter === this.counter) {
24495				this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
24496			}
24497		});
24498
24499	},
24500
24501	_clear: function(event, noPropagation) {
24502
24503		this.reverting = false;
24504		// We delay all events that have to be triggered to after the point where the placeholder has been removed and
24505		// everything else normalized again
24506		var i,
24507			delayedTriggers = [];
24508
24509		// We first have to update the dom position of the actual currentItem
24510		// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
24511		if(!this._noFinalSort && this.currentItem.parent().length) {
24512			this.placeholder.before(this.currentItem);
24513		}
24514		this._noFinalSort = null;
24515
24516		if(this.helper[0] === this.currentItem[0]) {
24517			for(i in this._storedCSS) {
24518				if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
24519					this._storedCSS[i] = "";
24520				}
24521			}
24522			this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
24523		} else {
24524			this.currentItem.show();
24525		}
24526
24527		if(this.fromOutside && !noPropagation) {
24528			delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
24529		}
24530		if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
24531			delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
24532		}
24533
24534		// Check if the items Container has Changed and trigger appropriate
24535		// events.
24536		if (this !== this.currentContainer) {
24537			if(!noPropagation) {
24538				delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
24539				delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); };  }).call(this, this.currentContainer));
24540				delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this));  }; }).call(this, this.currentContainer));
24541			}
24542		}
24543
24544
24545		//Post events to containers
24546		function delayEvent( type, instance, container ) {
24547			return function( event ) {
24548				container._trigger( type, event, instance._uiHash( instance ) );
24549			};
24550		}
24551		for (i = this.containers.length - 1; i >= 0; i--){
24552			if (!noPropagation) {
24553				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
24554			}
24555			if(this.containers[i].containerCache.over) {
24556				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
24557				this.containers[i].containerCache.over = 0;
24558			}
24559		}
24560
24561		//Do what was originally in plugins
24562		if ( this.storedCursor ) {
24563			this.document.find( "body" ).css( "cursor", this.storedCursor );
24564			this.storedStylesheet.remove();
24565		}
24566		if(this._storedOpacity) {
24567			this.helper.css("opacity", this._storedOpacity);
24568		}
24569		if(this._storedZIndex) {
24570			this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
24571		}
24572
24573		this.dragging = false;
24574
24575		if(!noPropagation) {
24576			this._trigger("beforeStop", event, this._uiHash());
24577		}
24578
24579		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
24580		this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
24581
24582		if ( !this.cancelHelperRemoval ) {
24583			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
24584				this.helper.remove();
24585			}
24586			this.helper = null;
24587		}
24588
24589		if(!noPropagation) {
24590			for (i=0; i < delayedTriggers.length; i++) {
24591				delayedTriggers[i].call(this, event);
24592			} //Trigger all delayed events
24593			this._trigger("stop", event, this._uiHash());
24594		}
24595
24596		this.fromOutside = false;
24597		return !this.cancelHelperRemoval;
24598
24599	},
24600
24601	_trigger: function() {
24602		if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
24603			this.cancel();
24604		}
24605	},
24606
24607	_uiHash: function(_inst) {
24608		var inst = _inst || this;
24609		return {
24610			helper: inst.helper,
24611			placeholder: inst.placeholder || $([]),
24612			position: inst.position,
24613			originalPosition: inst.originalPosition,
24614			offset: inst.positionAbs,
24615			item: inst.currentItem,
24616			sender: _inst ? _inst.element : null
24617		};
24618	}
24619
24620});
24621
24622
24623/*!
24624 * jQuery UI Spinner 1.11.4
24625 * http://jqueryui.com
24626 *
24627 * Copyright jQuery Foundation and other contributors
24628 * Released under the MIT license.
24629 * http://jquery.org/license
24630 *
24631 * http://api.jqueryui.com/spinner/
24632 */
24633
24634
24635function spinner_modifier( fn ) {
24636	return function() {
24637		var previous = this.element.val();
24638		fn.apply( this, arguments );
24639		this._refresh();
24640		if ( previous !== this.element.val() ) {
24641			this._trigger( "change" );
24642		}
24643	};
24644}
24645
24646var spinner = $.widget( "ui.spinner", {
24647	version: "1.11.4",
24648	defaultElement: "<input>",
24649	widgetEventPrefix: "spin",
24650	options: {
24651		culture: null,
24652		icons: {
24653			down: "ui-icon-triangle-1-s",
24654			up: "ui-icon-triangle-1-n"
24655		},
24656		incremental: true,
24657		max: null,
24658		min: null,
24659		numberFormat: null,
24660		page: 10,
24661		step: 1,
24662
24663		change: null,
24664		spin: null,
24665		start: null,
24666		stop: null
24667	},
24668
24669	_create: function() {
24670		// handle string values that need to be parsed
24671		this._setOption( "max", this.options.max );
24672		this._setOption( "min", this.options.min );
24673		this._setOption( "step", this.options.step );
24674
24675		// Only format if there is a value, prevents the field from being marked
24676		// as invalid in Firefox, see #9573.
24677		if ( this.value() !== "" ) {
24678			// Format the value, but don't constrain.
24679			this._value( this.element.val(), true );
24680		}
24681
24682		this._draw();
24683		this._on( this._events );
24684		this._refresh();
24685
24686		// turning off autocomplete prevents the browser from remembering the
24687		// value when navigating through history, so we re-enable autocomplete
24688		// if the page is unloaded before the widget is destroyed. #7790
24689		this._on( this.window, {
24690			beforeunload: function() {
24691				this.element.removeAttr( "autocomplete" );
24692			}
24693		});
24694	},
24695
24696	_getCreateOptions: function() {
24697		var options = {},
24698			element = this.element;
24699
24700		$.each( [ "min", "max", "step" ], function( i, option ) {
24701			var value = element.attr( option );
24702			if ( value !== undefined && value.length ) {
24703				options[ option ] = value;
24704			}
24705		});
24706
24707		return options;
24708	},
24709
24710	_events: {
24711		keydown: function( event ) {
24712			if ( this._start( event ) && this._keydown( event ) ) {
24713				event.preventDefault();
24714			}
24715		},
24716		keyup: "_stop",
24717		focus: function() {
24718			this.previous = this.element.val();
24719		},
24720		blur: function( event ) {
24721			if ( this.cancelBlur ) {
24722				delete this.cancelBlur;
24723				return;
24724			}
24725
24726			this._stop();
24727			this._refresh();
24728			if ( this.previous !== this.element.val() ) {
24729				this._trigger( "change", event );
24730			}
24731		},
24732		mousewheel: function( event, delta ) {
24733			if ( !delta ) {
24734				return;
24735			}
24736			if ( !this.spinning && !this._start( event ) ) {
24737				return false;
24738			}
24739
24740			this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
24741			clearTimeout( this.mousewheelTimer );
24742			this.mousewheelTimer = this._delay(function() {
24743				if ( this.spinning ) {
24744					this._stop( event );
24745				}
24746			}, 100 );
24747			event.preventDefault();
24748		},
24749		"mousedown .ui-spinner-button": function( event ) {
24750			var previous;
24751
24752			// We never want the buttons to have focus; whenever the user is
24753			// interacting with the spinner, the focus should be on the input.
24754			// If the input is focused then this.previous is properly set from
24755			// when the input first received focus. If the input is not focused
24756			// then we need to set this.previous based on the value before spinning.
24757			previous = this.element[0] === this.document[0].activeElement ?
24758				this.previous : this.element.val();
24759			function checkFocus() {
24760				var isActive = this.element[0] === this.document[0].activeElement;
24761				if ( !isActive ) {
24762					this.element.focus();
24763					this.previous = previous;
24764					// support: IE
24765					// IE sets focus asynchronously, so we need to check if focus
24766					// moved off of the input because the user clicked on the button.
24767					this._delay(function() {
24768						this.previous = previous;
24769					});
24770				}
24771			}
24772
24773			// ensure focus is on (or stays on) the text field
24774			event.preventDefault();
vendor: 5,275 bytes, lines 24775-24976
24775			checkFocus.call( this );
24776
24777			// support: IE
24778			// IE doesn't prevent moving focus even with event.preventDefault()
24779			// so we set a flag to know when we should ignore the blur event
24780			// and check (again) if focus moved off of the input.
24781			this.cancelBlur = true;
24782			this._delay(function() {
24783				delete this.cancelBlur;
24784				checkFocus.call( this );
24785			});
24786
24787			if ( this._start( event ) === false ) {
24788				return;
24789			}
24790
24791			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
24792		},
24793		"mouseup .ui-spinner-button": "_stop",
24794		"mouseenter .ui-spinner-button": function( event ) {
24795			// button will add ui-state-active if mouse was down while mouseleave and kept down
24796			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
24797				return;
24798			}
24799
24800			if ( this._start( event ) === false ) {
24801				return false;
24802			}
24803			this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
24804		},
24805		// TODO: do we really want to consider this a stop?
24806		// shouldn't we just stop the repeater and wait until mouseup before
24807		// we trigger the stop event?
24808		"mouseleave .ui-spinner-button": "_stop"
24809	},
24810
24811	_draw: function() {
24812		var uiSpinner = this.uiSpinner = this.element
24813			.addClass( "ui-spinner-input" )
24814			.attr( "autocomplete", "off" )
24815			.wrap( this._uiSpinnerHtml() )
24816			.parent()
24817				// add buttons
24818				.append( this._buttonHtml() );
24819
24820		this.element.attr( "role", "spinbutton" );
24821
24822		// button bindings
24823		this.buttons = uiSpinner.find( ".ui-spinner-button" )
24824			.attr( "tabIndex", -1 )
24825			.button()
24826			.removeClass( "ui-corner-all" );
24827
24828		// IE 6 doesn't understand height: 50% for the buttons
24829		// unless the wrapper has an explicit height
24830		if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
24831				uiSpinner.height() > 0 ) {
24832			uiSpinner.height( uiSpinner.height() );
24833		}
24834
24835		// disable spinner if element was already disabled
24836		if ( this.options.disabled ) {
24837			this.disable();
24838		}
24839	},
24840
24841	_keydown: function( event ) {
24842		var options = this.options,
24843			keyCode = $.ui.keyCode;
24844
24845		switch ( event.keyCode ) {
24846		case keyCode.UP:
24847			this._repeat( null, 1, event );
24848			return true;
24849		case keyCode.DOWN:
24850			this._repeat( null, -1, event );
24851			return true;
24852		case keyCode.PAGE_UP:
24853			this._repeat( null, options.page, event );
24854			return true;
24855		case keyCode.PAGE_DOWN:
24856			this._repeat( null, -options.page, event );
24857			return true;
24858		}
24859
24860		return false;
24861	},
24862
24863	_uiSpinnerHtml: function() {
24864		return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
24865	},
24866
24867	_buttonHtml: function() {
24868		return "" +
24869			"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
24870				"<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
24871			"</a>" +
24872			"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
24873				"<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
24874			"</a>";
24875	},
24876
24877	_start: function( event ) {
24878		if ( !this.spinning && this._trigger( "start", event ) === false ) {
24879			return false;
24880		}
24881
24882		if ( !this.counter ) {
24883			this.counter = 1;
24884		}
24885		this.spinning = true;
24886		return true;
24887	},
24888
24889	_repeat: function( i, steps, event ) {
24890		i = i || 500;
24891
24892		clearTimeout( this.timer );
24893		this.timer = this._delay(function() {
24894			this._repeat( 40, steps, event );
24895		}, i );
24896
24897		this._spin( steps * this.options.step, event );
24898	},
24899
24900	_spin: function( step, event ) {
24901		var value = this.value() || 0;
24902
24903		if ( !this.counter ) {
24904			this.counter = 1;
24905		}
24906
24907		value = this._adjustValue( value + step * this._increment( this.counter ) );
24908
24909		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
24910			this._value( value );
24911			this.counter++;
24912		}
24913	},
24914
24915	_increment: function( i ) {
24916		var incremental = this.options.incremental;
24917
24918		if ( incremental ) {
24919			return $.isFunction( incremental ) ?
24920				incremental( i ) :
24921				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
24922		}
24923
24924		return 1;
24925	},
24926
24927	_precision: function() {
24928		var precision = this._precisionOf( this.options.step );
24929		if ( this.options.min !== null ) {
24930			precision = Math.max( precision, this._precisionOf( this.options.min ) );
24931		}
24932		return precision;
24933	},
24934
24935	_precisionOf: function( num ) {
24936		var str = num.toString(),
24937			decimal = str.indexOf( "." );
24938		return decimal === -1 ? 0 : str.length - decimal - 1;
24939	},
24940
24941	_adjustValue: function( value ) {
24942		var base, aboveMin,
24943			options = this.options;
24944
24945		// make sure we're at a valid step
24946		// - find out where we are relative to the base (min or 0)
24947		base = options.min !== null ? options.min : 0;
24948		aboveMin = value - base;
24949		// - round to the nearest step
24950		aboveMin = Math.round(aboveMin / options.step) * options.step;
24951		// - rounding is based on 0, so adjust back to our base
24952		value = base + aboveMin;
24953
24954		// fix precision from bad JS floating point math
24955		value = parseFloat( value.toFixed( this._precision() ) );
24956
24957		// clamp the value
24958		if ( options.max !== null && value > options.max) {
24959			return options.max;
24960		}
24961		if ( options.min !== null && value < options.min ) {
24962			return options.min;
24963		}
24964
24965		return value;
24966	},
24967
24968	_stop: function( event ) {
24969		if ( !this.spinning ) {
24970			return;
24971		}
24972
24973		clearTimeout( this.timer );
24974		clearTimeout( this.mousewheelTimer );
24975		this.counter = 0;
24976		this.spinning = false;
vendor: 16,063 bytes, lines 24977-25594
24977		this._trigger( "stop", event );
24978	},
24979
24980	_setOption: function( key, value ) {
24981		if ( key === "culture" || key === "numberFormat" ) {
24982			var prevValue = this._parse( this.element.val() );
24983			this.options[ key ] = value;
24984			this.element.val( this._format( prevValue ) );
24985			return;
24986		}
24987
24988		if ( key === "max" || key === "min" || key === "step" ) {
24989			if ( typeof value === "string" ) {
24990				value = this._parse( value );
24991			}
24992		}
24993		if ( key === "icons" ) {
24994			this.buttons.first().find( ".ui-icon" )
24995				.removeClass( this.options.icons.up )
24996				.addClass( value.up );
24997			this.buttons.last().find( ".ui-icon" )
24998				.removeClass( this.options.icons.down )
24999				.addClass( value.down );
25000		}
25001
25002		this._super( key, value );
25003
25004		if ( key === "disabled" ) {
25005			this.widget().toggleClass( "ui-state-disabled", !!value );
25006			this.element.prop( "disabled", !!value );
25007			this.buttons.button( value ? "disable" : "enable" );
25008		}
25009	},
25010
25011	_setOptions: spinner_modifier(function( options ) {
25012		this._super( options );
25013	}),
25014
25015	_parse: function( val ) {
25016		if ( typeof val === "string" && val !== "" ) {
25017			val = window.Globalize && this.options.numberFormat ?
25018				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
25019		}
25020		return val === "" || isNaN( val ) ? null : val;
25021	},
25022
25023	_format: function( value ) {
25024		if ( value === "" ) {
25025			return "";
25026		}
25027		return window.Globalize && this.options.numberFormat ?
25028			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
25029			value;
25030	},
25031
25032	_refresh: function() {
25033		this.element.attr({
25034			"aria-valuemin": this.options.min,
25035			"aria-valuemax": this.options.max,
25036			// TODO: what should we do with values that can't be parsed?
25037			"aria-valuenow": this._parse( this.element.val() )
25038		});
25039	},
25040
25041	isValid: function() {
25042		var value = this.value();
25043
25044		// null is invalid
25045		if ( value === null ) {
25046			return false;
25047		}
25048
25049		// if value gets adjusted, it's invalid
25050		return value === this._adjustValue( value );
25051	},
25052
25053	// update the value without triggering change
25054	_value: function( value, allowAny ) {
25055		var parsed;
25056		if ( value !== "" ) {
25057			parsed = this._parse( value );
25058			if ( parsed !== null ) {
25059				if ( !allowAny ) {
25060					parsed = this._adjustValue( parsed );
25061				}
25062				value = this._format( parsed );
25063			}
25064		}
25065		this.element.val( value );
25066		this._refresh();
25067	},
25068
25069	_destroy: function() {
25070		this.element
25071			.removeClass( "ui-spinner-input" )
25072			.prop( "disabled", false )
25073			.removeAttr( "autocomplete" )
25074			.removeAttr( "role" )
25075			.removeAttr( "aria-valuemin" )
25076			.removeAttr( "aria-valuemax" )
25077			.removeAttr( "aria-valuenow" );
25078		this.uiSpinner.replaceWith( this.element );
25079	},
25080
25081	stepUp: spinner_modifier(function( steps ) {
25082		this._stepUp( steps );
25083	}),
25084	_stepUp: function( steps ) {
25085		if ( this._start() ) {
25086			this._spin( (steps || 1) * this.options.step );
25087			this._stop();
25088		}
25089	},
25090
25091	stepDown: spinner_modifier(function( steps ) {
25092		this._stepDown( steps );
25093	}),
25094	_stepDown: function( steps ) {
25095		if ( this._start() ) {
25096			this._spin( (steps || 1) * -this.options.step );
25097			this._stop();
25098		}
25099	},
25100
25101	pageUp: spinner_modifier(function( pages ) {
25102		this._stepUp( (pages || 1) * this.options.page );
25103	}),
25104
25105	pageDown: spinner_modifier(function( pages ) {
25106		this._stepDown( (pages || 1) * this.options.page );
25107	}),
25108
25109	value: function( newVal ) {
25110		if ( !arguments.length ) {
25111			return this._parse( this.element.val() );
25112		}
25113		spinner_modifier( this._value ).call( this, newVal );
25114	},
25115
25116	widget: function() {
25117		return this.uiSpinner;
25118	}
25119});
25120
25121
25122/*!
25123 * jQuery UI Tabs 1.11.4
25124 * http://jqueryui.com
25125 *
25126 * Copyright jQuery Foundation and other contributors
25127 * Released under the MIT license.
25128 * http://jquery.org/license
25129 *
25130 * http://api.jqueryui.com/tabs/
25131 */
25132
25133
25134var tabs = $.widget( "ui.tabs", {
25135	version: "1.11.4",
25136	delay: 300,
25137	options: {
25138		active: null,
25139		collapsible: false,
25140		event: "click",
25141		heightStyle: "content",
25142		hide: null,
25143		show: null,
25144
25145		// callbacks
25146		activate: null,
25147		beforeActivate: null,
25148		beforeLoad: null,
25149		load: null
25150	},
25151
25152	_isLocal: (function() {
25153		var rhash = /#.*$/;
25154
25155		return function( anchor ) {
25156			var anchorUrl, locationUrl;
25157
25158			// support: IE7
25159			// IE7 doesn't normalize the href property when set via script (#9317)
25160			anchor = anchor.cloneNode( false );
25161
25162			anchorUrl = anchor.href.replace( rhash, "" );
25163			locationUrl = location.href.replace( rhash, "" );
25164
25165			// decoding may throw an error if the URL isn't UTF-8 (#9518)
25166			try {
25167				anchorUrl = decodeURIComponent( anchorUrl );
25168			} catch ( error ) {}
25169			try {
25170				locationUrl = decodeURIComponent( locationUrl );
25171			} catch ( error ) {}
25172
25173			return anchor.hash.length > 1 && anchorUrl === locationUrl;
25174		};
25175	})(),
25176
25177	_create: function() {
25178		var that = this,
25179			options = this.options;
25180
25181		this.running = false;
25182
25183		this.element
25184			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
25185			.toggleClass( "ui-tabs-collapsible", options.collapsible );
25186
25187		this._processTabs();
25188		options.active = this._initialActive();
25189
25190		// Take disabling tabs via class attribute from HTML
25191		// into account and update option properly.
25192		if ( $.isArray( options.disabled ) ) {
25193			options.disabled = $.unique( options.disabled.concat(
25194				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
25195					return that.tabs.index( li );
25196				})
25197			) ).sort();
25198		}
25199
25200		// check for length avoids error when initializing empty list
25201		if ( this.options.active !== false && this.anchors.length ) {
25202			this.active = this._findActive( options.active );
25203		} else {
25204			this.active = $();
25205		}
25206
25207		this._refresh();
25208
25209		if ( this.active.length ) {
25210			this.load( options.active );
25211		}
25212	},
25213
25214	_initialActive: function() {
25215		var active = this.options.active,
25216			collapsible = this.options.collapsible,
25217			locationHash = location.hash.substring( 1 );
25218
25219		if ( active === null ) {
25220			// check the fragment identifier in the URL
25221			if ( locationHash ) {
25222				this.tabs.each(function( i, tab ) {
25223					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
25224						active = i;
25225						return false;
25226					}
25227				});
25228			}
25229
25230			// check for a tab marked active via a class
25231			if ( active === null ) {
25232				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
25233			}
25234
25235			// no active tab, set to false
25236			if ( active === null || active === -1 ) {
25237				active = this.tabs.length ? 0 : false;
25238			}
25239		}
25240
25241		// handle numbers: negative, out of range
25242		if ( active !== false ) {
25243			active = this.tabs.index( this.tabs.eq( active ) );
25244			if ( active === -1 ) {
25245				active = collapsible ? false : 0;
25246			}
25247		}
25248
25249		// don't allow collapsible: false and active: false
25250		if ( !collapsible && active === false && this.anchors.length ) {
25251			active = 0;
25252		}
25253
25254		return active;
25255	},
25256
25257	_getCreateEventData: function() {
25258		return {
25259			tab: this.active,
25260			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
25261		};
25262	},
25263
25264	_tabKeydown: function( event ) {
25265		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
25266			selectedIndex = this.tabs.index( focusedTab ),
25267			goingForward = true;
25268
25269		if ( this._handlePageNav( event ) ) {
25270			return;
25271		}
25272
25273		switch ( event.keyCode ) {
25274			case $.ui.keyCode.RIGHT:
25275			case $.ui.keyCode.DOWN:
25276				selectedIndex++;
25277				break;
25278			case $.ui.keyCode.UP:
25279			case $.ui.keyCode.LEFT:
25280				goingForward = false;
25281				selectedIndex--;
25282				break;
25283			case $.ui.keyCode.END:
25284				selectedIndex = this.anchors.length - 1;
25285				break;
25286			case $.ui.keyCode.HOME:
25287				selectedIndex = 0;
25288				break;
25289			case $.ui.keyCode.SPACE:
25290				// Activate only, no collapsing
25291				event.preventDefault();
25292				clearTimeout( this.activating );
25293				this._activate( selectedIndex );
25294				return;
25295			case $.ui.keyCode.ENTER:
25296				// Toggle (cancel delayed activation, allow collapsing)
25297				event.preventDefault();
25298				clearTimeout( this.activating );
25299				// Determine if we should collapse or activate
25300				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
25301				return;
25302			default:
25303				return;
25304		}
25305
25306		// Focus the appropriate tab, based on which key was pressed
25307		event.preventDefault();
25308		clearTimeout( this.activating );
25309		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
25310
25311		// Navigating with control/command key will prevent automatic activation
25312		if ( !event.ctrlKey && !event.metaKey ) {
25313
25314			// Update aria-selected immediately so that AT think the tab is already selected.
25315			// Otherwise AT may confuse the user by stating that they need to activate the tab,
25316			// but the tab will already be activated by the time the announcement finishes.
25317			focusedTab.attr( "aria-selected", "false" );
25318			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
25319
25320			this.activating = this._delay(function() {
25321				this.option( "active", selectedIndex );
25322			}, this.delay );
25323		}
25324	},
25325
25326	_panelKeydown: function( event ) {
25327		if ( this._handlePageNav( event ) ) {
25328			return;
25329		}
25330
25331		// Ctrl+up moves focus to the current tab
25332		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
25333			event.preventDefault();
25334			this.active.focus();
25335		}
25336	},
25337
25338	// Alt+page up/down moves focus to the previous/next tab (and activates)
25339	_handlePageNav: function( event ) {
25340		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
25341			this._activate( this._focusNextTab( this.options.active - 1, false ) );
25342			return true;
25343		}
25344		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
25345			this._activate( this._focusNextTab( this.options.active + 1, true ) );
25346			return true;
25347		}
25348	},
25349
25350	_findNextTab: function( index, goingForward ) {
25351		var lastTabIndex = this.tabs.length - 1;
25352
25353		function constrain() {
25354			if ( index > lastTabIndex ) {
25355				index = 0;
25356			}
25357			if ( index < 0 ) {
25358				index = lastTabIndex;
25359			}
25360			return index;
25361		}
25362
25363		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
25364			index = goingForward ? index + 1 : index - 1;
25365		}
25366
25367		return index;
25368	},
25369
25370	_focusNextTab: function( index, goingForward ) {
25371		index = this._findNextTab( index, goingForward );
25372		this.tabs.eq( index ).focus();
25373		return index;
25374	},
25375
25376	_setOption: function( key, value ) {
25377		if ( key === "active" ) {
25378			// _activate() will handle invalid values and update this.options
25379			this._activate( value );
25380			return;
25381		}
25382
25383		if ( key === "disabled" ) {
25384			// don't use the widget factory's disabled handling
25385			this._setupDisabled( value );
25386			return;
25387		}
25388
25389		this._super( key, value);
25390
25391		if ( key === "collapsible" ) {
25392			this.element.toggleClass( "ui-tabs-collapsible", value );
25393			// Setting collapsible: false while collapsed; open first panel
25394			if ( !value && this.options.active === false ) {
25395				this._activate( 0 );
25396			}
25397		}
25398
25399		if ( key === "event" ) {
25400			this._setupEvents( value );
25401		}
25402
25403		if ( key === "heightStyle" ) {
25404			this._setupHeightStyle( value );
25405		}
25406	},
25407
25408	_sanitizeSelector: function( hash ) {
25409		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
25410	},
25411
25412	refresh: function() {
25413		var options = this.options,
25414			lis = this.tablist.children( ":has(a[href])" );
25415
25416		// get disabled tabs from class attribute from HTML
25417		// this will get converted to a boolean if needed in _refresh()
25418		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
25419			return lis.index( tab );
25420		});
25421
25422		this._processTabs();
25423
25424		// was collapsed or no tabs
25425		if ( options.active === false || !this.anchors.length ) {
25426			options.active = false;
25427			this.active = $();
25428		// was active, but active tab is gone
25429		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
25430			// all remaining tabs are disabled
25431			if ( this.tabs.length === options.disabled.length ) {
25432				options.active = false;
25433				this.active = $();
25434			// activate previous tab
25435			} else {
25436				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
25437			}
25438		// was active, active tab still exists
25439		} else {
25440			// make sure active index is correct
25441			options.active = this.tabs.index( this.active );
25442		}
25443
25444		this._refresh();
25445	},
25446
25447	_refresh: function() {
25448		this._setupDisabled( this.options.disabled );
25449		this._setupEvents( this.options.event );
25450		this._setupHeightStyle( this.options.heightStyle );
25451
25452		this.tabs.not( this.active ).attr({
25453			"aria-selected": "false",
25454			"aria-expanded": "false",
25455			tabIndex: -1
25456		});
25457		this.panels.not( this._getPanelForTab( this.active ) )
25458			.hide()
25459			.attr({
25460				"aria-hidden": "true"
25461			});
25462
25463		// Make sure one tab is in the tab order
25464		if ( !this.active.length ) {
25465			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
25466		} else {
25467			this.active
25468				.addClass( "ui-tabs-active ui-state-active" )
25469				.attr({
25470					"aria-selected": "true",
25471					"aria-expanded": "true",
25472					tabIndex: 0
25473				});
25474			this._getPanelForTab( this.active )
25475				.show()
25476				.attr({
25477					"aria-hidden": "false"
25478				});
25479		}
25480	},
25481
25482	_processTabs: function() {
25483		var that = this,
25484			prevTabs = this.tabs,
25485			prevAnchors = this.anchors,
25486			prevPanels = this.panels;
25487
25488		this.tablist = this._getList()
25489			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
25490			.attr( "role", "tablist" )
25491
25492			// Prevent users from focusing disabled tabs via click
25493			.delegate( "> li", "mousedown" + this.eventNamespace, function( event ) {
25494				if ( $( this ).is( ".ui-state-disabled" ) ) {
25495					event.preventDefault();
25496				}
25497			})
25498
25499			// support: IE <9
25500			// Preventing the default action in mousedown doesn't prevent IE
25501			// from focusing the element, so if the anchor gets focused, blur.
25502			// We don't have to worry about focusing the previously focused
25503			// element since clicking on a non-focusable element should focus
25504			// the body anyway.
25505			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
25506				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
25507					this.blur();
25508				}
25509			});
25510
25511		this.tabs = this.tablist.find( "> li:has(a[href])" )
25512			.addClass( "ui-state-default ui-corner-top" )
25513			.attr({
25514				role: "tab",
25515				tabIndex: -1
25516			});
25517
25518		this.anchors = this.tabs.map(function() {
25519				return $( "a", this )[ 0 ];
25520			})
25521			.addClass( "ui-tabs-anchor" )
25522			.attr({
25523				role: "presentation",
25524				tabIndex: -1
25525			});
25526
25527		this.panels = $();
25528
25529		this.anchors.each(function( i, anchor ) {
25530			var selector, panel, panelId,
25531				anchorId = $( anchor ).uniqueId().attr( "id" ),
25532				tab = $( anchor ).closest( "li" ),
25533				originalAriaControls = tab.attr( "aria-controls" );
25534
25535			// inline tab
25536			if ( that._isLocal( anchor ) ) {
25537				selector = anchor.hash;
25538				panelId = selector.substring( 1 );
25539				panel = that.element.find( that._sanitizeSelector( selector ) );
25540			// remote tab
25541			} else {
25542				// If the tab doesn't already have aria-controls,
25543				// generate an id by using a throw-away element
25544				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
25545				selector = "#" + panelId;
25546				panel = that.element.find( selector );
25547				if ( !panel.length ) {
25548					panel = that._createPanel( panelId );
25549					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
25550				}
25551				panel.attr( "aria-live", "polite" );
25552			}
25553
25554			if ( panel.length) {
25555				that.panels = that.panels.add( panel );
25556			}
25557			if ( originalAriaControls ) {
25558				tab.data( "ui-tabs-aria-controls", originalAriaControls );
25559			}
25560			tab.attr({
25561				"aria-controls": panelId,
25562				"aria-labelledby": anchorId
25563			});
25564			panel.attr( "aria-labelledby", anchorId );
25565		});
25566
25567		this.panels
25568			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
25569			.attr( "role", "tabpanel" );
25570
25571		// Avoid memory leaks (#10056)
25572		if ( prevTabs ) {
25573			this._off( prevTabs.not( this.tabs ) );
25574			this._off( prevAnchors.not( this.anchors ) );
25575			this._off( prevPanels.not( this.panels ) );
25576		}
25577	},
25578
25579	// allow overriding how to find the list for rare usage scenarios (#7715)
25580	_getList: function() {
25581		return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
25582	},
25583
25584	_createPanel: function( id ) {
25585		return $( "<div>" )
25586			.attr( "id", id )
25587			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
25588			.data( "ui-tabs-destroy", true );
25589	},
25590
25591	_setupDisabled: function( disabled ) {
25592		if ( $.isArray( disabled ) ) {
25593			if ( !disabled.length ) {
25594				disabled = false;
vendor: 4,561 bytes, lines 25595-25762
25595			} else if ( disabled.length === this.anchors.length ) {
25596				disabled = true;
25597			}
25598		}
25599
25600		// disable tabs
25601		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
25602			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
25603				$( li )
25604					.addClass( "ui-state-disabled" )
25605					.attr( "aria-disabled", "true" );
25606			} else {
25607				$( li )
25608					.removeClass( "ui-state-disabled" )
25609					.removeAttr( "aria-disabled" );
25610			}
25611		}
25612
25613		this.options.disabled = disabled;
25614	},
25615
25616	_setupEvents: function( event ) {
25617		var events = {};
25618		if ( event ) {
25619			$.each( event.split(" "), function( index, eventName ) {
25620				events[ eventName ] = "_eventHandler";
25621			});
25622		}
25623
25624		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
25625		// Always prevent the default action, even when disabled
25626		this._on( true, this.anchors, {
25627			click: function( event ) {
25628				event.preventDefault();
25629			}
25630		});
25631		this._on( this.anchors, events );
25632		this._on( this.tabs, { keydown: "_tabKeydown" } );
25633		this._on( this.panels, { keydown: "_panelKeydown" } );
25634
25635		this._focusable( this.tabs );
25636		this._hoverable( this.tabs );
25637	},
25638
25639	_setupHeightStyle: function( heightStyle ) {
25640		var maxHeight,
25641			parent = this.element.parent();
25642
25643		if ( heightStyle === "fill" ) {
25644			maxHeight = parent.height();
25645			maxHeight -= this.element.outerHeight() - this.element.height();
25646
25647			this.element.siblings( ":visible" ).each(function() {
25648				var elem = $( this ),
25649					position = elem.css( "position" );
25650
25651				if ( position === "absolute" || position === "fixed" ) {
25652					return;
25653				}
25654				maxHeight -= elem.outerHeight( true );
25655			});
25656
25657			this.element.children().not( this.panels ).each(function() {
25658				maxHeight -= $( this ).outerHeight( true );
25659			});
25660
25661			this.panels.each(function() {
25662				$( this ).height( Math.max( 0, maxHeight -
25663					$( this ).innerHeight() + $( this ).height() ) );
25664			})
25665			.css( "overflow", "auto" );
25666		} else if ( heightStyle === "auto" ) {
25667			maxHeight = 0;
25668			this.panels.each(function() {
25669				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
25670			}).height( maxHeight );
25671		}
25672	},
25673
25674	_eventHandler: function( event ) {
25675		var options = this.options,
25676			active = this.active,
25677			anchor = $( event.currentTarget ),
25678			tab = anchor.closest( "li" ),
25679			clickedIsActive = tab[ 0 ] === active[ 0 ],
25680			collapsing = clickedIsActive && options.collapsible,
25681			toShow = collapsing ? $() : this._getPanelForTab( tab ),
25682			toHide = !active.length ? $() : this._getPanelForTab( active ),
25683			eventData = {
25684				oldTab: active,
25685				oldPanel: toHide,
25686				newTab: collapsing ? $() : tab,
25687				newPanel: toShow
25688			};
25689
25690		event.preventDefault();
25691
25692		if ( tab.hasClass( "ui-state-disabled" ) ||
25693				// tab is already loading
25694				tab.hasClass( "ui-tabs-loading" ) ||
25695				// can't switch durning an animation
25696				this.running ||
25697				// click on active header, but not collapsible
25698				( clickedIsActive && !options.collapsible ) ||
25699				// allow canceling activation
25700				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
25701			return;
25702		}
25703
25704		options.active = collapsing ? false : this.tabs.index( tab );
25705
25706		this.active = clickedIsActive ? $() : tab;
25707		if ( this.xhr ) {
25708			this.xhr.abort();
25709		}
25710
25711		if ( !toHide.length && !toShow.length ) {
25712			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
25713		}
25714
25715		if ( toShow.length ) {
25716			this.load( this.tabs.index( tab ), event );
25717		}
25718		this._toggle( event, eventData );
25719	},
25720
25721	// handles show/hide for selecting tabs
25722	_toggle: function( event, eventData ) {
25723		var that = this,
25724			toShow = eventData.newPanel,
25725			toHide = eventData.oldPanel;
25726
25727		this.running = true;
25728
25729		function complete() {
25730			that.running = false;
25731			that._trigger( "activate", event, eventData );
25732		}
25733
25734		function show() {
25735			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
25736
25737			if ( toShow.length && that.options.show ) {
25738				that._show( toShow, that.options.show, complete );
25739			} else {
25740				toShow.show();
25741				complete();
25742			}
25743		}
25744
25745		// start out by hiding, then showing, then completing
25746		if ( toHide.length && this.options.hide ) {
25747			this._hide( toHide, this.options.hide, function() {
25748				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
25749				show();
25750			});
25751		} else {
25752			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
25753			toHide.hide();
25754			show();
25755		}
25756
25757		toHide.attr( "aria-hidden", "true" );
25758		eventData.oldTab.attr({
25759			"aria-selected": "false",
25760			"aria-expanded": "false"
25761		});
25762		// If we're switching tabs, remove the old tab from the tab order.
vendor: 18,503 bytes, lines 25763-26453
25763		// If we're opening from collapsed state, remove the previous tab from the tab order.
25764		// If we're collapsing, then keep the collapsing tab in the tab order.
25765		if ( toShow.length && toHide.length ) {
25766			eventData.oldTab.attr( "tabIndex", -1 );
25767		} else if ( toShow.length ) {
25768			this.tabs.filter(function() {
25769				return $( this ).attr( "tabIndex" ) === 0;
25770			})
25771			.attr( "tabIndex", -1 );
25772		}
25773
25774		toShow.attr( "aria-hidden", "false" );
25775		eventData.newTab.attr({
25776			"aria-selected": "true",
25777			"aria-expanded": "true",
25778			tabIndex: 0
25779		});
25780	},
25781
25782	_activate: function( index ) {
25783		var anchor,
25784			active = this._findActive( index );
25785
25786		// trying to activate the already active panel
25787		if ( active[ 0 ] === this.active[ 0 ] ) {
25788			return;
25789		}
25790
25791		// trying to collapse, simulate a click on the current active header
25792		if ( !active.length ) {
25793			active = this.active;
25794		}
25795
25796		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
25797		this._eventHandler({
25798			target: anchor,
25799			currentTarget: anchor,
25800			preventDefault: $.noop
25801		});
25802	},
25803
25804	_findActive: function( index ) {
25805		return index === false ? $() : this.tabs.eq( index );
25806	},
25807
25808	_getIndex: function( index ) {
25809		// meta-function to give users option to provide a href string instead of a numerical index.
25810		if ( typeof index === "string" ) {
25811			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
25812		}
25813
25814		return index;
25815	},
25816
25817	_destroy: function() {
25818		if ( this.xhr ) {
25819			this.xhr.abort();
25820		}
25821
25822		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
25823
25824		this.tablist
25825			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
25826			.removeAttr( "role" );
25827
25828		this.anchors
25829			.removeClass( "ui-tabs-anchor" )
25830			.removeAttr( "role" )
25831			.removeAttr( "tabIndex" )
25832			.removeUniqueId();
25833
25834		this.tablist.unbind( this.eventNamespace );
25835
25836		this.tabs.add( this.panels ).each(function() {
25837			if ( $.data( this, "ui-tabs-destroy" ) ) {
25838				$( this ).remove();
25839			} else {
25840				$( this )
25841					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
25842						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
25843					.removeAttr( "tabIndex" )
25844					.removeAttr( "aria-live" )
25845					.removeAttr( "aria-busy" )
25846					.removeAttr( "aria-selected" )
25847					.removeAttr( "aria-labelledby" )
25848					.removeAttr( "aria-hidden" )
25849					.removeAttr( "aria-expanded" )
25850					.removeAttr( "role" );
25851			}
25852		});
25853
25854		this.tabs.each(function() {
25855			var li = $( this ),
25856				prev = li.data( "ui-tabs-aria-controls" );
25857			if ( prev ) {
25858				li
25859					.attr( "aria-controls", prev )
25860					.removeData( "ui-tabs-aria-controls" );
25861			} else {
25862				li.removeAttr( "aria-controls" );
25863			}
25864		});
25865
25866		this.panels.show();
25867
25868		if ( this.options.heightStyle !== "content" ) {
25869			this.panels.css( "height", "" );
25870		}
25871	},
25872
25873	enable: function( index ) {
25874		var disabled = this.options.disabled;
25875		if ( disabled === false ) {
25876			return;
25877		}
25878
25879		if ( index === undefined ) {
25880			disabled = false;
25881		} else {
25882			index = this._getIndex( index );
25883			if ( $.isArray( disabled ) ) {
25884				disabled = $.map( disabled, function( num ) {
25885					return num !== index ? num : null;
25886				});
25887			} else {
25888				disabled = $.map( this.tabs, function( li, num ) {
25889					return num !== index ? num : null;
25890				});
25891			}
25892		}
25893		this._setupDisabled( disabled );
25894	},
25895
25896	disable: function( index ) {
25897		var disabled = this.options.disabled;
25898		if ( disabled === true ) {
25899			return;
25900		}
25901
25902		if ( index === undefined ) {
25903			disabled = true;
25904		} else {
25905			index = this._getIndex( index );
25906			if ( $.inArray( index, disabled ) !== -1 ) {
25907				return;
25908			}
25909			if ( $.isArray( disabled ) ) {
25910				disabled = $.merge( [ index ], disabled ).sort();
25911			} else {
25912				disabled = [ index ];
25913			}
25914		}
25915		this._setupDisabled( disabled );
25916	},
25917
25918	load: function( index, event ) {
25919		index = this._getIndex( index );
25920		var that = this,
25921			tab = this.tabs.eq( index ),
25922			anchor = tab.find( ".ui-tabs-anchor" ),
25923			panel = this._getPanelForTab( tab ),
25924			eventData = {
25925				tab: tab,
25926				panel: panel
25927			},
25928			complete = function( jqXHR, status ) {
25929				if ( status === "abort" ) {
25930					that.panels.stop( false, true );
25931				}
25932
25933				tab.removeClass( "ui-tabs-loading" );
25934				panel.removeAttr( "aria-busy" );
25935
25936				if ( jqXHR === that.xhr ) {
25937					delete that.xhr;
25938				}
25939			};
25940
25941		// not remote
25942		if ( this._isLocal( anchor[ 0 ] ) ) {
25943			return;
25944		}
25945
25946		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
25947
25948		// support: jQuery <1.8
25949		// jQuery <1.8 returns false if the request is canceled in beforeSend,
25950		// but as of 1.8, $.ajax() always returns a jqXHR object.
25951		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
25952			tab.addClass( "ui-tabs-loading" );
25953			panel.attr( "aria-busy", "true" );
25954
25955			this.xhr
25956				.done(function( response, status, jqXHR ) {
25957					// support: jQuery <1.8
25958					// http://bugs.jquery.com/ticket/11778
25959					setTimeout(function() {
25960						panel.html( response );
25961						that._trigger( "load", event, eventData );
25962
25963						complete( jqXHR, status );
25964					}, 1 );
25965				})
25966				.fail(function( jqXHR, status ) {
25967					// support: jQuery <1.8
25968					// http://bugs.jquery.com/ticket/11778
25969					setTimeout(function() {
25970						complete( jqXHR, status );
25971					}, 1 );
25972				});
25973		}
25974	},
25975
25976	_ajaxSettings: function( anchor, event, eventData ) {
25977		var that = this;
25978		return {
25979			url: anchor.attr( "href" ),
25980			beforeSend: function( jqXHR, settings ) {
25981				return that._trigger( "beforeLoad", event,
25982					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
25983			}
25984		};
25985	},
25986
25987	_getPanelForTab: function( tab ) {
25988		var id = $( tab ).attr( "aria-controls" );
25989		return this.element.find( this._sanitizeSelector( "#" + id ) );
25990	}
25991});
25992
25993
25994/*!
25995 * jQuery UI Tooltip 1.11.4
25996 * http://jqueryui.com
25997 *
25998 * Copyright jQuery Foundation and other contributors
25999 * Released under the MIT license.
26000 * http://jquery.org/license
26001 *
26002 * http://api.jqueryui.com/tooltip/
26003 */
26004
26005
26006var tooltip = $.widget( "ui.tooltip", {
26007	version: "1.11.4",
26008	options: {
26009		content: function() {
26010			// support: IE<9, Opera in jQuery <1.7
26011			// .text() can't accept undefined, so coerce to a string
26012			var title = $( this ).attr( "title" ) || "";
26013			// Escape title, since we're going from an attribute to raw HTML
26014			return $( "<a>" ).text( title ).html();
26015		},
26016		hide: true,
26017		// Disabled elements have inconsistent behavior across browsers (#8661)
26018		items: "[title]:not([disabled])",
26019		position: {
26020			my: "left top+15",
26021			at: "left bottom",
26022			collision: "flipfit flip"
26023		},
26024		show: true,
26025		tooltipClass: null,
26026		track: false,
26027
26028		// callbacks
26029		close: null,
26030		open: null
26031	},
26032
26033	_addDescribedBy: function( elem, id ) {
26034		var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
26035		describedby.push( id );
26036		elem
26037			.data( "ui-tooltip-id", id )
26038			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
26039	},
26040
26041	_removeDescribedBy: function( elem ) {
26042		var id = elem.data( "ui-tooltip-id" ),
26043			describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
26044			index = $.inArray( id, describedby );
26045
26046		if ( index !== -1 ) {
26047			describedby.splice( index, 1 );
26048		}
26049
26050		elem.removeData( "ui-tooltip-id" );
26051		describedby = $.trim( describedby.join( " " ) );
26052		if ( describedby ) {
26053			elem.attr( "aria-describedby", describedby );
26054		} else {
26055			elem.removeAttr( "aria-describedby" );
26056		}
26057	},
26058
26059	_create: function() {
26060		this._on({
26061			mouseover: "open",
26062			focusin: "open"
26063		});
26064
26065		// IDs of generated tooltips, needed for destroy
26066		this.tooltips = {};
26067
26068		// IDs of parent tooltips where we removed the title attribute
26069		this.parents = {};
26070
26071		if ( this.options.disabled ) {
26072			this._disable();
26073		}
26074
26075		// Append the aria-live region so tooltips announce correctly
26076		this.liveRegion = $( "<div>" )
26077			.attr({
26078				role: "log",
26079				"aria-live": "assertive",
26080				"aria-relevant": "additions"
26081			})
26082			.addClass( "ui-helper-hidden-accessible" )
26083			.appendTo( this.document[ 0 ].body );
26084	},
26085
26086	_setOption: function( key, value ) {
26087		var that = this;
26088
26089		if ( key === "disabled" ) {
26090			this[ value ? "_disable" : "_enable" ]();
26091			this.options[ key ] = value;
26092			// disable element style changes
26093			return;
26094		}
26095
26096		this._super( key, value );
26097
26098		if ( key === "content" ) {
26099			$.each( this.tooltips, function( id, tooltipData ) {
26100				that._updateContent( tooltipData.element );
26101			});
26102		}
26103	},
26104
26105	_disable: function() {
26106		var that = this;
26107
26108		// close open tooltips
26109		$.each( this.tooltips, function( id, tooltipData ) {
26110			var event = $.Event( "blur" );
26111			event.target = event.currentTarget = tooltipData.element[ 0 ];
26112			that.close( event, true );
26113		});
26114
26115		// remove title attributes to prevent native tooltips
26116		this.element.find( this.options.items ).addBack().each(function() {
26117			var element = $( this );
26118			if ( element.is( "[title]" ) ) {
26119				element
26120					.data( "ui-tooltip-title", element.attr( "title" ) )
26121					.removeAttr( "title" );
26122			}
26123		});
26124	},
26125
26126	_enable: function() {
26127		// restore title attributes
26128		this.element.find( this.options.items ).addBack().each(function() {
26129			var element = $( this );
26130			if ( element.data( "ui-tooltip-title" ) ) {
26131				element.attr( "title", element.data( "ui-tooltip-title" ) );
26132			}
26133		});
26134	},
26135
26136	open: function( event ) {
26137		var that = this,
26138			target = $( event ? event.target : this.element )
26139				// we need closest here due to mouseover bubbling,
26140				// but always pointing at the same event target
26141				.closest( this.options.items );
26142
26143		// No element to show a tooltip for or the tooltip is already open
26144		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
26145			return;
26146		}
26147
26148		if ( target.attr( "title" ) ) {
26149			target.data( "ui-tooltip-title", target.attr( "title" ) );
26150		}
26151
26152		target.data( "ui-tooltip-open", true );
26153
26154		// kill parent tooltips, custom or native, for hover
26155		if ( event && event.type === "mouseover" ) {
26156			target.parents().each(function() {
26157				var parent = $( this ),
26158					blurEvent;
26159				if ( parent.data( "ui-tooltip-open" ) ) {
26160					blurEvent = $.Event( "blur" );
26161					blurEvent.target = blurEvent.currentTarget = this;
26162					that.close( blurEvent, true );
26163				}
26164				if ( parent.attr( "title" ) ) {
26165					parent.uniqueId();
26166					that.parents[ this.id ] = {
26167						element: this,
26168						title: parent.attr( "title" )
26169					};
26170					parent.attr( "title", "" );
26171				}
26172			});
26173		}
26174
26175		this._registerCloseHandlers( event, target );
26176		this._updateContent( target, event );
26177	},
26178
26179	_updateContent: function( target, event ) {
26180		var content,
26181			contentOption = this.options.content,
26182			that = this,
26183			eventType = event ? event.type : null;
26184
26185		if ( typeof contentOption === "string" ) {
26186			return this._open( event, target, contentOption );
26187		}
26188
26189		content = contentOption.call( target[0], function( response ) {
26190
26191			// IE may instantly serve a cached response for ajax requests
26192			// delay this call to _open so the other call to _open runs first
26193			that._delay(function() {
26194
26195				// Ignore async response if tooltip was closed already
26196				if ( !target.data( "ui-tooltip-open" ) ) {
26197					return;
26198				}
26199
26200				// jQuery creates a special event for focusin when it doesn't
26201				// exist natively. To improve performance, the native event
26202				// object is reused and the type is changed. Therefore, we can't
26203				// rely on the type being correct after the event finished
26204				// bubbling, so we set it back to the previous value. (#8740)
26205				if ( event ) {
26206					event.type = eventType;
26207				}
26208				this._open( event, target, response );
26209			});
26210		});
26211		if ( content ) {
26212			this._open( event, target, content );
26213		}
26214	},
26215
26216	_open: function( event, target, content ) {
26217		var tooltipData, tooltip, delayedShow, a11yContent,
26218			positionOption = $.extend( {}, this.options.position );
26219
26220		if ( !content ) {
26221			return;
26222		}
26223
26224		// Content can be updated multiple times. If the tooltip already
26225		// exists, then just update the content and bail.
26226		tooltipData = this._find( target );
26227		if ( tooltipData ) {
26228			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
26229			return;
26230		}
26231
26232		// if we have a title, clear it to prevent the native tooltip
26233		// we have to check first to avoid defining a title if none exists
26234		// (we don't want to cause an element to start matching [title])
26235		//
26236		// We use removeAttr only for key events, to allow IE to export the correct
26237		// accessible attributes. For mouse events, set to empty string to avoid
26238		// native tooltip showing up (happens only when removing inside mouseover).
26239		if ( target.is( "[title]" ) ) {
26240			if ( event && event.type === "mouseover" ) {
26241				target.attr( "title", "" );
26242			} else {
26243				target.removeAttr( "title" );
26244			}
26245		}
26246
26247		tooltipData = this._tooltip( target );
26248		tooltip = tooltipData.tooltip;
26249		this._addDescribedBy( target, tooltip.attr( "id" ) );
26250		tooltip.find( ".ui-tooltip-content" ).html( content );
26251
26252		// Support: Voiceover on OS X, JAWS on IE <= 9
26253		// JAWS announces deletions even when aria-relevant="additions"
26254		// Voiceover will sometimes re-read the entire log region's contents from the beginning
26255		this.liveRegion.children().hide();
26256		if ( content.clone ) {
26257			a11yContent = content.clone();
26258			a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
26259		} else {
26260			a11yContent = content;
26261		}
26262		$( "<div>" ).html( a11yContent ).appendTo( this.liveRegion );
26263
26264		function position( event ) {
26265			positionOption.of = event;
26266			if ( tooltip.is( ":hidden" ) ) {
26267				return;
26268			}
26269			tooltip.position( positionOption );
26270		}
26271		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
26272			this._on( this.document, {
26273				mousemove: position
26274			});
26275			// trigger once to override element-relative positioning
26276			position( event );
26277		} else {
26278			tooltip.position( $.extend({
26279				of: target
26280			}, this.options.position ) );
26281		}
26282
26283		tooltip.hide();
26284
26285		this._show( tooltip, this.options.show );
26286		// Handle tracking tooltips that are shown with a delay (#8644). As soon
26287		// as the tooltip is visible, position the tooltip using the most recent
26288		// event.
26289		if ( this.options.show && this.options.show.delay ) {
26290			delayedShow = this.delayedShow = setInterval(function() {
26291				if ( tooltip.is( ":visible" ) ) {
26292					position( positionOption.of );
26293					clearInterval( delayedShow );
26294				}
26295			}, $.fx.interval );
26296		}
26297
26298		this._trigger( "open", event, { tooltip: tooltip } );
26299	},
26300
26301	_registerCloseHandlers: function( event, target ) {
26302		var events = {
26303			keyup: function( event ) {
26304				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
26305					var fakeEvent = $.Event(event);
26306					fakeEvent.currentTarget = target[0];
26307					this.close( fakeEvent, true );
26308				}
26309			}
26310		};
26311
26312		// Only bind remove handler for delegated targets. Non-delegated
26313		// tooltips will handle this in destroy.
26314		if ( target[ 0 ] !== this.element[ 0 ] ) {
26315			events.remove = function() {
26316				this._removeTooltip( this._find( target ).tooltip );
26317			};
26318		}
26319
26320		if ( !event || event.type === "mouseover" ) {
26321			events.mouseleave = "close";
26322		}
26323		if ( !event || event.type === "focusin" ) {
26324			events.focusout = "close";
26325		}
26326		this._on( true, target, events );
26327	},
26328
26329	close: function( event ) {
26330		var tooltip,
26331			that = this,
26332			target = $( event ? event.currentTarget : this.element ),
26333			tooltipData = this._find( target );
26334
26335		// The tooltip may already be closed
26336		if ( !tooltipData ) {
26337
26338			// We set ui-tooltip-open immediately upon open (in open()), but only set the
26339			// additional data once there's actually content to show (in _open()). So even if the
26340			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
26341			// the period between open() and _open().
26342			target.removeData( "ui-tooltip-open" );
26343			return;
26344		}
26345
26346		tooltip = tooltipData.tooltip;
26347
26348		// disabling closes the tooltip, so we need to track when we're closing
26349		// to avoid an infinite loop in case the tooltip becomes disabled on close
26350		if ( tooltipData.closing ) {
26351			return;
26352		}
26353
26354		// Clear the interval for delayed tracking tooltips
26355		clearInterval( this.delayedShow );
26356
26357		// only set title if we had one before (see comment in _open())
26358		// If the title attribute has changed since open(), don't restore
26359		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
26360			target.attr( "title", target.data( "ui-tooltip-title" ) );
26361		}
26362
26363		this._removeDescribedBy( target );
26364
26365		tooltipData.hiding = true;
26366		tooltip.stop( true );
26367		this._hide( tooltip, this.options.hide, function() {
26368			that._removeTooltip( $( this ) );
26369		});
26370
26371		target.removeData( "ui-tooltip-open" );
26372		this._off( target, "mouseleave focusout keyup" );
26373
26374		// Remove 'remove' binding only on delegated targets
26375		if ( target[ 0 ] !== this.element[ 0 ] ) {
26376			this._off( target, "remove" );
26377		}
26378		this._off( this.document, "mousemove" );
26379
26380		if ( event && event.type === "mouseleave" ) {
26381			$.each( this.parents, function( id, parent ) {
26382				$( parent.element ).attr( "title", parent.title );
26383				delete that.parents[ id ];
26384			});
26385		}
26386
26387		tooltipData.closing = true;
26388		this._trigger( "close", event, { tooltip: tooltip } );
26389		if ( !tooltipData.hiding ) {
26390			tooltipData.closing = false;
26391		}
26392	},
26393
26394	_tooltip: function( element ) {
26395		var tooltip = $( "<div>" )
26396				.attr( "role", "tooltip" )
26397				.addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
26398					( this.options.tooltipClass || "" ) ),
26399			id = tooltip.uniqueId().attr( "id" );
26400
26401		$( "<div>" )
26402			.addClass( "ui-tooltip-content" )
26403			.appendTo( tooltip );
26404
26405		tooltip.appendTo( this.document[0].body );
26406
26407		return this.tooltips[ id ] = {
26408			element: element,
26409			tooltip: tooltip
26410		};
26411	},
26412
26413	_find: function( target ) {
26414		var id = target.data( "ui-tooltip-id" );
26415		return id ? this.tooltips[ id ] : null;
26416	},
26417
26418	_removeTooltip: function( tooltip ) {
26419		tooltip.remove();
26420		delete this.tooltips[ tooltip.attr( "id" ) ];
26421	},
26422
26423	_destroy: function() {
26424		var that = this;
26425
26426		// close open tooltips
26427		$.each( this.tooltips, function( id, tooltipData ) {
26428			// Delegate to close method to handle common cleanup
26429			var event = $.Event( "blur" ),
26430				element = tooltipData.element;
26431			event.target = event.currentTarget = element[ 0 ];
26432			that.close( event, true );
26433
26434			// Remove immediately; destroying an open tooltip doesn't use the
26435			// hide animation
26436			$( "#" + id ).remove();
26437
26438			// Restore the title
26439			if ( element.data( "ui-tooltip-title" ) ) {
26440				// If the title attribute has changed since open(), don't restore
26441				if ( !element.attr( "title" ) ) {
26442					element.attr( "title", element.data( "ui-tooltip-title" ) );
26443				}
26444				element.removeData( "ui-tooltip-title" );
26445			}
26446		});
26447		this.liveRegion.remove();
26448	}
26449});
26450
26451
26452
26453}));
26453
26454/* German initialisation for the jQuery UI date picker plugin. */
26455/* Written by Milian Wolff ([email protected]). */
26456(function( factory ) {
26457	if ( typeof define === "function" && define.amd ) {
26458
26459		// AMD. Register as an anonymous module.
26460		define([ "../datepicker" ], factory );
26461	} else {
26462
26463		// Browser globals
26464		factory( jQuery.datepicker );
26465	}
26466}(function( datepicker ) {
26467
26468datepicker.regional['de'] = {
26469	closeText: 'Schließen',
26470	prevText: '&#x3C;Zurück',
26471	nextText: 'Vor&#x3E;',
26472	currentText: 'Heute',
26473	monthNames: ['Januar','Februar','März','April','Mai','Juni',
26474	'Juli','August','September','Oktober','November','Dezember'],
26475	monthNamesShort: ['Jan','Feb','Mär','Apr','Mai','Jun',
26476	'Jul','Aug','Sep','Okt','Nov','Dez'],
26477	dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],
26478	dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],
26479	dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],
26480	weekHeader: 'KW',
26481	dateFormat: 'dd.mm.yy',
26482	firstDay: 1,
26483	isRTL: false,
26484	showMonthAfterYear: false,
26485	yearSuffix: ''};
26486datepicker.setDefaults(datepicker.regional['de']);
26487
26488return datepicker.regional['de'];
26489
26490}));
26491
26492var ARC = function(params) {
26493    var canvas  = params.element || document.createElement('canvas');
26494    var context = canvas.getContext('2d');
26495
26496    params = jQuery.extend(params, canvas.dataset);
26497
26498    // Make sure the render size is correct.
26499    var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
26500    canvas.width  = canvas.getBoundingClientRect().width;
26501    canvas.height = canvas.getBoundingClientRect().height;
26502    context.putImageData(imageData, 0, 0);
26503
26504    // Clear the canvas if told to do so.
26505    if (params.clear) {
26506        context.clearRect(0, 0, canvas.width, canvas.height);
26507    }
26508
26509    // Helper to convert degree to radians.
26510    var deg2rad = function(deg) {
26511        return deg * (Math.PI / 180);
26512    };
26513
26514    // Used to rotate the arc.
26515    var shift = deg2rad(params.start || 0);
26516
26517    // Calculate radius.
26518    var radius = params.radius || Math.min(canvas.width, canvas.height) / 2;
26519
26520    // Calculate thickness.
26521    var thickness = radius * ((params.thickness || 20) / 100);
26522
26523    // Draws an arc.
26524    var drawArc = function(angle, color, fill) {
26525        context.beginPath();
26526        context.lineWidth = thickness;
26527        context.arc(
26528            params.x || canvas.width  / 2,
26529            params.y || canvas.height / 2,
26530            radius - thickness / 2,
26531            shift,
26532            deg2rad(angle) + shift,
26533            fill
26534        );
26535        context.strokeStyle = color;
26536        context.stroke();
26537        context.closePath();
26538    };
26539
26540    // Draw filler.
26541    if (params.fillcolor != null) {
26542        context.beginPath();
26543        context.arc(
26544            params.x || canvas.width  / 2,
26545            params.y || canvas.height / 2,
26546            radius - thickness + 1,
26547            0, 2 * Math.PI
26548        );
26549        context.fillStyle = params.fillcolor;
26550        context.fill();
26551        context.closePath();
26552    }
26553
26554    // Draw back color.
26555    if (params.backcolor != null && params.angle < 360) {
26556        drawArc(params.angle, params.backcolor, true);
26557    }
26558
26559    // Draw front color.
26560    if (params.angle > 0) {
26561        drawArc(params.angle, params.forecolor, false);
26562    }
26563
26564    return canvas;
26565};
26566$(function() {
26567    // Helper to create nice bootstrap forms with javascript.
26568    var createForm = function(configuration, docroot, images) {
26569        var formId = "form-generated-" + Date.now();
26570
26571        var form = $('<form/>').on('submit', function(event) {
26572            event.preventDefault();
26573        });
26574
26575        for (var name in configuration) {
26576            var element = configuration[name];
26577
26578            var group = $('<fieldset/>').addClass('form-group').appendTo(form);
26579            var label = $('<label/>').attr('for', formId + '-' + name).html(element.label).appendTo(group);
26580
26581            var input;
26582
26583            if (element.type === 'password') {
26584                input = $('<input/>').attr('type', 'password').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
26585            } else if (element.type === 'varchar') {
26586                input = $('<input/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
26587            } else if (element.type === 'select') {
26588                input = $('<select/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
26589
26590                element.values.forEach(function(value) {
26591                    $('<option/>').html(value).appendTo(input);
26592                });
26593            } else if (element.type === 'image') {
26594                input = $('<select/>').attr('data-type', 'image').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
26595
26596                $('<option/>').appendTo(input);
26597
26598                images.forEach(function(value) {
26599                    $('<option/>').attr('value', value).html(value.substr(7)).appendTo(input);
26600                });
26601
26602                var wrapper = $('<div/>').addClass('row').append(group.children()).appendTo(group);
26603                var left = $('<div/>').addClass('col-xs-6').append(wrapper.children()).appendTo(wrapper);
26604                var right = $('<div/>').addClass('col-xs-6').appendTo(wrapper);
26605
26606                input.change(function() {
26607                    $(this).parent().next().css({
26608                        backgroundImage: 'url(' + docroot + 'assets/images/' + $(this).val() + ')',
26609                        backgroundSize: 'contain',
26610                        backgroundPosition: 'center center',
26611                        backgroundRepeat: 'no-repeat'
26612                    });
26613                });
26614
26615            } else if (element.type === 'text') {
26616                input = $('<textarea/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
26617            }
26618        }
26619
26620        return form;
26621    };
26622
26623    // Helper to create a modal containing a form.
26624    var createFormModal = function(configuration) {
26625        var modal   = $('<div/>').addClass('modal fade'   );
26626        var dialog  = $('<div/>').addClass('modal-dialog' ).appendTo(modal  );
26627        var content = $('<div/>').addClass('modal-content').appendTo(dialog );
26628        var header  = $('<div/>').addClass('modal-header' ).appendTo(content);
26629        var title   = $('<h4/>' ).addClass('modal-title'  ).appendTo(header );
26630        var body    = $('<div/>').addClass('modal-body'   ).appendTo(content);
26631        var footer  = $('<div/>').addClass('modal-footer' ).appendTo(content);
26632
26633        title.html(configuration.title);
26634
26635        body.append(createForm(configuration.form));
26636
26637        configuration.buttons.forEach(function(button) {
26638            $('<button/>').addClass('btn btn-' + button.type).html(button.label).on('click', button.action).appendTo(footer);
26639        });
26640
26641        modal.appendTo('body').modal({ keyboard: false }).on('hidden.bs.modal', function(event) {
26642            $(this).remove();
26643        });
26644
26645        return modal;
26646    };
26647
26648    var showLoginWindow = function() {
26649        createFormModal({
26650            title: 'Login',
26651            form: {
26652                password: { label: 'Password', type: 'password' }
26653            },
26654            buttons: [
26655                { label: 'Login', type: 'primary', action: function(event) {
26656                    var parts = $('body').data('editor').split('::');
26657
26658                    var url = parts[0];
26659                    var dataFile = parts[1];
26660                    var modal = $(this).parents('.modal');
26661                    var password = modal.find('input').val();
26662
26663                    $.post(url, $(this).parents('.modal').find('form').serialize() + '&dataFile=' + dataFile, function(response) {
26664                        // In this scope will the private script be called.
26665                        eval(response);
26666                    });
26667                } },
26668                { label: 'Close', type: 'danger', action: function(event) {
26669                    $(this).parents('.modal').modal('hide');
26670                } }
26671            ]
26672        });
26673    };
26674
26675    if (document.body.hasAttribute('data-editor')) {
26676        $(window).on('keypress', function(event) {
26677            if ((event.which === 28 || event.which === 35) && event.ctrlKey && $('body > .modal').length == 0) {
26678                event.preventDefault();
26679                showLoginWindow();
26680            }
26681        })
26682    }
26683});
26684
26685
26686
26687//-------------------------------------------\\
26688// Bootstrap (disable unused ones)           \\
26689// ------------------------------------------\\
26690
26691/**
26692 * --------------------------------------------------------------------------
26693 * Bootstrap (v4.0.0-alpha.2): util.js
26694 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
26695 * --------------------------------------------------------------------------
26696 */
26697
26698'use strict';
26699
26700var Util = (function ($) {
26701
26702  /**
26703   * ------------------------------------------------------------------------
26704   * Private TransitionEnd Helpers
26705   * ------------------------------------------------------------------------
26706   */
26707
26708  var transition = false;
26709
26710  var TransitionEndEvent = {
26711    WebkitTransition: 'webkitTransitionEnd',
26712    MozTransition: 'transitionend',
26713    OTransition: 'oTransitionEnd otransitionend',
26714    transition: 'transitionend'
26715  };
26716
26717  // shoutout AngusCroll (https://goo.gl/pxwQGp)
26718  function toType(obj) {
26719    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
26720  }
26721
26722  function isElement(obj) {
26723    return (obj[0] || obj).nodeType;
26724  }
26725
26726  function getSpecialTransitionEndEvent() {
26727    return {
26728      bindType: transition.end,
26729      delegateType: transition.end,
26730      handle: function handle(event) {
26731        if ($(event.target).is(this)) {
26732          return event.handleObj.handler.apply(this, arguments);
26733        }
26734      }
26735    };
26736  }
26737
26738  function transitionEndTest() {
26739    if (window.QUnit) {
26740      return false;
26741    }
26742
26743    var el = document.createElement('bootstrap');
26744
26745    for (var _name in TransitionEndEvent) {
26746      if (el.style[_name] !== undefined) {
26747        return { end: TransitionEndEvent[_name] };
26748      }
26749    }
26750
26751    return false;
26752  }
26753
26754  function transitionEndEmulator(duration) {
26755    var _this = this;
26756
26757    var called = false;
26758
26759    $(this).one(Util.TRANSITION_END, function () {
26760      called = true;
26761    });
26762
26763    setTimeout(function () {
26764      if (!called) {
26765        Util.triggerTransitionEnd(_this);
26766      }
26767    }, duration);
26768
26769    return this;
26770  }
26771
26772  function setTransitionEndSupport() {
26773    transition = transitionEndTest();
26774
26775    $.fn.emulateTransitionEnd = transitionEndEmulator;
26776
26777    if (Util.supportsTransitionEnd()) {
26778      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
26779    }
26780  }
26781
26782  /**
26783   * --------------------------------------------------------------------------
26784   * Public Util Api
26785   * --------------------------------------------------------------------------
26786   */
26787
26788  var Util = {
26789
26790    TRANSITION_END: 'bsTransitionEnd',
26791
26792    getUID: function getUID(prefix) {
26793      do {
26794        prefix += ~ ~(Math.random() * 1000000); // "~~" acts like a faster Math.floor() here
26795      } while (document.getElementById(prefix));
26796      return prefix;
26797    },
26798
26799    getSelectorFromElement: function getSelectorFromElement(element) {
26800      var selector = element.getAttribute('data-target');
26801
26802      if (!selector) {
26803        selector = element.getAttribute('href') || '';
26804        selector = /^#[a-z]/i.test(selector) ? selector : null;
26805      }
26806
26807      return selector;
26808    },
26809
26810    reflow: function reflow(element) {
26811      new Function('bs', 'return bs')(element.offsetHeight);
26812    },
26813
26814    triggerTransitionEnd: function triggerTransitionEnd(element) {
26815      $(element).trigger(transition.end);
26816    },
26817
26818    supportsTransitionEnd: function supportsTransitionEnd() {
26819      return Boolean(transition);
26820    },
26821
26822    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
26823      for (var property in configTypes) {
26824        if (configTypes.hasOwnProperty(property)) {
26825          var expectedTypes = configTypes[property];
26826          var value = config[property];
26827          var valueType = undefined;
26828
26829          if (value && isElement(value)) {
26830            valueType = 'element';
26831          } else {
26832            valueType = toType(value);
26833          }
26834
26835          if (!new RegExp(expectedTypes).test(valueType)) {
26836            throw new Error(componentName.toUpperCase() + ': ' + ('Option "' + property + '" provided type "' + valueType + '" ') + ('but expected type "' + expectedTypes + '".'));
26837          }
26838        }
26839      }
26840    }
26841  };
26842
26843  setTransitionEndSupport();
26844
26845  return Util;
26846})(jQuery);
26847//# sourceMappingURL=util.js.map
26848
26849//require('../../vendor/twitter/bootstrap/js/dist/alert');
26850//require('../../vendor/twitter/bootstrap/js/dist/button');
26851'use strict';
26852
26853var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
26854
26855function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
26856
26857/**
26858 * --------------------------------------------------------------------------
26859 * Bootstrap (v4.0.0-alpha.2): carousel.js
26860 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
26861 * --------------------------------------------------------------------------
26862 */
26863
26864var Carousel = (function ($) {
26865
26866  /**
26867   * ------------------------------------------------------------------------
26868   * Constants
26869   * ------------------------------------------------------------------------
26870   */
26871
26872  var NAME = 'carousel';
26873  var VERSION = '4.0.0-alpha';
26874  var DATA_KEY = 'bs.carousel';
26875  var EVENT_KEY = '.' + DATA_KEY;
26876  var DATA_API_KEY = '.data-api';
26877  var JQUERY_NO_CONFLICT = $.fn[NAME];
26878  var TRANSITION_DURATION = 600;
26879
26880  var Default = {
26881    interval: 5000,
26882    keyboard: true,
26883    slide: false,
26884    pause: 'hover',
26885    wrap: true
26886  };
26887
26888  var DefaultType = {
26889    interval: '(number|boolean)',
26890    keyboard: 'boolean',
26891    slide: '(boolean|string)',
26892    pause: '(string|boolean)',
26893    wrap: 'boolean'
26894  };
26895
26896  var Direction = {
26897    NEXT: 'next',
26898    PREVIOUS: 'prev'
26899  };
26900
26901  var Event = {
26902    SLIDE: 'slide' + EVENT_KEY,
26903    SLID: 'slid' + EVENT_KEY,
26904    KEYDOWN: 'keydown' + EVENT_KEY,
26905    MOUSEENTER: 'mouseenter' + EVENT_KEY,
26906    MOUSELEAVE: 'mouseleave' + EVENT_KEY,
26907    LOAD_DATA_API: 'load' + EVENT_KEY + DATA_API_KEY,
26908    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
26909  };
26910
26911  var ClassName = {
26912    CAROUSEL: 'carousel',
26913    ACTIVE: 'active',
26914    SLIDE: 'slide',
26915    RIGHT: 'right',
26916    LEFT: 'left',
26917    ITEM: 'carousel-item'
26918  };
26919
26920  var Selector = {
26921    ACTIVE: '.active',
26922    ACTIVE_ITEM: '.active.carousel-item',
26923    ITEM: '.carousel-item',
26924    NEXT_PREV: '.next, .prev',
26925    INDICATORS: '.carousel-indicators',
26926    DATA_SLIDE: '[data-slide], [data-slide-to]',
26927    DATA_RIDE: '[data-ride="carousel"]'
26928  };
26929
26930  /**
26931   * ------------------------------------------------------------------------
26932   * Class Definition
26933   * ------------------------------------------------------------------------
26934   */
26935
26936  var Carousel = (function () {
26937    function Carousel(element, config) {
26938      _classCallCheck(this, Carousel);
26939
26940      this._items = null;
26941      this._interval = null;
26942      this._activeElement = null;
26943
26944      this._isPaused = false;
26945      this._isSliding = false;
26946
26947      this._config = this._getConfig(config);
26948      this._element = $(element)[0];
26949      this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0];
26950
26951      this._addEventListeners();
26952    }
26953
26954    /**
26955     * ------------------------------------------------------------------------
26956     * Data Api implementation
26957     * ------------------------------------------------------------------------
26958     */
26959
26960    // getters
26961
26962    _createClass(Carousel, [{
26963      key: 'next',
26964
26965      // public
26966
26967      value: function next() {
26968        if (!this._isSliding) {
26969          this._slide(Direction.NEXT);
26970        }
26971      }
26972    }, {
26973      key: 'nextWhenVisible',
26974      value: function nextWhenVisible() {
26975        // Don't call next when the page isn't visible
26976        if (!document.hidden) {
26977          this.next();
26978        }
26979      }
26980    }, {
26981      key: 'prev',
26982      value: function prev() {
26983        if (!this._isSliding) {
26984          this._slide(Direction.PREVIOUS);
26985        }
26986      }
26987    }, {
26988      key: 'pause',
26989      value: function pause(event) {
26990        if (!event) {
26991          this._isPaused = true;
26992        }
26993
26994        if ($(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) {
26995          Util.triggerTransitionEnd(this._element);
26996          this.cycle(true);
26997        }
26998
26999        clearInterval(this._interval);
27000        this._interval = null;
27001      }
27002    }, {
27003      key: 'cycle',
27004      value: function cycle(event) {
27005        if (!event) {
27006          this._isPaused = false;
27007        }
27008
27009        if (this._interval) {
27010          clearInterval(this._interval);
27011          this._interval = null;
27012        }
27013
27014        if (this._config.interval && !this._isPaused) {
27015          this._interval = setInterval($.proxy(document.visibilityState ? this.nextWhenVisible : this.next, this), this._config.interval);
27016        }
27017      }
27018    }, {
27019      key: 'to',
27020      value: function to(index) {
27021        var _this = this;
27022
27023        this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
27024
27025        var activeIndex = this._getItemIndex(this._activeElement);
27026
27027        if (index > this._items.length - 1 || index < 0) {
27028          return;
27029        }
27030
27031        if (this._isSliding) {
27032          $(this._element).one(Event.SLID, function () {
27033            return _this.to(index);
27034          });
27035          return;
27036        }
27037
27038        if (activeIndex === index) {
27039          this.pause();
27040          this.cycle();
27041          return;
27042        }
27043
27044        var direction = index > activeIndex ? Direction.NEXT : Direction.PREVIOUS;
27045
27046        this._slide(direction, this._items[index]);
27047      }
27048    }, {
27049      key: 'dispose',
27050      value: function dispose() {
27051        $(this._element).off(EVENT_KEY);
27052        $.removeData(this._element, DATA_KEY);
27053
27054        this._items = null;
27055        this._config = null;
27056        this._element = null;
27057        this._interval = null;
27058        this._isPaused = null;
27059        this._isSliding = null;
27060        this._activeElement = null;
27061        this._indicatorsElement = null;
27062      }
27063
27064      // private
27065
27066    }, {
27067      key: '_getConfig',
27068      value: function _getConfig(config) {
27069        config = $.extend({}, Default, config);
27070        Util.typeCheckConfig(NAME, config, DefaultType);
27071        return config;
27072      }
27073    }, {
27074      key: '_addEventListeners',
27075      value: function _addEventListeners() {
27076        if (this._config.keyboard) {
27077          $(this._element).on(Event.KEYDOWN, $.proxy(this._keydown, this));
27078        }
27079
27080        if (this._config.pause === 'hover' && !('ontouchstart' in document.documentElement)) {
27081          $(this._element).on(Event.MOUSEENTER, $.proxy(this.pause, this)).on(Event.MOUSELEAVE, $.proxy(this.cycle, this));
27082        }
27083      }
27084    }, {
27085      key: '_keydown',
27086      value: function _keydown(event) {
27087        event.preventDefault();
27088
27089        if (/input|textarea/i.test(event.target.tagName)) {
27090          return;
27091        }
27092
27093        switch (event.which) {
27094          case 37:
27095            this.prev();break;
27096          case 39:
27097            this.next();break;
27098          default:
27099            return;
27100        }
27101      }
27102    }, {
27103      key: '_getItemIndex',
27104      value: function _getItemIndex(element) {
27105        this._items = $.makeArray($(element).parent().find(Selector.ITEM));
27106        return this._items.indexOf(element);
27107      }
27108    }, {
27109      key: '_getItemByDirection',
27110      value: function _getItemByDirection(direction, activeElement) {
27111        var isNextDirection = direction === Direction.NEXT;
27112        var isPrevDirection = direction === Direction.PREVIOUS;
27113        var activeIndex = this._getItemIndex(activeElement);
27114        var lastItemIndex = this._items.length - 1;
27115        var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
27116
27117        if (isGoingToWrap && !this._config.wrap) {
27118          return activeElement;
27119        }
27120
27121        var delta = direction === Direction.PREVIOUS ? -1 : 1;
27122        var itemIndex = (activeIndex + delta) % this._items.length;
27123
27124        return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
27125      }
27126    }, {
27127      key: '_triggerSlideEvent',
27128      value: function _triggerSlideEvent(relatedTarget, directionalClassname) {
27129        var slideEvent = $.Event(Event.SLIDE, {
27130          relatedTarget: relatedTarget,
27131          direction: directionalClassname
27132        });
27133
27134        $(this._element).trigger(slideEvent);
27135
27136        return slideEvent;
27137      }
27138    }, {
27139      key: '_setActiveIndicatorElement',
27140      value: function _setActiveIndicatorElement(element) {
27141        if (this._indicatorsElement) {
27142          $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
27143
27144          var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
27145
27146          if (nextIndicator) {
27147            $(nextIndicator).addClass(ClassName.ACTIVE);
27148          }
27149        }
27150      }
27151    }, {
27152      key: '_slide',
27153      value: function _slide(direction, element) {
27154        var _this2 = this;
27155
27156        var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
27157        var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
27158
27159        var isCycling = Boolean(this._interval);
27160
27161        var directionalClassName = direction === Direction.NEXT ? ClassName.LEFT : ClassName.RIGHT;
27162
27163        if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
27164          this._isSliding = false;
27165          return;
27166        }
27167
27168        var slideEvent = this._triggerSlideEvent(nextElement, directionalClassName);
27169        if (slideEvent.isDefaultPrevented()) {
27170          return;
27171        }
27172
27173        if (!activeElement || !nextElement) {
27174          // some weirdness is happening, so we bail
27175          return;
27176        }
27177
27178        this._isSliding = true;
27179
27180        if (isCycling) {
27181          this.pause();
27182        }
27183
27184        this._setActiveIndicatorElement(nextElement);
27185
27186        var slidEvent = $.Event(Event.SLID, {
27187          relatedTarget: nextElement,
27188          direction: directionalClassName
27189        });
27190
27191        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
27192
27193          $(nextElement).addClass(direction);
27194
27195          Util.reflow(nextElement);
27196
27197          $(activeElement).addClass(directionalClassName);
27198          $(nextElement).addClass(directionalClassName);
27199
27200          $(activeElement).one(Util.TRANSITION_END, function () {
27201            $(nextElement).removeClass(directionalClassName).removeClass(direction);
27202
27203            $(nextElement).addClass(ClassName.ACTIVE);
27204
27205            $(activeElement).removeClass(ClassName.ACTIVE).removeClass(direction).removeClass(directionalClassName);
27206
27207            _this2._isSliding = false;
27208
27209            setTimeout(function () {
27210              return $(_this2._element).trigger(slidEvent);
27211            }, 0);
27212          }).emulateTransitionEnd(TRANSITION_DURATION);
27213        } else {
27214          $(activeElement).removeClass(ClassName.ACTIVE);
27215          $(nextElement).addClass(ClassName.ACTIVE);
27216
27217          this._isSliding = false;
27218          $(this._element).trigger(slidEvent);
27219        }
27220
27221        if (isCycling) {
27222          this.cycle();
27223        }
27224      }
27225
27226      // static
27227
27228    }], [{
27229      key: '_jQueryInterface',
27230      value: function _jQueryInterface(config) {
27231        return this.each(function () {
27232          var data = $(this).data(DATA_KEY);
27233          var _config = $.extend({}, Default, $(this).data());
27234
27235          if (typeof config === 'object') {
27236            $.extend(_config, config);
27237          }
27238
27239          var action = typeof config === 'string' ? config : _config.slide;
27240
27241          if (!data) {
27242            data = new Carousel(this, _config);
27243            $(this).data(DATA_KEY, data);
27244          }
27245
27246          if (typeof config === 'number') {
27247            data.to(config);
27248          } else if (typeof action === 'string') {
27249            if (data[action] === undefined) {
27250              throw new Error('No method named "' + action + '"');
27251            }
27252            data[action]();
27253          } else if (_config.interval) {
27254            data.pause();
27255            data.cycle();
27256          }
27257        });
27258      }
27259    }, {
27260      key: '_dataApiClickHandler',
27261      value: function _dataApiClickHandler(event) {
27262        var selector = Util.getSelectorFromElement(this);
27263
27264        if (!selector) {
27265          return;
27266        }
27267
27268        var target = $(selector)[0];
27269
27270        if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
27271          return;
27272        }
27273
27274        var config = $.extend({}, $(target).data(), $(this).data());
27275        var slideIndex = this.getAttribute('data-slide-to');
27276
27277        if (slideIndex) {
27278          config.interval = false;
27279        }
27280
27281        Carousel._jQueryInterface.call($(target), config);
27282
27283        if (slideIndex) {
27284          $(target).data(DATA_KEY).to(slideIndex);
27285        }
27286
27287        event.preventDefault();
27288      }
27289    }, {
27290      key: 'VERSION',
27291      get: function get() {
27292        return VERSION;
27293      }
27294    }, {
27295      key: 'Default',
27296      get: function get() {
27297        return Default;
27298      }
27299    }]);
27300
27301    return Carousel;
27302  })();
27303
27304  $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
27305
27306  $(window).on(Event.LOAD_DATA_API, function () {
27307    $(Selector.DATA_RIDE).each(function () {
27308      var $carousel = $(this);
27309      Carousel._jQueryInterface.call($carousel, $carousel.data());
27310    });
27311  });
27312
27313  /**
27314   * ------------------------------------------------------------------------
27315   * jQuery
27316   * ------------------------------------------------------------------------
27317   */
27318
27319  $.fn[NAME] = Carousel._jQueryInterface;
27320  $.fn[NAME].Constructor = Carousel;
27321  $.fn[NAME].noConflict = function () {
27322    $.fn[NAME] = JQUERY_NO_CONFLICT;
27323    return Carousel._jQueryInterface;
27324  };
27325
27326  return Carousel;
27327})(jQuery);
27328//# sourceMappingURL=carousel.js.map
27329
27330'use strict';
27331
27332var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
27333
27334function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
27335
27336/**
27337 * --------------------------------------------------------------------------
27338 * Bootstrap (v4.0.0-alpha.2): collapse.js
27339 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
27340 * --------------------------------------------------------------------------
27341 */
27342
27343var Collapse = (function ($) {
27344
27345  /**
27346   * ------------------------------------------------------------------------
27347   * Constants
27348   * ------------------------------------------------------------------------
27349   */
27350
27351  var NAME = 'collapse';
27352  var VERSION = '4.0.0-alpha';
27353  var DATA_KEY = 'bs.collapse';
27354  var EVENT_KEY = '.' + DATA_KEY;
27355  var DATA_API_KEY = '.data-api';
27356  var JQUERY_NO_CONFLICT = $.fn[NAME];
27357  var TRANSITION_DURATION = 600;
27358
27359  var Default = {
27360    toggle: true,
27361    parent: ''
27362  };
27363
27364  var DefaultType = {
27365    toggle: 'boolean',
27366    parent: 'string'
27367  };
27368
27369  var Event = {
27370    SHOW: 'show' + EVENT_KEY,
27371    SHOWN: 'shown' + EVENT_KEY,
27372    HIDE: 'hide' + EVENT_KEY,
27373    HIDDEN: 'hidden' + EVENT_KEY,
27374    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
27375  };
27376
27377  var ClassName = {
27378    IN: 'in',
27379    COLLAPSE: 'collapse',
27380    COLLAPSING: 'collapsing',
27381    COLLAPSED: 'collapsed'
27382  };
27383
27384  var Dimension = {
27385    WIDTH: 'width',
27386    HEIGHT: 'height'
27387  };
27388
27389  var Selector = {
27390    ACTIVES: '.panel > .in, .panel > .collapsing',
27391    DATA_TOGGLE: '[data-toggle="collapse"]'
27392  };
27393
27394  /**
27395   * ------------------------------------------------------------------------
27396   * Class Definition
27397   * ------------------------------------------------------------------------
27398   */
27399
27400  var Collapse = (function () {
27401    function Collapse(element, config) {
27402      _classCallCheck(this, Collapse);
27403
27404      this._isTransitioning = false;
27405      this._element = element;
27406      this._config = this._getConfig(config);
27407      this._triggerArray = $.makeArray($('[data-toggle="collapse"][href="#' + element.id + '"],' + ('[data-toggle="collapse"][data-target="#' + element.id + '"]')));
27408
27409      this._parent = this._config.parent ? this._getParent() : null;
27410
27411      if (!this._config.parent) {
27412        this._addAriaAndCollapsedClass(this._element, this._triggerArray);
27413      }
27414
27415      if (this._config.toggle) {
27416        this.toggle();
27417      }
27418    }
27419
27420    /**
27421     * ------------------------------------------------------------------------
27422     * Data Api implementation
27423     * ------------------------------------------------------------------------
27424     */
27425
27426    // getters
27427
27428    _createClass(Collapse, [{
27429      key: 'toggle',
27430
27431      // public
27432
27433      value: function toggle() {
27434        if ($(this._element).hasClass(ClassName.IN)) {
27435          this.hide();
27436        } else {
27437          this.show();
27438        }
27439      }
27440    }, {
27441      key: 'show',
27442      value: function show() {
27443        var _this = this;
27444
27445        if (this._isTransitioning || $(this._element).hasClass(ClassName.IN)) {
27446          return;
27447        }
27448
27449        var actives = undefined;
27450        var activesData = undefined;
27451
27452        if (this._parent) {
27453          actives = $.makeArray($(this._parent).find(Selector.ACTIVES));
27454          if (!actives.length) {
27455            actives = null;
27456          }
27457        }
27458
27459        if (actives) {
27460          activesData = $(actives).data(DATA_KEY);
27461          if (activesData && activesData._isTransitioning) {
27462            return;
27463          }
27464        }
27465
27466        var startEvent = $.Event(Event.SHOW);
27467        $(this._element).trigger(startEvent);
27468        if (startEvent.isDefaultPrevented()) {
27469          return;
27470        }
27471
27472        if (actives) {
27473          Collapse._jQueryInterface.call($(actives), 'hide');
27474          if (!activesData) {
27475            $(actives).data(DATA_KEY, null);
27476          }
27477        }
27478
27479        var dimension = this._getDimension();
27480
27481        $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);
27482
27483        this._element.style[dimension] = 0;
27484        this._element.setAttribute('aria-expanded', true);
27485
27486        if (this._triggerArray.length) {
27487          $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);
27488        }
27489
27490        this.setTransitioning(true);
27491
27492        var complete = function complete() {
27493          $(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.IN);
27494
27495          _this._element.style[dimension] = '';
27496
27497          _this.setTransitioning(false);
27498
27499          $(_this._element).trigger(Event.SHOWN);
27500        };
27501
27502        if (!Util.supportsTransitionEnd()) {
27503          complete();
27504          return;
27505        }
27506
27507        var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
27508        var scrollSize = 'scroll' + capitalizedDimension;
27509
27510        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
27511
27512        this._element.style[dimension] = this._element[scrollSize] + 'px';
27513      }
27514    }, {
27515      key: 'hide',
27516      value: function hide() {
27517        var _this2 = this;
27518
27519        if (this._isTransitioning || !$(this._element).hasClass(ClassName.IN)) {
27520          return;
27521        }
27522
27523        var startEvent = $.Event(Event.HIDE);
27524        $(this._element).trigger(startEvent);
27525        if (startEvent.isDefaultPrevented()) {
27526          return;
27527        }
27528
27529        var dimension = this._getDimension();
27530        var offsetDimension = dimension === Dimension.WIDTH ? 'offsetWidth' : 'offsetHeight';
27531
27532        this._element.style[dimension] = this._element[offsetDimension] + 'px';
27533
27534        Util.reflow(this._element);
27535
27536        $(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.IN);
27537
27538        this._element.setAttribute('aria-expanded', false);
27539
27540        if (this._triggerArray.length) {
27541          $(this._triggerArray).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
27542        }
27543
27544        this.setTransitioning(true);
27545
27546        var complete = function complete() {
27547          _this2.setTransitioning(false);
27548          $(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
27549        };
27550
27551        this._element.style[dimension] = 0;
27552
27553        if (!Util.supportsTransitionEnd()) {
27554          complete();
27555          return;
27556        }
27557
27558        $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
27559      }
27560    }, {
27561      key: 'setTransitioning',
27562      value: function setTransitioning(isTransitioning) {
27563        this._isTransitioning = isTransitioning;
27564      }
27565    }, {
27566      key: 'dispose',
27567      value: function dispose() {
27568        $.removeData(this._element, DATA_KEY);
27569
27570        this._config = null;
27571        this._parent = null;
27572        this._element = null;
27573        this._triggerArray = null;
27574        this._isTransitioning = null;
27575      }
27576
27577      // private
27578
27579    }, {
27580      key: '_getConfig',
27581      value: function _getConfig(config) {
27582        config = $.extend({}, Default, config);
27583        config.toggle = Boolean(config.toggle); // coerce string values
27584        Util.typeCheckConfig(NAME, config, DefaultType);
27585        return config;
27586      }
27587    }, {
27588      key: '_getDimension',
27589      value: function _getDimension() {
27590        var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
27591        return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
27592      }
27593    }, {
27594      key: '_getParent',
27595      value: function _getParent() {
27596        var _this3 = this;
27597
27598        var parent = $(this._config.parent)[0];
27599        var selector = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]';
27600
27601        $(parent).find(selector).each(function (i, element) {
27602          _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
27603        });
27604
27605        return parent;
27606      }
27607    }, {
27608      key: '_addAriaAndCollapsedClass',
27609      value: function _addAriaAndCollapsedClass(element, triggerArray) {
27610        if (element) {
27611          var isOpen = $(element).hasClass(ClassName.IN);
27612          element.setAttribute('aria-expanded', isOpen);
27613
27614          if (triggerArray.length) {
27615            $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
27616          }
27617        }
27618      }
27619
27620      // static
27621
27622    }], [{
27623      key: '_getTargetFromElement',
27624      value: function _getTargetFromElement(element) {
27625        var selector = Util.getSelectorFromElement(element);
27626        return selector ? $(selector)[0] : null;
27627      }
27628    }, {
27629      key: '_jQueryInterface',
27630      value: function _jQueryInterface(config) {
27631        return this.each(function () {
27632          var $this = $(this);
27633          var data = $this.data(DATA_KEY);
27634          var _config = $.extend({}, Default, $this.data(), typeof config === 'object' && config);
27635
27636          if (!data && _config.toggle && /show|hide/.test(config)) {
27637            _config.toggle = false;
27638          }
27639
27640          if (!data) {
27641            data = new Collapse(this, _config);
27642            $this.data(DATA_KEY, data);
27643          }
27644
27645          if (typeof config === 'string') {
27646            if (data[config] === undefined) {
27647              throw new Error('No method named "' + config + '"');
27648            }
27649            data[config]();
27650          }
27651        });
27652      }
27653    }, {
27654      key: 'VERSION',
27655      get: function get() {
27656        return VERSION;
27657      }
27658    }, {
27659      key: 'Default',
27660      get: function get() {
27661        return Default;
27662      }
27663    }]);
27664
27665    return Collapse;
27666  })();
27667
27668  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
27669    event.preventDefault();
27670
27671    var target = Collapse._getTargetFromElement(this);
27672    var data = $(target).data(DATA_KEY);
27673    var config = data ? 'toggle' : $(this).data();
27674
27675    Collapse._jQueryInterface.call($(target), config);
27676  });
27677
27678  /**
27679   * ------------------------------------------------------------------------
27680   * jQuery
27681   * ------------------------------------------------------------------------
27682   */
27683
27684  $.fn[NAME] = Collapse._jQueryInterface;
27685  $.fn[NAME].Constructor = Collapse;
27686  $.fn[NAME].noConflict = function () {
27687    $.fn[NAME] = JQUERY_NO_CONFLICT;
27688    return Collapse._jQueryInterface;
27689  };
27690
27691  return Collapse;
27692})(jQuery);
27693//# sourceMappingURL=collapse.js.map
27694
27695'use strict';
27696
27697var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
27698
27699function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
27700
27701/**
27702 * --------------------------------------------------------------------------
27703 * Bootstrap (v4.0.0-alpha.2): dropdown.js
27704 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
27705 * --------------------------------------------------------------------------
27706 */
27707
27708var Dropdown = (function ($) {
27709
27710  /**
27711   * ------------------------------------------------------------------------
27712   * Constants
27713   * ------------------------------------------------------------------------
27714   */
27715
27716  var NAME = 'dropdown';
27717  var VERSION = '4.0.0-alpha';
27718  var DATA_KEY = 'bs.dropdown';
27719  var EVENT_KEY = '.' + DATA_KEY;
27720  var DATA_API_KEY = '.data-api';
27721  var JQUERY_NO_CONFLICT = $.fn[NAME];
27722
27723  var Event = {
27724    HIDE: 'hide' + EVENT_KEY,
27725    HIDDEN: 'hidden' + EVENT_KEY,
27726    SHOW: 'show' + EVENT_KEY,
27727    SHOWN: 'shown' + EVENT_KEY,
27728    CLICK: 'click' + EVENT_KEY,
27729    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY,
27730    KEYDOWN_DATA_API: 'keydown' + EVENT_KEY + DATA_API_KEY
27731  };
27732
27733  var ClassName = {
27734    BACKDROP: 'dropdown-backdrop',
27735    DISABLED: 'disabled',
27736    OPEN: 'open'
27737  };
27738
27739  var Selector = {
27740    BACKDROP: '.dropdown-backdrop',
27741    DATA_TOGGLE: '[data-toggle="dropdown"]',
27742    FORM_CHILD: '.dropdown form',
27743    ROLE_MENU: '[role="menu"]',
27744    ROLE_LISTBOX: '[role="listbox"]',
27745    NAVBAR_NAV: '.navbar-nav',
27746    VISIBLE_ITEMS: '[role="menu"] li:not(.disabled) a, ' + '[role="listbox"] li:not(.disabled) a'
27747  };
27748
27749  /**
27750   * ------------------------------------------------------------------------
27751   * Class Definition
27752   * ------------------------------------------------------------------------
27753   */
27754
27755  var Dropdown = (function () {
27756    function Dropdown(element) {
27757      _classCallCheck(this, Dropdown);
27758
27759      this._element = element;
27760
27761      this._addEventListeners();
27762    }
27763
27764    /**
27765     * ------------------------------------------------------------------------
27766     * Data Api implementation
27767     * ------------------------------------------------------------------------
27768     */
27769
27770    // getters
27771
27772    _createClass(Dropdown, [{
27773      key: 'toggle',
27774
27775      // public
27776
27777      value: function toggle() {
27778        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
27779          return false;
27780        }
27781
27782        var parent = Dropdown._getParentFromElement(this);
27783        var isActive = $(parent).hasClass(ClassName.OPEN);
27784
27785        Dropdown._clearMenus();
27786
27787        if (isActive) {
27788          return false;
27789        }
27790
27791        if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
27792
27793          // if mobile we use a backdrop because click events don't delegate
27794          var dropdown = document.createElement('div');
27795          dropdown.className = ClassName.BACKDROP;
27796          $(dropdown).insertBefore(this);
27797          $(dropdown).on('click', Dropdown._clearMenus);
27798        }
27799
27800        var relatedTarget = { relatedTarget: this };
27801        var showEvent = $.Event(Event.SHOW, relatedTarget);
27802
27803        $(parent).trigger(showEvent);
27804
27805        if (showEvent.isDefaultPrevented()) {
27806          return false;
27807        }
27808
27809        this.focus();
27810        this.setAttribute('aria-expanded', 'true');
27811
27812        $(parent).toggleClass(ClassName.OPEN);
27813        $(parent).trigger($.Event(Event.SHOWN, relatedTarget));
27814
27815        return false;
27816      }
27817    }, {
27818      key: 'dispose',
27819      value: function dispose() {
27820        $.removeData(this._element, DATA_KEY);
27821        $(this._element).off(EVENT_KEY);
27822        this._element = null;
27823      }
27824
27825      // private
27826
27827    }, {
27828      key: '_addEventListeners',
27829      value: function _addEventListeners() {
27830        $(this._element).on(Event.CLICK, this.toggle);
27831      }
27832
27833      // static
27834
27835    }], [{
27836      key: '_jQueryInterface',
27837      value: function _jQueryInterface(config) {
27838        return this.each(function () {
27839          var data = $(this).data(DATA_KEY);
27840
27841          if (!data) {
27842            $(this).data(DATA_KEY, data = new Dropdown(this));
27843          }
27844
27845          if (typeof config === 'string') {
27846            if (data[config] === undefined) {
27847              throw new Error('No method named "' + config + '"');
27848            }
27849            data[config].call(this);
27850          }
27851        });
27852      }
27853    }, {
27854      key: '_clearMenus',
27855      value: function _clearMenus(event) {
27856        if (event && event.which === 3) {
27857          return;
27858        }
27859
27860        var backdrop = $(Selector.BACKDROP)[0];
27861        if (backdrop) {
27862          backdrop.parentNode.removeChild(backdrop);
27863        }
27864
27865        var toggles = $.makeArray($(Selector.DATA_TOGGLE));
27866
27867        for (var i = 0; i < toggles.length; i++) {
27868          var _parent = Dropdown._getParentFromElement(toggles[i]);
27869          var relatedTarget = { relatedTarget: toggles[i] };
27870
27871          if (!$(_parent).hasClass(ClassName.OPEN)) {
27872            continue;
27873          }
27874
27875          if (event && event.type === 'click' && /input|textarea/i.test(event.target.tagName) && $.contains(_parent, event.target)) {
27876            continue;
27877          }
27878
27879          var hideEvent = $.Event(Event.HIDE, relatedTarget);
27880          $(_parent).trigger(hideEvent);
27881          if (hideEvent.isDefaultPrevented()) {
27882            continue;
27883          }
27884
27885          toggles[i].setAttribute('aria-expanded', 'false');
27886
27887          $(_parent).removeClass(ClassName.OPEN).trigger($.Event(Event.HIDDEN, relatedTarget));
27888        }
27889      }
27890    }, {
27891      key: '_getParentFromElement',
27892      value: function _getParentFromElement(element) {
27893        var parent = undefined;
27894        var selector = Util.getSelectorFromElement(element);
27895
27896        if (selector) {
27897          parent = $(selector)[0];
27898        }
27899
27900        return parent || element.parentNode;
27901      }
27902    }, {
27903      key: '_dataApiKeydownHandler',
27904      value: function _dataApiKeydownHandler(event) {
27905        if (!/(38|40|27|32)/.test(event.which) || /input|textarea/i.test(event.target.tagName)) {
27906          return;
27907        }
27908
27909        event.preventDefault();
27910        event.stopPropagation();
27911
27912        if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
27913          return;
27914        }
27915
27916        var parent = Dropdown._getParentFromElement(this);
27917        var isActive = $(parent).hasClass(ClassName.OPEN);
27918
27919        if (!isActive && event.which !== 27 || isActive && event.which === 27) {
27920
27921          if (event.which === 27) {
27922            var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
27923            $(toggle).trigger('focus');
27924          }
27925
27926          $(this).trigger('click');
27927          return;
27928        }
27929
27930        var items = $.makeArray($(Selector.VISIBLE_ITEMS));
27931
27932        items = items.filter(function (item) {
27933          return item.offsetWidth || item.offsetHeight;
27934        });
27935
27936        if (!items.length) {
27937          return;
27938        }
27939
27940        var index = items.indexOf(event.target);
27941
27942        if (event.which === 38 && index > 0) {
27943          // up
27944          index--;
27945        }
27946
27947        if (event.which === 40 && index < items.length - 1) {
27948          // down
27949          index++;
27950        }
27951
27952        if (! ~index) {
27953          index = 0;
27954        }
27955
27956        items[index].focus();
27957      }
27958    }, {
27959      key: 'VERSION',
27960      get: function get() {
27961        return VERSION;
27962      }
27963    }]);
27964
27965    return Dropdown;
27966  })();
27967
27968  $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_MENU, Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.ROLE_LISTBOX, Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API, Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, Dropdown.prototype.toggle).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
27969    e.stopPropagation();
27970  });
27971
27972  /**
27973   * ------------------------------------------------------------------------
27974   * jQuery
27975   * ------------------------------------------------------------------------
27976   */
27977
27978  $.fn[NAME] = Dropdown._jQueryInterface;
27979  $.fn[NAME].Constructor = Dropdown;
27980  $.fn[NAME].noConflict = function () {
27981    $.fn[NAME] = JQUERY_NO_CONFLICT;
27982    return Dropdown._jQueryInterface;
27983  };
27984
27985  return Dropdown;
27986})(jQuery);
27987//# sourceMappingURL=dropdown.js.map
27988
27989'use strict';
27990
27991var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
27992
27993function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
27994
27995/**
27996 * --------------------------------------------------------------------------
27997 * Bootstrap (v4.0.0-alpha.2): modal.js
27998 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
27999 * --------------------------------------------------------------------------
28000 */
28001
28002var Modal = (function ($) {
28003
28004  /**
28005   * ------------------------------------------------------------------------
28006   * Constants
28007   * ------------------------------------------------------------------------
28008   */
28009
28010  var NAME = 'modal';
28011  var VERSION = '4.0.0-alpha';
28012  var DATA_KEY = 'bs.modal';
28013  var EVENT_KEY = '.' + DATA_KEY;
28014  var DATA_API_KEY = '.data-api';
28015  var JQUERY_NO_CONFLICT = $.fn[NAME];
28016  var TRANSITION_DURATION = 300;
28017  var BACKDROP_TRANSITION_DURATION = 150;
28018
28019  var Default = {
28020    backdrop: true,
28021    keyboard: true,
28022    focus: true,
28023    show: true
28024  };
28025
28026  var DefaultType = {
28027    backdrop: '(boolean|string)',
28028    keyboard: 'boolean',
28029    focus: 'boolean',
28030    show: 'boolean'
28031  };
28032
28033  var Event = {
28034    HIDE: 'hide' + EVENT_KEY,
28035    HIDDEN: 'hidden' + EVENT_KEY,
28036    SHOW: 'show' + EVENT_KEY,
28037    SHOWN: 'shown' + EVENT_KEY,
28038    FOCUSIN: 'focusin' + EVENT_KEY,
28039    RESIZE: 'resize' + EVENT_KEY,
28040    CLICK_DISMISS: 'click.dismiss' + EVENT_KEY,
28041    KEYDOWN_DISMISS: 'keydown.dismiss' + EVENT_KEY,
28042    MOUSEUP_DISMISS: 'mouseup.dismiss' + EVENT_KEY,
28043    MOUSEDOWN_DISMISS: 'mousedown.dismiss' + EVENT_KEY,
28044    CLICK_DATA_API: 'click' + EVENT_KEY + DATA_API_KEY
28045  };
28046
28047  var ClassName = {
28048    SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
28049    BACKDROP: 'modal-backdrop',
28050    OPEN: 'modal-open',
28051    FADE: 'fade',
28052    IN: 'in'
28053  };
28054
28055  var Selector = {
28056    DIALOG: '.modal-dialog',
28057    DATA_TOGGLE: '[data-toggle="modal"]',
28058    DATA_DISMISS: '[data-dismiss="modal"]',
28059    FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
28060  };
28061
28062  /**
28063   * ------------------------------------------------------------------------
28064   * Class Definition
28065   * ------------------------------------------------------------------------
28066   */
28067
28068  var Modal = (function () {
28069    function Modal(element, config) {
28070      _classCallCheck(this, Modal);
28071
28072      this._config = this._getConfig(config);
28073      this._element = element;
28074      this._dialog = $(element).find(Selector.DIALOG)[0];
28075      this._backdrop = null;
28076      this._isShown = false;
28077      this._isBodyOverflowing = false;
28078      this._ignoreBackdropClick = false;
28079      this._originalBodyPadding = 0;
28080      this._scrollbarWidth = 0;
28081    }
28082
28083    /**
28084     * ------------------------------------------------------------------------
28085     * Data Api implementation
28086     * ------------------------------------------------------------------------
28087     */
28088
28089    // getters
28090
28091    _createClass(Modal, [{
28092      key: 'toggle',
28093
28094      // public
28095
28096      value: function toggle(relatedTarget) {
28097        return this._isShown ? this.hide() : this.show(relatedTarget);
28098      }
28099    }, {
28100      key: 'show',
28101      value: function show(relatedTarget) {
28102        var _this = this;
28103
28104        var showEvent = $.Event(Event.SHOW, {
28105          relatedTarget: relatedTarget
28106        });
28107
28108        $(this._element).trigger(showEvent);
28109
28110        if (this._isShown || showEvent.isDefaultPrevented()) {
28111          return;
28112        }
28113
28114        this._isShown = true;
28115
28116        this._checkScrollbar();
28117        this._setScrollbar();
28118
28119        $(document.body).addClass(ClassName.OPEN);
28120
28121        this._setEscapeEvent();
28122        this._setResizeEvent();
28123
28124        $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, $.proxy(this.hide, this));
28125
28126        $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
28127          $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
28128            if ($(event.target).is(_this._element)) {
28129              _this._ignoreBackdropClick = true;
28130            }
28131          });
28132        });
28133
28134        this._showBackdrop($.proxy(this._showElement, this, relatedTarget));
28135      }
28136    }, {
28137      key: 'hide',
28138      value: function hide(event) {
28139        if (event) {
28140          event.preventDefault();
28141        }
28142
28143        var hideEvent = $.Event(Event.HIDE);
28144
28145        $(this._element).trigger(hideEvent);
28146
28147        if (!this._isShown || hideEvent.isDefaultPrevented()) {
28148          return;
28149        }
28150
28151        this._isShown = false;
28152
28153        this._setEscapeEvent();
28154        this._setResizeEvent();
28155
28156        $(document).off(Event.FOCUSIN);
28157
28158        $(this._element).removeClass(ClassName.IN);
28159
28160        $(this._element).off(Event.CLICK_DISMISS);
28161        $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
28162
28163        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
28164
28165          $(this._element).one(Util.TRANSITION_END, $.proxy(this._hideModal, this)).emulateTransitionEnd(TRANSITION_DURATION);
28166        } else {
28167          this._hideModal();
28168        }
28169      }
28170    }, {
28171      key: 'dispose',
28172      value: function dispose() {
28173        $.removeData(this._element, DATA_KEY);
28174
28175        $(window).off(EVENT_KEY);
28176        $(document).off(EVENT_KEY);
28177        $(this._element).off(EVENT_KEY);
28178        $(this._backdrop).off(EVENT_KEY);
28179
28180        this._config = null;
28181        this._element = null;
28182        this._dialog = null;
28183        this._backdrop = null;
28184        this._isShown = null;
28185        this._isBodyOverflowing = null;
28186        this._ignoreBackdropClick = null;
28187        this._originalBodyPadding = null;
28188        this._scrollbarWidth = null;
28189      }
28190
28191      // private
28192
28193    }, {
28194      key: '_getConfig',
28195      value: function _getConfig(config) {
28196        config = $.extend({}, Default, config);
28197        Util.typeCheckConfig(NAME, config, DefaultType);
28198        return config;
28199      }
28200    }, {
28201      key: '_showElement',
28202      value: function _showElement(relatedTarget) {
28203        var _this2 = this;
28204
28205        var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
28206
28207        if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
28208          // don't move modals dom position
28209          document.body.appendChild(this._element);
28210        }
28211
28212        this._element.style.display = 'block';
28213        this._element.scrollTop = 0;
28214
28215        if (transition) {
28216          Util.reflow(this._element);
28217        }
28218
28219        $(this._element).addClass(ClassName.IN);
28220
28221        if (this._config.focus) {
28222          this._enforceFocus();
28223        }
28224
28225        var shownEvent = $.Event(Event.SHOWN, {
28226          relatedTarget: relatedTarget
28227        });
28228
28229        var transitionComplete = function transitionComplete() {
28230          if (_this2._config.focus) {
28231            _this2._element.focus();
28232          }
28233          $(_this2._element).trigger(shownEvent);
28234        };
28235
28236        if (transition) {
28237          $(this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
28238        } else {
28239          transitionComplete();
28240        }
28241      }
28242    }, {
28243      key: '_enforceFocus',
28244      value: function _enforceFocus() {
28245        var _this3 = this;
28246
28247        $(document).off(Event.FOCUSIN) // guard against infinite focus loop
28248        .on(Event.FOCUSIN, function (event) {
28249          if (_this3._element !== event.target && !$(_this3._element).has(event.target).length) {
28250            _this3._element.focus();
28251          }
28252        });
28253      }
28254    }, {
28255      key: '_setEscapeEvent',
28256      value: function _setEscapeEvent() {
28257        var _this4 = this;
28258
28259        if (this._isShown && this._config.keyboard) {
28260          $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
28261            if (event.which === 27) {
28262              _this4.hide();
28263            }
28264          });
28265        } else if (!this._isShown) {
28266          $(this._element).off(Event.KEYDOWN_DISMISS);
28267        }
28268      }
28269    }, {
28270      key: '_setResizeEvent',
28271      value: function _setResizeEvent() {
28272        if (this._isShown) {
28273          $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this));
28274        } else {
28275          $(window).off(Event.RESIZE);
28276        }
28277      }
28278    }, {
28279      key: '_hideModal',
28280      value: function _hideModal() {
28281        var _this5 = this;
28282
28283        this._element.style.display = 'none';
28284        this._showBackdrop(function () {
28285          $(document.body).removeClass(ClassName.OPEN);
28286          _this5._resetAdjustments();
28287          _this5._resetScrollbar();
28288          $(_this5._element).trigger(Event.HIDDEN);
28289        });
28290      }
28291    }, {
28292      key: '_removeBackdrop',
28293      value: function _removeBackdrop() {
28294        if (this._backdrop) {
28295          $(this._backdrop).remove();
28296          this._backdrop = null;
28297        }
28298      }
28299    }, {
28300      key: '_showBackdrop',
28301      value: function _showBackdrop(callback) {
28302        var _this6 = this;
28303
28304        var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
28305
28306        if (this._isShown && this._config.backdrop) {
28307          var doAnimate = Util.supportsTransitionEnd() && animate;
28308
28309          this._backdrop = document.createElement('div');
28310          this._backdrop.className = ClassName.BACKDROP;
28311
28312          if (animate) {
28313            $(this._backdrop).addClass(animate);
28314          }
28315
28316          $(this._backdrop).appendTo(document.body);
28317
28318          $(this._element).on(Event.CLICK_DISMISS, function (event) {
28319            if (_this6._ignoreBackdropClick) {
28320              _this6._ignoreBackdropClick = false;
28321              return;
28322            }
28323            if (event.target !== event.currentTarget) {
28324              return;
28325            }
28326            if (_this6._config.backdrop === 'static') {
28327              _this6._element.focus();
28328            } else {
28329              _this6.hide();
28330            }
28331          });
28332
28333          if (doAnimate) {
28334            Util.reflow(this._backdrop);
28335          }
28336
28337          $(this._backdrop).addClass(ClassName.IN);
28338
28339          if (!callback) {
28340            return;
28341          }
28342
28343          if (!doAnimate) {
28344            callback();
28345            return;
28346          }
28347
28348          $(this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
28349        } else if (!this._isShown && this._backdrop) {
28350          $(this._backdrop).removeClass(ClassName.IN);
28351
28352          var callbackRemove = function callbackRemove() {
28353            _this6._removeBackdrop();
28354            if (callback) {
28355              callback();
28356            }
28357          };
28358
28359          if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
28360            $(this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
28361          } else {
28362            callbackRemove();
28363          }
28364        } else if (callback) {
28365          callback();
28366        }
28367      }
28368
28369      // ----------------------------------------------------------------------
28370      // the following methods are used to handle overflowing modals
28371      // todo (fat): these should probably be refactored out of modal.js
28372      // ----------------------------------------------------------------------
28373
28374    }, {
28375      key: '_handleUpdate',
28376      value: function _handleUpdate() {
28377        this._adjustDialog();
28378      }
28379    }, {
28380      key: '_adjustDialog',
28381      value: function _adjustDialog() {
28382        var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
28383
28384        if (!this._isBodyOverflowing && isModalOverflowing) {
28385          this._element.style.paddingLeft = this._scrollbarWidth + 'px';
28386        }
28387
28388        if (this._isBodyOverflowing && !isModalOverflowing) {
28389          this._element.style.paddingRight = this._scrollbarWidth + 'px~';
28390        }
28391      }
28392    }, {
28393      key: '_resetAdjustments',
28394      value: function _resetAdjustments() {
28395        this._element.style.paddingLeft = '';
28396        this._element.style.paddingRight = '';
28397      }
28398    }, {
28399      key: '_checkScrollbar',
28400      value: function _checkScrollbar() {
28401        var fullWindowWidth = window.innerWidth;
28402        if (!fullWindowWidth) {
28403          // workaround for missing window.innerWidth in IE8
28404          var documentElementRect = document.documentElement.getBoundingClientRect();
28405          fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left);
28406        }
28407        this._isBodyOverflowing = document.body.clientWidth < fullWindowWidth;
28408        this._scrollbarWidth = this._getScrollbarWidth();
28409      }
28410    }, {
28411      key: '_setScrollbar',
28412      value: function _setScrollbar() {
28413        var bodyPadding = parseInt($(Selector.FIXED_CONTENT).css('padding-right') || 0, 10);
28414
28415        this._originalBodyPadding = document.body.style.paddingRight || '';
28416
28417        if (this._isBodyOverflowing) {
28418          document.body.style.paddingRight = bodyPadding + this._scrollbarWidth + 'px';
28419        }
28420      }
28421    }, {
28422      key: '_resetScrollbar',
28423      value: function _resetScrollbar() {
28424        document.body.style.paddingRight = this._originalBodyPadding;
28425      }
28426    }, {
28427      key: '_getScrollbarWidth',
28428      value: function _getScrollbarWidth() {
28429        // thx d.walsh
28430        var scrollDiv = document.createElement('div');
28431        scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
28432        document.body.appendChild(scrollDiv);
28433        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
28434        document.body.removeChild(scrollDiv);
28435        return scrollbarWidth;
28436      }
28437
28438      // static
28439
28440    }], [{
28441      key: '_jQueryInterface',
28442      value: function _jQueryInterface(config, relatedTarget) {
28443        return this.each(function () {
28444          var data = $(this).data(DATA_KEY);
28445          var _config = $.extend({}, Modal.Default, $(this).data(), typeof config === 'object' && config);
28446
28447          if (!data) {
28448            data = new Modal(this, _config);
28449            $(this).data(DATA_KEY, data);
28450          }
28451
28452          if (typeof config === 'string') {
28453            if (data[config] === undefined) {
28454              throw new Error('No method named "' + config + '"');
28455            }
28456            data[config](relatedTarget);
28457          } else if (_config.show) {
28458            data.show(relatedTarget);
28459          }
28460        });
28461      }
28462    }, {
28463      key: 'VERSION',
28464      get: function get() {
28465        return VERSION;
28466      }
28467    }, {
28468      key: 'Default',
28469      get: function get() {
28470        return Default;
28471      }
28472    }]);
28473
28474    return Modal;
28475  })();
28476
28477  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
28478    var _this7 = this;
28479
28480    var target = undefined;
28481    var selector = Util.getSelectorFromElement(this);
28482
28483    if (selector) {
28484      target = $(selector)[0];
28485    }
28486
28487    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
28488
28489    if (this.tagName === 'A') {
28490      event.preventDefault();
28491    }
28492
28493    var $target = $(target).one(Event.SHOW, function (showEvent) {
28494      if (showEvent.isDefaultPrevented()) {
28495        // only register focus restorer if modal will actually get shown
28496        return;
28497      }
28498
28499      $target.one(Event.HIDDEN, function () {
28500        if ($(_this7).is(':visible')) {
28501          _this7.focus();
28502        }
28503      });
28504    });
28505
28506    Modal._jQueryInterface.call($(target), config, this);
28507  });
28508
28509  /**
28510   * ------------------------------------------------------------------------
28511   * jQuery
28512   * ------------------------------------------------------------------------
28513   */
28514
28515  $.fn[NAME] = Modal._jQueryInterface;
28516  $.fn[NAME].Constructor = Modal;
28517  $.fn[NAME].noConflict = function () {
28518    $.fn[NAME] = JQUERY_NO_CONFLICT;
28519    return Modal._jQueryInterface;
28520  };
28521
28522  return Modal;
28523})(jQuery);
28524//# sourceMappingURL=modal.js.map
28525
28526//require('../../vendor/twitter/bootstrap/js/dist/scrollspy');
28527//require('../../vendor/twitter/bootstrap/js/dist/tab');
28528//require('../../vendor/twitter/bootstrap/js/dist/tooltip');
28529//require('../../vendor/twitter/bootstrap/js/dist/popover');
28530
28531
28532/*-------------------------------------------*\
28533 |* Editor                                    *|
28534 \*-------------------------------------------*/
28535
28536$(function() {
28537    // Helper to create nice bootstrap forms with javascript.
28538    var createForm = function(configuration, docroot, images) {
28539        var formId = "form-generated-" + Date.now();
28540
28541        var form = $('<form/>').on('submit', function(event) {
28542            event.preventDefault();
28543        });
28544
28545        for (var name in configuration) {
28546            var element = configuration[name];
28547
28548            var group = $('<fieldset/>').addClass('form-group').appendTo(form);
28549            var label = $('<label/>').attr('for', formId + '-' + name).html(element.label).appendTo(group);
28550
28551            var input;
28552
28553            if (element.type === 'password') {
28554                input = $('<input/>').attr('type', 'password').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
28555            } else if (element.type === 'varchar') {
28556                input = $('<input/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
28557            } else if (element.type === 'select') {
28558                input = $('<select/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
28559
28560                element.values.forEach(function(value) {
28561                    $('<option/>').html(value).appendTo(input);
28562                });
28563            } else if (element.type === 'image') {
28564                input = $('<select/>').attr('data-type', 'image').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
28565
28566                $('<option/>').appendTo(input);
28567
28568                images.forEach(function(value) {
28569                    $('<option/>').attr('value', value).html(value.substr(7)).appendTo(input);
28570                });
28571
28572                var wrapper = $('<div/>').addClass('row').append(group.children()).appendTo(group);
28573                var left = $('<div/>').addClass('col-xs-6').append(wrapper.children()).appendTo(wrapper);
28574                var right = $('<div/>').addClass('col-xs-6').appendTo(wrapper);
28575
28576                input.change(function() {
28577                    $(this).parent().next().css({
28578                        backgroundImage: 'url(' + docroot + 'assets/images/' + $(this).val() + ')',
28579                        backgroundSize: 'contain',
28580                        backgroundPosition: 'center center',
28581                        backgroundRepeat: 'no-repeat'
28582                    });
28583                });
28584
28585            } else if (element.type === 'text') {
28586                input = $('<textarea/>').attr('name', name).addClass('form-control').attr('id', formId + '-' + name).appendTo(group);
28587            }
28588        }
28589
28590        return form;
28591    };
28592
28593    // Helper to create a modal containing a form.
28594    var createFormModal = function(configuration) {
28595        var modal   = $('<div/>').addClass('modal fade'   );
28596        var dialog  = $('<div/>').addClass('modal-dialog' ).appendTo(modal  );
28597        var content = $('<div/>').addClass('modal-content').appendTo(dialog );
28598        var header  = $('<div/>').addClass('modal-header' ).appendTo(content);
28599        var title   = $('<h4/>' ).addClass('modal-title'  ).appendTo(header );
28600        var body    = $('<div/>').addClass('modal-body'   ).appendTo(content);
28601        var footer  = $('<div/>').addClass('modal-footer' ).appendTo(content);
28602
28603        title.html(configuration.title);
28604
28605        body.append(createForm(configuration.form));
28606
28607        configuration.buttons.forEach(function(button) {
28608            $('<button/>').addClass('btn btn-' + button.type).html(button.label).on('click', button.action).appendTo(footer);
28609        });
28610
28611        modal.appendTo('body').modal({ keyboard: false }).on('hidden.bs.modal', function(event) {
28612            $(this).remove();
28613        });
28614
28615        return modal;
28616    };
28617
28618    var showLoginWindow = function() {
28619        createFormModal({
28620            title: 'Login',
28621            form: {
28622                password: { label: 'Password', type: 'password' }
28623            },
28624            buttons: [
28625                { label: 'Login', type: 'primary', action: function(event) {
28626                    var parts = $('body').data('editor').split('::');
28627
28628                    var url = parts[0];
28629                    var dataFile = parts[1];
28630                    var modal = $(this).parents('.modal');
28631                    var password = modal.find('input').val();
28632
28633                    $.post(url, $(this).parents('.modal').find('form').serialize() + '&dataFile=' + dataFile, function(response) {
28634                        // In this scope will the private script be called.
28635                        eval(response);
28636                    });
28637                } },
28638                { label: 'Close', type: 'danger', action: function(event) {
28639                    $(this).parents('.modal').modal('hide');
28640                } }
28641            ]
28642        });
28643    };
28644
28645    if (document.body.hasAttribute('data-editor')) {
28646        $(window).on('keypress', function(event) {
28647            if ((event.which === 28 || event.which === 35) && event.ctrlKey && $('body > .modal').length == 0) {
28648                event.preventDefault();
28649                showLoginWindow();
28650            }
28651        })
28652    }
28653});
28654
28655
28656
28657/*-------------------------------------------*\
28658 |* Tweaks                                    *|
28659 \*-------------------------------------------*/
28660
28661$(function () {
28662    "use strict";
28663
28664    // Make anchors animated
28665    $(document).on('click', 'a[href^="#"]', function (event) {
28666        event.preventDefault();
28667
28668        var a = event.target.tagName === 'A' ? event.target : $(event.target).parents('a')[0];
28669        var link = a.href.split('#')[1];
28670        var scrollTarget = 0;
28671
28672        if (link !== '') {
28673            // HTML5 Specification checks for id first, then legacy name.
28674            var target = $('#' + link + ', [name="' + link + '"]');
28675
28676            if (target.length == 0) {
28677                return;
28678            }
28679
28680            scrollTarget = document.body.scrollTop + target[0].getBoundingClientRect().top - $('main').offset().top;
28681        }
28682
28683        $('html, body').animate({ scrollTop: scrollTarget });
28684    });
28685
28686    // Open external links and pdfs documents in new tab.
28687    $(document).on('click', 'a[href*="//"], a[href$=".pdf"]', function (event) {
28688        event.preventDefault();
28689        window.open(this.href);
28690    });
28691
28692    // Allow SVG Images to be styled with CSS.
28693    $('img[src$=".svg"]').each(function() {
28694        var $img = $(this);
28695        jQuery.get(this.src, function(svg) {
28696            var $svg = $(svg).find('svg').removeAttr('xmlns:a');
28697            $.each($img.prop("attributes"), function() {
28698                $svg.attr(this.name, this.value);
28699            });
28700            $img.replaceWith($svg);
28701        });
28702    });
28703});
28704
28705
28706//-------------------------------------------\\
28707// Client Scripts                            \\
28708// ------------------------------------------\\
28709
28710$(function () {
28711    "use strict";
28712
28713    // Mobile navigation opener.
28714    $(document).on('click', 'a.toggle-mobile-nav', function (event) {
28715        event.preventDefault();
28716
28717        $('body').toggleClass('open-nav');
28718
28719        $(this).blur();
28720    });
28721
28722    // Mobile language switcher.
28723    $(document).on('change', '.mobile-nav select', function (event) {
28724        event.preventDefault();
28725        window.location.href = $(this).val();
28726    });
28727});
28728
28729
28730$(function () {
28731    "use strict";
28732
28733    $(document).on('submit', 'section.prefab-contact form', function (event) {
28734        event.preventDefault();
28735
28736        $(this).find('.required').each(function() {
28737           $(this).parent().parent().removeClass('has-success').removeClass('has-danger').addClass( ($(this).val().trim() === '' || ( $(this).attr('type')=='checkbox' && !$(this).is(':checked') ) ) ? 'has-danger' : 'has-success');
28738        });
28739
28740        if ($(this).find('.has-danger').length == 0) {
28741            var form = this;
28742
28743            $(form).next().addClass('submitting').modal({
28744                backdrop: 'static',
28745                keyboard: false
28746            });
28747
28748            $.post($(form).data('handler'), $(form).serialize(), function() {
28749                $(form).next().removeClass('submitting').modal();
28750                $(form)[0].reset();
28751                $(form).find('.has-success').removeClass('has-success');
28752            });
28753        }
28754    });
28755});
28756
28757$(function () {
28758    "use strict";
28759
28760    $(document).on('click', 'img[data-gallery]', function () {
28761        // Collecting gallery data.
28762        var thumbnails = $('img[data-gallery="' + $(this).data('gallery') + '"]');
28763
28764        // Setup gallery html.
28765        var backdrop = $(document.createElement('section'));
28766        backdrop.addClass('prefab-gallery modal-backdrop hidden');
28767        backdrop.appendTo(document.body);
28768
28769        var images = $(document.createElement('div'));
28770        images.addClass('images');
28771        images.appendTo(backdrop);
28772
28773        var close = $(document.createElement('span'));
28774        close.addClass('fa fa-times-circle');
28775        close.appendTo(backdrop);
28776
28777        // First loop - prepare containers.
28778        for (var i = 0; i < thumbnails.length; i++) {
28779            var thumbnail = thumbnails.eq(i);
28780
28781            var container = $(document.createElement('div'));
28782            container.addClass('card');
28783            container.addClass('animation-slide');
28784
28785            container.data({image: thumbnail.attr('src').replace(/\-([0-9]+)(?:x([0-9]+))?(?:\-(crop))?\.(jpg|png)$/, '.$4')});
28786            container.appendTo(images);
28787
28788            if (thumbnail.attr('alt') != undefined) {
28789                var caption = $(document.createElement('p'));
28790                caption.html('<strong>' + thumbnail.attr('alt') + '</strong>');
28791
28792                if (thumbnail.data('description') != undefined) {
28793                    caption.append('<span class="hidden-xs-down">' + thumbnail.data('description') + '</span>');
28794                }
28795
28796                caption.appendTo(container);
28797            }
28798
28799            if (thumbnails.length > 1) {
28800                var prev = $(document.createElement('div'));
28801                prev.addClass('prev btn fa fa-chevron-left fa-spinner');
28802                prev.appendTo(container);
28803
28804                var next = $(document.createElement('div'));
28805                next.addClass('next btn fa fa-chevron-right fa-spinner');
28806                next.appendTo(container);
28807            }
28808        }
28809
28810        // Second loop to trigger images - we need to split this to correctly remove the spinners when an image is loaded.
28811        var imageCallback = function () {
28812            var current = $(this).parent();
28813            var prev = current.is(':first-child') ? current.siblings().last() : current.prev();
28814            var next = current.is(':last-child') ? current.siblings().first() : current.next();
28815
28816            prev.children('.next').removeClass('fa-spinner');
28817            next.children('.prev').removeClass('fa-spinner');
28818
28819            current.children('.loader').remove();
28820        };
28821
28822        images.children().each(function () {
28823            var image = $(document.createElement('img'));
28824
28825            image.on('load', imageCallback);
28826
28827            image.on('error', function() {
28828                imageCallback.call(this);
28829
28830                var errorNotice = $(document.createElement('div'));
28831                errorNotice.addClass('fa fa-exclamation-triangle');
28832                errorNotice.insertBefore(this);
28833
28834                $(this).remove();
28835            });
28836
28837            image.appendTo(this);
28838            image.attr({src: $(this).data('image')});
28839
28840            var loader = $(document.createElement('div'));
28841            loader.addClass('fa fa-spinner loader');
28842            loader.insertAfter(image);
28843        });
28844
28845        // Show layer (delayed for transition to work).
28846        setTimeout(function () {
28847            backdrop.removeClass('hidden').find('.images > div').eq(0).addClass('current');
28848        });
28849
28850        // Closing by clicking the backdrop
28851        backdrop.on('click', function (event) {
28852            // Do not trigger when clicking a child.
28853            if (event.target != this && event.target != close[0]) {
28854                event.stopPropagation();
28855                return;
28856            }
28857
28858            $(document).off('keypress', keyboardCallback);
28859
28860            $(this).one('transitionend', function () {
28861                $(this).remove();
28862            }).addClass('hidden');
28863        });
28864
28865        // Clicking the arrows.
28866        images.children().find('.prev').on('click', function () {
28867            var current = $(this).parent();
28868            var prev = current.is(':first-child') ? current.siblings().last() : current.prev();
28869
28870            current.one('transitionend', function () {
28871                current.removeClass('next');
28872                prev.addClass('prev');
28873                setTimeout(function () {
28874                    prev.addClass('current').removeClass('prev');
28875                });
28876            }).addClass('next').removeClass('current');
28877        });
28878
28879        images.children().find('.next').on('click', function () {
28880            var current = $(this).parent();
28881            var next = current.is(':last-child') ? current.siblings().first() : current.next();
28882
28883            current.one('transitionend', function () {
28884                current.removeClass('prev');
28885                next.addClass('next');
28886                setTimeout(function () {
28887                    next.addClass('current').removeClass('next');
28888                });
28889            }).addClass('prev').removeClass('current');
28890        });
28891
28892        // Swipe support.
28893        var touchStart = [null, null];
28894        var touchEnd = [null, null];
28895        // 10 pixels minimum to avoid triggering on "tip" - which might caue ~4-5 pixels movement.
28896        var touchDeadzone = 10;
28897        backdrop.on('touchstart', function (event) {
28898            touchStart = [event.originalEvent.touches[0].clientX, event.originalEvent.touches[0].clientY];
28899        }).on('touchmove', function (event) {
28900            touchEnd = [event.originalEvent.touches[0].clientX, event.originalEvent.touches[0].clientY];
28901        }).on('touchend', function () {
28902            var moved = [touchEnd[0] - touchStart[0], touchEnd[1] - touchStart[1]];
28903
28904            if (Math.abs(moved[0]) > Math.abs(moved[1]) && Math.abs(moved[0]) > touchDeadzone) {
28905                if (moved[0] < 0) {
28906                    images.children('.current').find('.next').trigger('click');
28907                } else {
28908                    images.children('.current').find('.prev').trigger('click');
28909                }
28910            } else if (Math.abs(moved[1]) > Math.abs(moved[0]) && (moved[1] * -1) > touchDeadzone) {
28911                backdrop.trigger('click');
28912            }
28913        });
28914
28915        // Arrow keys support.
28916        var keyboardCallback = function(event) {
28917            if (event.which === 39) {
28918                images.children('.current').find('.next').trigger('click')
28919            } else if (event.which === 37) {
28920                images.children('.current').find('.prev').trigger('click')
28921            } else if (event.which === 27) {
28922                backdrop.trigger('click');
28923            }
28924        };
28925
28926        $(document).on('keyup', keyboardCallback);
28927    });
28928});
28929
28930$(function () {
28931    "use strict";
28932
28933    $(document).on('click', 'section.prefab-slider ol.carousel-indicators li', function () {
28934        $(this).parents('.prefab-slider').carousel($(this).index());
28935    });
28936
28937    $(document).on('click', 'section.prefab-slider a.carousel-control.left', function () {
28938        $(this).parents('.prefab-slider').carousel('prev');
28939    });
28940
28941    $(document).on('click', 'section.prefab-slider a.carousel-control.right', function () {
28942        $(this).parents('.prefab-slider').carousel('next');
28943    });
28944
28945    // Swipe support.
28946    var touchStart = [null, null];
28947    var touchEnd = [null, null];
28948    // 10 pixels minimum to avoid triggering on "tip" - which might caue ~4-5 pixels movement.
28949    var touchDeadzone = 10;
28950    $(document).on('touchstart', 'section.prefab-slider .carousel-inner', function (event) {
28951        touchStart = [event.originalEvent.touches[0].clientX, event.originalEvent.touches[0].clientY];
28952    }).on('touchmove', 'section.prefab-slider .carousel-inner', function (event) {
28953        touchEnd = [event.originalEvent.touches[0].clientX, event.originalEvent.touches[0].clientY];
28954    }).on('touchend', 'section.prefab-slider .carousel-inner', function () {
28955        var moved = [touchEnd[0] - touchStart[0], touchEnd[1] - touchStart[1]];
28956
28957        if (Math.abs(moved[0]) > Math.abs(moved[1]) && Math.abs(moved[0]) > touchDeadzone) {
28958            if (moved[0] < 0) {
28959                $(this).parents('.prefab-slider').carousel('next');
28960            } else {
28961                $(this).parents('.prefab-slider').carousel('prev');
28962            }
28963        }
28964    });
28965});
28966
28967$(function () {
28968    "use strict";
28969
28970    $(window).on('orientationchange resize scroll', function () {
28971        var toTopElement = $('section.prefab-to-top');
28972        var shouldBeVisible = document.body.scrollTop > 0;
28973        var isVisible = toTopElement.hasClass('visible');
28974
28975        if (shouldBeVisible && !isVisible) {
28976            toTopElement.removeClass('hidden');
28977            setTimeout(function() {
28978                toTopElement.addClass('visible');
28979            });
28980        } else if (!shouldBeVisible && isVisible) {
28981            toTopElement.one('transitionend', function() {
28982                if (!toTopElement.hasClass('visible')) {
28983                    toTopElement.addClass('hidden');
28984                }
28985            }).removeClass('visible');
28986        }
28987    });
28988});
28989
28990
28991$(function () {
28992    "use strict";
28993
28994    $(document).on('click', 'section.cookieInfo button', function () {
28995       $('section.cookieInfo').addClass('hidden');
28996       setCookie("coockie_accepted", true, 365);
28997    });
28998});
28999
29000function setCookie(cname, cvalue, exdays) {
29001    var d = new Date();
29002    d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
29003    var expires = "expires="+d.toUTCString();
29004    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
29005}
29006
29007$(function () {
29008    "use strict";
29009
29010    $(window).on('load',function(){
29011        var url = window.location.href;
29012        if (url == 'https://www.hotel-hammer.com/' || url == 'https://www.hotel-hammer.com/home' || url == 'https://hotel-hammer.com/' || url == 'https://hotel-hammer.com/home') {
29013            $('#newsModal').modal('show');        
29014        }
29015    });
29016    
29017$('#closeNewsModal').on('click', function(){
29018    setCookie('newsModal', 'closed');
29019});
29020
29021    // Here goes the custom functionality!
29022    $('.toggleview, .shutter').click(function() {
29023       $(this).parents('.quickBooking').toggleClass('hideit');
29024    });
29025
29026    $('section.sidetab .tab').click(function() {
29027        $(this).parents('.sidetab-container').toggleClass('sidetab-open');
29028    });
29029
29030    $('.infoTrigger').click(function() {
29031        if ($(this).children('.infobox').hasClass('openBox')){
29032            $(this).children('.infobox').removeClass('openBox');
29033        }
29034        else {
29035            $('.infobox.openBox').removeClass('openBox');
29036            $(this).children('.infobox').addClass('openBox');
29037        }
29038
29039
29040    });
29041
29042
29043    // Helpfull debouncer - avoid triggering an event too often.
29044    window.debounce = function(callback, delay) {
29045        return function() {
29046            if (debounce.data.callbacks.indexOf(callback) != -1) {
29047                var index = debounce.data.callbacks.indexOf(callback);
29048                clearTimeout(debounce.data.timeouts[index]);
29049                debounce.data.callbacks.splice(index, 1);
29050                debounce.data.timeouts.splice(index, 1);
29051            }
29052
29053            debounce.data.callbacks.push(callback);
29054            debounce.data.timeouts.push(window.setTimeout(callback, delay));
29055        };
29056    };
29057    debounce.data = { timeouts: [], callbacks: [] };
29058
29059    // IE / Edge object-fit polyfill
29060    if (detectIE()) {
29061        var simulateObjectFit = function() {
29062            $('.object-fit').each(function() {
29063                var width = this.naturalWidth;
29064                var height = this.naturalHeight;
29065                var parentWidth = $(this).parents('div').width();
29066                var parentHeight = $(this).parents('div').height();
29067                var factor = Math.max(parentWidth / width, parentHeight/ height);
29068                $(this).css({ width: width * factor, height: height * factor, top: "50%", left: "50%", transform: "translate(-50%, -50%)" });
29069            });
29070        };
29071
29072        simulateObjectFit();
29073        $(window).on('resize', debounce(simulateObjectFit, 200));
29074    }
29075
29076    $('a[data-roomid]').click(function(event) {
29077        event.preventDefault();
29078        var roomId = $(this).data('roomid');
29079        Booking.Open({
29080            RoomID: roomId,
29081            Occupancy: 1,
29082        });
29083    });
29084    
29085    $('a[data-offerid]').click(function(event) {
29086        event.preventDefault();
29087        var offerId = $(this).data('offerid');
29088        Booking.Open({ OfferID: offerId });
29089    });
29090
29091    $('.quickBooking button[data-type="submit"]').on('click', function() {
29092       Booking.Open({
29093           CheckinDate: $(this).parents('.quickBooking').find('[name="from"]').val(),
29094           CheckoutDate: $(this).parents('.quickBooking').find('[name="to"]').val(),
29095       });
29096    });
29097
29098    $('.quickBooking .openDatepicker').on('click', function() {
29099        $(this).parent().find('input').focus();
29100    });
29101
29102    $('.quickBooking input').on('change', function() {
29103        var container = $(this).parent().find('[data-input="' + $(this).attr('name') + '"]');
29104        var date = $(this).val().split('-');
29105        container.children('.year').html(date[0]);
29106        container.children('.month').html(container.children('.month').data('month' + date[1]));
29107        container.children('.day').html(date[2] + '.');
29108    });
29109	
29110	$('.quickBooking input[name="from"]').on('change', function() {
29111		var date = new Date($(this).val());
29112		date.setDate(date.getDate() + 1);
29113		var curr_day = date.getDate();
29114		var curr_month = date.getMonth();
29115		var curr_year = date.getFullYear();
29116		curr_month++;
29117		var newDate = curr_year + "-" + padDigits(curr_month,2) + "-" + padDigits(curr_day,2);
29118		$('.quickBooking input[name="to"]').val(newDate);
29119		$('.quickBooking input[name="to"]').trigger("change");
29120	}).change().datepicker({ dateFormat: "yy-mm-dd", minDate: new Date() });
29121	
29122	$('.quickBooking input[name="to"]').on('change', function() {
29123		var dateTo = new Date($(this).val());
29124		var dateFrom = new Date($('.quickBooking input[name="from"]').val());
29125		if(dateFrom >= dateTo) {
29126			dateFrom.setDate(dateTo.getDate() - 1);
29127			
29128			var curr_day = dateFrom.getDate();
29129			var curr_month = dateFrom.getMonth();
29130			var curr_year = dateFrom.getFullYear();
29131			curr_month++;
29132			var newDate = curr_year + "-" + padDigits(curr_month,2) + "-" + padDigits(curr_day,2);
29133			$('.quickBooking input[name="from"]').val(newDate);
29134			$('.quickBooking input[name="from"]').trigger("change");
29135		}
29136	}).change().datepicker({ dateFormat: "yy-mm-dd", minDate: new Date(Date.now() + 1*24*60*60*1000) });
29137	
29138	
29139	function padDigits(number, digits) {
29140		return Array(Math.max(digits - String(number).length + 1, 0)).join(0) + number;
29141	}
29142
29143// Generate Arcs in Review Page
29144    $('.ratings canvas').each( function(){
29145        ARC({
29146            forecolor: '#ba9b4d', // Color of drawn arc.
29147            backcolor: '#ffffff', // Color of the rest of arc
29148            thickness: 20,       // Thickness of the arc.
29149            angle: parseInt($(this).data('overall')) * (360 / 100),   // The angle which will be filled with the foreColor
29150            start: -90,   // Starting angle, 0 is right, always clockwise.
29151            radius: null, // Radius for the arc. Uses maximum possible if null.
29152            element: this // Use canvas element to draw into this canvas and use this canvas size.
29153        });
29154    });
29155
29156    // Prevent background scrolling for fixed elements
29157    $('.noscroll').on('touchmove', function(event) {
29158        event.preventDefault();
29159    });
29160    
29161    //autorun slider homepage right top
29162    $('section.prefab-startscreen .menublock.smaller.textblock .carousel').carousel({
29163        interval: 9000
29164    })
29165    
29166    /**
29167 * detect IE
29168 * returns version of IE or false, if browser is not Internet Explorer
29169 */
29170function detectIE() {
29171    var ua = window.navigator.userAgent;
29172
29173    var msie = ua.indexOf('MSIE ');
29174    if (msie > 0) {
29175        // IE 10 or older => return version number
29176        return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
29177    }
29178
29179    var trident = ua.indexOf('Trident/');
29180    if (trident > 0) {
29181        // IE 11 => return version number
29182        var rv = ua.indexOf('rv:');
29183        return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
29184    }
29185
29186    var edge = ua.indexOf('Edge/');
29187    if (edge > 0) {
29188       // Edge (IE 12+) => return version number
29189       return parseInt(ua.substring(edge + 5, ua.indexOf('.', edge)), 10);
29190    }
29191
29192    // other browser
29193    return false;
29194}
29195
29196});
29197

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.