PageSourceSearch

https://abs.org.sg/Sitefinity/WebsiteTemplates/ContentLayout/App_Themes/ContentLayout/js/jquery-ui.js

js abs.org.sg collected 2026-09-24 08:47:34 UTC 520,098 bytes, 18,686 lines download raw bytes

vendor: 4,756 bytes, lines 1-143
1/*! jQuery UI - v1.12.0 - 2016-07-08
2* http://jqueryui.com
3* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
4* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6(function( factory ) {
7	if ( typeof define === "function" && define.amd ) {
8
9		// AMD. Register as an anonymous module.
10		define([ "jquery" ], factory );
11	} else {
12
13		// Browser globals
14		factory( jQuery );
15	}
16}(function( $ ) {
17
18$.ui = $.ui || {};
19
20var version = $.ui.version = "1.12.0";
21
22
23/*!
24 * jQuery UI Widget 1.12.0
25 * http://jqueryui.com
26 *
27 * Copyright jQuery Foundation and other contributors
28 * Released under the MIT license.
29 * http://jquery.org/license
30 */
31
32//>>label: Widget
33//>>group: Core
34//>>description: Provides a factory for creating stateful widgets with a common API.
35//>>docs: http://api.jqueryui.com/jQuery.widget/
36//>>demos: http://jqueryui.com/widget/
37
38
39
40var widgetUuid = 0;
41var widgetSlice = Array.prototype.slice;
42
43$.cleanData = ( function( orig ) {
44	return function( elems ) {
45		var events, elem, i;
46		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
47			try {
48
49				// Only trigger remove when necessary to save time
50				events = $._data( elem, "events" );
51				if ( events && events.remove ) {
52					$( elem ).triggerHandler( "remove" );
53				}
54
55			// Http://bugs.jquery.com/ticket/8235
56			} catch ( e ) {}
57		}
58		orig( elems );
59	};
60} )( $.cleanData );
61
62$.widget = function( name, base, prototype ) {
63	var existingConstructor, constructor, basePrototype;
64
65	// ProxiedPrototype allows the provided prototype to remain unmodified
66	// so that it can be used as a mixin for multiple widgets (#8876)
67	var proxiedPrototype = {};
68
69	var namespace = name.split( "." )[ 0 ];
70	name = name.split( "." )[ 1 ];
71	var fullName = namespace + "-" + name;
72
73	if ( !prototype ) {
74		prototype = base;
75		base = $.Widget;
76	}
77
78	if ( $.isArray( prototype ) ) {
79		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80	}
81
82	// Create selector for plugin
83	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84		return !!$.data( elem, fullName );
85	};
86
87	$[ namespace ] = $[ namespace ] || {};
88	existingConstructor = $[ namespace ][ name ];
89	constructor = $[ namespace ][ name ] = function( options, element ) {
90
91		// Allow instantiation without "new" keyword
92		if ( !this._createWidget ) {
93			return new constructor( options, element );
94		}
95
96		// Allow instantiation without initializing for simple inheritance
97		// must use "new" keyword (the code above always passes args)
98		if ( arguments.length ) {
99			this._createWidget( options, element );
100		}
101	};
102
103	// Extend with the existing constructor to carry over any static properties
104	$.extend( constructor, existingConstructor, {
105		version: prototype.version,
106
107		// Copy the object used to create the prototype in case we need to
108		// redefine the widget later
109		_proto: $.extend( {}, prototype ),
110
111		// Track widgets that inherit from this widget in case this widget is
112		// redefined after a widget inherits from it
113		_childConstructors: []
114	} );
115
116	basePrototype = new base();
117
118	// We need to make the options hash a property directly on the new instance
119	// otherwise we'll modify the options hash on the prototype that we're
120	// inheriting from
121	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122	$.each( prototype, function( prop, value ) {
123		if ( !$.isFunction( value ) ) {
124			proxiedPrototype[ prop ] = value;
125			return;
126		}
127		proxiedPrototype[ prop ] = ( function() {
128			function _super() {
129				return base.prototype[ prop ].apply( this, arguments );
130			}
131
132			function _superApply( args ) {
133				return base.prototype[ prop ].apply( this, args );
134			}
135
136			return function() {
137				var __super = this._super;
138				var __superApply = this._superApply;
139				var returnValue;
140
141				this._super = _super;
142				this._superApply = _superApply;
143
vendor: 4,870 bytes, lines 144-323
144				returnValue = value.apply( this, arguments );
145
146				this._super = __super;
147				this._superApply = __superApply;
148
149				return returnValue;
150			};
151		} )();
152	} );
153	constructor.prototype = $.widget.extend( basePrototype, {
154
155		// TODO: remove support for widgetEventPrefix
156		// always use the name + a colon as the prefix, e.g., draggable:start
157		// don't prefix for widgets that aren't DOM-based
158		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159	}, proxiedPrototype, {
160		constructor: constructor,
161		namespace: namespace,
162		widgetName: name,
163		widgetFullName: fullName
164	} );
165
166	// If this widget is being redefined then we need to find all widgets that
167	// are inheriting from it and redefine all of them so that they inherit from
168	// the new version of this widget. We're essentially trying to replace one
169	// level in the prototype chain.
170	if ( existingConstructor ) {
171		$.each( existingConstructor._childConstructors, function( i, child ) {
172			var childPrototype = child.prototype;
173
174			// Redefine the child widget using the same prototype that was
175			// originally used, but inherit from the new version of the base
176			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177				child._proto );
178		} );
179
180		// Remove the list of existing child constructors from the old constructor
181		// so the old child constructors can be garbage collected
182		delete existingConstructor._childConstructors;
183	} else {
184		base._childConstructors.push( constructor );
185	}
186
187	$.widget.bridge( name, constructor );
188
189	return constructor;
190};
191
192$.widget.extend = function( target ) {
193	var input = widgetSlice.call( arguments, 1 );
194	var inputIndex = 0;
195	var inputLength = input.length;
196	var key;
197	var value;
198
199	for ( ; inputIndex < inputLength; inputIndex++ ) {
200		for ( key in input[ inputIndex ] ) {
201			value = input[ inputIndex ][ key ];
202			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204				// Clone objects
205				if ( $.isPlainObject( value ) ) {
206					target[ key ] = $.isPlainObject( target[ key ] ) ?
207						$.widget.extend( {}, target[ key ], value ) :
208
209						// Don't extend strings, arrays, etc. with objects
210						$.widget.extend( {}, value );
211
212				// Copy everything else by reference
213				} else {
214					target[ key ] = value;
215				}
216			}
217		}
218	}
219	return target;
220};
221
222$.widget.bridge = function( name, object ) {
223	var fullName = object.prototype.widgetFullName || name;
224	$.fn[ name ] = function( options ) {
225		var isMethodCall = typeof options === "string";
226		var args = widgetSlice.call( arguments, 1 );
227		var returnValue = this;
228
229		if ( isMethodCall ) {
230			this.each( function() {
231				var methodValue;
232				var instance = $.data( this, fullName );
233
234				if ( options === "instance" ) {
235					returnValue = instance;
236					return false;
237				}
238
239				if ( !instance ) {
240					return $.error( "cannot call methods on " + name +
241						" prior to initialization; " +
242						"attempted to call method '" + options + "'" );
243				}
244
245				if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
246					return $.error( "no such method '" + options + "' for " + name +
247						" widget instance" );
248				}
249
250				methodValue = instance[ options ].apply( instance, args );
251
252				if ( methodValue !== instance && methodValue !== undefined ) {
253					returnValue = methodValue && methodValue.jquery ?
254						returnValue.pushStack( methodValue.get() ) :
255						methodValue;
256					return false;
257				}
258			} );
259		} else {
260
261			// Allow multiple hashes to be passed on init
262			if ( args.length ) {
263				options = $.widget.extend.apply( null, [ options ].concat( args ) );
264			}
265
266			this.each( function() {
267				var instance = $.data( this, fullName );
268				if ( instance ) {
269					instance.option( options || {} );
270					if ( instance._init ) {
271						instance._init();
272					}
273				} else {
274					$.data( this, fullName, new object( options, this ) );
275				}
276			} );
277		}
278
279		return returnValue;
280	};
281};
282
283$.Widget = function( /* options, element */ ) {};
284$.Widget._childConstructors = [];
285
286$.Widget.prototype = {
287	widgetName: "widget",
288	widgetEventPrefix: "",
289	defaultElement: "<div>",
290
291	options: {
292		classes: {},
293		disabled: false,
294
295		// Callbacks
296		create: null
297	},
298
299	_createWidget: function( options, element ) {
300		element = $( element || this.defaultElement || this )[ 0 ];
301		this.element = $( element );
302		this.uuid = widgetUuid++;
303		this.eventNamespace = "." + this.widgetName + this.uuid;
304
305		this.bindings = $();
306		this.hoverable = $();
307		this.focusable = $();
308		this.classesElementLookup = {};
309
310		if ( element !== this ) {
311			$.data( element, this.widgetFullName, this );
312			this._on( true, this.element, {
313				remove: function( event ) {
314					if ( event.target === element ) {
315						this.destroy();
316					}
317				}
318			} );
319			this.document = $( element.style ?
320
321				// Element within the document
322				element.ownerDocument :
323
vendor: 6,145 bytes, lines 324-561
324				// Element is window or document
325				element.document || element );
326			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
327		}
328
329		this.options = $.widget.extend( {},
330			this.options,
331			this._getCreateOptions(),
332			options );
333
334		this._create();
335
336		if ( this.options.disabled ) {
337			this._setOptionDisabled( this.options.disabled );
338		}
339
340		this._trigger( "create", null, this._getCreateEventData() );
341		this._init();
342	},
343
344	_getCreateOptions: function() {
345		return {};
346	},
347
348	_getCreateEventData: $.noop,
349
350	_create: $.noop,
351
352	_init: $.noop,
353
354	destroy: function() {
355		var that = this;
356
357		this._destroy();
358		$.each( this.classesElementLookup, function( key, value ) {
359			that._removeClass( value, key );
360		} );
361
362		// We can probably remove the unbind calls in 2.0
363		// all event bindings should go through this._on()
364		this.element
365			.off( this.eventNamespace )
366			.removeData( this.widgetFullName );
367		this.widget()
368			.off( this.eventNamespace )
369			.removeAttr( "aria-disabled" );
370
371		// Clean up events and states
372		this.bindings.off( this.eventNamespace );
373	},
374
375	_destroy: $.noop,
376
377	widget: function() {
378		return this.element;
379	},
380
381	option: function( key, value ) {
382		var options = key;
383		var parts;
384		var curOption;
385		var i;
386
387		if ( arguments.length === 0 ) {
388
389			// Don't return a reference to the internal hash
390			return $.widget.extend( {}, this.options );
391		}
392
393		if ( typeof key === "string" ) {
394
395			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
396			options = {};
397			parts = key.split( "." );
398			key = parts.shift();
399			if ( parts.length ) {
400				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
401				for ( i = 0; i < parts.length - 1; i++ ) {
402					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
403					curOption = curOption[ parts[ i ] ];
404				}
405				key = parts.pop();
406				if ( arguments.length === 1 ) {
407					return curOption[ key ] === undefined ? null : curOption[ key ];
408				}
409				curOption[ key ] = value;
410			} else {
411				if ( arguments.length === 1 ) {
412					return this.options[ key ] === undefined ? null : this.options[ key ];
413				}
414				options[ key ] = value;
415			}
416		}
417
418		this._setOptions( options );
419
420		return this;
421	},
422
423	_setOptions: function( options ) {
424		var key;
425
426		for ( key in options ) {
427			this._setOption( key, options[ key ] );
428		}
429
430		return this;
431	},
432
433	_setOption: function( key, value ) {
434		if ( key === "classes" ) {
435			this._setOptionClasses( value );
436		}
437
438		this.options[ key ] = value;
439
440		if ( key === "disabled" ) {
441			this._setOptionDisabled( value );
442		}
443
444		return this;
445	},
446
447	_setOptionClasses: function( value ) {
448		var classKey, elements, currentElements;
449
450		for ( classKey in value ) {
451			currentElements = this.classesElementLookup[ classKey ];
452			if ( value[ classKey ] === this.options.classes[ classKey ] ||
453					!currentElements ||
454					!currentElements.length ) {
455				continue;
456			}
457
458			// We are doing this to create a new jQuery object because the _removeClass() call
459			// on the next line is going to destroy the reference to the current elements being
460			// tracked. We need to save a copy of this collection so that we can add the new classes
461			// below.
462			elements = $( currentElements.get() );
463			this._removeClass( currentElements, classKey );
464
465			// We don't use _addClass() here, because that uses this.options.classes
466			// for generating the string of classes. We want to use the value passed in from
467			// _setOption(), this is the new value of the classes option which was passed to
468			// _setOption(). We pass this value directly to _classes().
469			elements.addClass( this._classes( {
470				element: elements,
471				keys: classKey,
472				classes: value,
473				add: true
474			} ) );
475		}
476	},
477
478	_setOptionDisabled: function( value ) {
479		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
480
481		// If the widget is becoming disabled, then nothing is interactive
482		if ( value ) {
483			this._removeClass( this.hoverable, null, "ui-state-hover" );
484			this._removeClass( this.focusable, null, "ui-state-focus" );
485		}
486	},
487
488	enable: function() {
489		return this._setOptions( { disabled: false } );
490	},
491
492	disable: function() {
493		return this._setOptions( { disabled: true } );
494	},
495
496	_classes: function( options ) {
497		var full = [];
498		var that = this;
499
500		options = $.extend( {
501			element: this.element,
502			classes: this.options.classes || {}
503		}, options );
504
505		function processClassString( classes, checkOption ) {
506			var current, i;
507			for ( i = 0; i < classes.length; i++ ) {
508				current = that.classesElementLookup[ classes[ i ] ] || $();
509				if ( options.add ) {
510					current = $( $.unique( current.get().concat( options.element.get() ) ) );
511				} else {
512					current = $( current.not( options.element ).get() );
513				}
514				that.classesElementLookup[ classes[ i ] ] = current;
515				full.push( classes[ i ] );
516				if ( checkOption && options.classes[ classes[ i ] ] ) {
517					full.push( options.classes[ classes[ i ] ] );
518				}
519			}
520		}
521
522		if ( options.keys ) {
523			processClassString( options.keys.match( /\S+/g ) || [], true );
524		}
525		if ( options.extra ) {
526			processClassString( options.extra.match( /\S+/g ) || [] );
527		}
528
529		return full.join( " " );
530	},
531
532	_removeClass: function( element, keys, extra ) {
533		return this._toggleClass( element, keys, extra, false );
534	},
535
536	_addClass: function( element, keys, extra ) {
537		return this._toggleClass( element, keys, extra, true );
538	},
539
540	_toggleClass: function( element, keys, extra, add ) {
541		add = ( typeof add === "boolean" ) ? add : extra;
542		var shift = ( typeof element === "string" || element === null ),
543			options = {
544				extra: shift ? keys : extra,
545				keys: shift ? element : keys,
546				element: shift ? this.element : element,
547				add: add
548			};
549		options.element.toggleClass( this._classes( options ), add );
550		return this;
551	},
552
553	_on: function( suppressDisabledCheck, element, handlers ) {
554		var delegateElement;
555		var instance = this;
556
557		// No suppressDisabledCheck flag, shuffle arguments
558		if ( typeof suppressDisabledCheck !== "boolean" ) {
559			handlers = element;
560			element = suppressDisabledCheck;
561			suppressDisabledCheck = false;
vendor: 4,288 bytes, lines 562-709
562		}
563
564		// No element argument, shuffle and use this.element
565		if ( !handlers ) {
566			handlers = element;
567			element = this.element;
568			delegateElement = this.widget();
569		} else {
570			element = delegateElement = $( element );
571			this.bindings = this.bindings.add( element );
572		}
573
574		$.each( handlers, function( event, handler ) {
575			function handlerProxy() {
576
577				// Allow widgets to customize the disabled handling
578				// - disabled as an array instead of boolean
579				// - disabled class as method for disabling individual parts
580				if ( !suppressDisabledCheck &&
581						( instance.options.disabled === true ||
582						$( this ).hasClass( "ui-state-disabled" ) ) ) {
583					return;
584				}
585				return ( typeof handler === "string" ? instance[ handler ] : handler )
586					.apply( instance, arguments );
587			}
588
589			// Copy the guid so direct unbinding works
590			if ( typeof handler !== "string" ) {
591				handlerProxy.guid = handler.guid =
592					handler.guid || handlerProxy.guid || $.guid++;
593			}
594
595			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
596			var eventName = match[ 1 ] + instance.eventNamespace;
597			var selector = match[ 2 ];
598
599			if ( selector ) {
600				delegateElement.on( eventName, selector, handlerProxy );
601			} else {
602				element.on( eventName, handlerProxy );
603			}
604		} );
605	},
606
607	_off: function( element, eventName ) {
608		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
609			this.eventNamespace;
610		element.off( eventName ).off( eventName );
611
612		// Clear the stack to avoid memory leaks (#10056)
613		this.bindings = $( this.bindings.not( element ).get() );
614		this.focusable = $( this.focusable.not( element ).get() );
615		this.hoverable = $( this.hoverable.not( element ).get() );
616	},
617
618	_delay: function( handler, delay ) {
619		function handlerProxy() {
620			return ( typeof handler === "string" ? instance[ handler ] : handler )
621				.apply( instance, arguments );
622		}
623		var instance = this;
624		return setTimeout( handlerProxy, delay || 0 );
625	},
626
627	_hoverable: function( element ) {
628		this.hoverable = this.hoverable.add( element );
629		this._on( element, {
630			mouseenter: function( event ) {
631				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
632			},
633			mouseleave: function( event ) {
634				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
635			}
636		} );
637	},
638
639	_focusable: function( element ) {
640		this.focusable = this.focusable.add( element );
641		this._on( element, {
642			focusin: function( event ) {
643				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
644			},
645			focusout: function( event ) {
646				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
647			}
648		} );
649	},
650
651	_trigger: function( type, event, data ) {
652		var prop, orig;
653		var callback = this.options[ type ];
654
655		data = data || {};
656		event = $.Event( event );
657		event.type = ( type === this.widgetEventPrefix ?
658			type :
659			this.widgetEventPrefix + type ).toLowerCase();
660
661		// The original event may come from any element
662		// so we need to reset the target on the new event
663		event.target = this.element[ 0 ];
664
665		// Copy original event properties over to the new event
666		orig = event.originalEvent;
667		if ( orig ) {
668			for ( prop in orig ) {
669				if ( !( prop in event ) ) {
670					event[ prop ] = orig[ prop ];
671				}
672			}
673		}
674
675		this.element.trigger( event, data );
676		return !( $.isFunction( callback ) &&
677			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
678			event.isDefaultPrevented() );
679	}
680};
681
682$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
683	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
684		if ( typeof options === "string" ) {
685			options = { effect: options };
686		}
687
688		var hasOptions;
689		var effectName = !options ?
690			method :
691			options === true || typeof options === "number" ?
692				defaultEffect :
693				options.effect || defaultEffect;
694
695		options = options || {};
696		if ( typeof options === "number" ) {
697			options = { duration: options };
698		}
699
700		hasOptions = !$.isEmptyObject( options );
701		options.complete = callback;
702
703		if ( options.delay ) {
704			element.delay( options.delay );
705		}
706
707		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
708			element[ method ]( options );
709		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 5,193 bytes, lines 710-910
710			element[ effectName ]( options.duration, options.easing, callback );
711		} else {
712			element.queue( function( next ) {
713				$( this )[ method ]();
714				if ( callback ) {
715					callback.call( element[ 0 ] );
716				}
717				next();
718			} );
719		}
720	};
721} );
722
723var widget = $.widget;
724
725
726/*!
727 * jQuery UI Position 1.12.0
728 * http://jqueryui.com
729 *
730 * Copyright jQuery Foundation and other contributors
731 * Released under the MIT license.
732 * http://jquery.org/license
733 *
734 * http://api.jqueryui.com/position/
735 */
736
737//>>label: Position
738//>>group: Core
739//>>description: Positions elements relative to other elements.
740//>>docs: http://api.jqueryui.com/position/
741//>>demos: http://jqueryui.com/position/
742
743
744( function() {
745var cachedScrollbarWidth, supportsOffsetFractions,
746	max = Math.max,
747	abs = Math.abs,
748	round = Math.round,
749	rhorizontal = /left|center|right/,
750	rvertical = /top|center|bottom/,
751	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
752	rposition = /^\w+/,
753	rpercent = /%$/,
754	_position = $.fn.position;
755
756// Support: IE <=9 only
757supportsOffsetFractions = function() {
758	var element = $( "<div>" )
759			.css( "position", "absolute" )
760			.appendTo( "body" )
761			.offset( {
762				top: 1.5,
763				left: 1.5
764			} ),
765		support = element.offset().top === 1.5;
766
767	element.remove();
768
769	supportsOffsetFractions = function() {
770		return support;
771	};
772
773	return support;
774};
775
776function getOffsets( offsets, width, height ) {
777	return [
778		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
779		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
780	];
781}
782
783function parseCss( element, property ) {
784	return parseInt( $.css( element, property ), 10 ) || 0;
785}
786
787function getDimensions( elem ) {
788	var raw = elem[ 0 ];
789	if ( raw.nodeType === 9 ) {
790		return {
791			width: elem.width(),
792			height: elem.height(),
793			offset: { top: 0, left: 0 }
794		};
795	}
796	if ( $.isWindow( raw ) ) {
797		return {
798			width: elem.width(),
799			height: elem.height(),
800			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
801		};
802	}
803	if ( raw.preventDefault ) {
804		return {
805			width: 0,
806			height: 0,
807			offset: { top: raw.pageY, left: raw.pageX }
808		};
809	}
810	return {
811		width: elem.outerWidth(),
812		height: elem.outerHeight(),
813		offset: elem.offset()
814	};
815}
816
817$.position = {
818	scrollbarWidth: function() {
819		if ( cachedScrollbarWidth !== undefined ) {
820			return cachedScrollbarWidth;
821		}
822		var w1, w2,
823			div = $( "<div " +
824				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
825				"<div style='height:100px;width:auto;'></div></div>" ),
826			innerDiv = div.children()[ 0 ];
827
828		$( "body" ).append( div );
829		w1 = innerDiv.offsetWidth;
830		div.css( "overflow", "scroll" );
831
832		w2 = innerDiv.offsetWidth;
833
834		if ( w1 === w2 ) {
835			w2 = div[ 0 ].clientWidth;
836		}
837
838		div.remove();
839
840		return ( cachedScrollbarWidth = w1 - w2 );
841	},
842	getScrollInfo: function( within ) {
843		var overflowX = within.isWindow || within.isDocument ? "" :
844				within.element.css( "overflow-x" ),
845			overflowY = within.isWindow || within.isDocument ? "" :
846				within.element.css( "overflow-y" ),
847			hasOverflowX = overflowX === "scroll" ||
848				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
849			hasOverflowY = overflowY === "scroll" ||
850				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
851		return {
852			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
853			height: hasOverflowX ? $.position.scrollbarWidth() : 0
854		};
855	},
856	getWithinInfo: function( element ) {
857		var withinElement = $( element || window ),
858			isWindow = $.isWindow( withinElement[ 0 ] ),
859			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
860			hasOffset = !isWindow && !isDocument;
861		return {
862			element: withinElement,
863			isWindow: isWindow,
864			isDocument: isDocument,
865			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
866			scrollLeft: withinElement.scrollLeft(),
867			scrollTop: withinElement.scrollTop(),
868			width: withinElement.outerWidth(),
869			height: withinElement.outerHeight()
870		};
871	}
872};
873
874$.fn.position = function( options ) {
875	if ( !options || !options.of ) {
876		return _position.apply( this, arguments );
877	}
878
879	// Make a copy, we don't want to modify arguments
880	options = $.extend( {}, options );
881
882	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
883		target = $( options.of ),
884		within = $.position.getWithinInfo( options.within ),
885		scrollInfo = $.position.getScrollInfo( within ),
886		collision = ( options.collision || "flip" ).split( " " ),
887		offsets = {};
888
889	dimensions = getDimensions( target );
890	if ( target[ 0 ].preventDefault ) {
891
892		// Force left top to allow flipping
893		options.at = "left top";
894	}
895	targetWidth = dimensions.width;
896	targetHeight = dimensions.height;
897	targetOffset = dimensions.offset;
898
899	// Clone to reuse original targetOffset later
900	basePosition = $.extend( {}, targetOffset );
901
902	// Force my and at to have valid horizontal and vertical positions
903	// if a value is missing or invalid, it will be converted to center
904	$.each( [ "my", "at" ], function() {
905		var pos = ( options[ this ] || "" ).split( " " ),
906			horizontalOffset,
907			verticalOffset;
908
909		if ( pos.length === 1 ) {
910			pos = rhorizontal.test( pos[ 0 ] ) ?
vendor: 4,807 bytes, lines 911-1069
911				pos.concat( [ "center" ] ) :
912				rvertical.test( pos[ 0 ] ) ?
913					[ "center" ].concat( pos ) :
914					[ "center", "center" ];
915		}
916		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
917		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
918
919		// Calculate offsets
920		horizontalOffset = roffset.exec( pos[ 0 ] );
921		verticalOffset = roffset.exec( pos[ 1 ] );
922		offsets[ this ] = [
923			horizontalOffset ? horizontalOffset[ 0 ] : 0,
924			verticalOffset ? verticalOffset[ 0 ] : 0
925		];
926
927		// Reduce to just the positions without the offsets
928		options[ this ] = [
929			rposition.exec( pos[ 0 ] )[ 0 ],
930			rposition.exec( pos[ 1 ] )[ 0 ]
931		];
932	} );
933
934	// Normalize collision option
935	if ( collision.length === 1 ) {
936		collision[ 1 ] = collision[ 0 ];
937	}
938
939	if ( options.at[ 0 ] === "right" ) {
940		basePosition.left += targetWidth;
941	} else if ( options.at[ 0 ] === "center" ) {
942		basePosition.left += targetWidth / 2;
943	}
944
945	if ( options.at[ 1 ] === "bottom" ) {
946		basePosition.top += targetHeight;
947	} else if ( options.at[ 1 ] === "center" ) {
948		basePosition.top += targetHeight / 2;
949	}
950
951	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
952	basePosition.left += atOffset[ 0 ];
953	basePosition.top += atOffset[ 1 ];
954
955	return this.each( function() {
956		var collisionPosition, using,
957			elem = $( this ),
958			elemWidth = elem.outerWidth(),
959			elemHeight = elem.outerHeight(),
960			marginLeft = parseCss( this, "marginLeft" ),
961			marginTop = parseCss( this, "marginTop" ),
962			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
963				scrollInfo.width,
964			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
965				scrollInfo.height,
966			position = $.extend( {}, basePosition ),
967			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
968
969		if ( options.my[ 0 ] === "right" ) {
970			position.left -= elemWidth;
971		} else if ( options.my[ 0 ] === "center" ) {
972			position.left -= elemWidth / 2;
973		}
974
975		if ( options.my[ 1 ] === "bottom" ) {
976			position.top -= elemHeight;
977		} else if ( options.my[ 1 ] === "center" ) {
978			position.top -= elemHeight / 2;
979		}
980
981		position.left += myOffset[ 0 ];
982		position.top += myOffset[ 1 ];
983
984		// If the browser doesn't support fractions, then round for consistent results
985		if ( !supportsOffsetFractions() ) {
986			position.left = round( position.left );
987			position.top = round( position.top );
988		}
989
990		collisionPosition = {
991			marginLeft: marginLeft,
992			marginTop: marginTop
993		};
994
995		$.each( [ "left", "top" ], function( i, dir ) {
996			if ( $.ui.position[ collision[ i ] ] ) {
997				$.ui.position[ collision[ i ] ][ dir ]( position, {
998					targetWidth: targetWidth,
999					targetHeight: targetHeight,
1000					elemWidth: elemWidth,
1001					elemHeight: elemHeight,
1002					collisionPosition: collisionPosition,
1003					collisionWidth: collisionWidth,
1004					collisionHeight: collisionHeight,
1005					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1006					my: options.my,
1007					at: options.at,
1008					within: within,
1009					elem: elem
1010				} );
1011			}
1012		} );
1013
1014		if ( options.using ) {
1015
1016			// Adds feedback as second argument to using callback, if present
1017			using = function( props ) {
1018				var left = targetOffset.left - position.left,
1019					right = left + targetWidth - elemWidth,
1020					top = targetOffset.top - position.top,
1021					bottom = top + targetHeight - elemHeight,
1022					feedback = {
1023						target: {
1024							element: target,
1025							left: targetOffset.left,
1026							top: targetOffset.top,
1027							width: targetWidth,
1028							height: targetHeight
1029						},
1030						element: {
1031							element: elem,
1032							left: position.left,
1033							top: position.top,
1034							width: elemWidth,
1035							height: elemHeight
1036						},
1037						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1038						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1039					};
1040				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1041					feedback.horizontal = "center";
1042				}
1043				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1044					feedback.vertical = "middle";
1045				}
1046				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1047					feedback.important = "horizontal";
1048				} else {
1049					feedback.important = "vertical";
1050				}
1051				options.using.call( this, props, feedback );
1052			};
1053		}
1054
1055		elem.offset( $.extend( position, { using: using } ) );
1056	} );
1057};
1058
1059$.ui.position = {
1060	fit: {
1061		left: function( position, data ) {
1062			var within = data.within,
1063				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1064				outerWidth = within.width,
1065				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1066				overLeft = withinOffset - collisionPosLeft,
1067				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1068				newOverRight;
1069
vendor: 5,709 bytes, lines 1070-1250
1070			// Element is wider than within
1071			if ( data.collisionWidth > outerWidth ) {
1072
1073				// Element is initially over the left side of within
1074				if ( overLeft > 0 && overRight <= 0 ) {
1075					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1076						withinOffset;
1077					position.left += overLeft - newOverRight;
1078
1079				// Element is initially over right side of within
1080				} else if ( overRight > 0 && overLeft <= 0 ) {
1081					position.left = withinOffset;
1082
1083				// Element is initially over both left and right sides of within
1084				} else {
1085					if ( overLeft > overRight ) {
1086						position.left = withinOffset + outerWidth - data.collisionWidth;
1087					} else {
1088						position.left = withinOffset;
1089					}
1090				}
1091
1092			// Too far left -> align with left edge
1093			} else if ( overLeft > 0 ) {
1094				position.left += overLeft;
1095
1096			// Too far right -> align with right edge
1097			} else if ( overRight > 0 ) {
1098				position.left -= overRight;
1099
1100			// Adjust based on position and margin
1101			} else {
1102				position.left = max( position.left - collisionPosLeft, position.left );
1103			}
1104		},
1105		top: function( position, data ) {
1106			var within = data.within,
1107				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1108				outerHeight = data.within.height,
1109				collisionPosTop = position.top - data.collisionPosition.marginTop,
1110				overTop = withinOffset - collisionPosTop,
1111				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1112				newOverBottom;
1113
1114			// Element is taller than within
1115			if ( data.collisionHeight > outerHeight ) {
1116
1117				// Element is initially over the top of within
1118				if ( overTop > 0 && overBottom <= 0 ) {
1119					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1120						withinOffset;
1121					position.top += overTop - newOverBottom;
1122
1123				// Element is initially over bottom of within
1124				} else if ( overBottom > 0 && overTop <= 0 ) {
1125					position.top = withinOffset;
1126
1127				// Element is initially over both top and bottom of within
1128				} else {
1129					if ( overTop > overBottom ) {
1130						position.top = withinOffset + outerHeight - data.collisionHeight;
1131					} else {
1132						position.top = withinOffset;
1133					}
1134				}
1135
1136			// Too far up -> align with top
1137			} else if ( overTop > 0 ) {
1138				position.top += overTop;
1139
1140			// Too far down -> align with bottom edge
1141			} else if ( overBottom > 0 ) {
1142				position.top -= overBottom;
1143
1144			// Adjust based on position and margin
1145			} else {
1146				position.top = max( position.top - collisionPosTop, position.top );
1147			}
1148		}
1149	},
1150	flip: {
1151		left: function( position, data ) {
1152			var within = data.within,
1153				withinOffset = within.offset.left + within.scrollLeft,
1154				outerWidth = within.width,
1155				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1156				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1157				overLeft = collisionPosLeft - offsetLeft,
1158				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1159				myOffset = data.my[ 0 ] === "left" ?
1160					-data.elemWidth :
1161					data.my[ 0 ] === "right" ?
1162						data.elemWidth :
1163						0,
1164				atOffset = data.at[ 0 ] === "left" ?
1165					data.targetWidth :
1166					data.at[ 0 ] === "right" ?
1167						-data.targetWidth :
1168						0,
1169				offset = -2 * data.offset[ 0 ],
1170				newOverRight,
1171				newOverLeft;
1172
1173			if ( overLeft < 0 ) {
1174				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1175					outerWidth - withinOffset;
1176				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1177					position.left += myOffset + atOffset + offset;
1178				}
1179			} else if ( overRight > 0 ) {
1180				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1181					atOffset + offset - offsetLeft;
1182				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1183					position.left += myOffset + atOffset + offset;
1184				}
1185			}
1186		},
1187		top: function( position, data ) {
1188			var within = data.within,
1189				withinOffset = within.offset.top + within.scrollTop,
1190				outerHeight = within.height,
1191				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1192				collisionPosTop = position.top - data.collisionPosition.marginTop,
1193				overTop = collisionPosTop - offsetTop,
1194				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1195				top = data.my[ 1 ] === "top",
1196				myOffset = top ?
1197					-data.elemHeight :
1198					data.my[ 1 ] === "bottom" ?
1199						data.elemHeight :
1200						0,
1201				atOffset = data.at[ 1 ] === "top" ?
1202					data.targetHeight :
1203					data.at[ 1 ] === "bottom" ?
1204						-data.targetHeight :
1205						0,
1206				offset = -2 * data.offset[ 1 ],
1207				newOverTop,
1208				newOverBottom;
1209			if ( overTop < 0 ) {
1210				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1211					outerHeight - withinOffset;
1212				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1213					position.top += myOffset + atOffset + offset;
1214				}
1215			} else if ( overBottom > 0 ) {
1216				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1217					offset - offsetTop;
1218				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1219					position.top += myOffset + atOffset + offset;
1220				}
1221			}
1222		}
1223	},
1224	flipfit: {
1225		left: function() {
1226			$.ui.position.flip.left.apply( this, arguments );
1227			$.ui.position.fit.left.apply( this, arguments );
1228		},
1229		top: function() {
1230			$.ui.position.flip.top.apply( this, arguments );
1231			$.ui.position.fit.top.apply( this, arguments );
1232		}
1233	}
1234};
1235
1236} )();
1237
1238var position = $.ui.position;
1239
1240
1241/*!
1242 * jQuery UI :data 1.12.0
1243 * http://jqueryui.com
1244 *
1245 * Copyright jQuery Foundation and other contributors
1246 * Released under the MIT license.
1247 * http://jquery.org/license
1248 */
1249
1250//>>label: :data Selector
vendor: 23,364 bytes, lines 1251-2206
1251//>>group: Core
1252//>>description: Selects elements which have data stored under the specified key.
1253//>>docs: http://api.jqueryui.com/data-selector/
1254
1255
1256var data = $.extend( $.expr[ ":" ], {
1257	data: $.expr.createPseudo ?
1258		$.expr.createPseudo( function( dataName ) {
1259			return function( elem ) {
1260				return !!$.data( elem, dataName );
1261			};
1262		} ) :
1263
1264		// Support: jQuery <1.8
1265		function( elem, i, match ) {
1266			return !!$.data( elem, match[ 3 ] );
1267		}
1268} );
1269
1270/*!
1271 * jQuery UI Disable Selection 1.12.0
1272 * http://jqueryui.com
1273 *
1274 * Copyright jQuery Foundation and other contributors
1275 * Released under the MIT license.
1276 * http://jquery.org/license
1277 */
1278
1279//>>label: disableSelection
1280//>>group: Core
1281//>>description: Disable selection of text content within the set of matched elements.
1282//>>docs: http://api.jqueryui.com/disableSelection/
1283
1284// This file is deprecated
1285
1286
1287var disableSelection = $.fn.extend( {
1288	disableSelection: ( function() {
1289		var eventType = "onselectstart" in document.createElement( "div" ) ?
1290			"selectstart" :
1291			"mousedown";
1292
1293		return function() {
1294			return this.on( eventType + ".ui-disableSelection", function( event ) {
1295				event.preventDefault();
1296			} );
1297		};
1298	} )(),
1299
1300	enableSelection: function() {
1301		return this.off( ".ui-disableSelection" );
1302	}
1303} );
1304
1305
1306/*!
1307 * jQuery UI Effects 1.12.0
1308 * http://jqueryui.com
1309 *
1310 * Copyright jQuery Foundation and other contributors
1311 * Released under the MIT license.
1312 * http://jquery.org/license
1313 */
1314
1315//>>label: Effects Core
1316//>>group: Effects
1317// jscs:disable maximumLineLength
1318//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1319// jscs:enable maximumLineLength
1320//>>docs: http://api.jqueryui.com/category/effects-core/
1321//>>demos: http://jqueryui.com/effect/
1322
1323
1324
1325var dataSpace = "ui-effects-",
1326	dataSpaceStyle = "ui-effects-style",
1327	dataSpaceAnimated = "ui-effects-animated",
1328
1329	// Create a local jQuery because jQuery Color relies on it and the
1330	// global may not exist with AMD and a custom build (#10199)
1331	jQuery = $;
1332
1333$.effects = {
1334	effect: {}
1335};
1336
1337/*!
1338 * jQuery Color Animations v2.1.2
1339 * https://github.com/jquery/jquery-color
1340 *
1341 * Copyright 2014 jQuery Foundation and other contributors
1342 * Released under the MIT license.
1343 * http://jquery.org/license
1344 *
1345 * Date: Wed Jan 16 08:47:09 2013 -0600
1346 */
1347( function( jQuery, undefined ) {
1348
1349	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1350		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1351
1352	// Plusequals test for += 100 -= 100
1353	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1354
1355	// A set of RE's that can match strings and generate color tuples.
1356	stringParsers = [ {
1357			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1358			parse: function( execResult ) {
1359				return [
1360					execResult[ 1 ],
1361					execResult[ 2 ],
1362					execResult[ 3 ],
1363					execResult[ 4 ]
1364				];
1365			}
1366		}, {
1367			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1368			parse: function( execResult ) {
1369				return [
1370					execResult[ 1 ] * 2.55,
1371					execResult[ 2 ] * 2.55,
1372					execResult[ 3 ] * 2.55,
1373					execResult[ 4 ]
1374				];
1375			}
1376		}, {
1377
1378			// This regex ignores A-F because it's compared against an already lowercased string
1379			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1380			parse: function( execResult ) {
1381				return [
1382					parseInt( execResult[ 1 ], 16 ),
1383					parseInt( execResult[ 2 ], 16 ),
1384					parseInt( execResult[ 3 ], 16 )
1385				];
1386			}
1387		}, {
1388
1389			// This regex ignores A-F because it's compared against an already lowercased string
1390			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1391			parse: function( execResult ) {
1392				return [
1393					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1394					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1395					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1396				];
1397			}
1398		}, {
1399			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1400			space: "hsla",
1401			parse: function( execResult ) {
1402				return [
1403					execResult[ 1 ],
1404					execResult[ 2 ] / 100,
1405					execResult[ 3 ] / 100,
1406					execResult[ 4 ]
1407				];
1408			}
1409		} ],
1410
1411	// JQuery.Color( )
1412	color = jQuery.Color = function( color, green, blue, alpha ) {
1413		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1414	},
1415	spaces = {
1416		rgba: {
1417			props: {
1418				red: {
1419					idx: 0,
1420					type: "byte"
1421				},
1422				green: {
1423					idx: 1,
1424					type: "byte"
1425				},
1426				blue: {
1427					idx: 2,
1428					type: "byte"
1429				}
1430			}
1431		},
1432
1433		hsla: {
1434			props: {
1435				hue: {
1436					idx: 0,
1437					type: "degrees"
1438				},
1439				saturation: {
1440					idx: 1,
1441					type: "percent"
1442				},
1443				lightness: {
1444					idx: 2,
1445					type: "percent"
1446				}
1447			}
1448		}
1449	},
1450	propTypes = {
1451		"byte": {
1452			floor: true,
1453			max: 255
1454		},
1455		"percent": {
1456			max: 1
1457		},
1458		"degrees": {
1459			mod: 360,
1460			floor: true
1461		}
1462	},
1463	support = color.support = {},
1464
1465	// Element for support tests
1466	supportElem = jQuery( "<p>" )[ 0 ],
1467
1468	// Colors = jQuery.Color.names
1469	colors,
1470
1471	// Local aliases of functions called often
1472	each = jQuery.each;
1473
1474// Determine rgba support immediately
1475supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1476support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1477
1478// Define cache name and alpha properties
1479// for rgba and hsla spaces
1480each( spaces, function( spaceName, space ) {
1481	space.cache = "_" + spaceName;
1482	space.props.alpha = {
1483		idx: 3,
1484		type: "percent",
1485		def: 1
1486	};
1487} );
1488
1489function clamp( value, prop, allowEmpty ) {
1490	var type = propTypes[ prop.type ] || {};
1491
1492	if ( value == null ) {
1493		return ( allowEmpty || !prop.def ) ? null : prop.def;
1494	}
1495
1496	// ~~ is an short way of doing floor for positive numbers
1497	value = type.floor ? ~~value : parseFloat( value );
1498
1499	// IE will pass in empty strings as value for alpha,
1500	// which will hit this case
1501	if ( isNaN( value ) ) {
1502		return prop.def;
1503	}
1504
1505	if ( type.mod ) {
1506
1507		// We add mod before modding to make sure that negatives values
1508		// get converted properly: -10 -> 350
1509		return ( value + type.mod ) % type.mod;
1510	}
1511
1512	// For now all property types without mod have min and max
1513	return 0 > value ? 0 : type.max < value ? type.max : value;
1514}
1515
1516function stringParse( string ) {
1517	var inst = color(),
1518		rgba = inst._rgba = [];
1519
1520	string = string.toLowerCase();
1521
1522	each( stringParsers, function( i, parser ) {
1523		var parsed,
1524			match = parser.re.exec( string ),
1525			values = match && parser.parse( match ),
1526			spaceName = parser.space || "rgba";
1527
1528		if ( values ) {
1529			parsed = inst[ spaceName ]( values );
1530
1531			// If this was an rgba parse the assignment might happen twice
1532			// oh well....
1533			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1534			rgba = inst._rgba = parsed._rgba;
1535
1536			// Exit each( stringParsers ) here because we matched
1537			return false;
1538		}
1539	} );
1540
1541	// Found a stringParser that handled it
1542	if ( rgba.length ) {
1543
1544		// If this came from a parsed string, force "transparent" when alpha is 0
1545		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1546		if ( rgba.join() === "0,0,0,0" ) {
1547			jQuery.extend( rgba, colors.transparent );
1548		}
1549		return inst;
1550	}
1551
1552	// Named colors
1553	return colors[ string ];
1554}
1555
1556color.fn = jQuery.extend( color.prototype, {
1557	parse: function( red, green, blue, alpha ) {
1558		if ( red === undefined ) {
1559			this._rgba = [ null, null, null, null ];
1560			return this;
1561		}
1562		if ( red.jquery || red.nodeType ) {
1563			red = jQuery( red ).css( green );
1564			green = undefined;
1565		}
1566
1567		var inst = this,
1568			type = jQuery.type( red ),
1569			rgba = this._rgba = [];
1570
1571		// More than 1 argument specified - assume ( red, green, blue, alpha )
1572		if ( green !== undefined ) {
1573			red = [ red, green, blue, alpha ];
1574			type = "array";
1575		}
1576
1577		if ( type === "string" ) {
1578			return this.parse( stringParse( red ) || colors._default );
1579		}
1580
1581		if ( type === "array" ) {
1582			each( spaces.rgba.props, function( key, prop ) {
1583				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1584			} );
1585			return this;
1586		}
1587
1588		if ( type === "object" ) {
1589			if ( red instanceof color ) {
1590				each( spaces, function( spaceName, space ) {
1591					if ( red[ space.cache ] ) {
1592						inst[ space.cache ] = red[ space.cache ].slice();
1593					}
1594				} );
1595			} else {
1596				each( spaces, function( spaceName, space ) {
1597					var cache = space.cache;
1598					each( space.props, function( key, prop ) {
1599
1600						// If the cache doesn't exist, and we know how to convert
1601						if ( !inst[ cache ] && space.to ) {
1602
1603							// If the value was null, we don't need to copy it
1604							// if the key was alpha, we don't need to copy it either
1605							if ( key === "alpha" || red[ key ] == null ) {
1606								return;
1607							}
1608							inst[ cache ] = space.to( inst._rgba );
1609						}
1610
1611						// This is the only case where we allow nulls for ALL properties.
1612						// call clamp with alwaysAllowEmpty
1613						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1614					} );
1615
1616					// Everything defined but alpha?
1617					if ( inst[ cache ] &&
1618							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1619
1620						// Use the default of 1
1621						inst[ cache ][ 3 ] = 1;
1622						if ( space.from ) {
1623							inst._rgba = space.from( inst[ cache ] );
1624						}
1625					}
1626				} );
1627			}
1628			return this;
1629		}
1630	},
1631	is: function( compare ) {
1632		var is = color( compare ),
1633			same = true,
1634			inst = this;
1635
1636		each( spaces, function( _, space ) {
1637			var localCache,
1638				isCache = is[ space.cache ];
1639			if ( isCache ) {
1640				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1641				each( space.props, function( _, prop ) {
1642					if ( isCache[ prop.idx ] != null ) {
1643						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1644						return same;
1645					}
1646				} );
1647			}
1648			return same;
1649		} );
1650		return same;
1651	},
1652	_space: function() {
1653		var used = [],
1654			inst = this;
1655		each( spaces, function( spaceName, space ) {
1656			if ( inst[ space.cache ] ) {
1657				used.push( spaceName );
1658			}
1659		} );
1660		return used.pop();
1661	},
1662	transition: function( other, distance ) {
1663		var end = color( other ),
1664			spaceName = end._space(),
1665			space = spaces[ spaceName ],
1666			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1667			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1668			result = start.slice();
1669
1670		end = end[ space.cache ];
1671		each( space.props, function( key, prop ) {
1672			var index = prop.idx,
1673				startValue = start[ index ],
1674				endValue = end[ index ],
1675				type = propTypes[ prop.type ] || {};
1676
1677			// If null, don't override start value
1678			if ( endValue === null ) {
1679				return;
1680			}
1681
1682			// If null - use end
1683			if ( startValue === null ) {
1684				result[ index ] = endValue;
1685			} else {
1686				if ( type.mod ) {
1687					if ( endValue - startValue > type.mod / 2 ) {
1688						startValue += type.mod;
1689					} else if ( startValue - endValue > type.mod / 2 ) {
1690						startValue -= type.mod;
1691					}
1692				}
1693				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1694			}
1695		} );
1696		return this[ spaceName ]( result );
1697	},
1698	blend: function( opaque ) {
1699
1700		// If we are already opaque - return ourself
1701		if ( this._rgba[ 3 ] === 1 ) {
1702			return this;
1703		}
1704
1705		var rgb = this._rgba.slice(),
1706			a = rgb.pop(),
1707			blend = color( opaque )._rgba;
1708
1709		return color( jQuery.map( rgb, function( v, i ) {
1710			return ( 1 - a ) * blend[ i ] + a * v;
1711		} ) );
1712	},
1713	toRgbaString: function() {
1714		var prefix = "rgba(",
1715			rgba = jQuery.map( this._rgba, function( v, i ) {
1716				return v == null ? ( i > 2 ? 1 : 0 ) : v;
1717			} );
1718
1719		if ( rgba[ 3 ] === 1 ) {
1720			rgba.pop();
1721			prefix = "rgb(";
1722		}
1723
1724		return prefix + rgba.join() + ")";
1725	},
1726	toHslaString: function() {
1727		var prefix = "hsla(",
1728			hsla = jQuery.map( this.hsla(), function( v, i ) {
1729				if ( v == null ) {
1730					v = i > 2 ? 1 : 0;
1731				}
1732
1733				// Catch 1 and 2
1734				if ( i && i < 3 ) {
1735					v = Math.round( v * 100 ) + "%";
1736				}
1737				return v;
1738			} );
1739
1740		if ( hsla[ 3 ] === 1 ) {
1741			hsla.pop();
1742			prefix = "hsl(";
1743		}
1744		return prefix + hsla.join() + ")";
1745	},
1746	toHexString: function( includeAlpha ) {
1747		var rgba = this._rgba.slice(),
1748			alpha = rgba.pop();
1749
1750		if ( includeAlpha ) {
1751			rgba.push( ~~( alpha * 255 ) );
1752		}
1753
1754		return "#" + jQuery.map( rgba, function( v ) {
1755
1756			// Default to 0 when nulls exist
1757			v = ( v || 0 ).toString( 16 );
1758			return v.length === 1 ? "0" + v : v;
1759		} ).join( "" );
1760	},
1761	toString: function() {
1762		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1763	}
1764} );
1765color.fn.parse.prototype = color.fn;
1766
1767// Hsla conversions adapted from:
1768// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1769
1770function hue2rgb( p, q, h ) {
1771	h = ( h + 1 ) % 1;
1772	if ( h * 6 < 1 ) {
1773		return p + ( q - p ) * h * 6;
1774	}
1775	if ( h * 2 < 1 ) {
1776		return q;
1777	}
1778	if ( h * 3 < 2 ) {
1779		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1780	}
1781	return p;
1782}
1783
1784spaces.hsla.to = function( rgba ) {
1785	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1786		return [ null, null, null, rgba[ 3 ] ];
1787	}
1788	var r = rgba[ 0 ] / 255,
1789		g = rgba[ 1 ] / 255,
1790		b = rgba[ 2 ] / 255,
1791		a = rgba[ 3 ],
1792		max = Math.max( r, g, b ),
1793		min = Math.min( r, g, b ),
1794		diff = max - min,
1795		add = max + min,
1796		l = add * 0.5,
1797		h, s;
1798
1799	if ( min === max ) {
1800		h = 0;
1801	} else if ( r === max ) {
1802		h = ( 60 * ( g - b ) / diff ) + 360;
1803	} else if ( g === max ) {
1804		h = ( 60 * ( b - r ) / diff ) + 120;
1805	} else {
1806		h = ( 60 * ( r - g ) / diff ) + 240;
1807	}
1808
1809	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1810	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1811	if ( diff === 0 ) {
1812		s = 0;
1813	} else if ( l <= 0.5 ) {
1814		s = diff / add;
1815	} else {
1816		s = diff / ( 2 - add );
1817	}
1818	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1819};
1820
1821spaces.hsla.from = function( hsla ) {
1822	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1823		return [ null, null, null, hsla[ 3 ] ];
1824	}
1825	var h = hsla[ 0 ] / 360,
1826		s = hsla[ 1 ],
1827		l = hsla[ 2 ],
1828		a = hsla[ 3 ],
1829		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1830		p = 2 * l - q;
1831
1832	return [
1833		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1834		Math.round( hue2rgb( p, q, h ) * 255 ),
1835		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1836		a
1837	];
1838};
1839
1840each( spaces, function( spaceName, space ) {
1841	var props = space.props,
1842		cache = space.cache,
1843		to = space.to,
1844		from = space.from;
1845
1846	// Makes rgba() and hsla()
1847	color.fn[ spaceName ] = function( value ) {
1848
1849		// Generate a cache for this space if it doesn't exist
1850		if ( to && !this[ cache ] ) {
1851			this[ cache ] = to( this._rgba );
1852		}
1853		if ( value === undefined ) {
1854			return this[ cache ].slice();
1855		}
1856
1857		var ret,
1858			type = jQuery.type( value ),
1859			arr = ( type === "array" || type === "object" ) ? value : arguments,
1860			local = this[ cache ].slice();
1861
1862		each( props, function( key, prop ) {
1863			var val = arr[ type === "object" ? key : prop.idx ];
1864			if ( val == null ) {
1865				val = local[ prop.idx ];
1866			}
1867			local[ prop.idx ] = clamp( val, prop );
1868		} );
1869
1870		if ( from ) {
1871			ret = color( from( local ) );
1872			ret[ cache ] = local;
1873			return ret;
1874		} else {
1875			return color( local );
1876		}
1877	};
1878
1879	// Makes red() green() blue() alpha() hue() saturation() lightness()
1880	each( props, function( key, prop ) {
1881
1882		// Alpha is included in more than one space
1883		if ( color.fn[ key ] ) {
1884			return;
1885		}
1886		color.fn[ key ] = function( value ) {
1887			var vtype = jQuery.type( value ),
1888				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1889				local = this[ fn ](),
1890				cur = local[ prop.idx ],
1891				match;
1892
1893			if ( vtype === "undefined" ) {
1894				return cur;
1895			}
1896
1897			if ( vtype === "function" ) {
1898				value = value.call( this, cur );
1899				vtype = jQuery.type( value );
1900			}
1901			if ( value == null && prop.empty ) {
1902				return this;
1903			}
1904			if ( vtype === "string" ) {
1905				match = rplusequals.exec( value );
1906				if ( match ) {
1907					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1908				}
1909			}
1910			local[ prop.idx ] = value;
1911			return this[ fn ]( local );
1912		};
1913	} );
1914} );
1915
1916// Add cssHook and .fx.step function for each named hook.
1917// accept a space separated string of properties
1918color.hook = function( hook ) {
1919	var hooks = hook.split( " " );
1920	each( hooks, function( i, hook ) {
1921		jQuery.cssHooks[ hook ] = {
1922			set: function( elem, value ) {
1923				var parsed, curElem,
1924					backgroundColor = "";
1925
1926				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1927						( parsed = stringParse( value ) ) ) ) {
1928					value = color( parsed || value );
1929					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1930						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1931						while (
1932							( backgroundColor === "" || backgroundColor === "transparent" ) &&
1933							curElem && curElem.style
1934						) {
1935							try {
1936								backgroundColor = jQuery.css( curElem, "backgroundColor" );
1937								curElem = curElem.parentNode;
1938							} catch ( e ) {
1939							}
1940						}
1941
1942						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1943							backgroundColor :
1944							"_default" );
1945					}
1946
1947					value = value.toRgbaString();
1948				}
1949				try {
1950					elem.style[ hook ] = value;
1951				} catch ( e ) {
1952
1953					// Wrapped to prevent IE from throwing errors on "invalid" values like
1954					// 'auto' or 'inherit'
1955				}
1956			}
1957		};
1958		jQuery.fx.step[ hook ] = function( fx ) {
1959			if ( !fx.colorInit ) {
1960				fx.start = color( fx.elem, hook );
1961				fx.end = color( fx.end );
1962				fx.colorInit = true;
1963			}
1964			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1965		};
1966	} );
1967
1968};
1969
1970color.hook( stepHooks );
1971
1972jQuery.cssHooks.borderColor = {
1973	expand: function( value ) {
1974		var expanded = {};
1975
1976		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1977			expanded[ "border" + part + "Color" ] = value;
1978		} );
1979		return expanded;
1980	}
1981};
1982
1983// Basic color names only.
1984// Usage of any of the other color names requires adding yourself or including
1985// jquery.color.svg-names.js.
1986colors = jQuery.Color.names = {
1987
1988	// 4.1. Basic color keywords
1989	aqua: "#00ffff",
1990	black: "#000000",
1991	blue: "#0000ff",
1992	fuchsia: "#ff00ff",
1993	gray: "#808080",
1994	green: "#008000",
1995	lime: "#00ff00",
1996	maroon: "#800000",
1997	navy: "#000080",
1998	olive: "#808000",
1999	purple: "#800080",
2000	red: "#ff0000",
2001	silver: "#c0c0c0",
2002	teal: "#008080",
2003	white: "#ffffff",
2004	yellow: "#ffff00",
2005
2006	// 4.2.3. "transparent" color keyword
2007	transparent: [ null, null, null, 0 ],
2008
2009	_default: "#ffffff"
2010};
2011
2012} )( jQuery );
2013
2014/******************************************************************************/
2015/****************************** CLASS ANIMATIONS ******************************/
2016/******************************************************************************/
2017( function() {
2018
2019var classAnimationActions = [ "add", "remove", "toggle" ],
2020	shorthandStyles = {
2021		border: 1,
2022		borderBottom: 1,
2023		borderColor: 1,
2024		borderLeft: 1,
2025		borderRight: 1,
2026		borderTop: 1,
2027		borderWidth: 1,
2028		margin: 1,
2029		padding: 1
2030	};
2031
2032$.each(
2033	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2034	function( _, prop ) {
2035		$.fx.step[ prop ] = function( fx ) {
2036			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2037				jQuery.style( fx.elem, prop, fx.end );
2038				fx.setAttr = true;
2039			}
2040		};
2041	}
2042);
2043
2044function getElementStyles( elem ) {
2045	var key, len,
2046		style = elem.ownerDocument.defaultView ?
2047			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2048			elem.currentStyle,
2049		styles = {};
2050
2051	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2052		len = style.length;
2053		while ( len-- ) {
2054			key = style[ len ];
2055			if ( typeof style[ key ] === "string" ) {
2056				styles[ $.camelCase( key ) ] = style[ key ];
2057			}
2058		}
2059
2060	// Support: Opera, IE <9
2061	} else {
2062		for ( key in style ) {
2063			if ( typeof style[ key ] === "string" ) {
2064				styles[ key ] = style[ key ];
2065			}
2066		}
2067	}
2068
2069	return styles;
2070}
2071
2072function styleDifference( oldStyle, newStyle ) {
2073	var diff = {},
2074		name, value;
2075
2076	for ( name in newStyle ) {
2077		value = newStyle[ name ];
2078		if ( oldStyle[ name ] !== value ) {
2079			if ( !shorthandStyles[ name ] ) {
2080				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2081					diff[ name ] = value;
2082				}
2083			}
2084		}
2085	}
2086
2087	return diff;
2088}
2089
2090// Support: jQuery <1.8
2091if ( !$.fn.addBack ) {
2092	$.fn.addBack = function( selector ) {
2093		return this.add( selector == null ?
2094			this.prevObject : this.prevObject.filter( selector )
2095		);
2096	};
2097}
2098
2099$.effects.animateClass = function( value, duration, easing, callback ) {
2100	var o = $.speed( duration, easing, callback );
2101
2102	return this.queue( function() {
2103		var animated = $( this ),
2104			baseClass = animated.attr( "class" ) || "",
2105			applyClassChange,
2106			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2107
2108		// Map the animated objects to store the original styles.
2109		allAnimations = allAnimations.map( function() {
2110			var el = $( this );
2111			return {
2112				el: el,
2113				start: getElementStyles( this )
2114			};
2115		} );
2116
2117		// Apply class change
2118		applyClassChange = function() {
2119			$.each( classAnimationActions, function( i, action ) {
2120				if ( value[ action ] ) {
2121					animated[ action + "Class" ]( value[ action ] );
2122				}
2123			} );
2124		};
2125		applyClassChange();
2126
2127		// Map all animated objects again - calculate new styles and diff
2128		allAnimations = allAnimations.map( function() {
2129			this.end = getElementStyles( this.el[ 0 ] );
2130			this.diff = styleDifference( this.start, this.end );
2131			return this;
2132		} );
2133
2134		// Apply original class
2135		animated.attr( "class", baseClass );
2136
2137		// Map all animated objects again - this time collecting a promise
2138		allAnimations = allAnimations.map( function() {
2139			var styleInfo = this,
2140				dfd = $.Deferred(),
2141				opts = $.extend( {}, o, {
2142					queue: false,
2143					complete: function() {
2144						dfd.resolve( styleInfo );
2145					}
2146				} );
2147
2148			this.el.animate( this.diff, opts );
2149			return dfd.promise();
2150		} );
2151
2152		// Once all animations have completed:
2153		$.when.apply( $, allAnimations.get() ).done( function() {
2154
2155			// Set the final class
2156			applyClassChange();
2157
2158			// For each animated element,
2159			// clear all css properties that were animated
2160			$.each( arguments, function() {
2161				var el = this.el;
2162				$.each( this.diff, function( key ) {
2163					el.css( key, "" );
2164				} );
2165			} );
2166
2167			// This is guarnteed to be there if you use jQuery.speed()
2168			// it also handles dequeuing the next anim...
2169			o.complete.call( animated[ 0 ] );
2170		} );
2171	} );
2172};
2173
2174$.fn.extend( {
2175	addClass: ( function( orig ) {
2176		return function( classNames, speed, easing, callback ) {
2177			return speed ?
2178				$.effects.animateClass.call( this,
2179					{ add: classNames }, speed, easing, callback ) :
2180				orig.apply( this, arguments );
2181		};
2182	} )( $.fn.addClass ),
2183
2184	removeClass: ( function( orig ) {
2185		return function( classNames, speed, easing, callback ) {
2186			return arguments.length > 1 ?
2187				$.effects.animateClass.call( this,
2188					{ remove: classNames }, speed, easing, callback ) :
2189				orig.apply( this, arguments );
2190		};
2191	} )( $.fn.removeClass ),
2192
2193	toggleClass: ( function( orig ) {
2194		return function( classNames, force, speed, easing, callback ) {
2195			if ( typeof force === "boolean" || force === undefined ) {
2196				if ( !speed ) {
2197
2198					// Without speed parameter
2199					return orig.apply( this, arguments );
2200				} else {
2201					return $.effects.animateClass.call( this,
2202						( force ? { add: classNames } : { remove: classNames } ),
2203						speed, easing, callback );
2204				}
2205			} else {
2206
vendor: 6,240 bytes, lines 2207-2461
2207				// Without force parameter
2208				return $.effects.animateClass.call( this,
2209					{ toggle: classNames }, force, speed, easing );
2210			}
2211		};
2212	} )( $.fn.toggleClass ),
2213
2214	switchClass: function( remove, add, speed, easing, callback ) {
2215		return $.effects.animateClass.call( this, {
2216			add: add,
2217			remove: remove
2218		}, speed, easing, callback );
2219	}
2220} );
2221
2222} )();
2223
2224/******************************************************************************/
2225/*********************************** EFFECTS **********************************/
2226/******************************************************************************/
2227
2228( function() {
2229
2230if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2231	$.expr.filters.animated = ( function( orig ) {
2232		return function( elem ) {
2233			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2234		};
2235	} )( $.expr.filters.animated );
2236}
2237
2238if ( $.uiBackCompat !== false ) {
2239	$.extend( $.effects, {
2240
2241		// Saves a set of properties in a data storage
2242		save: function( element, set ) {
2243			var i = 0, length = set.length;
2244			for ( ; i < length; i++ ) {
2245				if ( set[ i ] !== null ) {
2246					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2247				}
2248			}
2249		},
2250
2251		// Restores a set of previously saved properties from a data storage
2252		restore: function( element, set ) {
2253			var val, i = 0, length = set.length;
2254			for ( ; i < length; i++ ) {
2255				if ( set[ i ] !== null ) {
2256					val = element.data( dataSpace + set[ i ] );
2257					element.css( set[ i ], val );
2258				}
2259			}
2260		},
2261
2262		setMode: function( el, mode ) {
2263			if ( mode === "toggle" ) {
2264				mode = el.is( ":hidden" ) ? "show" : "hide";
2265			}
2266			return mode;
2267		},
2268
2269		// Wraps the element around a wrapper that copies position properties
2270		createWrapper: function( element ) {
2271
2272			// If the element is already wrapped, return it
2273			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2274				return element.parent();
2275			}
2276
2277			// Wrap the element
2278			var props = {
2279					width: element.outerWidth( true ),
2280					height: element.outerHeight( true ),
2281					"float": element.css( "float" )
2282				},
2283				wrapper = $( "<div></div>" )
2284					.addClass( "ui-effects-wrapper" )
2285					.css( {
2286						fontSize: "100%",
2287						background: "transparent",
2288						border: "none",
2289						margin: 0,
2290						padding: 0
2291					} ),
2292
2293				// Store the size in case width/height are defined in % - Fixes #5245
2294				size = {
2295					width: element.width(),
2296					height: element.height()
2297				},
2298				active = document.activeElement;
2299
2300			// Support: Firefox
2301			// Firefox incorrectly exposes anonymous content
2302			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2303			try {
2304				active.id;
2305			} catch ( e ) {
2306				active = document.body;
2307			}
2308
2309			element.wrap( wrapper );
2310
2311			// Fixes #7595 - Elements lose focus when wrapped.
2312			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2313				$( active ).trigger( "focus" );
2314			}
2315
2316			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2317			// lose the reference to the wrapped element
2318			wrapper = element.parent();
2319
2320			// Transfer positioning properties to the wrapper
2321			if ( element.css( "position" ) === "static" ) {
2322				wrapper.css( { position: "relative" } );
2323				element.css( { position: "relative" } );
2324			} else {
2325				$.extend( props, {
2326					position: element.css( "position" ),
2327					zIndex: element.css( "z-index" )
2328				} );
2329				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2330					props[ pos ] = element.css( pos );
2331					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2332						props[ pos ] = "auto";
2333					}
2334				} );
2335				element.css( {
2336					position: "relative",
2337					top: 0,
2338					left: 0,
2339					right: "auto",
2340					bottom: "auto"
2341				} );
2342			}
2343			element.css( size );
2344
2345			return wrapper.css( props ).show();
2346		},
2347
2348		removeWrapper: function( element ) {
2349			var active = document.activeElement;
2350
2351			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2352				element.parent().replaceWith( element );
2353
2354				// Fixes #7595 - Elements lose focus when wrapped.
2355				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2356					$( active ).trigger( "focus" );
2357				}
2358			}
2359
2360			return element;
2361		}
2362	} );
2363}
2364
2365$.extend( $.effects, {
2366	version: "1.12.0",
2367
2368	define: function( name, mode, effect ) {
2369		if ( !effect ) {
2370			effect = mode;
2371			mode = "effect";
2372		}
2373
2374		$.effects.effect[ name ] = effect;
2375		$.effects.effect[ name ].mode = mode;
2376
2377		return effect;
2378	},
2379
2380	scaledDimensions: function( element, percent, direction ) {
2381		if ( percent === 0 ) {
2382			return {
2383				height: 0,
2384				width: 0,
2385				outerHeight: 0,
2386				outerWidth: 0
2387			};
2388		}
2389
2390		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2391			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2392
2393		return {
2394			height: element.height() * y,
2395			width: element.width() * x,
2396			outerHeight: element.outerHeight() * y,
2397			outerWidth: element.outerWidth() * x
2398		};
2399
2400	},
2401
2402	clipToBox: function( animation ) {
2403		return {
2404			width: animation.clip.right - animation.clip.left,
2405			height: animation.clip.bottom - animation.clip.top,
2406			left: animation.clip.left,
2407			top: animation.clip.top
2408		};
2409	},
2410
2411	// Injects recently queued functions to be first in line (after "inprogress")
2412	unshift: function( element, queueLength, count ) {
2413		var queue = element.queue();
2414
2415		if ( queueLength > 1 ) {
2416			queue.splice.apply( queue,
2417				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2418		}
2419		element.dequeue();
2420	},
2421
2422	saveStyle: function( element ) {
2423		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2424	},
2425
2426	restoreStyle: function( element ) {
2427		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2428		element.removeData( dataSpaceStyle );
2429	},
2430
2431	mode: function( element, mode ) {
2432		var hidden = element.is( ":hidden" );
2433
2434		if ( mode === "toggle" ) {
2435			mode = hidden ? "show" : "hide";
2436		}
2437		if ( hidden ? mode === "hide" : mode === "show" ) {
2438			mode = "none";
2439		}
2440		return mode;
2441	},
2442
2443	// Translates a [top,left] array into a baseline value
2444	getBaseline: function( origin, original ) {
2445		var y, x;
2446
2447		switch ( origin[ 0 ] ) {
2448		case "top":
2449			y = 0;
2450			break;
2451		case "middle":
2452			y = 0.5;
2453			break;
2454		case "bottom":
2455			y = 1;
2456			break;
2457		default:
2458			y = origin[ 0 ] / original.height;
2459		}
2460
2461		switch ( origin[ 1 ] ) {
vendor: 4,228 bytes, lines 2462-2634
2462		case "left":
2463			x = 0;
2464			break;
2465		case "center":
2466			x = 0.5;
2467			break;
2468		case "right":
2469			x = 1;
2470			break;
2471		default:
2472			x = origin[ 1 ] / original.width;
2473		}
2474
2475		return {
2476			x: x,
2477			y: y
2478		};
2479	},
2480
2481	// Creates a placeholder element so that the original element can be made absolute
2482	createPlaceholder: function( element ) {
2483		var placeholder,
2484			cssPosition = element.css( "position" ),
2485			position = element.position();
2486
2487		// Lock in margins first to account for form elements, which
2488		// will change margin if you explicitly set height
2489		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2490		// Support: Safari
2491		element.css( {
2492			marginTop: element.css( "marginTop" ),
2493			marginBottom: element.css( "marginBottom" ),
2494			marginLeft: element.css( "marginLeft" ),
2495			marginRight: element.css( "marginRight" )
2496		} )
2497		.outerWidth( element.outerWidth() )
2498		.outerHeight( element.outerHeight() );
2499
2500		if ( /^(static|relative)/.test( cssPosition ) ) {
2501			cssPosition = "absolute";
2502
2503			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2504
2505				// Convert inline to inline block to account for inline elements
2506				// that turn to inline block based on content (like img)
2507				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2508					"inline-block" :
2509					"block",
2510				visibility: "hidden",
2511
2512				// Margins need to be set to account for margin collapse
2513				marginTop: element.css( "marginTop" ),
2514				marginBottom: element.css( "marginBottom" ),
2515				marginLeft: element.css( "marginLeft" ),
2516				marginRight: element.css( "marginRight" ),
2517				"float": element.css( "float" )
2518			} )
2519			.outerWidth( element.outerWidth() )
2520			.outerHeight( element.outerHeight() )
2521			.addClass( "ui-effects-placeholder" );
2522
2523			element.data( dataSpace + "placeholder", placeholder );
2524		}
2525
2526		element.css( {
2527			position: cssPosition,
2528			left: position.left,
2529			top: position.top
2530		} );
2531
2532		return placeholder;
2533	},
2534
2535	removePlaceholder: function( element ) {
2536		var dataKey = dataSpace + "placeholder",
2537				placeholder = element.data( dataKey );
2538
2539		if ( placeholder ) {
2540			placeholder.remove();
2541			element.removeData( dataKey );
2542		}
2543	},
2544
2545	// Removes a placeholder if it exists and restores
2546	// properties that were modified during placeholder creation
2547	cleanUp: function( element ) {
2548		$.effects.restoreStyle( element );
2549		$.effects.removePlaceholder( element );
2550	},
2551
2552	setTransition: function( element, list, factor, value ) {
2553		value = value || {};
2554		$.each( list, function( i, x ) {
2555			var unit = element.cssUnit( x );
2556			if ( unit[ 0 ] > 0 ) {
2557				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2558			}
2559		} );
2560		return value;
2561	}
2562} );
2563
2564// Return an effect options object for the given parameters:
2565function _normalizeArguments( effect, options, speed, callback ) {
2566
2567	// Allow passing all options as the first parameter
2568	if ( $.isPlainObject( effect ) ) {
2569		options = effect;
2570		effect = effect.effect;
2571	}
2572
2573	// Convert to an object
2574	effect = { effect: effect };
2575
2576	// Catch (effect, null, ...)
2577	if ( options == null ) {
2578		options = {};
2579	}
2580
2581	// Catch (effect, callback)
2582	if ( $.isFunction( options ) ) {
2583		callback = options;
2584		speed = null;
2585		options = {};
2586	}
2587
2588	// Catch (effect, speed, ?)
2589	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2590		callback = speed;
2591		speed = options;
2592		options = {};
2593	}
2594
2595	// Catch (effect, options, callback)
2596	if ( $.isFunction( speed ) ) {
2597		callback = speed;
2598		speed = null;
2599	}
2600
2601	// Add options to effect
2602	if ( options ) {
2603		$.extend( effect, options );
2604	}
2605
2606	speed = speed || options.duration;
2607	effect.duration = $.fx.off ? 0 :
2608		typeof speed === "number" ? speed :
2609		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2610		$.fx.speeds._default;
2611
2612	effect.complete = callback || options.complete;
2613
2614	return effect;
2615}
2616
2617function standardAnimationOption( option ) {
2618
2619	// Valid standard speeds (nothing, number, named speed)
2620	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2621		return true;
2622	}
2623
2624	// Invalid strings - treat as "normal" speed
2625	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2626		return true;
2627	}
2628
2629	// Complete callback
2630	if ( $.isFunction( option ) ) {
2631		return true;
2632	}
2633
2634	// Options hash (but not naming an effect)
vendor: 4,796 bytes, lines 2635-2818
2635	if ( typeof option === "object" && !option.effect ) {
2636		return true;
2637	}
2638
2639	// Didn't match any standard API
2640	return false;
2641}
2642
2643$.fn.extend( {
2644	effect: function( /* effect, options, speed, callback */ ) {
2645		var args = _normalizeArguments.apply( this, arguments ),
2646			effectMethod = $.effects.effect[ args.effect ],
2647			defaultMode = effectMethod.mode,
2648			queue = args.queue,
2649			queueName = queue || "fx",
2650			complete = args.complete,
2651			mode = args.mode,
2652			modes = [],
2653			prefilter = function( next ) {
2654				var el = $( this ),
2655					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2656
2657				// Sentinel for duck-punching the :animated psuedo-selector
2658				el.data( dataSpaceAnimated, true );
2659
2660				// Save effect mode for later use,
2661				// we can't just call $.effects.mode again later,
2662				// as the .show() below destroys the initial state
2663				modes.push( normalizedMode );
2664
2665				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2666				if ( defaultMode && ( normalizedMode === "show" ||
2667						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2668					el.show();
2669				}
2670
2671				if ( !defaultMode || normalizedMode !== "none" ) {
2672					$.effects.saveStyle( el );
2673				}
2674
2675				if ( $.isFunction( next ) ) {
2676					next();
2677				}
2678			};
2679
2680		if ( $.fx.off || !effectMethod ) {
2681
2682			// Delegate to the original method (e.g., .show()) if possible
2683			if ( mode ) {
2684				return this[ mode ]( args.duration, complete );
2685			} else {
2686				return this.each( function() {
2687					if ( complete ) {
2688						complete.call( this );
2689					}
2690				} );
2691			}
2692		}
2693
2694		function run( next ) {
2695			var elem = $( this );
2696
2697			function cleanup() {
2698				elem.removeData( dataSpaceAnimated );
2699
2700				$.effects.cleanUp( elem );
2701
2702				if ( args.mode === "hide" ) {
2703					elem.hide();
2704				}
2705
2706				done();
2707			}
2708
2709			function done() {
2710				if ( $.isFunction( complete ) ) {
2711					complete.call( elem[ 0 ] );
2712				}
2713
2714				if ( $.isFunction( next ) ) {
2715					next();
2716				}
2717			}
2718
2719			// Override mode option on a per element basis,
2720			// as toggle can be either show or hide depending on element state
2721			args.mode = modes.shift();
2722
2723			if ( $.uiBackCompat !== false && !defaultMode ) {
2724				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2725
2726					// Call the core method to track "olddisplay" properly
2727					elem[ mode ]();
2728					done();
2729				} else {
2730					effectMethod.call( elem[ 0 ], args, done );
2731				}
2732			} else {
2733				if ( args.mode === "none" ) {
2734
2735					// Call the core method to track "olddisplay" properly
2736					elem[ mode ]();
2737					done();
2738				} else {
2739					effectMethod.call( elem[ 0 ], args, cleanup );
2740				}
2741			}
2742		}
2743
2744		// Run prefilter on all elements first to ensure that
2745		// any showing or hiding happens before placeholder creation,
2746		// which ensures that any layout changes are correctly captured.
2747		return queue === false ?
2748			this.each( prefilter ).each( run ) :
2749			this.queue( queueName, prefilter ).queue( queueName, run );
2750	},
2751
2752	show: ( function( orig ) {
2753		return function( option ) {
2754			if ( standardAnimationOption( option ) ) {
2755				return orig.apply( this, arguments );
2756			} else {
2757				var args = _normalizeArguments.apply( this, arguments );
2758				args.mode = "show";
2759				return this.effect.call( this, args );
2760			}
2761		};
2762	} )( $.fn.show ),
2763
2764	hide: ( function( orig ) {
2765		return function( option ) {
2766			if ( standardAnimationOption( option ) ) {
2767				return orig.apply( this, arguments );
2768			} else {
2769				var args = _normalizeArguments.apply( this, arguments );
2770				args.mode = "hide";
2771				return this.effect.call( this, args );
2772			}
2773		};
2774	} )( $.fn.hide ),
2775
2776	toggle: ( function( orig ) {
2777		return function( option ) {
2778			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2779				return orig.apply( this, arguments );
2780			} else {
2781				var args = _normalizeArguments.apply( this, arguments );
2782				args.mode = "toggle";
2783				return this.effect.call( this, args );
2784			}
2785		};
2786	} )( $.fn.toggle ),
2787
2788	cssUnit: function( key ) {
2789		var style = this.css( key ),
2790			val = [];
2791
2792		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2793			if ( style.indexOf( unit ) > 0 ) {
2794				val = [ parseFloat( style ), unit ];
2795			}
2796		} );
2797		return val;
2798	},
2799
2800	cssClip: function( clipObj ) {
2801		if ( clipObj ) {
2802			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2803				clipObj.bottom + "px " + clipObj.left + "px)" );
2804		}
2805		return parseClip( this.css( "clip" ), this );
2806	},
2807
2808	transfer: function( options, done ) {
2809		var element = $( this ),
2810			target = $( options.to ),
2811			targetFixed = target.css( "position" ) === "fixed",
2812			body = $( "body" ),
2813			fixTop = targetFixed ? body.scrollTop() : 0,
2814			fixLeft = targetFixed ? body.scrollLeft() : 0,
2815			endPosition = target.offset(),
2816			animation = {
2817				top: endPosition.top - fixTop,
2818				left: endPosition.left - fixLeft,
vendor: 27,020 bytes, lines 2819-3848
2819				height: target.innerHeight(),
2820				width: target.innerWidth()
2821			},
2822			startPosition = element.offset(),
2823			transfer = $( "<div class='ui-effects-transfer'></div>" )
2824				.appendTo( "body" )
2825				.addClass( options.className )
2826				.css( {
2827					top: startPosition.top - fixTop,
2828					left: startPosition.left - fixLeft,
2829					height: element.innerHeight(),
2830					width: element.innerWidth(),
2831					position: targetFixed ? "fixed" : "absolute"
2832				} )
2833				.animate( animation, options.duration, options.easing, function() {
2834					transfer.remove();
2835					if ( $.isFunction( done ) ) {
2836						done();
2837					}
2838				} );
2839	}
2840} );
2841
2842function parseClip( str, element ) {
2843		var outerWidth = element.outerWidth(),
2844			outerHeight = element.outerHeight(),
2845			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
2846			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2847
2848		return {
2849			top: parseFloat( values[ 1 ] ) || 0,
2850			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2851			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2852			left: parseFloat( values[ 4 ] ) || 0
2853		};
2854}
2855
2856$.fx.step.clip = function( fx ) {
2857	if ( !fx.clipInit ) {
2858		fx.start = $( fx.elem ).cssClip();
2859		if ( typeof fx.end === "string" ) {
2860			fx.end = parseClip( fx.end, fx.elem );
2861		}
2862		fx.clipInit = true;
2863	}
2864
2865	$( fx.elem ).cssClip( {
2866		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2867		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2868		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2869		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2870	} );
2871};
2872
2873} )();
2874
2875/******************************************************************************/
2876/*********************************** EASING ***********************************/
2877/******************************************************************************/
2878
2879( function() {
2880
2881// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2882
2883var baseEasings = {};
2884
2885$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2886	baseEasings[ name ] = function( p ) {
2887		return Math.pow( p, i + 2 );
2888	};
2889} );
2890
2891$.extend( baseEasings, {
2892	Sine: function( p ) {
2893		return 1 - Math.cos( p * Math.PI / 2 );
2894	},
2895	Circ: function( p ) {
2896		return 1 - Math.sqrt( 1 - p * p );
2897	},
2898	Elastic: function( p ) {
2899		return p === 0 || p === 1 ? p :
2900			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2901	},
2902	Back: function( p ) {
2903		return p * p * ( 3 * p - 2 );
2904	},
2905	Bounce: function( p ) {
2906		var pow2,
2907			bounce = 4;
2908
2909		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2910		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2911	}
2912} );
2913
2914$.each( baseEasings, function( name, easeIn ) {
2915	$.easing[ "easeIn" + name ] = easeIn;
2916	$.easing[ "easeOut" + name ] = function( p ) {
2917		return 1 - easeIn( 1 - p );
2918	};
2919	$.easing[ "easeInOut" + name ] = function( p ) {
2920		return p < 0.5 ?
2921			easeIn( p * 2 ) / 2 :
2922			1 - easeIn( p * -2 + 2 ) / 2;
2923	};
2924} );
2925
2926} )();
2927
2928var effect = $.effects;
2929
2930
2931/*!
2932 * jQuery UI Effects Blind 1.12.0
2933 * http://jqueryui.com
2934 *
2935 * Copyright jQuery Foundation and other contributors
2936 * Released under the MIT license.
2937 * http://jquery.org/license
2938 */
2939
2940//>>label: Blind Effect
2941//>>group: Effects
2942//>>description: Blinds the element.
2943//>>docs: http://api.jqueryui.com/blind-effect/
2944//>>demos: http://jqueryui.com/effect/
2945
2946
2947
2948var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2949	var map = {
2950			up: [ "bottom", "top" ],
2951			vertical: [ "bottom", "top" ],
2952			down: [ "top", "bottom" ],
2953			left: [ "right", "left" ],
2954			horizontal: [ "right", "left" ],
2955			right: [ "left", "right" ]
2956		},
2957		element = $( this ),
2958		direction = options.direction || "up",
2959		start = element.cssClip(),
2960		animate = { clip: $.extend( {}, start ) },
2961		placeholder = $.effects.createPlaceholder( element );
2962
2963	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2964
2965	if ( options.mode === "show" ) {
2966		element.cssClip( animate.clip );
2967		if ( placeholder ) {
2968			placeholder.css( $.effects.clipToBox( animate ) );
2969		}
2970
2971		animate.clip = start;
2972	}
2973
2974	if ( placeholder ) {
2975		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2976	}
2977
2978	element.animate( animate, {
2979		queue: false,
2980		duration: options.duration,
2981		easing: options.easing,
2982		complete: done
2983	} );
2984} );
2985
2986
2987/*!
2988 * jQuery UI Effects Bounce 1.12.0
2989 * http://jqueryui.com
2990 *
2991 * Copyright jQuery Foundation and other contributors
2992 * Released under the MIT license.
2993 * http://jquery.org/license
2994 */
2995
2996//>>label: Bounce Effect
2997//>>group: Effects
2998//>>description: Bounces an element horizontally or vertically n times.
2999//>>docs: http://api.jqueryui.com/bounce-effect/
3000//>>demos: http://jqueryui.com/effect/
3001
3002
3003
3004var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
3005	var upAnim, downAnim, refValue,
3006		element = $( this ),
3007
3008		// Defaults:
3009		mode = options.mode,
3010		hide = mode === "hide",
3011		show = mode === "show",
3012		direction = options.direction || "up",
3013		distance = options.distance,
3014		times = options.times || 5,
3015
3016		// Number of internal animations
3017		anims = times * 2 + ( show || hide ? 1 : 0 ),
3018		speed = options.duration / anims,
3019		easing = options.easing,
3020
3021		// Utility:
3022		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3023		motion = ( direction === "up" || direction === "left" ),
3024		i = 0,
3025
3026		queuelen = element.queue().length;
3027
3028	$.effects.createPlaceholder( element );
3029
3030	refValue = element.css( ref );
3031
3032	// Default distance for the BIGGEST bounce is the outer Distance / 3
3033	if ( !distance ) {
3034		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3035	}
3036
3037	if ( show ) {
3038		downAnim = { opacity: 1 };
3039		downAnim[ ref ] = refValue;
3040
3041		// If we are showing, force opacity 0 and set the initial position
3042		// then do the "first" animation
3043		element
3044			.css( "opacity", 0 )
3045			.css( ref, motion ? -distance * 2 : distance * 2 )
3046			.animate( downAnim, speed, easing );
3047	}
3048
3049	// Start at the smallest distance if we are hiding
3050	if ( hide ) {
3051		distance = distance / Math.pow( 2, times - 1 );
3052	}
3053
3054	downAnim = {};
3055	downAnim[ ref ] = refValue;
3056
3057	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3058	for ( ; i < times; i++ ) {
3059		upAnim = {};
3060		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3061
3062		element
3063			.animate( upAnim, speed, easing )
3064			.animate( downAnim, speed, easing );
3065
3066		distance = hide ? distance * 2 : distance / 2;
3067	}
3068
3069	// Last Bounce when Hiding
3070	if ( hide ) {
3071		upAnim = { opacity: 0 };
3072		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3073
3074		element.animate( upAnim, speed, easing );
3075	}
3076
3077	element.queue( done );
3078
3079	$.effects.unshift( element, queuelen, anims + 1 );
3080} );
3081
3082
3083/*!
3084 * jQuery UI Effects Clip 1.12.0
3085 * http://jqueryui.com
3086 *
3087 * Copyright jQuery Foundation and other contributors
3088 * Released under the MIT license.
3089 * http://jquery.org/license
3090 */
3091
3092//>>label: Clip Effect
3093//>>group: Effects
3094//>>description: Clips the element on and off like an old TV.
3095//>>docs: http://api.jqueryui.com/clip-effect/
3096//>>demos: http://jqueryui.com/effect/
3097
3098
3099
3100var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3101	var start,
3102		animate = {},
3103		element = $( this ),
3104		direction = options.direction || "vertical",
3105		both = direction === "both",
3106		horizontal = both || direction === "horizontal",
3107		vertical = both || direction === "vertical";
3108
3109	start = element.cssClip();
3110	animate.clip = {
3111		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3112		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3113		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3114		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3115	};
3116
3117	$.effects.createPlaceholder( element );
3118
3119	if ( options.mode === "show" ) {
3120		element.cssClip( animate.clip );
3121		animate.clip = start;
3122	}
3123
3124	element.animate( animate, {
3125		queue: false,
3126		duration: options.duration,
3127		easing: options.easing,
3128		complete: done
3129	} );
3130
3131} );
3132
3133
3134/*!
3135 * jQuery UI Effects Drop 1.12.0
3136 * http://jqueryui.com
3137 *
3138 * Copyright jQuery Foundation and other contributors
3139 * Released under the MIT license.
3140 * http://jquery.org/license
3141 */
3142
3143//>>label: Drop Effect
3144//>>group: Effects
3145//>>description: Moves an element in one direction and hides it at the same time.
3146//>>docs: http://api.jqueryui.com/drop-effect/
3147//>>demos: http://jqueryui.com/effect/
3148
3149
3150
3151var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3152
3153	var distance,
3154		element = $( this ),
3155		mode = options.mode,
3156		show = mode === "show",
3157		direction = options.direction || "left",
3158		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3159		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3160		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3161		animation = {
3162			opacity: 0
3163		};
3164
3165	$.effects.createPlaceholder( element );
3166
3167	distance = options.distance ||
3168		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3169
3170	animation[ ref ] = motion + distance;
3171
3172	if ( show ) {
3173		element.css( animation );
3174
3175		animation[ ref ] = oppositeMotion + distance;
3176		animation.opacity = 1;
3177	}
3178
3179	// Animate
3180	element.animate( animation, {
3181		queue: false,
3182		duration: options.duration,
3183		easing: options.easing,
3184		complete: done
3185	} );
3186} );
3187
3188
3189/*!
3190 * jQuery UI Effects Explode 1.12.0
3191 * http://jqueryui.com
3192 *
3193 * Copyright jQuery Foundation and other contributors
3194 * Released under the MIT license.
3195 * http://jquery.org/license
3196 */
3197
3198//>>label: Explode Effect
3199//>>group: Effects
3200// jscs:disable maximumLineLength
3201//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3202// jscs:enable maximumLineLength
3203//>>docs: http://api.jqueryui.com/explode-effect/
3204//>>demos: http://jqueryui.com/effect/
3205
3206
3207
3208var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3209
3210	var i, j, left, top, mx, my,
3211		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3212		cells = rows,
3213		element = $( this ),
3214		mode = options.mode,
3215		show = mode === "show",
3216
3217		// Show and then visibility:hidden the element before calculating offset
3218		offset = element.show().css( "visibility", "hidden" ).offset(),
3219
3220		// Width and height of a piece
3221		width = Math.ceil( element.outerWidth() / cells ),
3222		height = Math.ceil( element.outerHeight() / rows ),
3223		pieces = [];
3224
3225	// Children animate complete:
3226	function childComplete() {
3227		pieces.push( this );
3228		if ( pieces.length === rows * cells ) {
3229			animComplete();
3230		}
3231	}
3232
3233	// Clone the element for each row and cell.
3234	for ( i = 0; i < rows; i++ ) { // ===>
3235		top = offset.top + i * height;
3236		my = i - ( rows - 1 ) / 2;
3237
3238		for ( j = 0; j < cells; j++ ) { // |||
3239			left = offset.left + j * width;
3240			mx = j - ( cells - 1 ) / 2;
3241
3242			// Create a clone of the now hidden main element that will be absolute positioned
3243			// within a wrapper div off the -left and -top equal to size of our pieces
3244			element
3245				.clone()
3246				.appendTo( "body" )
3247				.wrap( "<div></div>" )
3248				.css( {
3249					position: "absolute",
3250					visibility: "visible",
3251					left: -j * width,
3252					top: -i * height
3253				} )
3254
3255				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3256				// where the original was located +left and +top equal to the size of pieces
3257				.parent()
3258					.addClass( "ui-effects-explode" )
3259					.css( {
3260						position: "absolute",
3261						overflow: "hidden",
3262						width: width,
3263						height: height,
3264						left: left + ( show ? mx * width : 0 ),
3265						top: top + ( show ? my * height : 0 ),
3266						opacity: show ? 0 : 1
3267					} )
3268					.animate( {
3269						left: left + ( show ? 0 : mx * width ),
3270						top: top + ( show ? 0 : my * height ),
3271						opacity: show ? 1 : 0
3272					}, options.duration || 500, options.easing, childComplete );
3273		}
3274	}
3275
3276	function animComplete() {
3277		element.css( {
3278			visibility: "visible"
3279		} );
3280		$( pieces ).remove();
3281		done();
3282	}
3283} );
3284
3285
3286/*!
3287 * jQuery UI Effects Fade 1.12.0
3288 * http://jqueryui.com
3289 *
3290 * Copyright jQuery Foundation and other contributors
3291 * Released under the MIT license.
3292 * http://jquery.org/license
3293 */
3294
3295//>>label: Fade Effect
3296//>>group: Effects
3297//>>description: Fades the element.
3298//>>docs: http://api.jqueryui.com/fade-effect/
3299//>>demos: http://jqueryui.com/effect/
3300
3301
3302
3303var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3304	var show = options.mode === "show";
3305
3306	$( this )
3307		.css( "opacity", show ? 0 : 1 )
3308		.animate( {
3309			opacity: show ? 1 : 0
3310		}, {
3311			queue: false,
3312			duration: options.duration,
3313			easing: options.easing,
3314			complete: done
3315		} );
3316} );
3317
3318
3319/*!
3320 * jQuery UI Effects Fold 1.12.0
3321 * http://jqueryui.com
3322 *
3323 * Copyright jQuery Foundation and other contributors
3324 * Released under the MIT license.
3325 * http://jquery.org/license
3326 */
3327
3328//>>label: Fold Effect
3329//>>group: Effects
3330//>>description: Folds an element first horizontally and then vertically.
3331//>>docs: http://api.jqueryui.com/fold-effect/
3332//>>demos: http://jqueryui.com/effect/
3333
3334
3335
3336var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3337
3338	// Create element
3339	var element = $( this ),
3340		mode = options.mode,
3341		show = mode === "show",
3342		hide = mode === "hide",
3343		size = options.size || 15,
3344		percent = /([0-9]+)%/.exec( size ),
3345		horizFirst = !!options.horizFirst,
3346		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3347		duration = options.duration / 2,
3348
3349		placeholder = $.effects.createPlaceholder( element ),
3350
3351		start = element.cssClip(),
3352		animation1 = { clip: $.extend( {}, start ) },
3353		animation2 = { clip: $.extend( {}, start ) },
3354
3355		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3356
3357		queuelen = element.queue().length;
3358
3359	if ( percent ) {
3360		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3361	}
3362	animation1.clip[ ref[ 0 ] ] = size;
3363	animation2.clip[ ref[ 0 ] ] = size;
3364	animation2.clip[ ref[ 1 ] ] = 0;
3365
3366	if ( show ) {
3367		element.cssClip( animation2.clip );
3368		if ( placeholder ) {
3369			placeholder.css( $.effects.clipToBox( animation2 ) );
3370		}
3371
3372		animation2.clip = start;
3373	}
3374
3375	// Animate
3376	element
3377		.queue( function( next ) {
3378			if ( placeholder ) {
3379				placeholder
3380					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3381					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3382			}
3383
3384			next();
3385		} )
3386		.animate( animation1, duration, options.easing )
3387		.animate( animation2, duration, options.easing )
3388		.queue( done );
3389
3390	$.effects.unshift( element, queuelen, 4 );
3391} );
3392
3393
3394/*!
3395 * jQuery UI Effects Highlight 1.12.0
3396 * http://jqueryui.com
3397 *
3398 * Copyright jQuery Foundation and other contributors
3399 * Released under the MIT license.
3400 * http://jquery.org/license
3401 */
3402
3403//>>label: Highlight Effect
3404//>>group: Effects
3405//>>description: Highlights the background of an element in a defined color for a custom duration.
3406//>>docs: http://api.jqueryui.com/highlight-effect/
3407//>>demos: http://jqueryui.com/effect/
3408
3409
3410
3411var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3412	var element = $( this ),
3413		animation = {
3414			backgroundColor: element.css( "backgroundColor" )
3415		};
3416
3417	if ( options.mode === "hide" ) {
3418		animation.opacity = 0;
3419	}
3420
3421	$.effects.saveStyle( element );
3422
3423	element
3424		.css( {
3425			backgroundImage: "none",
3426			backgroundColor: options.color || "#ffff99"
3427		} )
3428		.animate( animation, {
3429			queue: false,
3430			duration: options.duration,
3431			easing: options.easing,
3432			complete: done
3433		} );
3434} );
3435
3436
3437/*!
3438 * jQuery UI Effects Size 1.12.0
3439 * http://jqueryui.com
3440 *
3441 * Copyright jQuery Foundation and other contributors
3442 * Released under the MIT license.
3443 * http://jquery.org/license
3444 */
3445
3446//>>label: Size Effect
3447//>>group: Effects
3448//>>description: Resize an element to a specified width and height.
3449//>>docs: http://api.jqueryui.com/size-effect/
3450//>>demos: http://jqueryui.com/effect/
3451
3452
3453
3454var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3455
3456	// Create element
3457	var baseline, factor, temp,
3458		element = $( this ),
3459
3460		// Copy for children
3461		cProps = [ "fontSize" ],
3462		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3463		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3464
3465		// Set options
3466		mode = options.mode,
3467		restore = mode !== "effect",
3468		scale = options.scale || "both",
3469		origin = options.origin || [ "middle", "center" ],
3470		position = element.css( "position" ),
3471		pos = element.position(),
3472		original = $.effects.scaledDimensions( element ),
3473		from = options.from || original,
3474		to = options.to || $.effects.scaledDimensions( element, 0 );
3475
3476	$.effects.createPlaceholder( element );
3477
3478	if ( mode === "show" ) {
3479		temp = from;
3480		from = to;
3481		to = temp;
3482	}
3483
3484	// Set scaling factor
3485	factor = {
3486		from: {
3487			y: from.height / original.height,
3488			x: from.width / original.width
3489		},
3490		to: {
3491			y: to.height / original.height,
3492			x: to.width / original.width
3493		}
3494	};
3495
3496	// Scale the css box
3497	if ( scale === "box" || scale === "both" ) {
3498
3499		// Vertical props scaling
3500		if ( factor.from.y !== factor.to.y ) {
3501			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3502			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3503		}
3504
3505		// Horizontal props scaling
3506		if ( factor.from.x !== factor.to.x ) {
3507			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3508			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3509		}
3510	}
3511
3512	// Scale the content
3513	if ( scale === "content" || scale === "both" ) {
3514
3515		// Vertical props scaling
3516		if ( factor.from.y !== factor.to.y ) {
3517			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3518			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3519		}
3520	}
3521
3522	// Adjust the position properties based on the provided origin points
3523	if ( origin ) {
3524		baseline = $.effects.getBaseline( origin, original );
3525		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3526		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3527		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3528		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3529	}
3530	element.css( from );
3531
3532	// Animate the children if desired
3533	if ( scale === "content" || scale === "both" ) {
3534
3535		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3536		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3537
3538		// Only animate children with width attributes specified
3539		// TODO: is this right? should we include anything with css width specified as well
3540		element.find( "*[width]" ).each( function() {
3541			var child = $( this ),
3542				childOriginal = $.effects.scaledDimensions( child ),
3543				childFrom = {
3544					height: childOriginal.height * factor.from.y,
3545					width: childOriginal.width * factor.from.x,
3546					outerHeight: childOriginal.outerHeight * factor.from.y,
3547					outerWidth: childOriginal.outerWidth * factor.from.x
3548				},
3549				childTo = {
3550					height: childOriginal.height * factor.to.y,
3551					width: childOriginal.width * factor.to.x,
3552					outerHeight: childOriginal.height * factor.to.y,
3553					outerWidth: childOriginal.width * factor.to.x
3554				};
3555
3556			// Vertical props scaling
3557			if ( factor.from.y !== factor.to.y ) {
3558				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3559				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3560			}
3561
3562			// Horizontal props scaling
3563			if ( factor.from.x !== factor.to.x ) {
3564				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3565				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3566			}
3567
3568			if ( restore ) {
3569				$.effects.saveStyle( child );
3570			}
3571
3572			// Animate children
3573			child.css( childFrom );
3574			child.animate( childTo, options.duration, options.easing, function() {
3575
3576				// Restore children
3577				if ( restore ) {
3578					$.effects.restoreStyle( child );
3579				}
3580			} );
3581		} );
3582	}
3583
3584	// Animate
3585	element.animate( to, {
3586		queue: false,
3587		duration: options.duration,
3588		easing: options.easing,
3589		complete: function() {
3590
3591			var offset = element.offset();
3592
3593			if ( to.opacity === 0 ) {
3594				element.css( "opacity", from.opacity );
3595			}
3596
3597			if ( !restore ) {
3598				element
3599					.css( "position", position === "static" ? "relative" : position )
3600					.offset( offset );
3601
3602				// Need to save style here so that automatic style restoration
3603				// doesn't restore to the original styles from before the animation.
3604				$.effects.saveStyle( element );
3605			}
3606
3607			done();
3608		}
3609	} );
3610
3611} );
3612
3613
3614/*!
3615 * jQuery UI Effects Scale 1.12.0
3616 * http://jqueryui.com
3617 *
3618 * Copyright jQuery Foundation and other contributors
3619 * Released under the MIT license.
3620 * http://jquery.org/license
3621 */
3622
3623//>>label: Scale Effect
3624//>>group: Effects
3625//>>description: Grows or shrinks an element and its content.
3626//>>docs: http://api.jqueryui.com/scale-effect/
3627//>>demos: http://jqueryui.com/effect/
3628
3629
3630
3631var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3632
3633	// Create element
3634	var el = $( this ),
3635		mode = options.mode,
3636		percent = parseInt( options.percent, 10 ) ||
3637			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3638
3639		newOptions = $.extend( true, {
3640			from: $.effects.scaledDimensions( el ),
3641			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3642			origin: options.origin || [ "middle", "center" ]
3643		}, options );
3644
3645	// Fade option to support puff
3646	if ( options.fade ) {
3647		newOptions.from.opacity = 1;
3648		newOptions.to.opacity = 0;
3649	}
3650
3651	$.effects.effect.size.call( this, newOptions, done );
3652} );
3653
3654
3655/*!
3656 * jQuery UI Effects Puff 1.12.0
3657 * http://jqueryui.com
3658 *
3659 * Copyright jQuery Foundation and other contributors
3660 * Released under the MIT license.
3661 * http://jquery.org/license
3662 */
3663
3664//>>label: Puff Effect
3665//>>group: Effects
3666//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3667//>>docs: http://api.jqueryui.com/puff-effect/
3668//>>demos: http://jqueryui.com/effect/
3669
3670
3671
3672var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3673	var newOptions = $.extend( true, {}, options, {
3674		fade: true,
3675		percent: parseInt( options.percent, 10 ) || 150
3676	} );
3677
3678	$.effects.effect.scale.call( this, newOptions, done );
3679} );
3680
3681
3682/*!
3683 * jQuery UI Effects Pulsate 1.12.0
3684 * http://jqueryui.com
3685 *
3686 * Copyright jQuery Foundation and other contributors
3687 * Released under the MIT license.
3688 * http://jquery.org/license
3689 */
3690
3691//>>label: Pulsate Effect
3692//>>group: Effects
3693//>>description: Pulsates an element n times by changing the opacity to zero and back.
3694//>>docs: http://api.jqueryui.com/pulsate-effect/
3695//>>demos: http://jqueryui.com/effect/
3696
3697
3698
3699var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3700	var element = $( this ),
3701		mode = options.mode,
3702		show = mode === "show",
3703		hide = mode === "hide",
3704		showhide = show || hide,
3705
3706		// Showing or hiding leaves off the "last" animation
3707		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3708		duration = options.duration / anims,
3709		animateTo = 0,
3710		i = 1,
3711		queuelen = element.queue().length;
3712
3713	if ( show || !element.is( ":visible" ) ) {
3714		element.css( "opacity", 0 ).show();
3715		animateTo = 1;
3716	}
3717
3718	// Anims - 1 opacity "toggles"
3719	for ( ; i < anims; i++ ) {
3720		element.animate( { opacity: animateTo }, duration, options.easing );
3721		animateTo = 1 - animateTo;
3722	}
3723
3724	element.animate( { opacity: animateTo }, duration, options.easing );
3725
3726	element.queue( done );
3727
3728	$.effects.unshift( element, queuelen, anims + 1 );
3729} );
3730
3731
3732/*!
3733 * jQuery UI Effects Shake 1.12.0
3734 * http://jqueryui.com
3735 *
3736 * Copyright jQuery Foundation and other contributors
3737 * Released under the MIT license.
3738 * http://jquery.org/license
3739 */
3740
3741//>>label: Shake Effect
3742//>>group: Effects
3743//>>description: Shakes an element horizontally or vertically n times.
3744//>>docs: http://api.jqueryui.com/shake-effect/
3745//>>demos: http://jqueryui.com/effect/
3746
3747
3748
3749var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3750
3751	var i = 1,
3752		element = $( this ),
3753		direction = options.direction || "left",
3754		distance = options.distance || 20,
3755		times = options.times || 3,
3756		anims = times * 2 + 1,
3757		speed = Math.round( options.duration / anims ),
3758		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3759		positiveMotion = ( direction === "up" || direction === "left" ),
3760		animation = {},
3761		animation1 = {},
3762		animation2 = {},
3763
3764		queuelen = element.queue().length;
3765
3766	$.effects.createPlaceholder( element );
3767
3768	// Animation
3769	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3770	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3771	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3772
3773	// Animate
3774	element.animate( animation, speed, options.easing );
3775
3776	// Shakes
3777	for ( ; i < times; i++ ) {
3778		element
3779			.animate( animation1, speed, options.easing )
3780			.animate( animation2, speed, options.easing );
3781	}
3782
3783	element
3784		.animate( animation1, speed, options.easing )
3785		.animate( animation, speed / 2, options.easing )
3786		.queue( done );
3787
3788	$.effects.unshift( element, queuelen, anims + 1 );
3789} );
3790
3791
3792/*!
3793 * jQuery UI Effects Slide 1.12.0
3794 * http://jqueryui.com
3795 *
3796 * Copyright jQuery Foundation and other contributors
3797 * Released under the MIT license.
3798 * http://jquery.org/license
3799 */
3800
3801//>>label: Slide Effect
3802//>>group: Effects
3803//>>description: Slides an element in and out of the viewport.
3804//>>docs: http://api.jqueryui.com/slide-effect/
3805//>>demos: http://jqueryui.com/effect/
3806
3807
3808
3809var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3810	var startClip, startRef,
3811		element = $( this ),
3812		map = {
3813			up: [ "bottom", "top" ],
3814			down: [ "top", "bottom" ],
3815			left: [ "right", "left" ],
3816			right: [ "left", "right" ]
3817		},
3818		mode = options.mode,
3819		direction = options.direction || "left",
3820		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3821		positiveMotion = ( direction === "up" || direction === "left" ),
3822		distance = options.distance ||
3823			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3824		animation = {};
3825
3826	$.effects.createPlaceholder( element );
3827
3828	startClip = element.cssClip();
3829	startRef = element.position()[ ref ];
3830
3831	// Define hide animation
3832	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3833	animation.clip = element.cssClip();
3834	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3835
3836	// Reverse the animation if we're showing
3837	if ( mode === "show" ) {
3838		element.cssClip( animation.clip );
3839		element.css( ref, animation[ ref ] );
3840		animation.clip = startClip;
3841		animation[ ref ] = startRef;
3842	}
3843
3844	// Actually animate
3845	element.animate( animation, {
3846		queue: false,
3847		duration: options.duration,
3848		easing: options.easing,
vendor: 4,900 bytes, lines 3849-4044
3849		complete: done
3850	} );
3851} );
3852
3853
3854/*!
3855 * jQuery UI Effects Transfer 1.12.0
3856 * http://jqueryui.com
3857 *
3858 * Copyright jQuery Foundation and other contributors
3859 * Released under the MIT license.
3860 * http://jquery.org/license
3861 */
3862
3863//>>label: Transfer Effect
3864//>>group: Effects
3865//>>description: Displays a transfer effect from one element to another.
3866//>>docs: http://api.jqueryui.com/transfer-effect/
3867//>>demos: http://jqueryui.com/effect/
3868
3869
3870
3871var effect;
3872if ( $.uiBackCompat !== false ) {
3873	effect = $.effects.define( "transfer", function( options, done ) {
3874		$( this ).transfer( options, done );
3875	} );
3876}
3877var effectsEffectTransfer = effect;
3878
3879
3880/*!
3881 * jQuery UI Focusable 1.12.0
3882 * http://jqueryui.com
3883 *
3884 * Copyright jQuery Foundation and other contributors
3885 * Released under the MIT license.
3886 * http://jquery.org/license
3887 */
3888
3889//>>label: :focusable Selector
3890//>>group: Core
3891//>>description: Selects elements which can be focused.
3892//>>docs: http://api.jqueryui.com/focusable-selector/
3893
3894
3895
3896// Selectors
3897$.ui.focusable = function( element, hasTabindex ) {
3898	var map, mapName, img, focusableIfVisible, fieldset,
3899		nodeName = element.nodeName.toLowerCase();
3900
3901	if ( "area" === nodeName ) {
3902		map = element.parentNode;
3903		mapName = map.name;
3904		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3905			return false;
3906		}
3907		img = $( "img[usemap='#" + mapName + "']" );
3908		return img.length > 0 && img.is( ":visible" );
3909	}
3910
3911	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3912		focusableIfVisible = !element.disabled;
3913
3914		if ( focusableIfVisible ) {
3915
3916			// Form controls within a disabled fieldset are disabled.
3917			// However, controls within the fieldset's legend do not get disabled.
3918			// Since controls generally aren't placed inside legends, we skip
3919			// this portion of the check.
3920			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3921			if ( fieldset ) {
3922				focusableIfVisible = !fieldset.disabled;
3923			}
3924		}
3925	} else if ( "a" === nodeName ) {
3926		focusableIfVisible = element.href || hasTabindex;
3927	} else {
3928		focusableIfVisible = hasTabindex;
3929	}
3930
3931	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3932};
3933
3934// Support: IE 8 only
3935// IE 8 doesn't resolve inherit to visible/hidden for computed values
3936function visible( element ) {
3937	var visibility = element.css( "visibility" );
3938	while ( visibility === "inherit" ) {
3939		element = element.parent();
3940		visibility = element.css( "visibility" );
3941	}
3942	return visibility !== "hidden";
3943}
3944
3945$.extend( $.expr[ ":" ], {
3946	focusable: function( element ) {
3947		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3948	}
3949} );
3950
3951var focusable = $.ui.focusable;
3952
3953
3954
3955
3956// Support: IE8 Only
3957// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3958// with a string, so we need to find the proper form.
3959var form = $.fn.form = function() {
3960	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3961};
3962
3963
3964/*!
3965 * jQuery UI Form Reset Mixin 1.12.0
3966 * http://jqueryui.com
3967 *
3968 * Copyright jQuery Foundation and other contributors
3969 * Released under the MIT license.
3970 * http://jquery.org/license
3971 */
3972
3973//>>label: Form Reset Mixin
3974//>>group: Core
3975//>>description: Refresh input widgets when their form is reset
3976//>>docs: http://api.jqueryui.com/form-reset-mixin/
3977
3978
3979
3980var formResetMixin = $.ui.formResetMixin = {
3981	_formResetHandler: function() {
3982		var form = $( this );
3983
3984		// Wait for the form reset to actually happen before refreshing
3985		setTimeout( function() {
3986			var instances = form.data( "ui-form-reset-instances" );
3987			$.each( instances, function() {
3988				this.refresh();
3989			} );
3990		} );
3991	},
3992
3993	_bindFormResetHandler: function() {
3994		this.form = this.element.form();
3995		if ( !this.form.length ) {
3996			return;
3997		}
3998
3999		var instances = this.form.data( "ui-form-reset-instances" ) || [];
4000		if ( !instances.length ) {
4001
4002			// We don't use _on() here because we use a single event handler per form
4003			this.form.on( "reset.ui-form-reset", this._formResetHandler );
4004		}
4005		instances.push( this );
4006		this.form.data( "ui-form-reset-instances", instances );
4007	},
4008
4009	_unbindFormResetHandler: function() {
4010		if ( !this.form.length ) {
4011			return;
4012		}
4013
4014		var instances = this.form.data( "ui-form-reset-instances" );
4015		instances.splice( $.inArray( this, instances ), 1 );
4016		if ( instances.length ) {
4017			this.form.data( "ui-form-reset-instances", instances );
4018		} else {
4019			this.form
4020				.removeData( "ui-form-reset-instances" )
4021				.off( "reset.ui-form-reset" );
4022		}
4023	}
4024};
4025
4026
4027/*!
4028 * jQuery UI Support for jQuery core 1.7.x 1.12.0
4029 * http://jqueryui.com
4030 *
4031 * Copyright jQuery Foundation and other contributors
4032 * Released under the MIT license.
4033 * http://jquery.org/license
4034 *
4035 */
4036
4037//>>label: jQuery 1.7 Support
4038//>>group: Core
4039//>>description: Support version 1.7.x of jQuery core
4040
4041
4042
4043// Support: jQuery 1.7 only
4044// Not a great way to check versions, but since we only support 
40441.7+ and only
4045// need to detect <1.8, this is a simple check that should suffice. Checking
4046// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4047// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4048// 1.7 anymore). See #11197 for why we're not using feature detection.
4049if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4050
4051	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4052	// Unlike jQuery Core 1.8+, these only support numeric values to set the
4053	// dimensions in pixels
4054	$.each( [ "Width", "Height" ], function( i, name ) {
4055		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4056			type = name.toLowerCase(),
4057			orig = {
4058				innerWidth: $.fn.innerWidth,
4059				innerHeight: $.fn.innerHeight,
4060				outerWidth: $.fn.outerWidth,
4061				outerHeight: $.fn.outerHeight
4062			};
4063
4064		function reduce( elem, size, border, margin ) {
4065			$.each( side, function() {
4066				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4067				if ( border ) {
4068					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4069				}
4070				if ( margin ) {
4071					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4072				}
4073			} );
4074			return size;
4075		}
4076
4077		$.fn[ "inner" + name ] = function( size ) {
4078			if ( size === undefined ) {
4079				return orig[ "inner" + name ].call( this );
4080			}
4081
4082			return this.each( function() {
4083				$( this ).css( type, reduce( this, size ) + "px" );
4084			} );
4085		};
4086
4087		$.fn[ "outer" + name ] = function( size, margin ) {
4088			if ( typeof size !== "number" ) {
4089				return orig[ "outer" + name ].call( this, size );
4090			}
4091
4092			return this.each( function() {
4093				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4094			} );
4095		};
4096	} );
4097
4098	$.fn.addBack = function( selector ) {
4099		return this.add( selector == null ?
4100			this.prevObject : this.prevObject.filter( selector )
4101		);
4102	};
4103}
4104
4105;
4106/*!
4107 * jQuery UI Keycode 1.12.0
4108 * http://jqueryui.com
4109 *
4110 * Copyright jQuery Foundation and other contributors
4111 * Released under the MIT license.
4112 * http://jquery.org/license
4113 */
4114
4115//>>label: Keycode
4116//>>group: Core
4117//>>description: Provide keycodes as keynames
4118//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4119
4120
4121var keycode = $.ui.keyCode = {
4122	BACKSPACE: 8,
4123	COMMA: 188,
4124	DELETE: 46,
4125	DOWN: 40,
4126	END: 35,
4127	ENTER: 13,
4128	ESCAPE: 27,
4129	HOME: 36,
4130	LEFT: 37,
4131	PAGE_DOWN: 34,
4132	PAGE_UP: 33,
4133	PERIOD: 190,
4134	RIGHT: 39,
4135	SPACE: 32,
4136	TAB: 9,
4137	UP: 38
4138};
4139
4140
4141
4142
4143// Internal use only
4144var escapeSelector = $.ui.escapeSelector = ( function() {
4145	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4146	return function( selector ) {
4147		return selector.replace( selectorEscape, "\\$1" );
4148	};
4149} )();
4150
4151
4152/*!
4153 * jQuery UI Labels 1.12.0
4154 * http://jqueryui.com
4155 *
4156 * Copyright jQuery Foundation and other contributors
4157 * Released under the MIT license.
4158 * http://jquery.org/license
4159 */
4160
4161//>>label: labels
4162//>>group: Core
4163//>>description: Find all the labels associated with a given input
4164//>>docs: http://api.jqueryui.com/labels/
4165
4166
4167
4168var labels = $.fn.labels = function() {
4169	var ancestor, selector, id, labels, ancestors;
4170
4171	// Check control.labels first
4172	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4173		return this.pushStack( this[ 0 ].labels );
4174	}
4175
4176	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4177	// Above browsers do not support control.labels. Everything below is to support them
4178	// as well as document fragments. control.labels does not work on document fragments
4179	labels = this.eq( 0 ).parents( "label" );
4180
4181	// Look for the label based on the id
4182	id = this.attr( "id" );
4183	if ( id ) {
4184
4185		// We don't search against the document in case the element
4186		// is disconnected from the DOM
4187		ancestor = this.eq( 0 ).parents().last();
4188
4189		// Get a full set of top level ancestors
4190		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4191
4192		// Create a selector for the label based on the id
4193		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4194
4195		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4196
4197	}
4198
4199	// Return whatever we have found for labels
4200	return this.pushStack( labels );
4201};
4202
4203
4204/*!
4205 * jQuery UI Scroll Parent 1.12.0
4206 * http://jqueryui.com
4207 *
4208 * Copyright jQuery Foundation and other contributors
4209 * Released under the MIT license.
4210 * http://jquery.org/license
4211 */
4212
4213//>>label: scrollParent
4214//>>group: Core
4215//>>description: Get the closest ancestor element that is scrollable.
4216//>>docs: http://api.jqueryui.com/scrollParent/
4217
4218
4219
4220var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4221	var position = this.css( "position" ),
4222		excludeStaticParent = position === "absolute",
4223		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4224		scrollParent = this.parents().filter( function() {
4225			var parent = $( this );
4226			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4227				return false;
vendor: 5,582 bytes, lines 4228-4471
4228			}
4229			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4230				parent.css( "overflow-x" ) );
4231		} ).eq( 0 );
4232
4233	return position === "fixed" || !scrollParent.length ?
4234		$( this[ 0 ].ownerDocument || document ) :
4235		scrollParent;
4236};
4237
4238
4239/*!
4240 * jQuery UI Tabbable 1.12.0
4241 * http://jqueryui.com
4242 *
4243 * Copyright jQuery Foundation and other contributors
4244 * Released under the MIT license.
4245 * http://jquery.org/license
4246 */
4247
4248//>>label: :tabbable Selector
4249//>>group: Core
4250//>>description: Selects elements which can be tabbed to.
4251//>>docs: http://api.jqueryui.com/tabbable-selector/
4252
4253
4254
4255var tabbable = $.extend( $.expr[ ":" ], {
4256	tabbable: function( element ) {
4257		var tabIndex = $.attr( element, "tabindex" ),
4258			hasTabindex = tabIndex != null;
4259		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4260	}
4261} );
4262
4263
4264/*!
4265 * jQuery UI Unique ID 1.12.0
4266 * http://jqueryui.com
4267 *
4268 * Copyright jQuery Foundation and other contributors
4269 * Released under the MIT license.
4270 * http://jquery.org/license
4271 */
4272
4273//>>label: uniqueId
4274//>>group: Core
4275//>>description: Functions to generate and remove uniqueId's
4276//>>docs: http://api.jqueryui.com/uniqueId/
4277
4278
4279
4280var uniqueId = $.fn.extend( {
4281	uniqueId: ( function() {
4282		var uuid = 0;
4283
4284		return function() {
4285			return this.each( function() {
4286				if ( !this.id ) {
4287					this.id = "ui-id-" + ( ++uuid );
4288				}
4289			} );
4290		};
4291	} )(),
4292
4293	removeUniqueId: function() {
4294		return this.each( function() {
4295			if ( /^ui-id-\d+$/.test( this.id ) ) {
4296				$( this ).removeAttr( "id" );
4297			}
4298		} );
4299	}
4300} );
4301
4302
4303/*!
4304 * jQuery UI Accordion 1.12.0
4305 * http://jqueryui.com
4306 *
4307 * Copyright jQuery Foundation and other contributors
4308 * Released under the MIT license.
4309 * http://jquery.org/license
4310 */
4311
4312//>>label: Accordion
4313//>>group: Widgets
4314// jscs:disable maximumLineLength
4315//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4316// jscs:enable maximumLineLength
4317//>>docs: http://api.jqueryui.com/accordion/
4318//>>demos: http://jqueryui.com/accordion/
4319//>>css.structure: ../../themes/base/core.css
4320//>>css.structure: ../../themes/base/accordion.css
4321//>>css.theme: ../../themes/base/theme.css
4322
4323
4324
4325var widgetsAccordion = $.widget( "ui.accordion", {
4326	version: "1.12.0",
4327	options: {
4328		active: 0,
4329		animate: {},
4330		classes: {
4331			"ui-accordion-header": "ui-corner-top",
4332			"ui-accordion-header-collapsed": "ui-corner-all",
4333			"ui-accordion-content": "ui-corner-bottom"
4334		},
4335		collapsible: false,
4336		event: "click",
4337		header: "> li > :first-child, > :not(li):even",
4338		heightStyle: "auto",
4339		icons: {
4340			activeHeader: "ui-icon-triangle-1-s",
4341			header: "ui-icon-triangle-1-e"
4342		},
4343
4344		// Callbacks
4345		activate: null,
4346		beforeActivate: null
4347	},
4348
4349	hideProps: {
4350		borderTopWidth: "hide",
4351		borderBottomWidth: "hide",
4352		paddingTop: "hide",
4353		paddingBottom: "hide",
4354		height: "hide"
4355	},
4356
4357	showProps: {
4358		borderTopWidth: "show",
4359		borderBottomWidth: "show",
4360		paddingTop: "show",
4361		paddingBottom: "show",
4362		height: "show"
4363	},
4364
4365	_create: function() {
4366		var options = this.options;
4367
4368		this.prevShow = this.prevHide = $();
4369		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4370		this.element.attr( "role", "tablist" );
4371
4372		// Don't allow collapsible: false and active: false / null
4373		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4374			options.active = 0;
4375		}
4376
4377		this._processPanels();
4378
4379		// handle negative values
4380		if ( options.active < 0 ) {
4381			options.active += this.headers.length;
4382		}
4383		this._refresh();
4384	},
4385
4386	_getCreateEventData: function() {
4387		return {
4388			header: this.active,
4389			panel: !this.active.length ? $() : this.active.next()
4390		};
4391	},
4392
4393	_createIcons: function() {
4394		var icon, children,
4395			icons = this.options.icons;
4396
4397		if ( icons ) {
4398			icon = $( "<span>" );
4399			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4400			icon.prependTo( this.headers );
4401			children = this.active.children( ".ui-accordion-header-icon" );
4402			this._removeClass( children, icons.header )
4403				._addClass( children, null, icons.activeHeader )
4404				._addClass( this.headers, "ui-accordion-icons" );
4405		}
4406	},
4407
4408	_destroyIcons: function() {
4409		this._removeClass( this.headers, "ui-accordion-icons" );
4410		this.headers.children( ".ui-accordion-header-icon" ).remove();
4411	},
4412
4413	_destroy: function() {
4414		var contents;
4415
4416		// Clean up main element
4417		this.element.removeAttr( "role" );
4418
4419		// Clean up headers
4420		this.headers
4421			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4422			.removeUniqueId();
4423
4424		this._destroyIcons();
4425
4426		// Clean up content panels
4427		contents = this.headers.next()
4428			.css( "display", "" )
4429			.removeAttr( "role aria-hidden aria-labelledby" )
4430			.removeUniqueId();
4431
4432		if ( this.options.heightStyle !== "content" ) {
4433			contents.css( "height", "" );
4434		}
4435	},
4436
4437	_setOption: function( key, value ) {
4438		if ( key === "active" ) {
4439
4440			// _activate() will handle invalid values and update this.options
4441			this._activate( value );
4442			return;
4443		}
4444
4445		if ( key === "event" ) {
4446			if ( this.options.event ) {
4447				this._off( this.headers, this.options.event );
4448			}
4449			this._setupEvents( value );
4450		}
4451
4452		this._super( key, value );
4453
4454		// Setting collapsible: false while collapsed; open first panel
4455		if ( key === "collapsible" && !value && this.options.active === false ) {
4456			this._activate( 0 );
4457		}
4458
4459		if ( key === "icons" ) {
4460			this._destroyIcons();
4461			if ( value ) {
4462				this._createIcons();
4463			}
4464		}
4465	},
4466
4467	_setOptionDisabled: function( value ) {
4468		this._super( value );
4469
4470		this.element.attr( "aria-disabled", value );
4471
vendor: 16,234 bytes, lines 4472-5071
4472		// Support: IE8 Only
4473		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4474		// so we need to add the disabled class to the headers and panels
4475		this._toggleClass( null, "ui-state-disabled", !!value );
4476		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4477			!!value );
4478	},
4479
4480	_keydown: function( event ) {
4481		if ( event.altKey || event.ctrlKey ) {
4482			return;
4483		}
4484
4485		var keyCode = $.ui.keyCode,
4486			length = this.headers.length,
4487			currentIndex = this.headers.index( event.target ),
4488			toFocus = false;
4489
4490		switch ( event.keyCode ) {
4491		case keyCode.RIGHT:
4492		case keyCode.DOWN:
4493			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4494			break;
4495		case keyCode.LEFT:
4496		case keyCode.UP:
4497			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4498			break;
4499		case keyCode.SPACE:
4500		case keyCode.ENTER:
4501			this._eventHandler( event );
4502			break;
4503		case keyCode.HOME:
4504			toFocus = this.headers[ 0 ];
4505			break;
4506		case keyCode.END:
4507			toFocus = this.headers[ length - 1 ];
4508			break;
4509		}
4510
4511		if ( toFocus ) {
4512			$( event.target ).attr( "tabIndex", -1 );
4513			$( toFocus ).attr( "tabIndex", 0 );
4514			$( toFocus ).trigger( "focus" );
4515			event.preventDefault();
4516		}
4517	},
4518
4519	_panelKeyDown: function( event ) {
4520		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4521			$( event.currentTarget ).prev().trigger( "focus" );
4522		}
4523	},
4524
4525	refresh: function() {
4526		var options = this.options;
4527		this._processPanels();
4528
4529		// Was collapsed or no panel
4530		if ( ( options.active === false && options.collapsible === true ) ||
4531				!this.headers.length ) {
4532			options.active = false;
4533			this.active = $();
4534
4535		// active false only when collapsible is true
4536		} else if ( options.active === false ) {
4537			this._activate( 0 );
4538
4539		// was active, but active panel is gone
4540		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4541
4542			// all remaining panel are disabled
4543			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4544				options.active = false;
4545				this.active = $();
4546
4547			// activate previous panel
4548			} else {
4549				this._activate( Math.max( 0, options.active - 1 ) );
4550			}
4551
4552		// was active, active panel still exists
4553		} else {
4554
4555			// make sure active index is correct
4556			options.active = this.headers.index( this.active );
4557		}
4558
4559		this._destroyIcons();
4560
4561		this._refresh();
4562	},
4563
4564	_processPanels: function() {
4565		var prevHeaders = this.headers,
4566			prevPanels = this.panels;
4567
4568		this.headers = this.element.find( this.options.header );
4569		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4570			"ui-state-default" );
4571
4572		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4573		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4574
4575		// Avoid memory leaks (#10056)
4576		if ( prevPanels ) {
4577			this._off( prevHeaders.not( this.headers ) );
4578			this._off( prevPanels.not( this.panels ) );
4579		}
4580	},
4581
4582	_refresh: function() {
4583		var maxHeight,
4584			options = this.options,
4585			heightStyle = options.heightStyle,
4586			parent = this.element.parent();
4587
4588		this.active = this._findActive( options.active );
4589		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4590			._removeClass( this.active, "ui-accordion-header-collapsed" );
4591		this._addClass( this.active.next(), "ui-accordion-content-active" );
4592		this.active.next().show();
4593
4594		this.headers
4595			.attr( "role", "tab" )
4596			.each( function() {
4597				var header = $( this ),
4598					headerId = header.uniqueId().attr( "id" ),
4599					panel = header.next(),
4600					panelId = panel.uniqueId().attr( "id" );
4601				header.attr( "aria-controls", panelId );
4602				panel.attr( "aria-labelledby", headerId );
4603			} )
4604			.next()
4605				.attr( "role", "tabpanel" );
4606
4607		this.headers
4608			.not( this.active )
4609				.attr( {
4610					"aria-selected": "false",
4611					"aria-expanded": "false",
4612					tabIndex: -1
4613				} )
4614				.next()
4615					.attr( {
4616						"aria-hidden": "true"
4617					} )
4618					.hide();
4619
4620		// Make sure at least one header is in the tab order
4621		if ( !this.active.length ) {
4622			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4623		} else {
4624			this.active.attr( {
4625				"aria-selected": "true",
4626				"aria-expanded": "true",
4627				tabIndex: 0
4628			} )
4629				.next()
4630					.attr( {
4631						"aria-hidden": "false"
4632					} );
4633		}
4634
4635		this._createIcons();
4636
4637		this._setupEvents( options.event );
4638
4639		if ( heightStyle === "fill" ) {
4640			maxHeight = parent.height();
4641			this.element.siblings( ":visible" ).each( function() {
4642				var elem = $( this ),
4643					position = elem.css( "position" );
4644
4645				if ( position === "absolute" || position === "fixed" ) {
4646					return;
4647				}
4648				maxHeight -= elem.outerHeight( true );
4649			} );
4650
4651			this.headers.each( function() {
4652				maxHeight -= $( this ).outerHeight( true );
4653			} );
4654
4655			this.headers.next()
4656				.each( function() {
4657					$( this ).height( Math.max( 0, maxHeight -
4658						$( this ).innerHeight() + $( this ).height() ) );
4659				} )
4660				.css( "overflow", "auto" );
4661		} else if ( heightStyle === "auto" ) {
4662			maxHeight = 0;
4663			this.headers.next()
4664				.each( function() {
4665					var isVisible = $( this ).is( ":visible" );
4666					if ( !isVisible ) {
4667						$( this ).show();
4668					}
4669					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4670					if ( !isVisible ) {
4671						$( this ).hide();
4672					}
4673				} )
4674				.height( maxHeight );
4675		}
4676	},
4677
4678	_activate: function( index ) {
4679		var active = this._findActive( index )[ 0 ];
4680
4681		// Trying to activate the already active panel
4682		if ( active === this.active[ 0 ] ) {
4683			return;
4684		}
4685
4686		// Trying to collapse, simulate a click on the currently active header
4687		active = active || this.active[ 0 ];
4688
4689		this._eventHandler( {
4690			target: active,
4691			currentTarget: active,
4692			preventDefault: $.noop
4693		} );
4694	},
4695
4696	_findActive: function( selector ) {
4697		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4698	},
4699
4700	_setupEvents: function( event ) {
4701		var events = {
4702			keydown: "_keydown"
4703		};
4704		if ( event ) {
4705			$.each( event.split( " " ), function( index, eventName ) {
4706				events[ eventName ] = "_eventHandler";
4707			} );
4708		}
4709
4710		this._off( this.headers.add( this.headers.next() ) );
4711		this._on( this.headers, events );
4712		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4713		this._hoverable( this.headers );
4714		this._focusable( this.headers );
4715	},
4716
4717	_eventHandler: function( event ) {
4718		var activeChildren, clickedChildren,
4719			options = this.options,
4720			active = this.active,
4721			clicked = $( event.currentTarget ),
4722			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4723			collapsing = clickedIsActive && options.collapsible,
4724			toShow = collapsing ? $() : clicked.next(),
4725			toHide = active.next(),
4726			eventData = {
4727				oldHeader: active,
4728				oldPanel: toHide,
4729				newHeader: collapsing ? $() : clicked,
4730				newPanel: toShow
4731			};
4732
4733		event.preventDefault();
4734
4735		if (
4736
4737				// click on active header, but not collapsible
4738				( clickedIsActive && !options.collapsible ) ||
4739
4740				// allow canceling activation
4741				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4742			return;
4743		}
4744
4745		options.active = collapsing ? false : this.headers.index( clicked );
4746
4747		// When the call to ._toggle() comes after the class changes
4748		// it causes a very odd bug in IE 8 (see #6720)
4749		this.active = clickedIsActive ? $() : clicked;
4750		this._toggle( eventData );
4751
4752		// Switch classes
4753		// corner classes on the previously active header stay after the animation
4754		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4755		if ( options.icons ) {
4756			activeChildren = active.children( ".ui-accordion-header-icon" );
4757			this._removeClass( activeChildren, null, options.icons.activeHeader )
4758				._addClass( activeChildren, null, options.icons.header );
4759		}
4760
4761		if ( !clickedIsActive ) {
4762			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4763				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4764			if ( options.icons ) {
4765				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4766				this._removeClass( clickedChildren, null, options.icons.header )
4767					._addClass( clickedChildren, null, options.icons.activeHeader );
4768			}
4769
4770			this._addClass( clicked.next(), "ui-accordion-content-active" );
4771		}
4772	},
4773
4774	_toggle: function( data ) {
4775		var toShow = data.newPanel,
4776			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4777
4778		// Handle activating a panel during the animation for another activation
4779		this.prevShow.add( this.prevHide ).stop( true, true );
4780		this.prevShow = toShow;
4781		this.prevHide = toHide;
4782
4783		if ( this.options.animate ) {
4784			this._animate( toShow, toHide, data );
4785		} else {
4786			toHide.hide();
4787			toShow.show();
4788			this._toggleComplete( data );
4789		}
4790
4791		toHide.attr( {
4792			"aria-hidden": "true"
4793		} );
4794		toHide.prev().attr( {
4795			"aria-selected": "false",
4796			"aria-expanded": "false"
4797		} );
4798
4799		// if we're switching panels, remove the old header from the tab order
4800		// if we're opening from collapsed state, remove the previous header from the tab order
4801		// if we're collapsing, then keep the collapsing header in the tab order
4802		if ( toShow.length && toHide.length ) {
4803			toHide.prev().attr( {
4804				"tabIndex": -1,
4805				"aria-expanded": "false"
4806			} );
4807		} else if ( toShow.length ) {
4808			this.headers.filter( function() {
4809				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4810			} )
4811				.attr( "tabIndex", -1 );
4812		}
4813
4814		toShow
4815			.attr( "aria-hidden", "false" )
4816			.prev()
4817				.attr( {
4818					"aria-selected": "true",
4819					"aria-expanded": "true",
4820					tabIndex: 0
4821				} );
4822	},
4823
4824	_animate: function( toShow, toHide, data ) {
4825		var total, easing, duration,
4826			that = this,
4827			adjust = 0,
4828			boxSizing = toShow.css( "box-sizing" ),
4829			down = toShow.length &&
4830				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4831			animate = this.options.animate || {},
4832			options = down && animate.down || animate,
4833			complete = function() {
4834				that._toggleComplete( data );
4835			};
4836
4837		if ( typeof options === "number" ) {
4838			duration = options;
4839		}
4840		if ( typeof options === "string" ) {
4841			easing = options;
4842		}
4843
4844		// fall back from options to animation in case of partial down settings
4845		easing = easing || options.easing || animate.easing;
4846		duration = duration || options.duration || animate.duration;
4847
4848		if ( !toHide.length ) {
4849			return toShow.animate( this.showProps, duration, easing, complete );
4850		}
4851		if ( !toShow.length ) {
4852			return toHide.animate( this.hideProps, duration, easing, complete );
4853		}
4854
4855		total = toShow.show().outerHeight();
4856		toHide.animate( this.hideProps, {
4857			duration: duration,
4858			easing: easing,
4859			step: function( now, fx ) {
4860				fx.now = Math.round( now );
4861			}
4862		} );
4863		toShow
4864			.hide()
4865			.animate( this.showProps, {
4866				duration: duration,
4867				easing: easing,
4868				complete: complete,
4869				step: function( now, fx ) {
4870					fx.now = Math.round( now );
4871					if ( fx.prop !== "height" ) {
4872						if ( boxSizing === "content-box" ) {
4873							adjust += fx.now;
4874						}
4875					} else if ( that.options.heightStyle !== "content" ) {
4876						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4877						adjust = 0;
4878					}
4879				}
4880			} );
4881	},
4882
4883	_toggleComplete: function( data ) {
4884		var toHide = data.oldPanel,
4885			prev = toHide.prev();
4886
4887		this._removeClass( toHide, "ui-accordion-content-active" );
4888		this._removeClass( prev, "ui-accordion-header-active" )
4889			._addClass( prev, "ui-accordion-header-collapsed" );
4890
4891		// Work around for rendering bug in IE (#5421)
4892		if ( toHide.length ) {
4893			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4894		}
4895		this._trigger( "activate", null, data );
4896	}
4897} );
4898
4899
4900
4901var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4902	var activeElement;
4903
4904	// Support: IE 9 only
4905	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4906	try {
4907		activeElement = document.activeElement;
4908	} catch ( error ) {
4909		activeElement = document.body;
4910	}
4911
4912	// Support: IE 9 - 11 only
4913	// IE may return null instead of an element
4914	// Interestingly, this only seems to occur when NOT in an iframe
4915	if ( !activeElement ) {
4916		activeElement = document.body;
4917	}
4918
4919	// Support: IE 11 only
4920	// IE11 returns a seemingly empty object in some cases when accessing
4921	// document.activeElement from an <iframe>
4922	if ( !activeElement.nodeName ) {
4923		activeElement = document.body;
4924	}
4925
4926	return activeElement;
4927};
4928
4929
4930/*!
4931 * jQuery UI Menu 1.12.0
4932 * http://jqueryui.com
4933 *
4934 * Copyright jQuery Foundation and other contributors
4935 * Released under the MIT license.
4936 * http://jquery.org/license
4937 */
4938
4939//>>label: Menu
4940//>>group: Widgets
4941//>>description: Creates nestable menus.
4942//>>docs: http://api.jqueryui.com/menu/
4943//>>demos: http://jqueryui.com/menu/
4944//>>css.structure: ../../themes/base/core.css
4945//>>css.structure: ../../themes/base/menu.css
4946//>>css.theme: ../../themes/base/theme.css
4947
4948
4949
4950var widgetsMenu = $.widget( "ui.menu", {
4951	version: "1.12.0",
4952	defaultElement: "<ul>",
4953	delay: 300,
4954	options: {
4955		icons: {
4956			submenu: "ui-icon-caret-1-e"
4957		},
4958		items: "> *",
4959		menus: "ul",
4960		position: {
4961			my: "left top",
4962			at: "right top"
4963		},
4964		role: "menu",
4965
4966		// Callbacks
4967		blur: null,
4968		focus: null,
4969		select: null
4970	},
4971
4972	_create: function() {
4973		this.activeMenu = this.element;
4974
4975		// Flag used to prevent firing of the click handler
4976		// as the event bubbles up through nested menus
4977		this.mouseHandled = false;
4978		this.element
4979			.uniqueId()
4980			.attr( {
4981				role: this.options.role,
4982				tabIndex: 0
4983			} );
4984
4985		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4986		this._on( {
4987
4988			// Prevent focus from sticking to links inside menu after clicking
4989			// them (focus should always stay on UL during navigation).
4990			"mousedown .ui-menu-item": function( event ) {
4991				event.preventDefault();
4992			},
4993			"click .ui-menu-item": function( event ) {
4994				var target = $( event.target );
4995				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4996				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4997					this.select( event );
4998
4999					// Only set the mouseHandled flag if the event will bubble, see #9469.
5000					if ( !event.isPropagationStopped() ) {
5001						this.mouseHandled = true;
5002					}
5003
5004					// Open submenu on click
5005					if ( target.has( ".ui-menu" ).length ) {
5006						this.expand( event );
5007					} else if ( !this.element.is( ":focus" ) &&
5008							active.closest( ".ui-menu" ).length ) {
5009
5010						// Redirect focus to the menu
5011						this.element.trigger( "focus", [ true ] );
5012
5013						// If the active item is on the top level, let it stay active.
5014						// Otherwise, blur the active item since it is no longer visible.
5015						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5016							clearTimeout( this.timer );
5017						}
5018					}
5019				}
5020			},
5021			"mouseenter .ui-menu-item": function( event ) {
5022
5023				// Ignore mouse events while typeahead is active, see #10458.
5024				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5025				// is over an item in the menu
5026				if ( this.previousFilter ) {
5027					return;
5028				}
5029
5030				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5031					target = $( event.currentTarget );
5032
5033				// Ignore bubbled events on parent items, see #11641
5034				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5035					return;
5036				}
5037
5038				// Remove ui-state-active class from siblings of the newly focused menu item
5039				// to avoid a jump caused by adjacent elements both having a class with a border
5040				this._removeClass( target.siblings().children( ".ui-state-active" ),
5041					null, "ui-state-active" );
5042				this.focus( event, target );
5043			},
5044			mouseleave: "collapseAll",
5045			"mouseleave .ui-menu": "collapseAll",
5046			focus: function( event, keepActiveItem ) {
5047
5048				// If there's already an active item, keep it active
5049				// If not, activate the first item
5050				var item = this.active || this.element.find( this.options.items ).eq( 0 );
5051
5052				if ( !keepActiveItem ) {
5053					this.focus( event, item );
5054				}
5055			},
5056			blur: function( event ) {
5057				this._delay( function() {
5058					var notContained = !$.contains(
5059						this.element[ 0 ],
5060						$.ui.safeActiveElement( this.document[ 0 ] )
5061					);
5062					if ( notContained ) {
5063						this.collapseAll( event );
5064					}
5065				} );
5066			},
5067			keydown: "_keydown"
5068		} );
5069
5070		this.refresh();
5071
vendor: 1,858 bytes, lines 5072-5148
5072		// Clicks outside of a menu collapse any open menus
5073		this._on( this.document, {
5074			click: function( event ) {
5075				if ( this._closeOnDocumentClick( event ) ) {
5076					this.collapseAll( event );
5077				}
5078
5079				// Reset the mouseHandled flag
5080				this.mouseHandled = false;
5081			}
5082		} );
5083	},
5084
5085	_destroy: function() {
5086		var items = this.element.find( ".ui-menu-item" )
5087				.removeAttr( "role aria-disabled" ),
5088			submenus = items.children( ".ui-menu-item-wrapper" )
5089				.removeUniqueId()
5090				.removeAttr( "tabIndex role aria-haspopup" );
5091
5092		// Destroy (sub)menus
5093		this.element
5094			.removeAttr( "aria-activedescendant" )
5095			.find( ".ui-menu" ).addBack()
5096				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5097					"tabIndex" )
5098				.removeUniqueId()
5099				.show();
5100
5101		submenus.children().each( function() {
5102			var elem = $( this );
5103			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5104				elem.remove();
5105			}
5106		} );
5107	},
5108
5109	_keydown: function( event ) {
5110		var match, prev, character, skip,
5111			preventDefault = true;
5112
5113		switch ( event.keyCode ) {
5114		case $.ui.keyCode.PAGE_UP:
5115			this.previousPage( event );
5116			break;
5117		case $.ui.keyCode.PAGE_DOWN:
5118			this.nextPage( event );
5119			break;
5120		case $.ui.keyCode.HOME:
5121			this._move( "first", "first", event );
5122			break;
5123		case $.ui.keyCode.END:
5124			this._move( "last", "last", event );
5125			break;
5126		case $.ui.keyCode.UP:
5127			this.previous( event );
5128			break;
5129		case $.ui.keyCode.DOWN:
5130			this.next( event );
5131			break;
5132		case $.ui.keyCode.LEFT:
5133			this.collapse( event );
5134			break;
5135		case $.ui.keyCode.RIGHT:
5136			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5137				this.expand( event );
5138			}
5139			break;
5140		case $.ui.keyCode.ENTER:
5141		case $.ui.keyCode.SPACE:
5142			this._activate( event );
5143			break;
5144		case $.ui.keyCode.ESCAPE:
5145			this.collapse( event );
5146			break;
5147		default:
5148			preventDefault = false;
5149			prev = this.previousFilter || "";
5150			character = String.fromCharCode( event.keyCode );
5151			skip = false
vendor: 7,324 bytes, lines 5151-5413
5151;
5152
5153			clearTimeout( this.filterTimer );
5154
5155			if ( character === prev ) {
5156				skip = true;
5157			} else {
5158				character = prev + character;
5159			}
5160
5161			match = this._filterMenuItems( character );
5162			match = skip && match.index( this.active.next() ) !== -1 ?
5163				this.active.nextAll( ".ui-menu-item" ) :
5164				match;
5165
5166			// If no matches on the current filter, reset to the last character pressed
5167			// to move down the menu to the first item that starts with that character
5168			if ( !match.length ) {
5169				character = String.fromCharCode( event.keyCode );
5170				match = this._filterMenuItems( character );
5171			}
5172
5173			if ( match.length ) {
5174				this.focus( event, match );
5175				this.previousFilter = character;
5176				this.filterTimer = this._delay( function() {
5177					delete this.previousFilter;
5178				}, 1000 );
5179			} else {
5180				delete this.previousFilter;
5181			}
5182		}
5183
5184		if ( preventDefault ) {
5185			event.preventDefault();
5186		}
5187	},
5188
5189	_activate: function( event ) {
5190		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5191			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5192				this.expand( event );
5193			} else {
5194				this.select( event );
5195			}
5196		}
5197	},
5198
5199	refresh: function() {
5200		var menus, items, newSubmenus, newItems, newWrappers,
5201			that = this,
5202			icon = this.options.icons.submenu,
5203			submenus = this.element.find( this.options.menus );
5204
5205		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5206
5207		// Initialize nested menus
5208		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5209			.hide()
5210			.attr( {
5211				role: this.options.role,
5212				"aria-hidden": "true",
5213				"aria-expanded": "false"
5214			} )
5215			.each( function() {
5216				var menu = $( this ),
5217					item = menu.prev(),
5218					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5219
5220				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5221				item
5222					.attr( "aria-haspopup", "true" )
5223					.prepend( submenuCaret );
5224				menu.attr( "aria-labelledby", item.attr( "id" ) );
5225			} );
5226
5227		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5228
5229		menus = submenus.add( this.element );
5230		items = menus.find( this.options.items );
5231
5232		// Initialize menu-items containing spaces and/or dashes only as dividers
5233		items.not( ".ui-menu-item" ).each( function() {
5234			var item = $( this );
5235			if ( that._isDivider( item ) ) {
5236				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5237			}
5238		} );
5239
5240		// Don't refresh list items that are already adapted
5241		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5242		newWrappers = newItems.children()
5243			.not( ".ui-menu" )
5244				.uniqueId()
5245				.attr( {
5246					tabIndex: -1,
5247					role: this._itemRole()
5248				} );
5249		this._addClass( newItems, "ui-menu-item" )
5250			._addClass( newWrappers, "ui-menu-item-wrapper" );
5251
5252		// Add aria-disabled attribute to any disabled menu item
5253		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5254
5255		// If the active item has been removed, blur the menu
5256		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5257			this.blur();
5258		}
5259	},
5260
5261	_itemRole: function() {
5262		return {
5263			menu: "menuitem",
5264			listbox: "option"
5265		}[ this.options.role ];
5266	},
5267
5268	_setOption: function( key, value ) {
5269		if ( key === "icons" ) {
5270			var icons = this.element.find( ".ui-menu-icon" );
5271			this._removeClass( icons, null, this.options.icons.submenu )
5272				._addClass( icons, null, value.submenu );
5273		}
5274		this._super( key, value );
5275	},
5276
5277	_setOptionDisabled: function( value ) {
5278		this._super( value );
5279
5280		this.element.attr( "aria-disabled", String( value ) );
5281		this._toggleClass( null, "ui-state-disabled", !!value );
5282	},
5283
5284	focus: function( event, item ) {
5285		var nested, focused, activeParent;
5286		this.blur( event, event && event.type === "focus" );
5287
5288		this._scrollIntoView( item );
5289
5290		this.active = item.first();
5291
5292		focused = this.active.children( ".ui-menu-item-wrapper" );
5293		this._addClass( focused, null, "ui-state-active" );
5294
5295		// Only update aria-activedescendant if there's a role
5296		// otherwise we assume focus is managed elsewhere
5297		if ( this.options.role ) {
5298			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5299		}
5300
5301		// Highlight active parent menu item, if any
5302		activeParent = this.active
5303			.parent()
5304				.closest( ".ui-menu-item" )
5305					.children( ".ui-menu-item-wrapper" );
5306		this._addClass( activeParent, null, "ui-state-active" );
5307
5308		if ( event && event.type === "keydown" ) {
5309			this._close();
5310		} else {
5311			this.timer = this._delay( function() {
5312				this._close();
5313			}, this.delay );
5314		}
5315
5316		nested = item.children( ".ui-menu" );
5317		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5318			this._startOpening( nested );
5319		}
5320		this.activeMenu = item.parent();
5321
5322		this._trigger( "focus", event, { item: item } );
5323	},
5324
5325	_scrollIntoView: function( item ) {
5326		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5327		if ( this._hasScroll() ) {
5328			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5329			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5330			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5331			scroll = this.activeMenu.scrollTop();
5332			elementHeight = this.activeMenu.height();
5333			itemHeight = item.outerHeight();
5334
5335			if ( offset < 0 ) {
5336				this.activeMenu.scrollTop( scroll + offset );
5337			} else if ( offset + itemHeight > elementHeight ) {
5338				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5339			}
5340		}
5341	},
5342
5343	blur: function( event, fromFocus ) {
5344		if ( !fromFocus ) {
5345			clearTimeout( this.timer );
5346		}
5347
5348		if ( !this.active ) {
5349			return;
5350		}
5351
5352		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5353			null, "ui-state-active" );
5354
5355		this._trigger( "blur", event, { item: this.active } );
5356		this.active = null;
5357	},
5358
5359	_startOpening: function( submenu ) {
5360		clearTimeout( this.timer );
5361
5362		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5363		// shift in the submenu position when mousing over the caret icon
5364		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5365			return;
5366		}
5367
5368		this.timer = this._delay( function() {
5369			this._close();
5370			this._open( submenu );
5371		}, this.delay );
5372	},
5373
5374	_open: function( submenu ) {
5375		var position = $.extend( {
5376			of: this.active
5377		}, this.options.position );
5378
5379		clearTimeout( this.timer );
5380		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5381			.hide()
5382			.attr( "aria-hidden", "true" );
5383
5384		submenu
5385			.show()
5386			.removeAttr( "aria-hidden" )
5387			.attr( "aria-expanded", "true" )
5388			.position( position );
5389	},
5390
5391	collapseAll: function( event, all ) {
5392		clearTimeout( this.timer );
5393		this.timer = this._delay( function() {
5394
5395			// If we were passed an event, look for the submenu that contains the event
5396			var currentMenu = all ? this.element :
5397				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5398
5399			// If we found no valid submenu ancestor, use the main menu to close all
5400			// sub menus anyway
5401			if ( !currentMenu.length ) {
5402				currentMenu = this.element;
5403			}
5404
5405			this._close( currentMenu );
5406
5407			this.blur( event );
5408
5409			// Work around active item staying active after menu is blurred
5410			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5411
5412			this.activeMenu = currentMenu;
5413		}, 
vendor: 6,612 bytes, lines 5413-5665
5413this.delay );
5414	},
5415
5416	// With no arguments, closes the currently active menu - if nothing is active
5417	// it closes all menus.  If passed an argument, it will search for menus BELOW
5418	_close: function( startMenu ) {
5419		if ( !startMenu ) {
5420			startMenu = this.active ? this.active.parent() : this.element;
5421		}
5422
5423		startMenu.find( ".ui-menu" )
5424			.hide()
5425			.attr( "aria-hidden", "true" )
5426			.attr( "aria-expanded", "false" );
5427	},
5428
5429	_closeOnDocumentClick: function( event ) {
5430		return !$( event.target ).closest( ".ui-menu" ).length;
5431	},
5432
5433	_isDivider: function( item ) {
5434
5435		// Match hyphen, em dash, en dash
5436		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5437	},
5438
5439	collapse: function( event ) {
5440		var newItem = this.active &&
5441			this.active.parent().closest( ".ui-menu-item", this.element );
5442		if ( newItem && newItem.length ) {
5443			this._close();
5444			this.focus( event, newItem );
5445		}
5446	},
5447
5448	expand: function( event ) {
5449		var newItem = this.active &&
5450			this.active
5451				.children( ".ui-menu " )
5452					.find( this.options.items )
5453						.first();
5454
5455		if ( newItem && newItem.length ) {
5456			this._open( newItem.parent() );
5457
5458			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5459			this._delay( function() {
5460				this.focus( event, newItem );
5461			} );
5462		}
5463	},
5464
5465	next: function( event ) {
5466		this._move( "next", "first", event );
5467	},
5468
5469	previous: function( event ) {
5470		this._move( "prev", "last", event );
5471	},
5472
5473	isFirstItem: function() {
5474		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5475	},
5476
5477	isLastItem: function() {
5478		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5479	},
5480
5481	_move: function( direction, filter, event ) {
5482		var next;
5483		if ( this.active ) {
5484			if ( direction === "first" || direction === "last" ) {
5485				next = this.active
5486					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5487					.eq( -1 );
5488			} else {
5489				next = this.active
5490					[ direction + "All" ]( ".ui-menu-item" )
5491					.eq( 0 );
5492			}
5493		}
5494		if ( !next || !next.length || !this.active ) {
5495			next = this.activeMenu.find( this.options.items )[ filter ]();
5496		}
5497
5498		this.focus( event, next );
5499	},
5500
5501	nextPage: function( event ) {
5502		var item, base, height;
5503
5504		if ( !this.active ) {
5505			this.next( event );
5506			return;
5507		}
5508		if ( this.isLastItem() ) {
5509			return;
5510		}
5511		if ( this._hasScroll() ) {
5512			base = this.active.offset().top;
5513			height = this.element.height();
5514			this.active.nextAll( ".ui-menu-item" ).each( function() {
5515				item = $( this );
5516				return item.offset().top - base - height < 0;
5517			} );
5518
5519			this.focus( event, item );
5520		} else {
5521			this.focus( event, this.activeMenu.find( this.options.items )
5522				[ !this.active ? "first" : "last" ]() );
5523		}
5524	},
5525
5526	previousPage: function( event ) {
5527		var item, base, height;
5528		if ( !this.active ) {
5529			this.next( event );
5530			return;
5531		}
5532		if ( this.isFirstItem() ) {
5533			return;
5534		}
5535		if ( this._hasScroll() ) {
5536			base = this.active.offset().top;
5537			height = this.element.height();
5538			this.active.prevAll( ".ui-menu-item" ).each( function() {
5539				item = $( this );
5540				return item.offset().top - base + height > 0;
5541			} );
5542
5543			this.focus( event, item );
5544		} else {
5545			this.focus( event, this.activeMenu.find( this.options.items ).first() );
5546		}
5547	},
5548
5549	_hasScroll: function() {
5550		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5551	},
5552
5553	select: function( event ) {
5554
5555		// TODO: It should never be possible to not have an active item at this
5556		// point, but the tests don't trigger mouseenter before click.
5557		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5558		var ui = { item: this.active };
5559		if ( !this.active.has( ".ui-menu" ).length ) {
5560			this.collapseAll( event, true );
5561		}
5562		this._trigger( "select", event, ui );
5563	},
5564
5565	_filterMenuItems: function( character ) {
5566		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5567			regex = new RegExp( "^" + escapedCharacter, "i" );
5568
5569		return this.activeMenu
5570			.find( this.options.items )
5571
5572				// Only match on items, not dividers or other content (#10571)
5573				.filter( ".ui-menu-item" )
5574					.filter( function() {
5575						return regex.test(
5576							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5577					} );
5578	}
5579} );
5580
5581
5582/*!
5583 * jQuery UI Autocomplete 1.12.0
5584 * http://jqueryui.com
5585 *
5586 * Copyright jQuery Foundation and other contributors
5587 * Released under the MIT license.
5588 * http://jquery.org/license
5589 */
5590
5591//>>label: Autocomplete
5592//>>group: Widgets
5593//>>description: Lists suggested words as the user is typing.
5594//>>docs: http://api.jqueryui.com/autocomplete/
5595//>>demos: http://jqueryui.com/autocomplete/
5596//>>css.structure: ../../themes/base/core.css
5597//>>css.structure: ../../themes/base/autocomplete.css
5598//>>css.theme: ../../themes/base/theme.css
5599
5600
5601
5602$.widget( "ui.autocomplete", {
5603	version: "1.12.0",
5604	defaultElement: "<input>",
5605	options: {
5606		appendTo: null,
5607		autoFocus: false,
5608		delay: 300,
5609		minLength: 1,
5610		position: {
5611			my: "left top",
5612			at: "left bottom",
5613			collision: "none"
5614		},
5615		source: null,
5616
5617		// Callbacks
5618		change: null,
5619		close: null,
5620		focus: null,
5621		open: null,
5622		response: null,
5623		search: null,
5624		select: null
5625	},
5626
5627	requestIndex: 0,
5628	pending: 0,
5629
5630	_create: function() {
5631
5632		// Some browsers only repeat keydown events, not keypress events,
5633		// so we use the suppressKeyPress flag to determine if we've already
5634		// handled the keydown event. #7269
5635		// Unfortunately the code for & in keypress is the same as the up arrow,
5636		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5637		// events when we know the keydown event was used to modify the
5638		// search term. #7799
5639		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5640			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5641			isTextarea = nodeName === "textarea",
5642			isInput = nodeName === "input";
5643
5644		// Textareas are always multi-line
5645		// Inputs are always single-line, even if inside a contentEditable element
5646		// IE also treats inputs as contentEditable
5647		// All other element types are determined by whether or not they're contentEditable
5648		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5649
5650		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5651		this.isNewMenu = true;
5652
5653		this._addClass( "ui-autocomplete-input" );
5654		this.element.attr( "autocomplete", "off" );
5655
5656		this._on( this.element, {
5657			keydown: function( event ) {
5658				if ( this.element.prop( "readOnly" ) ) {
5659					suppressKeyPress = true;
5660					suppressInput = true;
5661					suppressKeyPressRepeat = true;
5662					return;
5663				}
5664
5665				suppressKeyPress = false;
vendor: 8,598 bytes, lines 5666-5985
5666				suppressInput = false;
5667				suppressKeyPressRepeat = false;
5668				var keyCode = $.ui.keyCode;
5669				switch ( event.keyCode ) {
5670				case keyCode.PAGE_UP:
5671					suppressKeyPress = true;
5672					this._move( "previousPage", event );
5673					break;
5674				case keyCode.PAGE_DOWN:
5675					suppressKeyPress = true;
5676					this._move( "nextPage", event );
5677					break;
5678				case keyCode.UP:
5679					suppressKeyPress = true;
5680					this._keyEvent( "previous", event );
5681					break;
5682				case keyCode.DOWN:
5683					suppressKeyPress = true;
5684					this._keyEvent( "next", event );
5685					break;
5686				case keyCode.ENTER:
5687
5688					// when menu is open and has focus
5689					if ( this.menu.active ) {
5690
5691						// #6055 - Opera still allows the keypress to occur
5692						// which causes forms to submit
5693						suppressKeyPress = true;
5694						event.preventDefault();
5695						this.menu.select( event );
5696					}
5697					break;
5698				case keyCode.TAB:
5699					if ( this.menu.active ) {
5700						this.menu.select( event );
5701					}
5702					break;
5703				case keyCode.ESCAPE:
5704					if ( this.menu.element.is( ":visible" ) ) {
5705						if ( !this.isMultiLine ) {
5706							this._value( this.term );
5707						}
5708						this.close( event );
5709
5710						// Different browsers have different default behavior for escape
5711						// Single press can mean undo or clear
5712						// Double press in IE means clear the whole form
5713						event.preventDefault();
5714					}
5715					break;
5716				default:
5717					suppressKeyPressRepeat = true;
5718
5719					// search timeout should be triggered before the input value is changed
5720					this._searchTimeout( event );
5721					break;
5722				}
5723			},
5724			keypress: function( event ) {
5725				if ( suppressKeyPress ) {
5726					suppressKeyPress = false;
5727					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5728						event.preventDefault();
5729					}
5730					return;
5731				}
5732				if ( suppressKeyPressRepeat ) {
5733					return;
5734				}
5735
5736				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5737				var keyCode = $.ui.keyCode;
5738				switch ( event.keyCode ) {
5739				case keyCode.PAGE_UP:
5740					this._move( "previousPage", event );
5741					break;
5742				case keyCode.PAGE_DOWN:
5743					this._move( "nextPage", event );
5744					break;
5745				case keyCode.UP:
5746					this._keyEvent( "previous", event );
5747					break;
5748				case keyCode.DOWN:
5749					this._keyEvent( "next", event );
5750					break;
5751				}
5752			},
5753			input: function( event ) {
5754				if ( suppressInput ) {
5755					suppressInput = false;
5756					event.preventDefault();
5757					return;
5758				}
5759				this._searchTimeout( event );
5760			},
5761			focus: function() {
5762				this.selectedItem = null;
5763				this.previous = this._value();
5764			},
5765			blur: function( event ) {
5766				if ( this.cancelBlur ) {
5767					delete this.cancelBlur;
5768					return;
5769				}
5770
5771				clearTimeout( this.searching );
5772				this.close( event );
5773				this._change( event );
5774			}
5775		} );
5776
5777		this._initSource();
5778		this.menu = $( "<ul>" )
5779			.appendTo( this._appendTo() )
5780			.menu( {
5781
5782				// disable ARIA support, the live region takes care of that
5783				role: null
5784			} )
5785			.hide()
5786			.menu( "instance" );
5787
5788		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5789		this._on( this.menu.element, {
5790			mousedown: function( event ) {
5791
5792				// prevent moving focus out of the text field
5793				event.preventDefault();
5794
5795				// IE doesn't prevent moving focus even with event.preventDefault()
5796				// so we set a flag to know when we should ignore the blur event
5797				this.cancelBlur = true;
5798				this._delay( function() {
5799					delete this.cancelBlur;
5800
5801					// Support: IE 8 only
5802					// Right clicking a menu item or selecting text from the menu items will
5803					// result in focus moving out of the input. However, we've already received
5804					// and ignored the blur event because of the cancelBlur flag set above. So
5805					// we restore focus to ensure that the menu closes properly based on the user's
5806					// next actions.
5807					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5808						this.element.trigger( "focus" );
5809					}
5810				} );
5811			},
5812			menufocus: function( event, ui ) {
5813				var label, item;
5814
5815				// support: Firefox
5816				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5817				if ( this.isNewMenu ) {
5818					this.isNewMenu = false;
5819					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5820						this.menu.blur();
5821
5822						this.document.one( "mousemove", function() {
5823							$( event.target ).trigger( event.originalEvent );
5824						} );
5825
5826						return;
5827					}
5828				}
5829
5830				item = ui.item.data( "ui-autocomplete-item" );
5831				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5832
5833					// use value to match what will end up in the input, if it was a key event
5834					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5835						this._value( item.value );
5836					}
5837				}
5838
5839				// Announce the value in the liveRegion
5840				label = ui.item.attr( "aria-label" ) || item.value;
5841				if ( label && $.trim( label ).length ) {
5842					this.liveRegion.children().hide();
5843					$( "<div>" ).text( label ).appendTo( this.liveRegion );
5844				}
5845			},
5846			menuselect: function( event, ui ) {
5847				var item = ui.item.data( "ui-autocomplete-item" ),
5848					previous = this.previous;
5849
5850				// Only trigger when focus was lost (click on menu)
5851				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5852					this.element.trigger( "focus" );
5853					this.previous = previous;
5854
5855					// #6109 - IE triggers two focus events and the second
5856					// is asynchronous, so we need to reset the previous
5857					// term synchronously and asynchronously :-(
5858					this._delay( function() {
5859						this.previous = previous;
5860						this.selectedItem = item;
5861					} );
5862				}
5863
5864				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5865					this._value( item.value );
5866				}
5867
5868				// reset the term after the select event
5869				// this allows custom select handling to work properly
5870				this.term = this._value();
5871
5872				this.close( event );
5873				this.selectedItem = item;
5874			}
5875		} );
5876
5877		this.liveRegion = $( "<div>", {
5878			role: "status",
5879			"aria-live": "assertive",
5880			"aria-relevant": "additions"
5881		} )
5882			.appendTo( this.document[ 0 ].body );
5883
5884		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5885
5886		// Turning off autocomplete prevents the browser from remembering the
5887		// value when navigating through history, so we re-enable autocomplete
5888		// if the page is unloaded before the widget is destroyed. #7790
5889		this._on( this.window, {
5890			beforeunload: function() {
5891				this.element.removeAttr( "autocomplete" );
5892			}
5893		} );
5894	},
5895
5896	_destroy: function() {
5897		clearTimeout( this.searching );
5898		this.element.removeAttr( "autocomplete" );
5899		this.menu.element.remove();
5900		this.liveRegion.remove();
5901	},
5902
5903	_setOption: function( key, value ) {
5904		this._super( key, value );
5905		if ( key === "source" ) {
5906			this._initSource();
5907		}
5908		if ( key === "appendTo" ) {
5909			this.menu.element.appendTo( this._appendTo() );
5910		}
5911		if ( key === "disabled" && value && this.xhr ) {
5912			this.xhr.abort();
5913		}
5914	},
5915
5916	_isEventTargetInWidget: function( event ) {
5917		var menuElement = this.menu.element[ 0 ];
5918
5919		return event.target === this.element[ 0 ] ||
5920			event.target === menuElement ||
5921			$.contains( menuElement, event.target );
5922	},
5923
5924	_closeOnClickOutside: function( event ) {
5925		if ( !this._isEventTargetInWidget( event ) ) {
5926			this.close();
5927		}
5928	},
5929
5930	_appendTo: function() {
5931		var element = this.options.appendTo;
5932
5933		if ( element ) {
5934			element = element.jquery || element.nodeType ?
5935				$( element ) :
5936				this.document.find( element ).eq( 0 );
5937		}
5938
5939		if ( !element || !element[ 0 ] ) {
5940			element = this.element.closest( ".ui-front, dialog" );
5941		}
5942
5943		if ( !element.length ) {
5944			element = this.document[ 0 ].body;
5945		}
5946
5947		return element;
5948	},
5949
5950	_initSource: function() {
5951		var array, url,
5952			that = this;
5953		if ( $.isArray( this.options.source ) ) {
5954			array = this.options.source;
5955			this.source = function( request, response ) {
5956				response( $.ui.autocomplete.filter( array, request.term ) );
5957			};
5958		} else if ( typeof this.options.source === "string" ) {
5959			url = this.options.source;
5960			this.source = function( request, response ) {
5961				if ( that.xhr ) {
5962					that.xhr.abort();
5963				}
5964				that.xhr = $.ajax( {
5965					url: url,
5966					data: request,
5967					dataType: "json",
5968					success: function( data ) {
5969						response( data );
5970					},
5971					error: function() {
5972						response( [] );
5973					}
5974				} );
5975			};
5976		} else {
5977			this.source = this.options.source;
5978		}
5979	},
5980
5981	_searchTimeout: function( event ) {
5982		clearTimeout( this.searching );
5983		this.searching = this._delay( function() {
5984
5985			// Search if the value has changed, or if the user retypes the same value (see #7434)
vendor: 4,901 bytes, lines 5986-6188
5986			var equalValues = this.term === this._value(),
5987				menuVisible = this.menu.element.is( ":visible" ),
5988				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5989
5990			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5991				this.selectedItem = null;
5992				this.search( null, event );
5993			}
5994		}, this.options.delay );
5995	},
5996
5997	search: function( value, event ) {
5998		value = value != null ? value : this._value();
5999
6000		// Always save the actual value, not the one passed as an argument
6001		this.term = this._value();
6002
6003		if ( value.length < this.options.minLength ) {
6004			return this.close( event );
6005		}
6006
6007		if ( this._trigger( "search", event ) === false ) {
6008			return;
6009		}
6010
6011		return this._search( value );
6012	},
6013
6014	_search: function( value ) {
6015		this.pending++;
6016		this._addClass( "ui-autocomplete-loading" );
6017		this.cancelSearch = false;
6018
6019		this.source( { term: value }, this._response() );
6020	},
6021
6022	_response: function() {
6023		var index = ++this.requestIndex;
6024
6025		return $.proxy( function( content ) {
6026			if ( index === this.requestIndex ) {
6027				this.__response( content );
6028			}
6029
6030			this.pending--;
6031			if ( !this.pending ) {
6032				this._removeClass( "ui-autocomplete-loading" );
6033			}
6034		}, this );
6035	},
6036
6037	__response: function( content ) {
6038		if ( content ) {
6039			content = this._normalize( content );
6040		}
6041		this._trigger( "response", null, { content: content } );
6042		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6043			this._suggest( content );
6044			this._trigger( "open" );
6045		} else {
6046
6047			// use ._close() instead of .close() so we don't cancel future searches
6048			this._close();
6049		}
6050	},
6051
6052	close: function( event ) {
6053		this.cancelSearch = true;
6054		this._close( event );
6055	},
6056
6057	_close: function( event ) {
6058
6059		// Remove the handler that closes the menu on outside clicks
6060		this._off( this.document, "mousedown" );
6061
6062		if ( this.menu.element.is( ":visible" ) ) {
6063			this.menu.element.hide();
6064			this.menu.blur();
6065			this.isNewMenu = true;
6066			this._trigger( "close", event );
6067		}
6068	},
6069
6070	_change: function( event ) {
6071		if ( this.previous !== this._value() ) {
6072			this._trigger( "change", event, { item: this.selectedItem } );
6073		}
6074	},
6075
6076	_normalize: function( items ) {
6077
6078		// assume all items have the right format when the first item is complete
6079		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6080			return items;
6081		}
6082		return $.map( items, function( item ) {
6083			if ( typeof item === "string" ) {
6084				return {
6085					label: item,
6086					value: item
6087				};
6088			}
6089			return $.extend( {}, item, {
6090				label: item.label || item.value,
6091				value: item.value || item.label
6092			} );
6093		} );
6094	},
6095
6096	_suggest: function( items ) {
6097		var ul = this.menu.element.empty();
6098		this._renderMenu( ul, items );
6099		this.isNewMenu = true;
6100		this.menu.refresh();
6101
6102		// Size and position menu
6103		ul.show();
6104		this._resizeMenu();
6105		ul.position( $.extend( {
6106			of: this.element
6107		}, this.options.position ) );
6108
6109		if ( this.options.autoFocus ) {
6110			this.menu.next();
6111		}
6112
6113		// Listen for interactions outside of the widget (#6642)
6114		this._on( this.document, {
6115			mousedown: "_closeOnClickOutside"
6116		} );
6117	},
6118
6119	_resizeMenu: function() {
6120		var ul = this.menu.element;
6121		ul.outerWidth( Math.max(
6122
6123			// Firefox wraps long text (possibly a rounding bug)
6124			// so we add 1px to avoid the wrapping (#7513)
6125			ul.width( "" ).outerWidth() + 1,
6126			this.element.outerWidth()
6127		) );
6128	},
6129
6130	_renderMenu: function( ul, items ) {
6131		var that = this;
6132		$.each( items, function( index, item ) {
6133			that._renderItemData( ul, item );
6134		} );
6135	},
6136
6137	_renderItemData: function( ul, item ) {
6138		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6139	},
6140
6141	_renderItem: function( ul, item ) {
6142		return $( "<li>" )
6143			.append( $( "<div>" ).text( item.label ) )
6144			.appendTo( ul );
6145	},
6146
6147	_move: function( direction, event ) {
6148		if ( !this.menu.element.is( ":visible" ) ) {
6149			this.search( null, event );
6150			return;
6151		}
6152		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6153				this.menu.isLastItem() && /^next/.test( direction ) ) {
6154
6155			if ( !this.isMultiLine ) {
6156				this._value( this.term );
6157			}
6158
6159			this.menu.blur();
6160			return;
6161		}
6162		this.menu[ direction ]( event );
6163	},
6164
6165	widget: function() {
6166		return this.menu.element;
6167	},
6168
6169	_value: function() {
6170		return this.valueMethod.apply( this.element, arguments );
6171	},
6172
6173	_keyEvent: function( keyEvent, event ) {
6174		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6175			this._move( keyEvent, event );
6176
6177			// Prevents moving cursor to beginning/end of the text field in some browsers
6178			event.preventDefault();
6179		}
6180	},
6181
6182	// Support: Chrome <=50
6183	// We should be able to just use this.element.prop( "isContentEditable" )
6184	// but hidden elements always report false in Chrome.
6185	// https://code.google.com/p/chromium/issues/detail?id=313082
6186	_isContentEditable: function( element ) {
6187		if ( !element.length ) {
6188			return false;
vendor: 14,880 bytes, lines 6189-6712
6189		}
6190
6191		var editable = element.prop( "contentEditable" );
6192
6193		if ( editable === "inherit" ) {
6194		  return this._isContentEditable( element.parent() );
6195		}
6196
6197		return editable === "true";
6198	}
6199} );
6200
6201$.extend( $.ui.autocomplete, {
6202	escapeRegex: function( value ) {
6203		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6204	},
6205	filter: function( array, term ) {
6206		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6207		return $.grep( array, function( value ) {
6208			return matcher.test( value.label || value.value || value );
6209		} );
6210	}
6211} );
6212
6213// Live region extension, adding a `messages` option
6214// NOTE: This is an experimental API. We are still investigating
6215// a full solution for string manipulation and internationalization.
6216$.widget( "ui.autocomplete", $.ui.autocomplete, {
6217	options: {
6218		messages: {
6219			noResults: "No search results.",
6220			results: function( amount ) {
6221				return amount + ( amount > 1 ? " results are" : " result is" ) +
6222					" available, use up and down arrow keys to navigate.";
6223			}
6224		}
6225	},
6226
6227	__response: function( content ) {
6228		var message;
6229		this._superApply( arguments );
6230		if ( this.options.disabled || this.cancelSearch ) {
6231			return;
6232		}
6233		if ( content && content.length ) {
6234			message = this.options.messages.results( content.length );
6235		} else {
6236			message = this.options.messages.noResults;
6237		}
6238		this.liveRegion.children().hide();
6239		$( "<div>" ).text( message ).appendTo( this.liveRegion );
6240	}
6241} );
6242
6243var widgetsAutocomplete = $.ui.autocomplete;
6244
6245
6246/*!
6247 * jQuery UI Controlgroup 1.12.0
6248 * http://jqueryui.com
6249 *
6250 * Copyright jQuery Foundation and other contributors
6251 * Released under the MIT license.
6252 * http://jquery.org/license
6253 */
6254
6255//>>label: Controlgroup
6256//>>group: Widgets
6257//>>description: Visually groups form control widgets
6258//>>docs: http://api.jqueryui.com/controlgroup/
6259//>>demos: http://jqueryui.com/controlgroup/
6260//>>css.structure: ../../themes/base/core.css
6261//>>css.structure: ../../themes/base/controlgroup.css
6262//>>css.theme: ../../themes/base/theme.css
6263
6264
6265var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6266
6267var widgetsControlgroup = $.widget( "ui.controlgroup", {
6268	version: "1.12.0",
6269	defaultElement: "<div>",
6270	options: {
6271		direction: "horizontal",
6272		disabled: null,
6273		onlyVisible: true,
6274		items: {
6275			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6276			"controlgroupLabel": ".ui-controlgroup-label",
6277			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6278			"selectmenu": "select",
6279			"spinner": ".ui-spinner-input"
6280		}
6281	},
6282
6283	_create: function() {
6284		this._enhance();
6285	},
6286
6287	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6288	_enhance: function() {
6289		this.element.attr( "role", "toolbar" );
6290		this.refresh();
6291	},
6292
6293	_destroy: function() {
6294		this._callChildMethod( "destroy" );
6295		this.childWidgets.removeData( "ui-controlgroup-data" );
6296		this.element.removeAttr( "role" );
6297		if ( this.options.items.controlgroupLabel ) {
6298			this.element
6299				.find( this.options.items.controlgroupLabel )
6300				.find( ".ui-controlgroup-label-contents" )
6301				.contents().unwrap();
6302		}
6303	},
6304
6305	_initWidgets: function() {
6306		var that = this,
6307			childWidgets = [];
6308
6309		// First we iterate over each of the items options
6310		$.each( this.options.items, function( widget, selector ) {
6311			var labels;
6312			var options = {};
6313
6314			// Make sure the widget has a selector set
6315			if ( !selector ) {
6316				return;
6317			}
6318
6319			if ( widget === "controlgroupLabel" ) {
6320				labels = that.element.find( selector );
6321				labels.each( function() {
6322					var element = $( this );
6323
6324					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6325						return;
6326					}
6327					element.contents()
6328						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6329				} );
6330				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6331				childWidgets = childWidgets.concat( labels.get() );
6332				return;
6333			}
6334
6335			// Make sure the widget actually exists
6336			if ( !$.fn[ widget ] ) {
6337				return;
6338			}
6339
6340			// We assume everything is in the middle to start because we can't determine
6341			// first / last elements until all enhancments are done.
6342			if ( that[ "_" + widget + "Options" ] ) {
6343				options = that[ "_" + widget + "Options" ]( "middle" );
6344			}
6345
6346			// Find instances of this widget inside controlgroup and init them
6347			that.element
6348				.find( selector )
6349				.each( function() {
6350					var element = $( this );
6351					var instance = element[ widget ]( "instance" );
6352
6353					// We need to clone the default options for this type of widget to avoid
6354					// polluting the variable options which has a wider scope than a single widget.
6355					var instanceOptions = $.widget.extend( {}, options );
6356
6357					// If the button is the child of a spinner ignore it
6358					// TODO: Find a more generic solution
6359					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6360						return;
6361					}
6362
6363					// Create the widget if it doesn't exist
6364					if ( !instance ) {
6365						instance = element[ widget ]()[ widget ]( "instance" );
6366					}
6367					if ( instance ) {
6368						instanceOptions.classes =
6369							that._resolveClassesValues( instanceOptions.classes, instance );
6370					}
6371					element[ widget ]( instanceOptions );
6372
6373					// Store an instance of the controlgroup to be able to reference
6374					// from the outermost element for changing options and refresh
6375					var widgetElement = element[ widget ]( "widget" );
6376					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6377						instance ? instance : element[ widget ]( "instance" ) );
6378
6379					childWidgets.push( widgetElement[ 0 ] );
6380				} );
6381		} );
6382
6383		this.childWidgets = $( $.unique( childWidgets ) );
6384		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6385	},
6386
6387	_callChildMethod: function( method ) {
6388		this.childWidgets.each( function() {
6389			var element = $( this ),
6390				data = element.data( "ui-controlgroup-data" );
6391			if ( data && data[ method ] ) {
6392				data[ method ]();
6393			}
6394		} );
6395	},
6396
6397	_updateCornerClass: function( element, position ) {
6398		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6399		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6400
6401		this._removeClass( element, null, remove );
6402		this._addClass( element, null, add );
6403	},
6404
6405	_buildSimpleOptions: function( position, key ) {
6406		var direction = this.options.direction === "vertical";
6407		var result = {
6408			classes: {}
6409		};
6410		result.classes[ key ] = {
6411			"middle": "",
6412			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6413			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6414			"only": "ui-corner-all"
6415		}[ position ];
6416
6417		return result;
6418	},
6419
6420	_spinnerOptions: function( position ) {
6421		var options = this._buildSimpleOptions( position, "ui-spinner" );
6422
6423		options.classes[ "ui-spinner-up" ] = "";
6424		options.classes[ "ui-spinner-down" ] = "";
6425
6426		return options;
6427	},
6428
6429	_buttonOptions: function( position ) {
6430		return this._buildSimpleOptions( position, "ui-button" );
6431	},
6432
6433	_checkboxradioOptions: function( position ) {
6434		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6435	},
6436
6437	_selectmenuOptions: function( position ) {
6438		var direction = this.options.direction === "vertical";
6439		return {
6440			width: direction ? "auto" : false,
6441			classes: {
6442				middle: {
6443					"ui-selectmenu-button-open": "",
6444					"ui-selectmenu-button-closed": ""
6445				},
6446				first: {
6447					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6448					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6449				},
6450				last: {
6451					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6452					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6453				},
6454				only: {
6455					"ui-selectmenu-button-open": "ui-corner-top",
6456					"ui-selectmenu-button-closed": "ui-corner-all"
6457				}
6458
6459			}[ position ]
6460		};
6461	},
6462
6463	_resolveClassesValues: function( classes, instance ) {
6464		var result = {};
6465		$.each( classes, function( key ) {
6466			var current = instance.options.classes[ key ] || "";
6467			current = current.replace( controlgroupCornerRegex, "" ).trim();
6468			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6469		} );
6470		return result;
6471	},
6472
6473	_setOption: function( key, value ) {
6474		if ( key === "direction" ) {
6475			this._removeClass( "ui-controlgroup-" + this.options.direction );
6476		}
6477
6478		this._super( key, value );
6479		if ( key === "disabled" ) {
6480			this._callChildMethod( value ? "disable" : "enable" );
6481			return;
6482		}
6483
6484		this.refresh();
6485	},
6486
6487	refresh: function() {
6488		var children,
6489			that = this;
6490
6491		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6492
6493		if ( this.options.direction === "horizontal" ) {
6494			this._addClass( null, "ui-helper-clearfix" );
6495		}
6496		this._initWidgets();
6497
6498		children = this.childWidgets;
6499
6500		// We filter here because we need to track all childWidgets not just the visible ones
6501		if ( this.options.onlyVisible ) {
6502			children = children.filter( ":visible" );
6503		}
6504
6505		if ( children.length ) {
6506
6507			// We do this last because we need to make sure all enhancment is done
6508			// before determining first and last
6509			$.each( [ "first", "last" ], function( index, value ) {
6510				var instance = children[ value ]().data( "ui-controlgroup-data" );
6511
6512				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6513					var options = that[ "_" + instance.widgetName + "Options" ](
6514						children.length === 1 ? "only" : value
6515					);
6516					options.classes = that._resolveClassesValues( options.classes, instance );
6517					instance.element[ instance.widgetName ]( options );
6518				} else {
6519					that._updateCornerClass( children[ value ](), value );
6520				}
6521			} );
6522
6523			// Finally call the refresh method on each of the child widgets.
6524			this._callChildMethod( "refresh" );
6525		}
6526	}
6527} );
6528
6529/*!
6530 * jQuery UI Checkboxradio 1.12.0
6531 * http://jqueryui.com
6532 *
6533 * Copyright jQuery Foundation and other contributors
6534 * Released under the MIT license.
6535 * http://jquery.org/license
6536 */
6537
6538//>>label: Checkboxradio
6539//>>group: Widgets
6540//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6541//>>docs: http://api.jqueryui.com/checkboxradio/
6542//>>demos: http://jqueryui.com/checkboxradio/
6543//>>css.structure: ../../themes/base/core.css
6544//>>css.structure: ../../themes/base/button.css
6545//>>css.structure: ../../themes/base/checkboxradio.css
6546//>>css.theme: ../../themes/base/theme.css
6547
6548
6549
6550$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6551	version: "1.12.0",
6552	options: {
6553		disabled: null,
6554		label: null,
6555		icon: true,
6556		classes: {
6557			"ui-checkboxradio-label": "ui-corner-all",
6558			"ui-checkboxradio-icon": "ui-corner-all"
6559		}
6560	},
6561
6562	_getCreateOptions: function() {
6563		var disabled, labels;
6564		var that = this;
6565		var options = this._super() || {};
6566
6567		// We read the type here, because it makes more sense to throw a element type error first,
6568		// rather then the error for lack of a label. Often if its the wrong type, it
6569		// won't have a label (e.g. calling on a div, btn, etc)
6570		this._readType();
6571
6572		labels = this.element.labels();
6573
6574		// If there are multiple labels, use the last one
6575		this.label = $( labels[ labels.length - 1 ] );
6576		if ( !this.label.length ) {
6577			$.error( "No label found for checkboxradio widget" );
6578		}
6579
6580		this.originalLabel = "";
6581
6582		// We need to get the label text but this may also need to make sure it does not contain the
6583		// input itself.
6584		this.label.contents().not( this.element ).each( function() {
6585
6586			// The label contents could be text, html, or a mix. We concat each element to get a
6587			// string representation of the label, without the input as part of it.
6588			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6589		} );
6590
6591		// Set the label option if we found label text
6592		if ( this.originalLabel ) {
6593			options.label = this.originalLabel;
6594		}
6595
6596		disabled = this.element[ 0 ].disabled;
6597		if ( disabled != null ) {
6598			options.disabled = disabled;
6599		}
6600		return options;
6601	},
6602
6603	_create: function() {
6604		var checked = this.element[ 0 ].checked;
6605
6606		this._bindFormResetHandler();
6607
6608		if ( this.options.disabled == null ) {
6609			this.options.disabled = this.element[ 0 ].disabled;
6610		}
6611
6612		this._setOption( "disabled", this.options.disabled );
6613		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6614		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6615
6616		if ( this.type === "radio" ) {
6617			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6618		}
6619
6620		if ( this.options.label && this.options.label !== this.originalLabel ) {
6621			this._updateLabel();
6622		} else if ( this.originalLabel ) {
6623			this.options.label = this.originalLabel;
6624		}
6625
6626		this._enhance();
6627
6628		if ( checked ) {
6629			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6630			if ( this.icon ) {
6631				this._addClass( this.icon, null, "ui-state-hover" );
6632			}
6633		}
6634
6635		this._on( {
6636			change: "_toggleClasses",
6637			focus: function() {
6638				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6639			},
6640			blur: function() {
6641				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6642			}
6643		} );
6644	},
6645
6646	_readType: function() {
6647		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6648		this.type = this.element[ 0 ].type;
6649		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6650			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6651				" and element.type=" + this.type );
6652		}
6653	},
6654
6655	// Support jQuery Mobile enhanced option
6656	_enhance: function() {
6657		this._updateIcon( this.element[ 0 ].checked );
6658	},
6659
6660	widget: function() {
6661		return this.label;
6662	},
6663
6664	_getRadioGroup: function() {
6665		var group;
6666		var name = this.element[ 0 ].name;
6667		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6668
6669		if ( !name ) {
6670			return $( [] );
6671		}
6672
6673		if ( this.form.length ) {
6674			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6675		} else {
6676
6677			// Not inside a form, check all inputs that also are not inside a form
6678			group = $( nameSelector ).filter( function() {
6679				return $( this ).form().length === 0;
6680			} );
6681		}
6682
6683		return group.not( this.element );
6684	},
6685
6686	_toggleClasses: function() {
6687		var checked = this.element[ 0 ].checked;
6688		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6689
6690		if ( this.options.icon && this.type === "checkbox" ) {
6691			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6692				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6693		}
6694
6695		if ( this.type === "radio" ) {
6696			this._getRadioGroup()
6697				.each( function() {
6698					var instance = $( this ).checkboxradio( "instance" );
6699
6700					if ( instance ) {
6701						instance._removeClass( instance.label,
6702							"ui-checkboxradio-checked", "ui-state-active" );
6703					}
6704				} );
6705		}
6706	},
6707
6708	_destroy: function() {
6709		this._unbindFormResetHandler();
6710
6711		if ( this.icon ) {
6712			this.icon.remove();
vendor: 4,339 bytes, lines 6713-6878
6713			this.iconSpace.remove();
6714		}
6715	},
6716
6717	_setOption: function( key, value ) {
6718
6719		// We don't allow the value to be set to nothing
6720		if ( key === "label" && !value ) {
6721			return;
6722		}
6723
6724		this._super( key, value );
6725
6726		if ( key === "disabled" ) {
6727			this._toggleClass( this.label, null, "ui-state-disabled", value );
6728			this.element[ 0 ].disabled = value;
6729
6730			// Don't refresh when setting disabled
6731			return;
6732		}
6733		this.refresh();
6734	},
6735
6736	_updateIcon: function( checked ) {
6737		var toAdd = "ui-icon ui-icon-background ";
6738
6739		if ( this.options.icon ) {
6740			if ( !this.icon ) {
6741				this.icon = $( "<span>" );
6742				this.iconSpace = $( "<span> </span>" );
6743				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6744			}
6745
6746			if ( this.type === "checkbox" ) {
6747				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6748				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6749			} else {
6750				toAdd += "ui-icon-blank";
6751			}
6752			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6753			if ( !checked ) {
6754				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6755			}
6756			this.icon.prependTo( this.label ).after( this.iconSpace );
6757		} else if ( this.icon !== undefined ) {
6758			this.icon.remove();
6759			this.iconSpace.remove();
6760			delete this.icon;
6761		}
6762	},
6763
6764	_updateLabel: function() {
6765
6766		// Remove the contents of the label ( minus the icon, icon space, and input )
6767		this.label.contents().not( this.element.add( this.icon ).add( this.iconSpace ) ).remove();
6768		this.label.append( this.options.label );
6769	},
6770
6771	refresh: function() {
6772		var checked = this.element[ 0 ].checked,
6773			isDisabled = this.element[ 0 ].disabled;
6774
6775		this._updateIcon( checked );
6776		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6777		if ( this.options.label !== null ) {
6778			this._updateLabel();
6779		}
6780
6781		if ( isDisabled !== this.options.disabled ) {
6782			this._setOptions( { "disabled": isDisabled } );
6783		}
6784	}
6785
6786} ] );
6787
6788var widgetsCheckboxradio = $.ui.checkboxradio;
6789
6790
6791/*!
6792 * jQuery UI Button 1.12.0
6793 * http://jqueryui.com
6794 *
6795 * Copyright jQuery Foundation and other contributors
6796 * Released under the MIT license.
6797 * http://jquery.org/license
6798 */
6799
6800//>>label: Button
6801//>>group: Widgets
6802//>>description: Enhances a form with themeable buttons.
6803//>>docs: http://api.jqueryui.com/button/
6804//>>demos: http://jqueryui.com/button/
6805//>>css.structure: ../../themes/base/core.css
6806//>>css.structure: ../../themes/base/button.css
6807//>>css.theme: ../../themes/base/theme.css
6808
6809
6810
6811$.widget( "ui.button", {
6812	version: "1.12.0",
6813	defaultElement: "<button>",
6814	options: {
6815		classes: {
6816			"ui-button": "ui-corner-all"
6817		},
6818		disabled: null,
6819		icon: null,
6820		iconPosition: "beginning",
6821		label: null,
6822		showLabel: true
6823	},
6824
6825	_getCreateOptions: function() {
6826		var disabled,
6827
6828			// This is to support cases like in jQuery Mobile where the base widget does have
6829			// an implementation of _getCreateOptions
6830			options = this._super() || {};
6831
6832		this.isInput = this.element.is( "input" );
6833
6834		disabled = this.element[ 0 ].disabled;
6835		if ( disabled != null ) {
6836			options.disabled = disabled;
6837		}
6838
6839		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6840		if ( this.originalLabel ) {
6841			options.label = this.originalLabel;
6842		}
6843
6844		return options;
6845	},
6846
6847	_create: function() {
6848		if ( !this.option.showLabel & !this.options.icon ) {
6849			this.options.showLabel = true;
6850		}
6851
6852		// We have to check the option again here even though we did in _getCreateOptions,
6853		// because null may have been passed on init which would override what was set in
6854		// _getCreateOptions
6855		if ( this.options.disabled == null ) {
6856			this.options.disabled = this.element[ 0 ].disabled || false;
6857		}
6858
6859		this.hasTitle = !!this.element.attr( "title" );
6860
6861		// Check to see if the label needs to be set or if its already correct
6862		if ( this.options.label && this.options.label !== this.originalLabel ) {
6863			if ( this.isInput ) {
6864				this.element.val( this.options.label );
6865			} else {
6866				this.element.html( this.options.label );
6867			}
6868		}
6869		this._addClass( "ui-button", "ui-widget" );
6870		this._setOption( "disabled", this.options.disabled );
6871		this._enhance();
6872
6873		if ( this.element.is( "a" ) ) {
6874			this._on( {
6875				"keyup": function( event ) {
6876					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6877						event.preventDefault();
6878
vendor: 11,926 bytes, lines 6879-7248
6879						// Support: PhantomJS <= 1.9, IE 8 Only
6880						// If a native click is available use it so we actually cause navigation
6881						// otherwise just trigger a click event
6882						if ( this.element[ 0 ].click ) {
6883							this.element[ 0 ].click();
6884						} else {
6885							this.element.trigger( "click" );
6886						}
6887					}
6888				}
6889			} );
6890		}
6891	},
6892
6893	_enhance: function() {
6894		if ( !this.element.is( "button" ) ) {
6895			this.element.attr( "role", "button" );
6896		}
6897
6898		if ( this.options.icon ) {
6899			this._updateIcon( "icon", this.options.icon );
6900			this._updateTooltip();
6901		}
6902	},
6903
6904	_updateTooltip: function() {
6905		this.title = this.element.attr( "title" );
6906
6907		if ( !this.options.showLabel && !this.title ) {
6908			this.element.attr( "title", this.options.label );
6909		}
6910	},
6911
6912	_updateIcon: function( option, value ) {
6913		var icon = option !== "iconPosition",
6914			position = icon ? this.options.iconPosition : value,
6915			displayBlock = position === "top" || position === "bottom";
6916
6917		// Create icon
6918		if ( !this.icon ) {
6919			this.icon = $( "<span>" );
6920
6921			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6922
6923			if ( !this.options.showLabel ) {
6924				this._addClass( "ui-button-icon-only" );
6925			}
6926		} else if ( icon ) {
6927
6928			// If we are updating the icon remove the old icon class
6929			this._removeClass( this.icon, null, this.options.icon );
6930		}
6931
6932		// If we are updating the icon add the new icon class
6933		if ( icon ) {
6934			this._addClass( this.icon, null, value );
6935		}
6936
6937		this._attachIcon( position );
6938
6939		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6940		// the iconSpace if there is one.
6941		if ( displayBlock ) {
6942			this._addClass( this.icon, null, "ui-widget-icon-block" );
6943			if ( this.iconSpace ) {
6944				this.iconSpace.remove();
6945			}
6946		} else {
6947
6948			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6949			// space if it does not exist
6950			if ( !this.iconSpace ) {
6951				this.iconSpace = $( "<span> </span>" );
6952				this._addClass( this.iconSpace, "ui-button-icon-space" );
6953			}
6954			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6955			this._attachIconSpace( position );
6956		}
6957	},
6958
6959	_destroy: function() {
6960		this.element.removeAttr( "role" );
6961
6962		if ( this.icon ) {
6963			this.icon.remove();
6964		}
6965		if ( this.iconSpace ) {
6966			this.iconSpace.remove();
6967		}
6968		if ( !this.hasTitle ) {
6969			this.element.removeAttr( "title" );
6970		}
6971	},
6972
6973	_attachIconSpace: function( iconPosition ) {
6974		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6975	},
6976
6977	_attachIcon: function( iconPosition ) {
6978		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6979	},
6980
6981	_setOptions: function( options ) {
6982		var newShowLabel = options.showLabel === undefined ?
6983				this.options.showLabel :
6984				options.showLabel,
6985			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6986
6987		if ( !newShowLabel && !newIcon ) {
6988			options.showLabel = true;
6989		}
6990		this._super( options );
6991	},
6992
6993	_setOption: function( key, value ) {
6994		if ( key === "icon" ) {
6995			if ( value ) {
6996				this._updateIcon( key, value );
6997			} else if ( this.icon ) {
6998				this.icon.remove();
6999				if ( this.iconSpace ) {
7000					this.iconSpace.remove();
7001				}
7002			}
7003		}
7004
7005		if ( key === "iconPosition" ) {
7006			this._updateIcon( key, value );
7007		}
7008
7009		// Make sure we can't end up with a button that has neither text nor icon
7010		if ( key === "showLabel" ) {
7011				this._toggleClass( "ui-button-icon-only", null, !value );
7012				this._updateTooltip();
7013		}
7014
7015		if ( key === "label" ) {
7016			if ( this.isInput ) {
7017				this.element.val( value );
7018			} else {
7019
7020				// If there is an icon, append it, else nothing then append the value
7021				// this avoids removal of the icon when setting label text
7022				this.element.html( value );
7023				if ( this.icon ) {
7024					this._attachIcon( this.options.iconPosition );
7025					this._attachIconSpace( this.options.iconPosition );
7026				}
7027			}
7028		}
7029
7030		this._super( key, value );
7031
7032		if ( key === "disabled" ) {
7033			this._toggleClass( null, "ui-state-disabled", value );
7034			this.element[ 0 ].disabled = value;
7035			if ( value ) {
7036				this.element.blur();
7037			}
7038		}
7039	},
7040
7041	refresh: function() {
7042
7043		// Make sure to only check disabled if its an element that supports this otherwise
7044		// check for the disabled class to determine state
7045		var isDisabled = this.element.is( "input, button" ) ?
7046			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7047
7048		if ( isDisabled !== this.options.disabled ) {
7049			this._setOptions( { disabled: isDisabled } );
7050		}
7051
7052		this._updateTooltip();
7053	}
7054} );
7055
7056// DEPRECATED
7057if ( $.uiBackCompat !== false ) {
7058
7059	// Text and Icons options
7060	$.widget( "ui.button", $.ui.button, {
7061		options: {
7062			text: true,
7063			icons: {
7064				primary: null,
7065				secondary: null
7066			}
7067		},
7068
7069		_create: function() {
7070			if ( this.options.showLabel && !this.options.text ) {
7071				this.options.showLabel = this.options.text;
7072			}
7073			if ( !this.options.showLabel && this.options.text ) {
7074				this.options.text = this.options.showLabel;
7075			}
7076			if ( !this.options.icon && ( this.options.icons.primary ||
7077					this.options.icons.secondary ) ) {
7078				if ( this.options.icons.primary ) {
7079					this.options.icon = this.options.icons.primary;
7080				} else {
7081					this.options.icon = this.options.icons.secondary;
7082					this.options.iconPosition = "end";
7083				}
7084			} else if ( this.options.icon ) {
7085				this.options.icons.primary = this.options.icon;
7086			}
7087			this._super();
7088		},
7089
7090		_setOption: function( key, value ) {
7091			if ( key === "text" ) {
7092				this._super( "showLabel", value );
7093				return;
7094			}
7095			if ( key === "showLabel" ) {
7096				this.options.text = value;
7097			}
7098			if ( key === "icon" ) {
7099				this.options.icons.primary = value;
7100			}
7101			if ( key === "icons" ) {
7102				if ( value.primary ) {
7103					this._super( "icon", value.primary );
7104					this._super( "iconPosition", "beginning" );
7105				} else if ( value.secondary ) {
7106					this._super( "icon", value.secondary );
7107					this._super( "iconPosition", "end" );
7108				}
7109			}
7110			this._superApply( arguments );
7111		}
7112	} );
7113
7114	$.fn.button = ( function( orig ) {
7115		return function() {
7116			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7117					( this.length && this[ 0 ].tagName === "INPUT" && (
7118						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7119					) ) ) {
7120				return orig.apply( this, arguments );
7121			}
7122			if ( !$.ui.checkboxradio ) {
7123				$.error( "Checkboxradio widget missing" );
7124			}
7125			if ( arguments.length === 0 ) {
7126				return this.checkboxradio( {
7127					"icon": false
7128				} );
7129			}
7130			return this.checkboxradio.apply( this, arguments );
7131		};
7132	} )( $.fn.button );
7133
7134	$.fn.buttonset = function() {
7135		if ( !$.ui.controlgroup ) {
7136			$.error( "Controlgroup widget missing" );
7137		}
7138		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7139			return this.controlgroup.apply( this,
7140				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7141		}
7142		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7143			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7144		}
7145		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7146			arguments[ 0 ].items = {
7147				button: arguments[ 0 ].items
7148			};
7149		}
7150		return this.controlgroup.apply( this, arguments );
7151	};
7152}
7153
7154var widgetsButton = $.ui.button;
7155
7156
7157// jscs:disable maximumLineLength
7158/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7159/*!
7160 * jQuery UI Datepicker 1.12.0
7161 * http://jqueryui.com
7162 *
7163 * Copyright jQuery Foundation and other contributors
7164 * Released under the MIT license.
7165 * http://jquery.org/license
7166 */
7167
7168//>>label: Datepicker
7169//>>group: Widgets
7170//>>description: Displays a calendar from an input or inline for selecting dates.
7171//>>docs: http://api.jqueryui.com/datepicker/
7172//>>demos: http://jqueryui.com/datepicker/
7173//>>css.structure: ../../themes/base/core.css
7174//>>css.structure: ../../themes/base/datepicker.css
7175//>>css.theme: ../../themes/base/theme.css
7176
7177
7178
7179$.extend( $.ui, { datepicker: { version: "1.12.0" } } );
7180
7181var datepicker_instActive;
7182
7183function datepicker_getZindex( elem ) {
7184	var position, value;
7185	while ( elem.length && elem[ 0 ] !== document ) {
7186
7187		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7188		// This makes behavior of this function consistent across browsers
7189		// WebKit always returns auto if the element is positioned
7190		position = elem.css( "position" );
7191		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7192
7193			// IE returns 0 when zIndex is not specified
7194			// other browsers return a string
7195			// we ignore the case of nested elements with an explicit value of 0
7196			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7197			value = parseInt( elem.css( "zIndex" ), 10 );
7198			if ( !isNaN( value ) && value !== 0 ) {
7199				return value;
7200			}
7201		}
7202		elem = elem.parent();
7203	}
7204
7205	return 0;
7206}
7207/* Date picker manager.
7208   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7209   Settings for (groups of) date pickers are maintained in an instance object,
7210   allowing multiple different settings on the same page. */
7211
7212function Datepicker() {
7213	this._curInst = null; // The current instance in use
7214	this._keyEvent = false; // If the last event was a key event
7215	this._disabledInputs = []; // List of date picker inputs that have been disabled
7216	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7217	this._inDialog = false; // True if showing within a "dialog", false if not
7218	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7219	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7220	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7221	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7222	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7223	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7224	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7225	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7226	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7227	this.regional = []; // Available regional settings, indexed by language code
7228	this.regional[ "" ] = { // Default regional settings
7229		closeText: "Done", // Display text for close link
7230		prevText: "Prev", // Display text for previous month link
7231		nextText: "Next", // Display text for next month link
7232		currentText: "Today", // Display text for current month link
7233		monthNames: [ "January","February","March","April","May","June",
7234			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7235		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7236		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7237		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7238		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7239		weekHeader: "Wk", // Column header for week of the year
7240		dateFormat: "mm/dd/yy", // See format options on parseDate
7241		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7242		isRTL: false, // True if right-to-left language, false if left-to-right
7243		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7244		yearSuffix: "" // Additional text to append to the year in the month headers
7245	};
7246	this._defaults = { // Global defaults for all the date picker instances
7247		showOn: "focus", // "focus" for popup on focus,
7248			// "button" for trigger button, or "both" for either
vendor: 6,628 bytes, lines 7249-7381
7249		showAnim: "fadeIn", // Name of jQuery animation for popup
7250		showOptions: {}, // Options for enhanced animations
7251		defaultDate: null, // Used when field is blank: actual date,
7252			// +/-number for offset from today, null for today
7253		appendText: "", // Display text following the input box, e.g. showing the format
7254		buttonText: "...", // Text for trigger button
7255		buttonImage: "", // URL for trigger button image
7256		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7257		hideIfNoPrevNext: false, // True to hide next/previous month links
7258			// if not applicable, false to just disable them
7259		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7260		gotoCurrent: false, // True if today link goes back to current selection instead
7261		changeMonth: false, // True if month can be selected directly, false if only prev/next
7262		changeYear: false, // True if year can be selected directly, false if only prev/next
7263		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7264			// either relative to today's year (-nn:+nn), relative to currently displayed year
7265			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7266		showOtherMonths: false, // True to show dates in other months, false to leave blank
7267		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7268		showWeek: false, // True to show week of the year, false to not show it
7269		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7270			// takes a Date and returns the number of the week for it
7271		shortYearCutoff: "+10", // Short year values < this are in the current century,
7272			// > this are in the previous century,
7273			// string value starting with "+" for current year + value
7274		minDate: null, // The earliest selectable date, or null for no limit
7275		maxDate: null, // The latest selectable date, or null for no limit
7276		duration: "fast", // Duration of display/closure
7277		beforeShowDay: null, // Function that takes a date and returns an array with
7278			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7279			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7280		beforeShow: null, // Function that takes an input field and
7281			// returns a set of custom settings for the date picker
7282		onSelect: null, // Define a callback function when a date is selected
7283		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7284		onClose: null, // Define a callback function when the datepicker is closed
7285		numberOfMonths: 1, // Number of months to show at a time
7286		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7287		stepMonths: 1, // Number of months to step back/forward
7288		stepBigMonths: 12, // Number of months to step back/forward for the big links
7289		altField: "", // Selector for an alternate field to store selected dates into
7290		altFormat: "", // The date format to use for the alternate field
7291		constrainInput: true, // The input is constrained by the current date format
7292		showButtonPanel: false, // True to show button panel, false to not show it
7293		autoSize: false, // True to size the input for the date format, false to leave as is
7294		disabled: false // The initial disabled state
7295	};
7296	$.extend( this._defaults, this.regional[ "" ] );
7297	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7298	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7299	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7300}
7301
7302$.extend( Datepicker.prototype, {
7303	/* Class name added to elements to indicate already configured with a date picker. */
7304	markerClassName: "hasDatepicker",
7305
7306	//Keep track of the maximum number of rows displayed (see #7043)
7307	maxRows: 4,
7308
7309	// TODO rename to "widget" when switching to widget factory
7310	_widgetDatepicker: function() {
7311		return this.dpDiv;
7312	},
7313
7314	/* Override the default settings for all instances of the date picker.
7315	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7316	 * @return the manager object
7317	 */
7318	setDefaults: function( settings ) {
7319		datepicker_extendRemove( this._defaults, settings || {} );
7320		return this;
7321	},
7322
7323	/* Attach the date picker to a jQuery selection.
7324	 * @param  target	element - the target input field or division or span
7325	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7326	 */
7327	_attachDatepicker: function( target, settings ) {
7328		var nodeName, inline, inst;
7329		nodeName = target.nodeName.toLowerCase();
7330		inline = ( nodeName === "div" || nodeName === "span" );
7331		if ( !target.id ) {
7332			this.uuid += 1;
7333			target.id = "dp" + this.uuid;
7334		}
7335		inst = this._newInst( $( target ), inline );
7336		inst.settings = $.extend( {}, settings || {} );
7337		if ( nodeName === "input" ) {
7338			this._connectDatepicker( target, inst );
7339		} else if ( inline ) {
7340			this._inlineDatepicker( target, inst );
7341		}
7342	},
7343
7344	/* Create a new instance object. */
7345	_newInst: function( target, inline ) {
7346		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7347		return { id: id, input: target, // associated target
7348			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7349			drawMonth: 0, drawYear: 0, // month being drawn
7350			inline: inline, // is datepicker inline or not
7351			dpDiv: ( !inline ? this.dpDiv : // presentation div
7352			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7353	},
7354
7355	/* Attach the date picker to an input field. */
7356	_connectDatepicker: function( target, inst ) {
7357		var input = $( target );
7358		inst.append = $( [] );
7359		inst.trigger = $( [] );
7360		if ( input.hasClass( this.markerClassName ) ) {
7361			return;
7362		}
7363		this._attachments( input, inst );
7364		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7365			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7366		this._autoSize( inst );
7367		$.data( target, "datepicker", inst );
7368
7369		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7370		if ( inst.settings.disabled ) {
7371			this._disableDatepicker( target );
7372		}
7373	},
7374
7375	/* Make attachments based on settings. */
7376	_attachments: function( input, inst ) {
7377		var showOn, buttonText, buttonImage,
7378			appendText = this._get( inst, "appendText" ),
7379			isRTL = this._get( inst, "isRTL" );
7380
7381		if ( inst.append ) {
vendor: 13,169 bytes, lines 7382-7752
7382			inst.append.remove();
7383		}
7384		if ( appendText ) {
7385			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7386			input[ isRTL ? "before" : "after" ]( inst.append );
7387		}
7388
7389		input.off( "focus", this._showDatepicker );
7390
7391		if ( inst.trigger ) {
7392			inst.trigger.remove();
7393		}
7394
7395		showOn = this._get( inst, "showOn" );
7396		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7397			input.on( "focus", this._showDatepicker );
7398		}
7399		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7400			buttonText = this._get( inst, "buttonText" );
7401			buttonImage = this._get( inst, "buttonImage" );
7402			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7403				$( "<img/>" ).addClass( this._triggerClass ).
7404					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7405				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7406					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7407					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7408			input[ isRTL ? "before" : "after" ]( inst.trigger );
7409			inst.trigger.on( "click", function() {
7410				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7411					$.datepicker._hideDatepicker();
7412				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7413					$.datepicker._hideDatepicker();
7414					$.datepicker._showDatepicker( input[ 0 ] );
7415				} else {
7416					$.datepicker._showDatepicker( input[ 0 ] );
7417				}
7418				return false;
7419			} );
7420		}
7421	},
7422
7423	/* Apply the maximum length for the date format. */
7424	_autoSize: function( inst ) {
7425		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7426			var findMax, max, maxI, i,
7427				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7428				dateFormat = this._get( inst, "dateFormat" );
7429
7430			if ( dateFormat.match( /[DM]/ ) ) {
7431				findMax = function( names ) {
7432					max = 0;
7433					maxI = 0;
7434					for ( i = 0; i < names.length; i++ ) {
7435						if ( names[ i ].length > max ) {
7436							max = names[ i ].length;
7437							maxI = i;
7438						}
7439					}
7440					return maxI;
7441				};
7442				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7443					"monthNames" : "monthNamesShort" ) ) ) );
7444				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7445					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7446			}
7447			inst.input.attr( "size", this._formatDate( inst, date ).length );
7448		}
7449	},
7450
7451	/* Attach an inline date picker to a div. */
7452	_inlineDatepicker: function( target, inst ) {
7453		var divSpan = $( target );
7454		if ( divSpan.hasClass( this.markerClassName ) ) {
7455			return;
7456		}
7457		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7458		$.data( target, "datepicker", inst );
7459		this._setDate( inst, this._getDefaultDate( inst ), true );
7460		this._updateDatepicker( inst );
7461		this._updateAlternate( inst );
7462
7463		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7464		if ( inst.settings.disabled ) {
7465			this._disableDatepicker( target );
7466		}
7467
7468		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7469		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7470		inst.dpDiv.css( "display", "block" );
7471	},
7472
7473	/* Pop-up the date picker in a "dialog" box.
7474	 * @param  input element - ignored
7475	 * @param  date	string or Date - the initial date to display
7476	 * @param  onSelect  function - the function to call when a date is selected
7477	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7478	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7479	 *					event - with x/y coordinates or
7480	 *					leave empty for default (screen centre)
7481	 * @return the manager object
7482	 */
7483	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7484		var id, browserWidth, browserHeight, scrollX, scrollY,
7485			inst = this._dialogInst; // internal instance
7486
7487		if ( !inst ) {
7488			this.uuid += 1;
7489			id = "dp" + this.uuid;
7490			this._dialogInput = $( "<input type='text' id='" + id +
7491				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7492			this._dialogInput.on( "keydown", this._doKeyDown );
7493			$( "body" ).append( this._dialogInput );
7494			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7495			inst.settings = {};
7496			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7497		}
7498		datepicker_extendRemove( inst.settings, settings || {} );
7499		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7500		this._dialogInput.val( date );
7501
7502		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7503		if ( !this._pos ) {
7504			browserWidth = document.documentElement.clientWidth;
7505			browserHeight = document.documentElement.clientHeight;
7506			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7507			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7508			this._pos = // should use actual width/height below
7509				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7510		}
7511
7512		// Move input on screen for focus, but hidden behind dialog
7513		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7514		inst.settings.onSelect = onSelect;
7515		this._inDialog = true;
7516		this.dpDiv.addClass( this._dialogClass );
7517		this._showDatepicker( this._dialogInput[ 0 ] );
7518		if ( $.blockUI ) {
7519			$.blockUI( this.dpDiv );
7520		}
7521		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7522		return this;
7523	},
7524
7525	/* Detach a datepicker from its control.
7526	 * @param  target	element - the target input field or division or span
7527	 */
7528	_destroyDatepicker: function( target ) {
7529		var nodeName,
7530			$target = $( target ),
7531			inst = $.data( target, "datepicker" );
7532
7533		if ( !$target.hasClass( this.markerClassName ) ) {
7534			return;
7535		}
7536
7537		nodeName = target.nodeName.toLowerCase();
7538		$.removeData( target, "datepicker" );
7539		if ( nodeName === "input" ) {
7540			inst.append.remove();
7541			inst.trigger.remove();
7542			$target.removeClass( this.markerClassName ).
7543				off( "focus", this._showDatepicker ).
7544				off( "keydown", this._doKeyDown ).
7545				off( "keypress", this._doKeyPress ).
7546				off( "keyup", this._doKeyUp );
7547		} else if ( nodeName === "div" || nodeName === "span" ) {
7548			$target.removeClass( this.markerClassName ).empty();
7549		}
7550
7551		if ( datepicker_instActive === inst ) {
7552			datepicker_instActive = null;
7553		}
7554	},
7555
7556	/* Enable the date picker to a jQuery selection.
7557	 * @param  target	element - the target input field or division or span
7558	 */
7559	_enableDatepicker: function( target ) {
7560		var nodeName, inline,
7561			$target = $( target ),
7562			inst = $.data( target, "datepicker" );
7563
7564		if ( !$target.hasClass( this.markerClassName ) ) {
7565			return;
7566		}
7567
7568		nodeName = target.nodeName.toLowerCase();
7569		if ( nodeName === "input" ) {
7570			target.disabled = false;
7571			inst.trigger.filter( "button" ).
7572				each( function() { this.disabled = false; } ).end().
7573				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7574		} else if ( nodeName === "div" || nodeName === "span" ) {
7575			inline = $target.children( "." + this._inlineClass );
7576			inline.children().removeClass( "ui-state-disabled" );
7577			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7578				prop( "disabled", false );
7579		}
7580		this._disabledInputs = $.map( this._disabledInputs,
7581			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7582	},
7583
7584	/* Disable the date picker to a jQuery selection.
7585	 * @param  target	element - the target input field or division or span
7586	 */
7587	_disableDatepicker: function( target ) {
7588		var nodeName, inline,
7589			$target = $( target ),
7590			inst = $.data( target, "datepicker" );
7591
7592		if ( !$target.hasClass( this.markerClassName ) ) {
7593			return;
7594		}
7595
7596		nodeName = target.nodeName.toLowerCase();
7597		if ( nodeName === "input" ) {
7598			target.disabled = true;
7599			inst.trigger.filter( "button" ).
7600				each( function() { this.disabled = true; } ).end().
7601				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7602		} else if ( nodeName === "div" || nodeName === "span" ) {
7603			inline = $target.children( "." + this._inlineClass );
7604			inline.children().addClass( "ui-state-disabled" );
7605			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7606				prop( "disabled", true );
7607		}
7608		this._disabledInputs = $.map( this._disabledInputs,
7609			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7610		this._disabledInputs[ this._disabledInputs.length ] = target;
7611	},
7612
7613	/* Is the first field in a jQuery collection disabled as a datepicker?
7614	 * @param  target	element - the target input field or division or span
7615	 * @return boolean - true if disabled, false if enabled
7616	 */
7617	_isDisabledDatepicker: function( target ) {
7618		if ( !target ) {
7619			return false;
7620		}
7621		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7622			if ( this._disabledInputs[ i ] === target ) {
7623				return true;
7624			}
7625		}
7626		return false;
7627	},
7628
7629	/* Retrieve the instance data for the target control.
7630	 * @param  target  element - the target input field or division or span
7631	 * @return  object - the associated instance data
7632	 * @throws  error if a jQuery problem getting data
7633	 */
7634	_getInst: function( target ) {
7635		try {
7636			return $.data( target, "datepicker" );
7637		}
7638		catch ( err ) {
7639			throw "Missing instance data for this datepicker";
7640		}
7641	},
7642
7643	/* Update or retrieve the settings for a date picker attached to an input field or division.
7644	 * @param  target  element - the target input field or division or span
7645	 * @param  name	object - the new settings to update or
7646	 *				string - the name of the setting to change or retrieve,
7647	 *				when retrieving also "all" for all instance settings or
7648	 *				"defaults" for all global defaults
7649	 * @param  value   any - the new value for the setting
7650	 *				(omit if above is an object or to retrieve a value)
7651	 */
7652	_optionDatepicker: function( target, name, value ) {
7653		var settings, date, minDate, maxDate,
7654			inst = this._getInst( target );
7655
7656		if ( arguments.length === 2 && typeof name === "string" ) {
7657			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7658				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7659				this._get( inst, name ) ) : null ) );
7660		}
7661
7662		settings = name || {};
7663		if ( typeof name === "string" ) {
7664			settings = {};
7665			settings[ name ] = value;
7666		}
7667
7668		if ( inst ) {
7669			if ( this._curInst === inst ) {
7670				this._hideDatepicker();
7671			}
7672
7673			date = this._getDateDatepicker( target, true );
7674			minDate = this._getMinMaxDate( inst, "min" );
7675			maxDate = this._getMinMaxDate( inst, "max" );
7676			datepicker_extendRemove( inst.settings, settings );
7677
7678			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7679			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7680				inst.settings.minDate = this._formatDate( inst, minDate );
7681			}
7682			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7683				inst.settings.maxDate = this._formatDate( inst, maxDate );
7684			}
7685			if ( "disabled" in settings ) {
7686				if ( settings.disabled ) {
7687					this._disableDatepicker( target );
7688				} else {
7689					this._enableDatepicker( target );
7690				}
7691			}
7692			this._attachments( $( target ), inst );
7693			this._autoSize( inst );
7694			this._setDate( inst, date );
7695			this._updateAlternate( inst );
7696			this._updateDatepicker( inst );
7697		}
7698	},
7699
7700	// Change method deprecated
7701	_changeDatepicker: function( target, name, value ) {
7702		this._optionDatepicker( target, name, value );
7703	},
7704
7705	/* Redraw the date picker attached to an input field or division.
7706	 * @param  target  element - the target input field or division or span
7707	 */
7708	_refreshDatepicker: function( target ) {
7709		var inst = this._getInst( target );
7710		if ( inst ) {
7711			this._updateDatepicker( inst );
7712		}
7713	},
7714
7715	/* Set the dates for a jQuery selection.
7716	 * @param  target element - the target input field or division or span
7717	 * @param  date	Date - the new date
7718	 */
7719	_setDateDatepicker: function( target, date ) {
7720		var inst = this._getInst( target );
7721		if ( inst ) {
7722			this._setDate( inst, date );
7723			this._updateDatepicker( inst );
7724			this._updateAlternate( inst );
7725		}
7726	},
7727
7728	/* Get the date(s) for the first entry in a jQuery selection.
7729	 * @param  target element - the target input field or division or span
7730	 * @param  noDefault boolean - true if no default date is to be used
7731	 * @return Date - the current date
7732	 */
7733	_getDateDatepicker: function( target, noDefault ) {
7734		var inst = this._getInst( target );
7735		if ( inst && !inst.inline ) {
7736			this._setDateFromField( inst, noDefault );
7737		}
7738		return ( inst ? this._getDate( inst ) : null );
7739	},
7740
7741	/* Handle keystrokes. */
7742	_doKeyDown: function( event ) {
7743		var onSelect, dateStr, sel,
7744			inst = $.datepicker._getInst( event.target ),
7745			handled = true,
7746			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7747
7748		inst._keyEvent = true;
7749		if ( $.datepicker._datepickerShowing ) {
7750			switch ( event.keyCode ) {
7751				case 9: $.datepicker._hideDatepicker();
7752						handled = false;
vendor: 4,635 bytes, lines 7753-7880
7753						break; // hide on tab out
7754				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7755									$.datepicker._currentClass + ")", inst.dpDiv );
7756						if ( sel[ 0 ] ) {
7757							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7758						}
7759
7760						onSelect = $.datepicker._get( inst, "onSelect" );
7761						if ( onSelect ) {
7762							dateStr = $.datepicker._formatDate( inst );
7763
7764							// Trigger custom callback
7765							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7766						} else {
7767							$.datepicker._hideDatepicker();
7768						}
7769
7770						return false; // don't submit the form
7771				case 27: $.datepicker._hideDatepicker();
7772						break; // hide on escape
7773				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7774							-$.datepicker._get( inst, "stepBigMonths" ) :
7775							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7776						break; // previous month/year on page up/+ ctrl
7777				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7778							+$.datepicker._get( inst, "stepBigMonths" ) :
7779							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7780						break; // next month/year on page down/+ ctrl
7781				case 35: if ( event.ctrlKey || event.metaKey ) {
7782							$.datepicker._clearDate( event.target );
7783						}
7784						handled = event.ctrlKey || event.metaKey;
7785						break; // clear on ctrl or command +end
7786				case 36: if ( event.ctrlKey || event.metaKey ) {
7787							$.datepicker._gotoToday( event.target );
7788						}
7789						handled = event.ctrlKey || event.metaKey;
7790						break; // current on ctrl or command +home
7791				case 37: if ( event.ctrlKey || event.metaKey ) {
7792							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7793						}
7794						handled = event.ctrlKey || event.metaKey;
7795
7796						// -1 day on ctrl or command +left
7797						if ( event.originalEvent.altKey ) {
7798							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7799								-$.datepicker._get( inst, "stepBigMonths" ) :
7800								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7801						}
7802
7803						// next month/year on alt +left on Mac
7804						break;
7805				case 38: if ( event.ctrlKey || event.metaKey ) {
7806							$.datepicker._adjustDate( event.target, -7, "D" );
7807						}
7808						handled = event.ctrlKey || event.metaKey;
7809						break; // -1 week on ctrl or command +up
7810				case 39: if ( event.ctrlKey || event.metaKey ) {
7811							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7812						}
7813						handled = event.ctrlKey || event.metaKey;
7814
7815						// +1 day on ctrl or command +right
7816						if ( event.originalEvent.altKey ) {
7817							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7818								+$.datepicker._get( inst, "stepBigMonths" ) :
7819								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7820						}
7821
7822						// next month/year on alt +right
7823						break;
7824				case 40: if ( event.ctrlKey || event.metaKey ) {
7825							$.datepicker._adjustDate( event.target, +7, "D" );
7826						}
7827						handled = event.ctrlKey || event.metaKey;
7828						break; // +1 week on ctrl or command +down
7829				default: handled = false;
7830			}
7831		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7832			$.datepicker._showDatepicker( this );
7833		} else {
7834			handled = false;
7835		}
7836
7837		if ( handled ) {
7838			event.preventDefault();
7839			event.stopPropagation();
7840		}
7841	},
7842
7843	/* Filter entered characters - based on date format. */
7844	_doKeyPress: function( event ) {
7845		var chars, chr,
7846			inst = $.datepicker._getInst( event.target );
7847
7848		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7849			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7850			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7851			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7852		}
7853	},
7854
7855	/* Synchronise manual entry and field/alternate field. */
7856	_doKeyUp: function( event ) {
7857		var date,
7858			inst = $.datepicker._getInst( event.target );
7859
7860		if ( inst.input.val() !== inst.lastVal ) {
7861			try {
7862				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7863					( inst.input ? inst.input.val() : null ),
7864					$.datepicker._getFormatConfig( inst ) );
7865
7866				if ( date ) { // only if valid
7867					$.datepicker._setDateFromField( inst );
7868					$.datepicker._updateAlternate( inst );
7869					$.datepicker._updateDatepicker( inst );
7870				}
7871			}
7872			catch ( err ) {
7873			}
7874		}
7875		return true;
7876	},
7877
7878	/* Pop-up the date picker for a given input field.
7879	 * If false returned from beforeShow event handler do not show.
7880	 * @param  input  element - the input field attached to the date picker or
vendor: 9,739 bytes, lines 7881-8159
7881	 *					event - if triggered by focus
7882	 */
7883	_showDatepicker: function( input ) {
7884		input = input.target || input;
7885		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7886			input = $( "input", input.parentNode )[ 0 ];
7887		}
7888
7889		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7890			return;
7891		}
7892
7893		var inst, beforeShow, beforeShowSettings, isFixed,
7894			offset, showAnim, duration;
7895
7896		inst = $.datepicker._getInst( input );
7897		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7898			$.datepicker._curInst.dpDiv.stop( true, true );
7899			if ( inst && $.datepicker._datepickerShowing ) {
7900				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7901			}
7902		}
7903
7904		beforeShow = $.datepicker._get( inst, "beforeShow" );
7905		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7906		if ( beforeShowSettings === false ) {
7907			return;
7908		}
7909		datepicker_extendRemove( inst.settings, beforeShowSettings );
7910
7911		inst.lastVal = null;
7912		$.datepicker._lastInput = input;
7913		$.datepicker._setDateFromField( inst );
7914
7915		if ( $.datepicker._inDialog ) { // hide cursor
7916			input.value = "";
7917		}
7918		if ( !$.datepicker._pos ) { // position below input
7919			$.datepicker._pos = $.datepicker._findPos( input );
7920			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7921		}
7922
7923		isFixed = false;
7924		$( input ).parents().each( function() {
7925			isFixed |= $( this ).css( "position" ) === "fixed";
7926			return !isFixed;
7927		} );
7928
7929		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7930		$.datepicker._pos = null;
7931
7932		//to avoid flashes on Firefox
7933		inst.dpDiv.empty();
7934
7935		// determine sizing offscreen
7936		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7937		$.datepicker._updateDatepicker( inst );
7938
7939		// fix width for dynamic number of date pickers
7940		// and adjust position before showing
7941		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7942		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7943			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7944			left: offset.left + "px", top: offset.top + "px" } );
7945
7946		if ( !inst.inline ) {
7947			showAnim = $.datepicker._get( inst, "showAnim" );
7948			duration = $.datepicker._get( inst, "duration" );
7949			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7950			$.datepicker._datepickerShowing = true;
7951
7952			if ( $.effects && $.effects.effect[ showAnim ] ) {
7953				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7954			} else {
7955				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7956			}
7957
7958			if ( $.datepicker._shouldFocusInput( inst ) ) {
7959				inst.input.trigger( "focus" );
7960			}
7961
7962			$.datepicker._curInst = inst;
7963		}
7964	},
7965
7966	/* Generate the date picker content. */
7967	_updateDatepicker: function( inst ) {
7968		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7969		datepicker_instActive = inst; // for delegate hover events
7970		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7971		this._attachHandlers( inst );
7972
7973		var origyearshtml,
7974			numMonths = this._getNumberOfMonths( inst ),
7975			cols = numMonths[ 1 ],
7976			width = 17,
7977			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7978
7979		if ( activeCell.length > 0 ) {
7980			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7981		}
7982
7983		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7984		if ( cols > 1 ) {
7985			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7986		}
7987		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7988			"Class" ]( "ui-datepicker-multi" );
7989		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7990			"Class" ]( "ui-datepicker-rtl" );
7991
7992		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7993			inst.input.trigger( "focus" );
7994		}
7995
7996		// Deffered render of the years select (to avoid flashes on Firefox)
7997		if ( inst.yearshtml ) {
7998			origyearshtml = inst.yearshtml;
7999			setTimeout( function() {
8000
8001				//assure that inst.yearshtml didn't change.
8002				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8003					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8004				}
8005				origyearshtml = inst.yearshtml = null;
8006			}, 0 );
8007		}
8008	},
8009
8010	// #6694 - don't focus the input if it's already focused
8011	// this breaks the change event in IE
8012	// Support: IE and jQuery <1.9
8013	_shouldFocusInput: function( inst ) {
8014		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8015	},
8016
8017	/* Check positioning to remain on screen. */
8018	_checkOffset: function( inst, offset, isFixed ) {
8019		var dpWidth = inst.dpDiv.outerWidth(),
8020			dpHeight = inst.dpDiv.outerHeight(),
8021			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8022			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8023			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8024			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8025
8026		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8027		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8028		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8029
8030		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8031		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8032			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8033		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8034			Math.abs( dpHeight + inputHeight ) : 0 );
8035
8036		return offset;
8037	},
8038
8039	/* Find an object's position on the screen. */
8040	_findPos: function( obj ) {
8041		var position,
8042			inst = this._getInst( obj ),
8043			isRTL = this._get( inst, "isRTL" );
8044
8045		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8046			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8047		}
8048
8049		position = $( obj ).offset();
8050		return [ position.left, position.top ];
8051	},
8052
8053	/* Hide the date picker from view.
8054	 * @param  input  element - the input field attached to the date picker
8055	 */
8056	_hideDatepicker: function( input ) {
8057		var showAnim, duration, postProcess, onClose,
8058			inst = this._curInst;
8059
8060		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8061			return;
8062		}
8063
8064		if ( this._datepickerShowing ) {
8065			showAnim = this._get( inst, "showAnim" );
8066			duration = this._get( inst, "duration" );
8067			postProcess = function() {
8068				$.datepicker._tidyDialog( inst );
8069			};
8070
8071			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8072			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8073				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8074			} else {
8075				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8076					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8077			}
8078
8079			if ( !showAnim ) {
8080				postProcess();
8081			}
8082			this._datepickerShowing = false;
8083
8084			onClose = this._get( inst, "onClose" );
8085			if ( onClose ) {
8086				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8087			}
8088
8089			this._lastInput = null;
8090			if ( this._inDialog ) {
8091				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8092				if ( $.blockUI ) {
8093					$.unblockUI();
8094					$( "body" ).append( this.dpDiv );
8095				}
8096			}
8097			this._inDialog = false;
8098		}
8099	},
8100
8101	/* Tidy up after a dialog display. */
8102	_tidyDialog: function( inst ) {
8103		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8104	},
8105
8106	/* Close date picker if clicked elsewhere. */
8107	_checkExternalClick: function( event ) {
8108		if ( !$.datepicker._curInst ) {
8109			return;
8110		}
8111
8112		var $target = $( event.target ),
8113			inst = $.datepicker._getInst( $target[ 0 ] );
8114
8115		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8116				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8117				!$target.hasClass( $.datepicker.markerClassName ) &&
8118				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8119				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8120			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8121				$.datepicker._hideDatepicker();
8122		}
8123	},
8124
8125	/* Adjust one of the date sub-fields. */
8126	_adjustDate: function( id, offset, period ) {
8127		var target = $( id ),
8128			inst = this._getInst( target[ 0 ] );
8129
8130		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8131			return;
8132		}
8133		this._adjustInstDate( inst, offset +
8134			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8135			period );
8136		this._updateDatepicker( inst );
8137	},
8138
8139	/* Action for current link. */
8140	_gotoToday: function( id ) {
8141		var date,
8142			target = $( id ),
8143			inst = this._getInst( target[ 0 ] );
8144
8145		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8146			inst.selectedDay = inst.currentDay;
8147			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8148			inst.drawYear = inst.selectedYear = inst.currentYear;
8149		} else {
8150			date = new Date();
8151			inst.selectedDay = date.getDate();
8152			inst.drawMonth = inst.selectedMonth = date.getMonth();
8153			inst.drawYear = inst.selectedYear = date.getFullYear();
8154		}
8155		this._notifyChange( inst );
8156		this._adjustDate( target );
8157	},
8158
8159	/* Action for selecting a new month/year. */
vendor: 2,372 bytes, lines 8160-8235
8160	_selectMonthYear: function( id, select, period ) {
8161		var target = $( id ),
8162			inst = this._getInst( target[ 0 ] );
8163
8164		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8165		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8166			parseInt( select.options[ select.selectedIndex ].value, 10 );
8167
8168		this._notifyChange( inst );
8169		this._adjustDate( target );
8170	},
8171
8172	/* Action for selecting a day. */
8173	_selectDay: function( id, month, year, td ) {
8174		var inst,
8175			target = $( id );
8176
8177		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8178			return;
8179		}
8180
8181		inst = this._getInst( target[ 0 ] );
8182		inst.selectedDay = inst.currentDay = $( "a", td ).html();
8183		inst.selectedMonth = inst.currentMonth = month;
8184		inst.selectedYear = inst.currentYear = year;
8185		this._selectDate( id, this._formatDate( inst,
8186			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8187	},
8188
8189	/* Erase the input field and hide the date picker. */
8190	_clearDate: function( id ) {
8191		var target = $( id );
8192		this._selectDate( target, "" );
8193	},
8194
8195	/* Update the input field with the selected date. */
8196	_selectDate: function( id, dateStr ) {
8197		var onSelect,
8198			target = $( id ),
8199			inst = this._getInst( target[ 0 ] );
8200
8201		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8202		if ( inst.input ) {
8203			inst.input.val( dateStr );
8204		}
8205		this._updateAlternate( inst );
8206
8207		onSelect = this._get( inst, "onSelect" );
8208		if ( onSelect ) {
8209			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8210		} else if ( inst.input ) {
8211			inst.input.trigger( "change" ); // fire the change event
8212		}
8213
8214		if ( inst.inline ) {
8215			this._updateDatepicker( inst );
8216		} else {
8217			this._hideDatepicker();
8218			this._lastInput = inst.input[ 0 ];
8219			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8220				inst.input.trigger( "focus" ); // restore focus
8221			}
8222			this._lastInput = null;
8223		}
8224	},
8225
8226	/* Update any alternate field to synchronise with the main field. */
8227	_updateAlternate: function( inst ) {
8228		var altFormat, date, dateStr,
8229			altField = this._get( inst, "altField" );
8230
8231		if ( altField ) { // update alternate field too
8232			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8233			date = this._getDate( inst );
8234			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8235			$
vendor: 13,647 bytes, lines 8235-8674
8235( altField ).val( dateStr );
8236		}
8237	},
8238
8239	/* Set as beforeShowDay function to prevent selection of weekends.
8240	 * @param  date  Date - the date to customise
8241	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8242	 */
8243	noWeekends: function( date ) {
8244		var day = date.getDay();
8245		return [ ( day > 0 && day < 6 ), "" ];
8246	},
8247
8248	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8249	 * @param  date  Date - the date to get the week for
8250	 * @return  number - the number of the week within the year that contains this date
8251	 */
8252	iso8601Week: function( date ) {
8253		var time,
8254			checkDate = new Date( date.getTime() );
8255
8256		// Find Thursday of this week starting on Monday
8257		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8258
8259		time = checkDate.getTime();
8260		checkDate.setMonth( 0 ); // Compare with Jan 1
8261		checkDate.setDate( 1 );
8262		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8263	},
8264
8265	/* Parse a string value into a date object.
8266	 * See formatDate below for the possible formats.
8267	 *
8268	 * @param  format string - the expected format of the date
8269	 * @param  value string - the date in the above format
8270	 * @param  settings Object - attributes include:
8271	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8272	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8273	 *					dayNames		string[7] - names of the days from Sunday (optional)
8274	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8275	 *					monthNames		string[12] - names of the months (optional)
8276	 * @return  Date - the extracted date value or null if value is blank
8277	 */
8278	parseDate: function( format, value, settings ) {
8279		if ( format == null || value == null ) {
8280			throw "Invalid arguments";
8281		}
8282
8283		value = ( typeof value === "object" ? value.toString() : value + "" );
8284		if ( value === "" ) {
8285			return null;
8286		}
8287
8288		var iFormat, dim, extra,
8289			iValue = 0,
8290			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8291			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8292				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8293			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8294			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8295			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8296			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8297			year = -1,
8298			month = -1,
8299			day = -1,
8300			doy = -1,
8301			literal = false,
8302			date,
8303
8304			// Check whether a format character is doubled
8305			lookAhead = function( match ) {
8306				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8307				if ( matches ) {
8308					iFormat++;
8309				}
8310				return matches;
8311			},
8312
8313			// Extract a number from the string value
8314			getNumber = function( match ) {
8315				var isDoubled = lookAhead( match ),
8316					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8317					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8318					minSize = ( match === "y" ? size : 1 ),
8319					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8320					num = value.substring( iValue ).match( digits );
8321				if ( !num ) {
8322					throw "Missing number at position " + iValue;
8323				}
8324				iValue += num[ 0 ].length;
8325				return parseInt( num[ 0 ], 10 );
8326			},
8327
8328			// Extract a name from the string value and convert to an index
8329			getName = function( match, shortNames, longNames ) {
8330				var index = -1,
8331					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8332						return [ [ k, v ] ];
8333					} ).sort( function( a, b ) {
8334						return -( a[ 1 ].length - b[ 1 ].length );
8335					} );
8336
8337				$.each( names, function( i, pair ) {
8338					var name = pair[ 1 ];
8339					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8340						index = pair[ 0 ];
8341						iValue += name.length;
8342						return false;
8343					}
8344				} );
8345				if ( index !== -1 ) {
8346					return index + 1;
8347				} else {
8348					throw "Unknown name at position " + iValue;
8349				}
8350			},
8351
8352			// Confirm that a literal character matches the string value
8353			checkLiteral = function() {
8354				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8355					throw "Unexpected literal at position " + iValue;
8356				}
8357				iValue++;
8358			};
8359
8360		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8361			if ( literal ) {
8362				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8363					literal = false;
8364				} else {
8365					checkLiteral();
8366				}
8367			} else {
8368				switch ( format.charAt( iFormat ) ) {
8369					case "d":
8370						day = getNumber( "d" );
8371						break;
8372					case "D":
8373						getName( "D", dayNamesShort, dayNames );
8374						break;
8375					case "o":
8376						doy = getNumber( "o" );
8377						break;
8378					case "m":
8379						month = getNumber( "m" );
8380						break;
8381					case "M":
8382						month = getName( "M", monthNamesShort, monthNames );
8383						break;
8384					case "y":
8385						year = getNumber( "y" );
8386						break;
8387					case "@":
8388						date = new Date( getNumber( "@" ) );
8389						year = date.getFullYear();
8390						month = date.getMonth() + 1;
8391						day = date.getDate();
8392						break;
8393					case "!":
8394						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8395						year = date.getFullYear();
8396						month = date.getMonth() + 1;
8397						day = date.getDate();
8398						break;
8399					case "'":
8400						if ( lookAhead( "'" ) ) {
8401							checkLiteral();
8402						} else {
8403							literal = true;
8404						}
8405						break;
8406					default:
8407						checkLiteral();
8408				}
8409			}
8410		}
8411
8412		if ( iValue < value.length ) {
8413			extra = value.substr( iValue );
8414			if ( !/^\s+/.test( extra ) ) {
8415				throw "Extra/unparsed characters found in date: " + extra;
8416			}
8417		}
8418
8419		if ( year === -1 ) {
8420			year = new Date().getFullYear();
8421		} else if ( year < 100 ) {
8422			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8423				( year <= shortYearCutoff ? 0 : -100 );
8424		}
8425
8426		if ( doy > -1 ) {
8427			month = 1;
8428			day = doy;
8429			do {
8430				dim = this._getDaysInMonth( year, month - 1 );
8431				if ( day <= dim ) {
8432					break;
8433				}
8434				month++;
8435				day -= dim;
8436			} while ( true );
8437		}
8438
8439		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8440		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8441			throw "Invalid date"; // E.g. 31/02/00
8442		}
8443		return date;
8444	},
8445
8446	/* Standard date formats. */
8447	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8448	COOKIE: "D, dd M yy",
8449	ISO_8601: "yy-mm-dd",
8450	RFC_822: "D, d M y",
8451	RFC_850: "DD, dd-M-y",
8452	RFC_1036: "D, d M y",
8453	RFC_1123: "D, d M yy",
8454	RFC_2822: "D, d M yy",
8455	RSS: "D, d M y", // RFC 822
8456	TICKS: "!",
8457	TIMESTAMP: "@",
8458	W3C: "yy-mm-dd", // ISO 8601
8459
8460	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8461		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8462
8463	/* Format a date object into a string value.
8464	 * The format can be combinations of the following:
8465	 * d  - day of month (no leading zero)
8466	 * dd - day of month (two digit)
8467	 * o  - day of year (no leading zeros)
8468	 * oo - day of year (three digit)
8469	 * D  - day name short
8470	 * DD - day name long
8471	 * m  - month of year (no leading zero)
8472	 * mm - month of year (two digit)
8473	 * M  - month name short
8474	 * MM - month name long
8475	 * y  - year (two digit)
8476	 * yy - year (four digit)
8477	 * @ - Unix timestamp (ms since 01/01/1970)
8478	 * ! - Windows ticks (100ns since 01/01/0001)
8479	 * "..." - literal text
8480	 * '' - single quote
8481	 *
8482	 * @param  format string - the desired format of the date
8483	 * @param  date Date - the date value to format
8484	 * @param  settings Object - attributes include:
8485	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8486	 *					dayNames		string[7] - names of the days from Sunday (optional)
8487	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8488	 *					monthNames		string[12] - names of the months (optional)
8489	 * @return  string - the date in the above format
8490	 */
8491	formatDate: function( format, date, settings ) {
8492		if ( !date ) {
8493			return "";
8494		}
8495
8496		var iFormat,
8497			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8498			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8499			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8500			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8501
8502			// Check whether a format character is doubled
8503			lookAhead = function( match ) {
8504				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8505				if ( matches ) {
8506					iFormat++;
8507				}
8508				return matches;
8509			},
8510
8511			// Format a number, with leading zero if necessary
8512			formatNumber = function( match, value, len ) {
8513				var num = "" + value;
8514				if ( lookAhead( match ) ) {
8515					while ( num.length < len ) {
8516						num = "0" + num;
8517					}
8518				}
8519				return num;
8520			},
8521
8522			// Format a name, short or long as requested
8523			formatName = function( match, value, shortNames, longNames ) {
8524				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8525			},
8526			output = "",
8527			literal = false;
8528
8529		if ( date ) {
8530			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8531				if ( literal ) {
8532					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8533						literal = false;
8534					} else {
8535						output += format.charAt( iFormat );
8536					}
8537				} else {
8538					switch ( format.charAt( iFormat ) ) {
8539						case "d":
8540							output += formatNumber( "d", date.getDate(), 2 );
8541							break;
8542						case "D":
8543							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8544							break;
8545						case "o":
8546							output += formatNumber( "o",
8547								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8548							break;
8549						case "m":
8550							output += formatNumber( "m", date.getMonth() + 1, 2 );
8551							break;
8552						case "M":
8553							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8554							break;
8555						case "y":
8556							output += ( lookAhead( "y" ) ? date.getFullYear() :
8557								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8558							break;
8559						case "@":
8560							output += date.getTime();
8561							break;
8562						case "!":
8563							output += date.getTime() * 10000 + this._ticksTo1970;
8564							break;
8565						case "'":
8566							if ( lookAhead( "'" ) ) {
8567								output += "'";
8568							} else {
8569								literal = true;
8570							}
8571							break;
8572						default:
8573							output += format.charAt( iFormat );
8574					}
8575				}
8576			}
8577		}
8578		return output;
8579	},
8580
8581	/* Extract all possible characters from the date format. */
8582	_possibleChars: function( format ) {
8583		var iFormat,
8584			chars = "",
8585			literal = false,
8586
8587			// Check whether a format character is doubled
8588			lookAhead = function( match ) {
8589				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8590				if ( matches ) {
8591					iFormat++;
8592				}
8593				return matches;
8594			};
8595
8596		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8597			if ( literal ) {
8598				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8599					literal = false;
8600				} else {
8601					chars += format.charAt( iFormat );
8602				}
8603			} else {
8604				switch ( format.charAt( iFormat ) ) {
8605					case "d": case "m": case "y": case "@":
8606						chars += "0123456789";
8607						break;
8608					case "D": case "M":
8609						return null; // Accept anything
8610					case "'":
8611						if ( lookAhead( "'" ) ) {
8612							chars += "'";
8613						} else {
8614							literal = true;
8615						}
8616						break;
8617					default:
8618						chars += format.charAt( iFormat );
8619				}
8620			}
8621		}
8622		return chars;
8623	},
8624
8625	/* Get a setting value, defaulting if necessary. */
8626	_get: function( inst, name ) {
8627		return inst.settings[ name ] !== undefined ?
8628			inst.settings[ name ] : this._defaults[ name ];
8629	},
8630
8631	/* Parse existing date and initialise date picker. */
8632	_setDateFromField: function( inst, noDefault ) {
8633		if ( inst.input.val() === inst.lastVal ) {
8634			return;
8635		}
8636
8637		var dateFormat = this._get( inst, "dateFormat" ),
8638			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8639			defaultDate = this._getDefaultDate( inst ),
8640			date = defaultDate,
8641			settings = this._getFormatConfig( inst );
8642
8643		try {
8644			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8645		} catch ( event ) {
8646			dates = ( noDefault ? "" : dates );
8647		}
8648		inst.selectedDay = date.getDate();
8649		inst.drawMonth = inst.selectedMonth = date.getMonth();
8650		inst.drawYear = inst.selectedYear = date.getFullYear();
8651		inst.currentDay = ( dates ? date.getDate() : 0 );
8652		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8653		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8654		this._adjustInstDate( inst );
8655	},
8656
8657	/* Retrieve the default date shown on opening. */
8658	_getDefaultDate: function( inst ) {
8659		return this._restrictMinMax( inst,
8660			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8661	},
8662
8663	/* A date may be specified as an exact value or a relative one. */
8664	_determineDate: function( inst, date, defaultDate ) {
8665		var offsetNumeric = function( offset ) {
8666				var date = new Date();
8667				date.setDate( date.getDate() + offset );
8668				return date;
8669			},
8670			offsetString = function( offset ) {
8671				try {
8672					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8673						offset, $.datepicker._getFormatConfig( inst ) );
8674				}
8674
8675				
vendor: 6,426 bytes, lines 8675-8849
8675catch ( e ) {
8676
8677					// Ignore
8678				}
8679
8680				var date = ( offset.toLowerCase().match( /^c/ ) ?
8681					$.datepicker._getDate( inst ) : null ) || new Date(),
8682					year = date.getFullYear(),
8683					month = date.getMonth(),
8684					day = date.getDate(),
8685					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8686					matches = pattern.exec( offset );
8687
8688				while ( matches ) {
8689					switch ( matches[ 2 ] || "d" ) {
8690						case "d" : case "D" :
8691							day += parseInt( matches[ 1 ], 10 ); break;
8692						case "w" : case "W" :
8693							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8694						case "m" : case "M" :
8695							month += parseInt( matches[ 1 ], 10 );
8696							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8697							break;
8698						case "y": case "Y" :
8699							year += parseInt( matches[ 1 ], 10 );
8700							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8701							break;
8702					}
8703					matches = pattern.exec( offset );
8704				}
8705				return new Date( year, month, day );
8706			},
8707			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8708				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8709
8710		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8711		if ( newDate ) {
8712			newDate.setHours( 0 );
8713			newDate.setMinutes( 0 );
8714			newDate.setSeconds( 0 );
8715			newDate.setMilliseconds( 0 );
8716		}
8717		return this._daylightSavingAdjust( newDate );
8718	},
8719
8720	/* Handle switch to/from daylight saving.
8721	 * Hours may be non-zero on daylight saving cut-over:
8722	 * > 12 when midnight changeover, but then cannot generate
8723	 * midnight datetime, so jump to 1AM, otherwise reset.
8724	 * @param  date  (Date) the date to check
8725	 * @return  (Date) the corrected date
8726	 */
8727	_daylightSavingAdjust: function( date ) {
8728		if ( !date ) {
8729			return null;
8730		}
8731		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8732		return date;
8733	},
8734
8735	/* Set the date(s) directly. */
8736	_setDate: function( inst, date, noChange ) {
8737		var clear = !date,
8738			origMonth = inst.selectedMonth,
8739			origYear = inst.selectedYear,
8740			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8741
8742		inst.selectedDay = inst.currentDay = newDate.getDate();
8743		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8744		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8745		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8746			this._notifyChange( inst );
8747		}
8748		this._adjustInstDate( inst );
8749		if ( inst.input ) {
8750			inst.input.val( clear ? "" : this._formatDate( inst ) );
8751		}
8752	},
8753
8754	/* Retrieve the date(s) directly. */
8755	_getDate: function( inst ) {
8756		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8757			this._daylightSavingAdjust( new Date(
8758			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8759			return startDate;
8760	},
8761
8762	/* Attach the onxxx handlers.  These are declared statically so
8763	 * they work with static code transformers like Caja.
8764	 */
8765	_attachHandlers: function( inst ) {
8766		var stepMonths = this._get( inst, "stepMonths" ),
8767			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8768		inst.dpDiv.find( "[data-handler]" ).map( function() {
8769			var handler = {
8770				prev: function() {
8771					$.datepicker._adjustDate( id, -stepMonths, "M" );
8772				},
8773				next: function() {
8774					$.datepicker._adjustDate( id, +stepMonths, "M" );
8775				},
8776				hide: function() {
8777					$.datepicker._hideDatepicker();
8778				},
8779				today: function() {
8780					$.datepicker._gotoToday( id );
8781				},
8782				selectDay: function() {
8783					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8784					return false;
8785				},
8786				selectMonth: function() {
8787					$.datepicker._selectMonthYear( id, this, "M" );
8788					return false;
8789				},
8790				selectYear: function() {
8791					$.datepicker._selectMonthYear( id, this, "Y" );
8792					return false;
8793				}
8794			};
8795			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8796		} );
8797	},
8798
8799	/* Generate the HTML for the current state of the date picker. */
8800	_generateHTML: function( inst ) {
8801		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8802			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8803			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8804			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8805			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8806			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8807			tempDate = new Date(),
8808			today = this._daylightSavingAdjust(
8809				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8810			isRTL = this._get( inst, "isRTL" ),
8811			showButtonPanel = this._get( inst, "showButtonPanel" ),
8812			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8813			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8814			numMonths = this._getNumberOfMonths( inst ),
8815			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8816			stepMonths = this._get( inst, "stepMonths" ),
8817			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8818			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8819				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8820			minDate = this._getMinMaxDate( inst, "min" ),
8821			maxDate = this._getMinMaxDate( inst, "max" ),
8822			drawMonth = inst.drawMonth - showCurrentAtPos,
8823			drawYear = inst.drawYear;
8824
8825		if ( drawMonth < 0 ) {
8826			drawMonth += 12;
8827			drawYear--;
8828		}
8829		if ( maxDate ) {
8830			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8831				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8832			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8833			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8834				drawMonth--;
8835				if ( drawMonth < 0 ) {
8836					drawMonth = 11;
8837					drawYear--;
8838				}
8839			}
8840		}
8841		inst.drawMonth = drawMonth;
8842		inst.drawYear = drawYear;
8843
8844		prevText = this._get( inst, "prevText" );
8845		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8846			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8847			this._getFormatConfig( inst ) ) );
8848
8849		
vendor: 3,273 bytes, lines 8849-8901
8849prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8850			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8851			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8852			( 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>" ) );
8853
8854		nextText = this._get( inst, "nextText" );
8855		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8856			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8857			this._getFormatConfig( inst ) ) );
8858
8859		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8860			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8861			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8862			( 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>" ) );
8863
8864		currentText = this._get( inst, "currentText" );
8865		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8866		currentText = ( !navigationAsDateFormat ? currentText :
8867			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8868
8869		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'>" +
8870			this._get( inst, "closeText" ) + "</button>" : "" );
8871
8872		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8873			( 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'" +
8874			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8875
8876		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8877		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8878
8879		showWeek = this._get( inst, "showWeek" );
8880		dayNames = this._get( inst, "dayNames" );
8881		dayNamesMin = this._get( inst, "dayNamesMin" );
8882		monthNames = this._get( inst, "monthNames" );
8883		monthNamesShort = this._get( inst, "monthNamesShort" );
8884		beforeShowDay = this._get( inst, "beforeShowDay" );
8885		showOtherMonths = this._get( inst, "showOtherMonths" );
8886		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8887		defaultDate = this._getDefaultDate( inst );
8888		html = "";
8889
8890		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8891			group = "";
8892			this.maxRows = 4;
8893			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8894				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8895				cornerClass = " ui-corner-all";
8896				calender = "";
8897				if ( isMultiMonth ) {
8898					calender += "<div class='ui-datepicker-group";
8899					if ( numMonths[ 1 ] > 1 ) {
8900						switch ( col ) {
8901							case 0: calender += " ui-datepicker-group-first";
vendor: 5,222 bytes, lines 8902-8980
8902								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8903							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8904								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8905							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8906						}
8907					}
8908					calender += "'>";
8909				}
8910				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8911					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8912					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8913					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8914					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8915					"</div><table class='ui-datepicker-calendar'><thead>" +
8916					"<tr>";
8917				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8918				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8919					day = ( dow + firstDay ) % 7;
8920					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8921						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8922				}
8923				calender += thead + "</tr></thead><tbody>";
8924				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8925				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8926					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8927				}
8928				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8929				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8930				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8931				this.maxRows = numRows;
8932				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8933				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8934					calender += "<tr>";
8935					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8936						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8937					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8938						daySettings = ( beforeShowDay ?
8939							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8940						otherMonth = ( printDate.getMonth() !== drawMonth );
8941						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8942							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8943						tbody += "<td class='" +
8944							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8945							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8946							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8947							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8948
8949							// or defaultDate is current printedDate and defaultDate is selectedDate
8950							" " + this._dayOverClass : "" ) + // highlight selected day
8951							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8952							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8953							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8954							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8955							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8956							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8957							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8958							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8959							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8960							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8961							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8962							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8963						printDate.setDate( printDate.getDate() + 1 );
8964						printDate = this._daylightSavingAdjust( printDate );
8965					}
8966					calender += tbody + "</tr>";
8967				}
8968				drawMonth++;
8969				if ( drawMonth > 11 ) {
8970					drawMonth = 0;
8971					drawYear++;
8972				}
8973				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8974							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8975				group += calender;
8976			}
8977			html += group;
8978		}
8979		html += buttonPanel;
8980		inst._keyEvent = false;
vendor: 10,686 bytes, lines 8981-9256
8981		return html;
8982	},
8983
8984	/* Generate the month and year header. */
8985	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8986			secondary, monthNames, monthNamesShort ) {
8987
8988		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8989			changeMonth = this._get( inst, "changeMonth" ),
8990			changeYear = this._get( inst, "changeYear" ),
8991			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8992			html = "<div class='ui-datepicker-title'>",
8993			monthHtml = "";
8994
8995		// Month selection
8996		if ( secondary || !changeMonth ) {
8997			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
8998		} else {
8999			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9000			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9001			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9002			for ( month = 0; month < 12; month++ ) {
9003				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9004					monthHtml += "<option value='" + month + "'" +
9005						( month === drawMonth ? " selected='selected'" : "" ) +
9006						">" + monthNamesShort[ month ] + "</option>";
9007				}
9008			}
9009			monthHtml += "</select>";
9010		}
9011
9012		if ( !showMonthAfterYear ) {
9013			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9014		}
9015
9016		// Year selection
9017		if ( !inst.yearshtml ) {
9018			inst.yearshtml = "";
9019			if ( secondary || !changeYear ) {
9020				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9021			} else {
9022
9023				// determine range of years to display
9024				years = this._get( inst, "yearRange" ).split( ":" );
9025				thisYear = new Date().getFullYear();
9026				determineYear = function( value ) {
9027					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9028						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9029						parseInt( value, 10 ) ) );
9030					return ( isNaN( year ) ? thisYear : year );
9031				};
9032				year = determineYear( years[ 0 ] );
9033				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9034				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9035				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9036				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9037				for ( ; year <= endYear; year++ ) {
9038					inst.yearshtml += "<option value='" + year + "'" +
9039						( year === drawYear ? " selected='selected'" : "" ) +
9040						">" + year + "</option>";
9041				}
9042				inst.yearshtml += "</select>";
9043
9044				html += inst.yearshtml;
9045				inst.yearshtml = null;
9046			}
9047		}
9048
9049		html += this._get( inst, "yearSuffix" );
9050		if ( showMonthAfterYear ) {
9051			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9052		}
9053		html += "</div>"; // Close datepicker_header
9054		return html;
9055	},
9056
9057	/* Adjust one of the date sub-fields. */
9058	_adjustInstDate: function( inst, offset, period ) {
9059		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9060			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9061			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9062			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9063
9064		inst.selectedDay = date.getDate();
9065		inst.drawMonth = inst.selectedMonth = date.getMonth();
9066		inst.drawYear = inst.selectedYear = date.getFullYear();
9067		if ( period === "M" || period === "Y" ) {
9068			this._notifyChange( inst );
9069		}
9070	},
9071
9072	/* Ensure a date is within any min/max bounds. */
9073	_restrictMinMax: function( inst, date ) {
9074		var minDate = this._getMinMaxDate( inst, "min" ),
9075			maxDate = this._getMinMaxDate( inst, "max" ),
9076			newDate = ( minDate && date < minDate ? minDate : date );
9077		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9078	},
9079
9080	/* Notify change of month/year. */
9081	_notifyChange: function( inst ) {
9082		var onChange = this._get( inst, "onChangeMonthYear" );
9083		if ( onChange ) {
9084			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9085				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9086		}
9087	},
9088
9089	/* Determine the number of months to show. */
9090	_getNumberOfMonths: function( inst ) {
9091		var numMonths = this._get( inst, "numberOfMonths" );
9092		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9093	},
9094
9095	/* Determine the current maximum date - ensure no time components are set. */
9096	_getMinMaxDate: function( inst, minMax ) {
9097		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9098	},
9099
9100	/* Find the number of days in a given month. */
9101	_getDaysInMonth: function( year, month ) {
9102		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9103	},
9104
9105	/* Find the day of the week of the first of a month. */
9106	_getFirstDayOfMonth: function( year, month ) {
9107		return new Date( year, month, 1 ).getDay();
9108	},
9109
9110	/* Determines if we should allow a "next/prev" month display change. */
9111	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9112		var numMonths = this._getNumberOfMonths( inst ),
9113			date = this._daylightSavingAdjust( new Date( curYear,
9114			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9115
9116		if ( offset < 0 ) {
9117			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9118		}
9119		return this._isInRange( inst, date );
9120	},
9121
9122	/* Is the given date in the accepted range? */
9123	_isInRange: function( inst, date ) {
9124		var yearSplit, currentYear,
9125			minDate = this._getMinMaxDate( inst, "min" ),
9126			maxDate = this._getMinMaxDate( inst, "max" ),
9127			minYear = null,
9128			maxYear = null,
9129			years = this._get( inst, "yearRange" );
9130			if ( years ) {
9131				yearSplit = years.split( ":" );
9132				currentYear = new Date().getFullYear();
9133				minYear = parseInt( yearSplit[ 0 ], 10 );
9134				maxYear = parseInt( yearSplit[ 1 ], 10 );
9135				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9136					minYear += currentYear;
9137				}
9138				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9139					maxYear += currentYear;
9140				}
9141			}
9142
9143		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9144			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9145			( !minYear || date.getFullYear() >= minYear ) &&
9146			( !maxYear || date.getFullYear() <= maxYear ) );
9147	},
9148
9149	/* Provide the configuration settings for formatting/parsing. */
9150	_getFormatConfig: function( inst ) {
9151		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9152		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9153			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9154		return { shortYearCutoff: shortYearCutoff,
9155			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9156			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9157	},
9158
9159	/* Format the given date for display. */
9160	_formatDate: function( inst, day, month, year ) {
9161		if ( !day ) {
9162			inst.currentDay = inst.selectedDay;
9163			inst.currentMonth = inst.selectedMonth;
9164			inst.currentYear = inst.selectedYear;
9165		}
9166		var date = ( day ? ( typeof day === "object" ? day :
9167			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9168			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9169		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9170	}
9171} );
9172
9173/*
9174 * Bind hover events for datepicker elements.
9175 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9176 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9177 */
9178function datepicker_bindHover( dpDiv ) {
9179	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9180	return dpDiv.on( "mouseout", selector, function() {
9181			$( this ).removeClass( "ui-state-hover" );
9182			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9183				$( this ).removeClass( "ui-datepicker-prev-hover" );
9184			}
9185			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9186				$( this ).removeClass( "ui-datepicker-next-hover" );
9187			}
9188		} )
9189		.on( "mouseover", selector, datepicker_handleMouseover );
9190}
9191
9192function datepicker_handleMouseover() {
9193	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9194		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9195		$( this ).addClass( "ui-state-hover" );
9196		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9197			$( this ).addClass( "ui-datepicker-prev-hover" );
9198		}
9199		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9200			$( this ).addClass( "ui-datepicker-next-hover" );
9201		}
9202	}
9203}
9204
9205/* jQuery extend now ignores nulls! */
9206function datepicker_extendRemove( target, props ) {
9207	$.extend( target, props );
9208	for ( var name in props ) {
9209		if ( props[ name ] == null ) {
9210			target[ name ] = props[ name ];
9211		}
9212	}
9213	return target;
9214}
9215
9216/* Invoke the datepicker functionality.
9217   @param  options  string - a command, optionally followed by additional parameters or
9218					Object - settings for attaching new datepicker functionality
9219   @return  jQuery object */
9220$.fn.datepicker = function( options ) {
9221
9222	/* Verify an empty collection wasn't passed - Fixes #6976 */
9223	if ( !this.length ) {
9224		return this;
9225	}
9226
9227	/* Initialise the date picker. */
9228	if ( !$.datepicker.initialized ) {
9229		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9230		$.datepicker.initialized = true;
9231	}
9232
9233	/* Append datepicker main container to body if not exist. */
9234	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9235		$( "body" ).append( $.datepicker.dpDiv );
9236	}
9237
9238	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9239	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9240		return $.datepicker[ "_" + options + "Datepicker" ].
9241			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9242	}
9243	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9244		return $.datepicker[ "_" + options + "Datepicker" ].
9245			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9246	}
9247	return this.each( function() {
9248		typeof options === "string" ?
9249			$.datepicker[ "_" + options + "Datepicker" ].
9250				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9251			$.datepicker._attachDatepicker( this, options );
9252	} );
9253};
9254
9255$.datepicker = new Datepicker(); // singleton instance
9256$.datepicker.initialized = false;
vendor: 11,871 bytes, lines 9257-9716
9257$.datepicker.uuid = new Date().getTime();
9258$.datepicker.version = "1.12.0";
9259
9260var widgetsDatepicker = $.datepicker;
9261
9262
9263
9264
9265// This file is deprecated
9266var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9267
9268/*!
9269 * jQuery UI Mouse 1.12.0
9270 * http://jqueryui.com
9271 *
9272 * Copyright jQuery Foundation and other contributors
9273 * Released under the MIT license.
9274 * http://jquery.org/license
9275 */
9276
9277//>>label: Mouse
9278//>>group: Widgets
9279//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9280//>>docs: http://api.jqueryui.com/mouse/
9281
9282
9283
9284var mouseHandled = false;
9285$( document ).on( "mouseup", function() {
9286	mouseHandled = false;
9287} );
9288
9289var widgetsMouse = $.widget( "ui.mouse", {
9290	version: "1.12.0",
9291	options: {
9292		cancel: "input, textarea, button, select, option",
9293		distance: 1,
9294		delay: 0
9295	},
9296	_mouseInit: function() {
9297		var that = this;
9298
9299		this.element
9300			.on( "mousedown." + this.widgetName, function( event ) {
9301				return that._mouseDown( event );
9302			} )
9303			.on( "click." + this.widgetName, function( event ) {
9304				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9305					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9306					event.stopImmediatePropagation();
9307					return false;
9308				}
9309			} );
9310
9311		this.started = false;
9312	},
9313
9314	// TODO: make sure destroying one instance of mouse doesn't mess with
9315	// other instances of mouse
9316	_mouseDestroy: function() {
9317		this.element.off( "." + this.widgetName );
9318		if ( this._mouseMoveDelegate ) {
9319			this.document
9320				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9321				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9322		}
9323	},
9324
9325	_mouseDown: function( event ) {
9326
9327		// don't let more than one widget handle mouseStart
9328		if ( mouseHandled ) {
9329			return;
9330		}
9331
9332		this._mouseMoved = false;
9333
9334		// We may have missed mouseup (out of window)
9335		( this._mouseStarted && this._mouseUp( event ) );
9336
9337		this._mouseDownEvent = event;
9338
9339		var that = this,
9340			btnIsLeft = ( event.which === 1 ),
9341
9342			// event.target.nodeName works around a bug in IE 8 with
9343			// disabled inputs (#7620)
9344			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9345				$( event.target ).closest( this.options.cancel ).length : false );
9346		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9347			return true;
9348		}
9349
9350		this.mouseDelayMet = !this.options.delay;
9351		if ( !this.mouseDelayMet ) {
9352			this._mouseDelayTimer = setTimeout( function() {
9353				that.mouseDelayMet = true;
9354			}, this.options.delay );
9355		}
9356
9357		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9358			this._mouseStarted = ( this._mouseStart( event ) !== false );
9359			if ( !this._mouseStarted ) {
9360				event.preventDefault();
9361				return true;
9362			}
9363		}
9364
9365		// Click event may never have fired (Gecko & Opera)
9366		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9367			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9368		}
9369
9370		// These delegates are required to keep context
9371		this._mouseMoveDelegate = function( event ) {
9372			return that._mouseMove( event );
9373		};
9374		this._mouseUpDelegate = function( event ) {
9375			return that._mouseUp( event );
9376		};
9377
9378		this.document
9379			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9380			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9381
9382		event.preventDefault();
9383
9384		mouseHandled = true;
9385		return true;
9386	},
9387
9388	_mouseMove: function( event ) {
9389
9390		// Only check for mouseups outside the document if you've moved inside the document
9391		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9392		// fire a mousemove event if content is placed under the cursor. See #7778
9393		// Support: IE <9
9394		if ( this._mouseMoved ) {
9395
9396			// IE mouseup check - mouseup happened when mouse was out of window
9397			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9398					!event.button ) {
9399				return this._mouseUp( event );
9400
9401			// Iframe mouseup check - mouseup occurred in another document
9402			} else if ( !event.which ) {
9403
9404				// Support: Safari <=8 - 9
9405				// Safari sets which to 0 if you press any of the following keys
9406				// during a drag (#14461)
9407				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9408						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9409					this.ignoreMissingWhich = true;
9410				} else if ( !this.ignoreMissingWhich ) {
9411					return this._mouseUp( event );
9412				}
9413			}
9414		}
9415
9416		if ( event.which || event.button ) {
9417			this._mouseMoved = true;
9418		}
9419
9420		if ( this._mouseStarted ) {
9421			this._mouseDrag( event );
9422			return event.preventDefault();
9423		}
9424
9425		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9426			this._mouseStarted =
9427				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9428			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9429		}
9430
9431		return !this._mouseStarted;
9432	},
9433
9434	_mouseUp: function( event ) {
9435		this.document
9436			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9437			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9438
9439		if ( this._mouseStarted ) {
9440			this._mouseStarted = false;
9441
9442			if ( event.target === this._mouseDownEvent.target ) {
9443				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9444			}
9445
9446			this._mouseStop( event );
9447		}
9448
9449		if ( this._mouseDelayTimer ) {
9450			clearTimeout( this._mouseDelayTimer );
9451			delete this._mouseDelayTimer;
9452		}
9453
9454		this.ignoreMissingWhich = false;
9455		mouseHandled = false;
9456		event.preventDefault();
9457	},
9458
9459	_mouseDistanceMet: function( event ) {
9460		return ( Math.max(
9461				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9462				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9463			) >= this.options.distance
9464		);
9465	},
9466
9467	_mouseDelayMet: function( /* event */ ) {
9468		return this.mouseDelayMet;
9469	},
9470
9471	// These are placeholder methods, to be overriden by extending plugin
9472	_mouseStart: function( /* event */ ) {},
9473	_mouseDrag: function( /* event */ ) {},
9474	_mouseStop: function( /* event */ ) {},
9475	_mouseCapture: function( /* event */ ) { return true; }
9476} );
9477
9478
9479
9480
9481// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9482var plugin = $.ui.plugin = {
9483	add: function( module, option, set ) {
9484		var i,
9485			proto = $.ui[ module ].prototype;
9486		for ( i in set ) {
9487			proto.plugins[ i ] = proto.plugins[ i ] || [];
9488			proto.plugins[ i ].push( [ option, set[ i ] ] );
9489		}
9490	},
9491	call: function( instance, name, args, allowDisconnected ) {
9492		var i,
9493			set = instance.plugins[ name ];
9494
9495		if ( !set ) {
9496			return;
9497		}
9498
9499		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9500				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9501			return;
9502		}
9503
9504		for ( i = 0; i < set.length; i++ ) {
9505			if ( instance.options[ set[ i ][ 0 ] ] ) {
9506				set[ i ][ 1 ].apply( instance.element, args );
9507			}
9508		}
9509	}
9510};
9511
9512
9513
9514var safeBlur = $.ui.safeBlur = function( element ) {
9515
9516	// Support: IE9 - 10 only
9517	// If the <body> is blurred, IE will switch windows, see #9420
9518	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9519		$( element ).trigger( "blur" );
9520	}
9521};
9522
9523
9524/*!
9525 * jQuery UI Draggable 1.12.0
9526 * http://jqueryui.com
9527 *
9528 * Copyright jQuery Foundation and other contributors
9529 * Released under the MIT license.
9530 * http://jquery.org/license
9531 */
9532
9533//>>label: Draggable
9534//>>group: Interactions
9535//>>description: Enables dragging functionality for any element.
9536//>>docs: http://api.jqueryui.com/draggable/
9537//>>demos: http://jqueryui.com/draggable/
9538//>>css.structure: ../../themes/base/draggable.css
9539
9540
9541
9542$.widget( "ui.draggable", $.ui.mouse, {
9543	version: "1.12.0",
9544	widgetEventPrefix: "drag",
9545	options: {
9546		addClasses: true,
9547		appendTo: "parent",
9548		axis: false,
9549		connectToSortable: false,
9550		containment: false,
9551		cursor: "auto",
9552		cursorAt: false,
9553		grid: false,
9554		handle: false,
9555		helper: "original",
9556		iframeFix: false,
9557		opacity: false,
9558		refreshPositions: false,
9559		revert: false,
9560		revertDuration: 500,
9561		scope: "default",
9562		scroll: true,
9563		scrollSensitivity: 20,
9564		scrollSpeed: 20,
9565		snap: false,
9566		snapMode: "both",
9567		snapTolerance: 20,
9568		stack: false,
9569		zIndex: false,
9570
9571		// Callbacks
9572		drag: null,
9573		start: null,
9574		stop: null
9575	},
9576	_create: function() {
9577
9578		if ( this.options.helper === "original" ) {
9579			this._setPositionRelative();
9580		}
9581		if ( this.options.addClasses ) {
9582			this._addClass( "ui-draggable" );
9583		}
9584		this._setHandleClassName();
9585
9586		this._mouseInit();
9587	},
9588
9589	_setOption: function( key, value ) {
9590		this._super( key, value );
9591		if ( key === "handle" ) {
9592			this._removeHandleClassName();
9593			this._setHandleClassName();
9594		}
9595	},
9596
9597	_destroy: function() {
9598		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9599			this.destroyOnClear = true;
9600			return;
9601		}
9602		this._removeHandleClassName();
9603		this._mouseDestroy();
9604	},
9605
9606	_mouseCapture: function( event ) {
9607		var o = this.options;
9608
9609		this._blurActiveElement( event );
9610
9611		// Among others, prevent a drag on a resizable-handle
9612		if ( this.helper || o.disabled ||
9613				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9614			return false;
9615		}
9616
9617		//Quit if we're not on a valid handle
9618		this.handle = this._getHandle( event );
9619		if ( !this.handle ) {
9620			return false;
9621		}
9622
9623		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9624
9625		return true;
9626
9627	},
9628
9629	_blockFrames: function( selector ) {
9630		this.iframeBlocks = this.document.find( selector ).map( function() {
9631			var iframe = $( this );
9632
9633			return $( "<div>" )
9634				.css( "position", "absolute" )
9635				.appendTo( iframe.parent() )
9636				.outerWidth( iframe.outerWidth() )
9637				.outerHeight( iframe.outerHeight() )
9638				.offset( iframe.offset() )[ 0 ];
9639		} );
9640	},
9641
9642	_unblockFrames: function() {
9643		if ( this.iframeBlocks ) {
9644			this.iframeBlocks.remove();
9645			delete this.iframeBlocks;
9646		}
9647	},
9648
9649	_blurActiveElement: function( event ) {
9650		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9651			target = $( event.target );
9652
9653		// Only blur if the event occurred on an element that is:
9654		// 1) within the draggable handle
9655		// 2) but not within the currently focused element
9656		// See #10527, #12472
9657		if ( this._getHandle( event ) && target.closest( activeElement ).length ) {
9658			return;
9659		}
9660
9661		// Blur any element that currently has focus, see #4261
9662		$.ui.safeBlur( activeElement );
9663	},
9664
9665	_mouseStart: function( event ) {
9666
9667		var o = this.options;
9668
9669		//Create and append the visible helper
9670		this.helper = this._createHelper( event );
9671
9672		this._addClass( this.helper, "ui-draggable-dragging" );
9673
9674		//Cache the helper size
9675		this._cacheHelperProportions();
9676
9677		//If ddmanager is used for droppables, set the global draggable
9678		if ( $.ui.ddmanager ) {
9679			$.ui.ddmanager.current = this;
9680		}
9681
9682		/*
9683		 * - Position generation -
9684		 * This block generates everything position related - it's the core of draggables.
9685		 */
9686
9687		//Cache the margins of the original element
9688		this._cacheMargins();
9689
9690		//Store the helper's css position
9691		this.cssPosition = this.helper.css( "position" );
9692		this.scrollParent = this.helper.scrollParent( true );
9693		this.offsetParent = this.helper.offsetParent();
9694		this.hasFixedAncestor = this.helper.parents().filter( function() {
9695				return $( this ).css( "position" ) === "fixed";
9696			} ).length > 0;
9697
9698		//The element's absolute position on the page minus margins
9699		this.positionAbs = this.element.offset();
9700		this._refreshOffsets( event );
9701
9702		//Generate the original position
9703		this.originalPosition = this.position = this._generatePosition( event, false );
9704		this.originalPageX = event.pageX;
9705		this.originalPageY = event.pageY;
9706
9707		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9708		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9709
9710		//Set a containment if given in the options
9711		this._setContainment();
9712
9713		//Trigger event + callbacks
9714		if ( this._trigger( "start", event ) === false ) {
9715			this._clear();
9716			return false;
vendor: 5,171 bytes, lines 9717-9914
9717		}
9718
9719		//Recache the helper size
9720		this._cacheHelperProportions();
9721
9722		//Prepare the droppable offsets
9723		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9724			$.ui.ddmanager.prepareOffsets( this, event );
9725		}
9726
9727		// Execute the drag once - this causes the helper not to be visible before getting its
9728		// correct position
9729		this._mouseDrag( event, true );
9730
9731		// If the ddmanager is used for droppables, inform the manager that dragging has started
9732		// (see #5003)
9733		if ( $.ui.ddmanager ) {
9734			$.ui.ddmanager.dragStart( this, event );
9735		}
9736
9737		return true;
9738	},
9739
9740	_refreshOffsets: function( event ) {
9741		this.offset = {
9742			top: this.positionAbs.top - this.margins.top,
9743			left: this.positionAbs.left - this.margins.left,
9744			scroll: false,
9745			parent: this._getParentOffset(),
9746			relative: this._getRelativeOffset()
9747		};
9748
9749		this.offset.click = {
9750			left: event.pageX - this.offset.left,
9751			top: event.pageY - this.offset.top
9752		};
9753	},
9754
9755	_mouseDrag: function( event, noPropagation ) {
9756
9757		// reset any necessary cached properties (see #5009)
9758		if ( this.hasFixedAncestor ) {
9759			this.offset.parent = this._getParentOffset();
9760		}
9761
9762		//Compute the helpers position
9763		this.position = this._generatePosition( event, true );
9764		this.positionAbs = this._convertPositionTo( "absolute" );
9765
9766		//Call plugins and callbacks and use the resulting position if something is returned
9767		if ( !noPropagation ) {
9768			var ui = this._uiHash();
9769			if ( this._trigger( "drag", event, ui ) === false ) {
9770				this._mouseUp( new $.Event( "mouseup", event ) );
9771				return false;
9772			}
9773			this.position = ui.position;
9774		}
9775
9776		this.helper[ 0 ].style.left = this.position.left + "px";
9777		this.helper[ 0 ].style.top = this.position.top + "px";
9778
9779		if ( $.ui.ddmanager ) {
9780			$.ui.ddmanager.drag( this, event );
9781		}
9782
9783		return false;
9784	},
9785
9786	_mouseStop: function( event ) {
9787
9788		//If we are using droppables, inform the manager about the drop
9789		var that = this,
9790			dropped = false;
9791		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9792			dropped = $.ui.ddmanager.drop( this, event );
9793		}
9794
9795		//if a drop comes from outside (a sortable)
9796		if ( this.dropped ) {
9797			dropped = this.dropped;
9798			this.dropped = false;
9799		}
9800
9801		if ( ( this.options.revert === "invalid" && !dropped ) ||
9802				( this.options.revert === "valid" && dropped ) ||
9803				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9804				this.options.revert.call( this.element, dropped ) )
9805		) {
9806			$( this.helper ).animate(
9807				this.originalPosition,
9808				parseInt( this.options.revertDuration, 10 ),
9809				function() {
9810					if ( that._trigger( "stop", event ) !== false ) {
9811						that._clear();
9812					}
9813				}
9814			);
9815		} else {
9816			if ( this._trigger( "stop", event ) !== false ) {
9817				this._clear();
9818			}
9819		}
9820
9821		return false;
9822	},
9823
9824	_mouseUp: function( event ) {
9825		this._unblockFrames();
9826
9827		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9828		// (see #5003)
9829		if ( $.ui.ddmanager ) {
9830			$.ui.ddmanager.dragStop( this, event );
9831		}
9832
9833		// Only need to focus if the event occurred on the draggable itself, see #10527
9834		if ( this.handleElement.is( event.target ) ) {
9835
9836			// The interaction is over; whether or not the click resulted in a drag,
9837			// focus the element
9838			this.element.trigger( "focus" );
9839		}
9840
9841		return $.ui.mouse.prototype._mouseUp.call( this, event );
9842	},
9843
9844	cancel: function() {
9845
9846		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9847			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9848		} else {
9849			this._clear();
9850		}
9851
9852		return this;
9853
9854	},
9855
9856	_getHandle: function( event ) {
9857		return this.options.handle ?
9858			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9859			true;
9860	},
9861
9862	_setHandleClassName: function() {
9863		this.handleElement = this.options.handle ?
9864			this.element.find( this.options.handle ) : this.element;
9865		this._addClass( this.handleElement, "ui-draggable-handle" );
9866	},
9867
9868	_removeHandleClassName: function() {
9869		this._removeClass( this.handleElement, "ui-draggable-handle" );
9870	},
9871
9872	_createHelper: function( event ) {
9873
9874		var o = this.options,
9875			helperIsFunction = $.isFunction( o.helper ),
9876			helper = helperIsFunction ?
9877				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9878				( o.helper === "clone" ?
9879					this.element.clone().removeAttr( "id" ) :
9880					this.element );
9881
9882		if ( !helper.parents( "body" ).length ) {
9883			helper.appendTo( ( o.appendTo === "parent" ?
9884				this.element[ 0 ].parentNode :
9885				o.appendTo ) );
9886		}
9887
9888		// Http://bugs.jqueryui.com/ticket/9446
9889		// a helper function can return the original element
9890		// which wouldn't have been set to relative in _create
9891		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9892			this._setPositionRelative();
9893		}
9894
9895		if ( helper[ 0 ] !== this.element[ 0 ] &&
9896				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9897			helper.css( "position", "absolute" );
9898		}
9899
9900		return helper;
9901
9902	},
9903
9904	_setPositionRelative: function() {
9905		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9906			this.element[ 0 ].style.position = "relative";
9907		}
9908	},
9909
9910	_adjustOffsetFromHelper: function( obj ) {
9911		if ( typeof obj === "string" ) {
9912			obj = obj.split( " " );
9913		}
9914		if ( $
vendor: 22,091 bytes, lines 9914-10623
9914.isArray( obj ) ) {
9915			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9916		}
9917		if ( "left" in obj ) {
9918			this.offset.click.left = obj.left + this.margins.left;
9919		}
9920		if ( "right" in obj ) {
9921			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9922		}
9923		if ( "top" in obj ) {
9924			this.offset.click.top = obj.top + this.margins.top;
9925		}
9926		if ( "bottom" in obj ) {
9927			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9928		}
9929	},
9930
9931	_isRootNode: function( element ) {
9932		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9933	},
9934
9935	_getParentOffset: function() {
9936
9937		//Get the offsetParent and cache its position
9938		var po = this.offsetParent.offset(),
9939			document = this.document[ 0 ];
9940
9941		// This is a special case where we need to modify a offset calculated on start, since the
9942		// following happened:
9943		// 1. The position of the helper is absolute, so it's position is calculated based on the
9944		// next positioned parent
9945		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9946		// the document, which means that the scroll is included in the initial calculation of the
9947		// offset of the parent, and never recalculated upon drag
9948		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9949				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9950			po.left += this.scrollParent.scrollLeft();
9951			po.top += this.scrollParent.scrollTop();
9952		}
9953
9954		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9955			po = { top: 0, left: 0 };
9956		}
9957
9958		return {
9959			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9960			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9961		};
9962
9963	},
9964
9965	_getRelativeOffset: function() {
9966		if ( this.cssPosition !== "relative" ) {
9967			return { top: 0, left: 0 };
9968		}
9969
9970		var p = this.element.position(),
9971			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9972
9973		return {
9974			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9975				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9976			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9977				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9978		};
9979
9980	},
9981
9982	_cacheMargins: function() {
9983		this.margins = {
9984			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9985			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9986			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9987			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9988		};
9989	},
9990
9991	_cacheHelperProportions: function() {
9992		this.helperProportions = {
9993			width: this.helper.outerWidth(),
9994			height: this.helper.outerHeight()
9995		};
9996	},
9997
9998	_setContainment: function() {
9999
10000		var isUserScrollable, c, ce,
10001			o = this.options,
10002			document = this.document[ 0 ];
10003
10004		this.relativeContainer = null;
10005
10006		if ( !o.containment ) {
10007			this.containment = null;
10008			return;
10009		}
10010
10011		if ( o.containment === "window" ) {
10012			this.containment = [
10013				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10014				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10015				$( window ).scrollLeft() + $( window ).width() -
10016					this.helperProportions.width - this.margins.left,
10017				$( window ).scrollTop() +
10018					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10019					this.helperProportions.height - this.margins.top
10020			];
10021			return;
10022		}
10023
10024		if ( o.containment === "document" ) {
10025			this.containment = [
10026				0,
10027				0,
10028				$( document ).width() - this.helperProportions.width - this.margins.left,
10029				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10030					this.helperProportions.height - this.margins.top
10031			];
10032			return;
10033		}
10034
10035		if ( o.containment.constructor === Array ) {
10036			this.containment = o.containment;
10037			return;
10038		}
10039
10040		if ( o.containment === "parent" ) {
10041			o.containment = this.helper[ 0 ].parentNode;
10042		}
10043
10044		c = $( o.containment );
10045		ce = c[ 0 ];
10046
10047		if ( !ce ) {
10048			return;
10049		}
10050
10051		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10052
10053		this.containment = [
10054			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10055				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10056			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10057				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10058			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10059				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10060				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10061				this.helperProportions.width -
10062				this.margins.left -
10063				this.margins.right,
10064			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10065				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10066				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10067				this.helperProportions.height -
10068				this.margins.top -
10069				this.margins.bottom
10070		];
10071		this.relativeContainer = c;
10072	},
10073
10074	_convertPositionTo: function( d, pos ) {
10075
10076		if ( !pos ) {
10077			pos = this.position;
10078		}
10079
10080		var mod = d === "absolute" ? 1 : -1,
10081			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10082
10083		return {
10084			top: (
10085
10086				// The absolute mouse position
10087				pos.top	+
10088
10089				// Only for relative positioned nodes: Relative offset from element to offset parent
10090				this.offset.relative.top * mod +
10091
10092				// The offsetParent's offset without borders (offset + border)
10093				this.offset.parent.top * mod -
10094				( ( this.cssPosition === "fixed" ?
10095					-this.offset.scroll.top :
10096					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10097			),
10098			left: (
10099
10100				// The absolute mouse position
10101				pos.left +
10102
10103				// Only for relative positioned nodes: Relative offset from element to offset parent
10104				this.offset.relative.left * mod +
10105
10106				// The offsetParent's offset without borders (offset + border)
10107				this.offset.parent.left * mod	-
10108				( ( this.cssPosition === "fixed" ?
10109					-this.offset.scroll.left :
10110					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10111			)
10112		};
10113
10114	},
10115
10116	_generatePosition: function( event, constrainPosition ) {
10117
10118		var containment, co, top, left,
10119			o = this.options,
10120			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10121			pageX = event.pageX,
10122			pageY = event.pageY;
10123
10124		// Cache the scroll
10125		if ( !scrollIsRootNode || !this.offset.scroll ) {
10126			this.offset.scroll = {
10127				top: this.scrollParent.scrollTop(),
10128				left: this.scrollParent.scrollLeft()
10129			};
10130		}
10131
10132		/*
10133		 * - Position constraining -
10134		 * Constrain the position to a mix of grid, containment.
10135		 */
10136
10137		// If we are not dragging yet, we won't check for options
10138		if ( constrainPosition ) {
10139			if ( this.containment ) {
10140				if ( this.relativeContainer ) {
10141					co = this.relativeContainer.offset();
10142					containment = [
10143						this.containment[ 0 ] + co.left,
10144						this.containment[ 1 ] + co.top,
10145						this.containment[ 2 ] + co.left,
10146						this.containment[ 3 ] + co.top
10147					];
10148				} else {
10149					containment = this.containment;
10150				}
10151
10152				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10153					pageX = containment[ 0 ] + this.offset.click.left;
10154				}
10155				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10156					pageY = containment[ 1 ] + this.offset.click.top;
10157				}
10158				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10159					pageX = containment[ 2 ] + this.offset.click.left;
10160				}
10161				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10162					pageY = containment[ 3 ] + this.offset.click.top;
10163				}
10164			}
10165
10166			if ( o.grid ) {
10167
10168				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10169				// argument errors in IE (see ticket #6950)
10170				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10171					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10172				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10173					top - this.offset.click.top > containment[ 3 ] ) ?
10174						top :
10175						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10176							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10177
10178				left = o.grid[ 0 ] ? this.originalPageX +
10179					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10180					this.originalPageX;
10181				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10182					left - this.offset.click.left > containment[ 2 ] ) ?
10183						left :
10184						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10185							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10186			}
10187
10188			if ( o.axis === "y" ) {
10189				pageX = this.originalPageX;
10190			}
10191
10192			if ( o.axis === "x" ) {
10193				pageY = this.originalPageY;
10194			}
10195		}
10196
10197		return {
10198			top: (
10199
10200				// The absolute mouse position
10201				pageY -
10202
10203				// Click offset (relative to the element)
10204				this.offset.click.top -
10205
10206				// Only for relative positioned nodes: Relative offset from element to offset parent
10207				this.offset.relative.top -
10208
10209				// The offsetParent's offset without borders (offset + border)
10210				this.offset.parent.top +
10211				( this.cssPosition === "fixed" ?
10212					-this.offset.scroll.top :
10213					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10214			),
10215			left: (
10216
10217				// The absolute mouse position
10218				pageX -
10219
10220				// Click offset (relative to the element)
10221				this.offset.click.left -
10222
10223				// Only for relative positioned nodes: Relative offset from element to offset parent
10224				this.offset.relative.left -
10225
10226				// The offsetParent's offset without borders (offset + border)
10227				this.offset.parent.left +
10228				( this.cssPosition === "fixed" ?
10229					-this.offset.scroll.left :
10230					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10231			)
10232		};
10233
10234	},
10235
10236	_clear: function() {
10237		this._removeClass( this.helper, "ui-draggable-dragging" );
10238		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10239			this.helper.remove();
10240		}
10241		this.helper = null;
10242		this.cancelHelperRemoval = false;
10243		if ( this.destroyOnClear ) {
10244			this.destroy();
10245		}
10246	},
10247
10248	// From now on bulk stuff - mainly helpers
10249
10250	_trigger: function( type, event, ui ) {
10251		ui = ui || this._uiHash();
10252		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10253
10254		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10255		if ( /^(drag|start|stop)/.test( type ) ) {
10256			this.positionAbs = this._convertPositionTo( "absolute" );
10257			ui.offset = this.positionAbs;
10258		}
10259		return $.Widget.prototype._trigger.call( this, type, event, ui );
10260	},
10261
10262	plugins: {},
10263
10264	_uiHash: function() {
10265		return {
10266			helper: this.helper,
10267			position: this.position,
10268			originalPosition: this.originalPosition,
10269			offset: this.positionAbs
10270		};
10271	}
10272
10273} );
10274
10275$.ui.plugin.add( "draggable", "connectToSortable", {
10276	start: function( event, ui, draggable ) {
10277		var uiSortable = $.extend( {}, ui, {
10278			item: draggable.element
10279		} );
10280
10281		draggable.sortables = [];
10282		$( draggable.options.connectToSortable ).each( function() {
10283			var sortable = $( this ).sortable( "instance" );
10284
10285			if ( sortable && !sortable.options.disabled ) {
10286				draggable.sortables.push( sortable );
10287
10288				// RefreshPositions is called at drag start to refresh the containerCache
10289				// which is used in drag. This ensures it's initialized and synchronized
10290				// with any changes that might have happened on the page since initialization.
10291				sortable.refreshPositions();
10292				sortable._trigger( "activate", event, uiSortable );
10293			}
10294		} );
10295	},
10296	stop: function( event, ui, draggable ) {
10297		var uiSortable = $.extend( {}, ui, {
10298			item: draggable.element
10299		} );
10300
10301		draggable.cancelHelperRemoval = false;
10302
10303		$.each( draggable.sortables, function() {
10304			var sortable = this;
10305
10306			if ( sortable.isOver ) {
10307				sortable.isOver = 0;
10308
10309				// Allow this sortable to handle removing the helper
10310				draggable.cancelHelperRemoval = true;
10311				sortable.cancelHelperRemoval = false;
10312
10313				// Use _storedCSS To restore properties in the sortable,
10314				// as this also handles revert (#9675) since the draggable
10315				// may have modified them in unexpected ways (#8809)
10316				sortable._storedCSS = {
10317					position: sortable.placeholder.css( "position" ),
10318					top: sortable.placeholder.css( "top" ),
10319					left: sortable.placeholder.css( "left" )
10320				};
10321
10322				sortable._mouseStop( event );
10323
10324				// Once drag has ended, the sortable should return to using
10325				// its original helper, not the shared helper from draggable
10326				sortable.options.helper = sortable.options._helper;
10327			} else {
10328
10329				// Prevent this Sortable from removing the helper.
10330				// However, don't set the draggable to remove the helper
10331				// either as another connected Sortable may yet handle the removal.
10332				sortable.cancelHelperRemoval = true;
10333
10334				sortable._trigger( "deactivate", event, uiSortable );
10335			}
10336		} );
10337	},
10338	drag: function( event, ui, draggable ) {
10339		$.each( draggable.sortables, function() {
10340			var innermostIntersecting = false,
10341				sortable = this;
10342
10343			// Copy over variables that sortable's _intersectsWith uses
10344			sortable.positionAbs = draggable.positionAbs;
10345			sortable.helperProportions = draggable.helperProportions;
10346			sortable.offset.click = draggable.offset.click;
10347
10348			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10349				innermostIntersecting = true;
10350
10351				$.each( draggable.sortables, function() {
10352
10353					// Copy over variables that sortable's _intersectsWith uses
10354					this.positionAbs = draggable.positionAbs;
10355					this.helperProportions = draggable.helperProportions;
10356					this.offset.click = draggable.offset.click;
10357
10358					if ( this !== sortable &&
10359							this._intersectsWith( this.containerCache ) &&
10360							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10361						innermostIntersecting = false;
10362					}
10363
10364					return innermostIntersecting;
10365				} );
10366			}
10367
10368			if ( innermostIntersecting ) {
10369
10370				// If it intersects, we use a little isOver variable and set it once,
10371				// so that the move-in stuff gets fired only once.
10372				if ( !sortable.isOver ) {
10373					sortable.isOver = 1;
10374
10375					// Store draggable's parent in case we need to reappend to it later.
10376					draggable._parent = ui.helper.parent();
10377
10378					sortable.currentItem = ui.helper
10379						.appendTo( sortable.element )
10380						.data( "ui-sortable-item", true );
10381
10382					// Store helper option to later restore it
10383					sortable.options._helper = sortable.options.helper;
10384
10385					sortable.options.helper = function() {
10386						return ui.helper[ 0 ];
10387					};
10388
10389					// Fire the start events of the sortable with our passed browser event,
10390					// and our own helper (so it doesn't create a new one)
10391					event.target = sortable.currentItem[ 0 ];
10392					sortable._mouseCapture( event, true );
10393					sortable._mouseStart( event, true, true );
10394
10395					// Because the browser event is way off the new appended portlet,
10396					// modify necessary variables to reflect the changes
10397					sortable.offset.click.top = draggable.offset.click.top;
10398					sortable.offset.click.left = draggable.offset.click.left;
10399					sortable.offset.parent.left -= draggable.offset.parent.left -
10400						sortable.offset.parent.left;
10401					sortable.offset.parent.top -= draggable.offset.parent.top -
10402						sortable.offset.parent.top;
10403
10404					draggable._trigger( "toSortable", event );
10405
10406					// Inform draggable that the helper is in a valid drop zone,
10407					// used solely in the revert option to handle "valid/invalid".
10408					draggable.dropped = sortable.element;
10409
10410					// Need to refreshPositions of all sortables in the case that
10411					// adding to one sortable changes the location of the other sortables (#9675)
10412					$.each( draggable.sortables, function() {
10413						this.refreshPositions();
10414					} );
10415
10416					// Hack so receive/update callbacks work (mostly)
10417					draggable.currentItem = draggable.element;
10418					sortable.fromOutside = draggable;
10419				}
10420
10421				if ( sortable.currentItem ) {
10422					sortable._mouseDrag( event );
10423
10424					// Copy the sortable's position because the draggable's can potentially reflect
10425					// a relative position, while sortable is always absolute, which the dragged
10426					// element has now become. (#8809)
10427					ui.position = sortable.position;
10428				}
10429			} else {
10430
10431				// If it doesn't intersect with the sortable, and it intersected before,
10432				// we fake the drag stop of the sortable, but make sure it doesn't remove
10433				// the helper by using cancelHelperRemoval.
10434				if ( sortable.isOver ) {
10435
10436					sortable.isOver = 0;
10437					sortable.cancelHelperRemoval = true;
10438
10439					// Calling sortable's mouseStop would trigger a revert,
10440					// so revert must be temporarily false until after mouseStop is called.
10441					sortable.options._revert = sortable.options.revert;
10442					sortable.options.revert = false;
10443
10444					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10445					sortable._mouseStop( event, true );
10446
10447					// Restore sortable behaviors that were modfied
10448					// when the draggable entered the sortable area (#9481)
10449					sortable.options.revert = sortable.options._revert;
10450					sortable.options.helper = sortable.options._helper;
10451
10452					if ( sortable.placeholder ) {
10453						sortable.placeholder.remove();
10454					}
10455
10456					// Restore and recalculate the draggable's offset considering the sortable
10457					// may have modified them in unexpected ways. (#8809, #10669)
10458					ui.helper.appendTo( draggable._parent );
10459					draggable._refreshOffsets( event );
10460					ui.position = draggable._generatePosition( event, true );
10461
10462					draggable._trigger( "fromSortable", event );
10463
10464					// Inform draggable that the helper is no longer in a valid drop zone
10465					draggable.dropped = false;
10466
10467					// Need to refreshPositions of all sortables just in case removing
10468					// from one sortable changes the location of other sortables (#9675)
10469					$.each( draggable.sortables, function() {
10470						this.refreshPositions();
10471					} );
10472				}
10473			}
10474		} );
10475	}
10476} );
10477
10478$.ui.plugin.add( "draggable", "cursor", {
10479	start: function( event, ui, instance ) {
10480		var t = $( "body" ),
10481			o = instance.options;
10482
10483		if ( t.css( "cursor" ) ) {
10484			o._cursor = t.css( "cursor" );
10485		}
10486		t.css( "cursor", o.cursor );
10487	},
10488	stop: function( event, ui, instance ) {
10489		var o = instance.options;
10490		if ( o._cursor ) {
10491			$( "body" ).css( "cursor", o._cursor );
10492		}
10493	}
10494} );
10495
10496$.ui.plugin.add( "draggable", "opacity", {
10497	start: function( event, ui, instance ) {
10498		var t = $( ui.helper ),
10499			o = instance.options;
10500		if ( t.css( "opacity" ) ) {
10501			o._opacity = t.css( "opacity" );
10502		}
10503		t.css( "opacity", o.opacity );
10504	},
10505	stop: function( event, ui, instance ) {
10506		var o = instance.options;
10507		if ( o._opacity ) {
10508			$( ui.helper ).css( "opacity", o._opacity );
10509		}
10510	}
10511} );
10512
10513$.ui.plugin.add( "draggable", "scroll", {
10514	start: function( event, ui, i ) {
10515		if ( !i.scrollParentNotHidden ) {
10516			i.scrollParentNotHidden = i.helper.scrollParent( false );
10517		}
10518
10519		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10520				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10521			i.overflowOffset = i.scrollParentNotHidden.offset();
10522		}
10523	},
10524	drag: function( event, ui, i  ) {
10525
10526		var o = i.options,
10527			scrolled = false,
10528			scrollParent = i.scrollParentNotHidden[ 0 ],
10529			document = i.document[ 0 ];
10530
10531		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10532			if ( !o.axis || o.axis !== "x" ) {
10533				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10534						o.scrollSensitivity ) {
10535					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10536				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10537					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10538				}
10539			}
10540
10541			if ( !o.axis || o.axis !== "y" ) {
10542				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10543						o.scrollSensitivity ) {
10544					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10545				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10546					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10547				}
10548			}
10549
10550		} else {
10551
10552			if ( !o.axis || o.axis !== "x" ) {
10553				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10554					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10555				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10556						o.scrollSensitivity ) {
10557					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10558				}
10559			}
10560
10561			if ( !o.axis || o.axis !== "y" ) {
10562				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10563					scrolled = $( document ).scrollLeft(
10564						$( document ).scrollLeft() - o.scrollSpeed
10565					);
10566				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10567						o.scrollSensitivity ) {
10568					scrolled = $( document ).scrollLeft(
10569						$( document ).scrollLeft() + o.scrollSpeed
10570					);
10571				}
10572			}
10573
10574		}
10575
10576		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10577			$.ui.ddmanager.prepareOffsets( i, event );
10578		}
10579
10580	}
10581} );
10582
10583$.ui.plugin.add( "draggable", "snap", {
10584	start: function( event, ui, i ) {
10585
10586		var o = i.options;
10587
10588		i.snapElements = [];
10589
10590		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10591			.each( function() {
10592				var $t = $( this ),
10593					$o = $t.offset();
10594				if ( this !== i.element[ 0 ] ) {
10595					i.snapElements.push( {
10596						item: this,
10597						width: $t.outerWidth(), height: $t.outerHeight(),
10598						top: $o.top, left: $o.left
10599					} );
10600				}
10601			} );
10602
10603	},
10604	drag: function( event, ui, inst ) {
10605
10606		var ts, bs, ls, rs, l, r, t, b, i, first,
10607			o = inst.options,
10608			d = o.snapTolerance,
10609			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10610			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10611
10612		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10613
10614			l = inst.snapElements[ i ].left - inst.margins.left;
10615			r = l + inst.snapElements[ i ].width;
10616			t = inst.snapElements[ i ].top - inst.margins.top;
10617			b = t + inst.snapElements[ i ].height;
10618
10619			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10620					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10621					inst.snapElements[ i ].item ) ) {
10622				if ( inst.snapElements[ i ].snapping ) {
10623					
10623( inst.options.snap.release &&
10624						inst.options.snap.release.call(
10625							inst.element,
10626							event,
10627							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10628						) );
10629				}
10630				inst.snapElements[ i ].snapping = false;
vendor: 58,744 bytes, lines 10631-13009
10631				continue;
10632			}
10633
10634			if ( o.snapMode !== "inner" ) {
10635				ts = Math.abs( t - y2 ) <= d;
10636				bs = Math.abs( b - y1 ) <= d;
10637				ls = Math.abs( l - x2 ) <= d;
10638				rs = Math.abs( r - x1 ) <= d;
10639				if ( ts ) {
10640					ui.position.top = inst._convertPositionTo( "relative", {
10641						top: t - inst.helperProportions.height,
10642						left: 0
10643					} ).top;
10644				}
10645				if ( bs ) {
10646					ui.position.top = inst._convertPositionTo( "relative", {
10647						top: b,
10648						left: 0
10649					} ).top;
10650				}
10651				if ( ls ) {
10652					ui.position.left = inst._convertPositionTo( "relative", {
10653						top: 0,
10654						left: l - inst.helperProportions.width
10655					} ).left;
10656				}
10657				if ( rs ) {
10658					ui.position.left = inst._convertPositionTo( "relative", {
10659						top: 0,
10660						left: r
10661					} ).left;
10662				}
10663			}
10664
10665			first = ( ts || bs || ls || rs );
10666
10667			if ( o.snapMode !== "outer" ) {
10668				ts = Math.abs( t - y1 ) <= d;
10669				bs = Math.abs( b - y2 ) <= d;
10670				ls = Math.abs( l - x1 ) <= d;
10671				rs = Math.abs( r - x2 ) <= d;
10672				if ( ts ) {
10673					ui.position.top = inst._convertPositionTo( "relative", {
10674						top: t,
10675						left: 0
10676					} ).top;
10677				}
10678				if ( bs ) {
10679					ui.position.top = inst._convertPositionTo( "relative", {
10680						top: b - inst.helperProportions.height,
10681						left: 0
10682					} ).top;
10683				}
10684				if ( ls ) {
10685					ui.position.left = inst._convertPositionTo( "relative", {
10686						top: 0,
10687						left: l
10688					} ).left;
10689				}
10690				if ( rs ) {
10691					ui.position.left = inst._convertPositionTo( "relative", {
10692						top: 0,
10693						left: r - inst.helperProportions.width
10694					} ).left;
10695				}
10696			}
10697
10698			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10699				( inst.options.snap.snap &&
10700					inst.options.snap.snap.call(
10701						inst.element,
10702						event,
10703						$.extend( inst._uiHash(), {
10704							snapItem: inst.snapElements[ i ].item
10705						} ) ) );
10706			}
10707			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10708
10709		}
10710
10711	}
10712} );
10713
10714$.ui.plugin.add( "draggable", "stack", {
10715	start: function( event, ui, instance ) {
10716		var min,
10717			o = instance.options,
10718			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10719				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10720					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10721			} );
10722
10723		if ( !group.length ) { return; }
10724
10725		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10726		$( group ).each( function( i ) {
10727			$( this ).css( "zIndex", min + i );
10728		} );
10729		this.css( "zIndex", ( min + group.length ) );
10730	}
10731} );
10732
10733$.ui.plugin.add( "draggable", "zIndex", {
10734	start: function( event, ui, instance ) {
10735		var t = $( ui.helper ),
10736			o = instance.options;
10737
10738		if ( t.css( "zIndex" ) ) {
10739			o._zIndex = t.css( "zIndex" );
10740		}
10741		t.css( "zIndex", o.zIndex );
10742	},
10743	stop: function( event, ui, instance ) {
10744		var o = instance.options;
10745
10746		if ( o._zIndex ) {
10747			$( ui.helper ).css( "zIndex", o._zIndex );
10748		}
10749	}
10750} );
10751
10752var widgetsDraggable = $.ui.draggable;
10753
10754
10755/*!
10756 * jQuery UI Resizable 1.12.0
10757 * http://jqueryui.com
10758 *
10759 * Copyright jQuery Foundation and other contributors
10760 * Released under the MIT license.
10761 * http://jquery.org/license
10762 */
10763
10764//>>label: Resizable
10765//>>group: Interactions
10766//>>description: Enables resize functionality for any element.
10767//>>docs: http://api.jqueryui.com/resizable/
10768//>>demos: http://jqueryui.com/resizable/
10769//>>css.structure: ../../themes/base/core.css
10770//>>css.structure: ../../themes/base/resizable.css
10771//>>css.theme: ../../themes/base/theme.css
10772
10773
10774
10775$.widget( "ui.resizable", $.ui.mouse, {
10776	version: "1.12.0",
10777	widgetEventPrefix: "resize",
10778	options: {
10779		alsoResize: false,
10780		animate: false,
10781		animateDuration: "slow",
10782		animateEasing: "swing",
10783		aspectRatio: false,
10784		autoHide: false,
10785		classes: {
10786			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10787		},
10788		containment: false,
10789		ghost: false,
10790		grid: false,
10791		handles: "e,s,se",
10792		helper: false,
10793		maxHeight: null,
10794		maxWidth: null,
10795		minHeight: 10,
10796		minWidth: 10,
10797
10798		// See #7960
10799		zIndex: 90,
10800
10801		// Callbacks
10802		resize: null,
10803		start: null,
10804		stop: null
10805	},
10806
10807	_num: function( value ) {
10808		return parseFloat( value ) || 0;
10809	},
10810
10811	_isNumber: function( value ) {
10812		return !isNaN( parseFloat( value ) );
10813	},
10814
10815	_hasScroll: function( el, a ) {
10816
10817		if ( $( el ).css( "overflow" ) === "hidden" ) {
10818			return false;
10819		}
10820
10821		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10822			has = false;
10823
10824		if ( el[ scroll ] > 0 ) {
10825			return true;
10826		}
10827
10828		// TODO: determine which cases actually cause this to happen
10829		// if the element doesn't have the scroll set, see if it's possible to
10830		// set the scroll
10831		el[ scroll ] = 1;
10832		has = ( el[ scroll ] > 0 );
10833		el[ scroll ] = 0;
10834		return has;
10835	},
10836
10837	_create: function() {
10838
10839		var margins,
10840			o = this.options,
10841			that = this;
10842		this._addClass( "ui-resizable" );
10843
10844		$.extend( this, {
10845			_aspectRatio: !!( o.aspectRatio ),
10846			aspectRatio: o.aspectRatio,
10847			originalElement: this.element,
10848			_proportionallyResizeElements: [],
10849			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10850		} );
10851
10852		// Wrap the element if it cannot hold child nodes
10853		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10854
10855			this.element.wrap(
10856				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10857					position: this.element.css( "position" ),
10858					width: this.element.outerWidth(),
10859					height: this.element.outerHeight(),
10860					top: this.element.css( "top" ),
10861					left: this.element.css( "left" )
10862				} )
10863			);
10864
10865			this.element = this.element.parent().data(
10866				"ui-resizable", this.element.resizable( "instance" )
10867			);
10868
10869			this.elementIsWrapper = true;
10870
10871			margins = {
10872				marginTop: this.originalElement.css( "marginTop" ),
10873				marginRight: this.originalElement.css( "marginRight" ),
10874				marginBottom: this.originalElement.css( "marginBottom" ),
10875				marginLeft: this.originalElement.css( "marginLeft" )
10876			};
10877
10878			this.element.css( margins );
10879			this.originalElement.css( "margin", 0 );
10880
10881			// support: Safari
10882			// Prevent Safari textarea resize
10883			this.originalResizeStyle = this.originalElement.css( "resize" );
10884			this.originalElement.css( "resize", "none" );
10885
10886			this._proportionallyResizeElements.push( this.originalElement.css( {
10887				position: "static",
10888				zoom: 1,
10889				display: "block"
10890			} ) );
10891
10892			// Support: IE9
10893			// avoid IE jump (hard set the margin)
10894			this.originalElement.css( margins );
10895
10896			this._proportionallyResize();
10897		}
10898
10899		this._setupHandles();
10900
10901		if ( o.autoHide ) {
10902			$( this.element )
10903				.on( "mouseenter", function() {
10904					if ( o.disabled ) {
10905						return;
10906					}
10907					that._removeClass( "ui-resizable-autohide" );
10908					that._handles.show();
10909				} )
10910				.on( "mouseleave", function() {
10911					if ( o.disabled ) {
10912						return;
10913					}
10914					if ( !that.resizing ) {
10915						that._addClass( "ui-resizable-autohide" );
10916						that._handles.hide();
10917					}
10918				} );
10919		}
10920
10921		this._mouseInit();
10922	},
10923
10924	_destroy: function() {
10925
10926		this._mouseDestroy();
10927
10928		var wrapper,
10929			_destroy = function( exp ) {
10930				$( exp )
10931					.removeData( "resizable" )
10932					.removeData( "ui-resizable" )
10933					.off( ".resizable" )
10934					.find( ".ui-resizable-handle" )
10935						.remove();
10936			};
10937
10938		// TODO: Unwrap at same DOM position
10939		if ( this.elementIsWrapper ) {
10940			_destroy( this.element );
10941			wrapper = this.element;
10942			this.originalElement.css( {
10943				position: wrapper.css( "position" ),
10944				width: wrapper.outerWidth(),
10945				height: wrapper.outerHeight(),
10946				top: wrapper.css( "top" ),
10947				left: wrapper.css( "left" )
10948			} ).insertAfter( wrapper );
10949			wrapper.remove();
10950		}
10951
10952		this.originalElement.css( "resize", this.originalResizeStyle );
10953		_destroy( this.originalElement );
10954
10955		return this;
10956	},
10957
10958	_setOption: function( key, value ) {
10959		this._super( key, value );
10960
10961		switch ( key ) {
10962		case "handles":
10963			this._removeHandles();
10964			this._setupHandles();
10965			break;
10966		default:
10967			break;
10968		}
10969	},
10970
10971	_setupHandles: function() {
10972		var o = this.options, handle, i, n, hname, axis, that = this;
10973		this.handles = o.handles ||
10974			( !$( ".ui-resizable-handle", this.element ).length ?
10975				"e,s,se" : {
10976					n: ".ui-resizable-n",
10977					e: ".ui-resizable-e",
10978					s: ".ui-resizable-s",
10979					w: ".ui-resizable-w",
10980					se: ".ui-resizable-se",
10981					sw: ".ui-resizable-sw",
10982					ne: ".ui-resizable-ne",
10983					nw: ".ui-resizable-nw"
10984				} );
10985
10986		this._handles = $();
10987		if ( this.handles.constructor === String ) {
10988
10989			if ( this.handles === "all" ) {
10990				this.handles = "n,e,s,w,se,sw,ne,nw";
10991			}
10992
10993			n = this.handles.split( "," );
10994			this.handles = {};
10995
10996			for ( i = 0; i < n.length; i++ ) {
10997
10998				handle = $.trim( n[ i ] );
10999				hname = "ui-resizable-" + handle;
11000				axis = $( "<div>" );
11001				this._addClass( axis, "ui-resizable-handle " + hname );
11002
11003				axis.css( { zIndex: o.zIndex } );
11004
11005				this.handles[ handle ] = ".ui-resizable-" + handle;
11006				this.element.append( axis );
11007			}
11008
11009		}
11010
11011		this._renderAxis = function( target ) {
11012
11013			var i, axis, padPos, padWrapper;
11014
11015			target = target || this.element;
11016
11017			for ( i in this.handles ) {
11018
11019				if ( this.handles[ i ].constructor === String ) {
11020					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11021				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11022					this.handles[ i ] = $( this.handles[ i ] );
11023					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11024				}
11025
11026				if ( this.elementIsWrapper &&
11027						this.originalElement[ 0 ]
11028							.nodeName
11029							.match( /^(textarea|input|select|button)$/i ) ) {
11030					axis = $( this.handles[ i ], this.element );
11031
11032					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11033						axis.outerHeight() :
11034						axis.outerWidth();
11035
11036					padPos = [ "padding",
11037						/ne|nw|n/.test( i ) ? "Top" :
11038						/se|sw|s/.test( i ) ? "Bottom" :
11039						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11040
11041					target.css( padPos, padWrapper );
11042
11043					this._proportionallyResize();
11044				}
11045
11046				this._handles = this._handles.add( this.handles[ i ] );
11047			}
11048		};
11049
11050		// TODO: make renderAxis a prototype function
11051		this._renderAxis( this.element );
11052
11053		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11054		this._handles.disableSelection();
11055
11056		this._handles.on( "mouseover", function() {
11057			if ( !that.resizing ) {
11058				if ( this.className ) {
11059					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11060				}
11061				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11062			}
11063		} );
11064
11065		if ( o.autoHide ) {
11066			this._handles.hide();
11067			this._addClass( "ui-resizable-autohide" );
11068		}
11069	},
11070
11071	_removeHandles: function() {
11072		this._handles.remove();
11073	},
11074
11075	_mouseCapture: function( event ) {
11076		var i, handle,
11077			capture = false;
11078
11079		for ( i in this.handles ) {
11080			handle = $( this.handles[ i ] )[ 0 ];
11081			if ( handle === event.target || $.contains( handle, event.target ) ) {
11082				capture = true;
11083			}
11084		}
11085
11086		return !this.options.disabled && capture;
11087	},
11088
11089	_mouseStart: function( event ) {
11090
11091		var curleft, curtop, cursor,
11092			o = this.options,
11093			el = this.element;
11094
11095		this.resizing = true;
11096
11097		this._renderProxy();
11098
11099		curleft = this._num( this.helper.css( "left" ) );
11100		curtop = this._num( this.helper.css( "top" ) );
11101
11102		if ( o.containment ) {
11103			curleft += $( o.containment ).scrollLeft() || 0;
11104			curtop += $( o.containment ).scrollTop() || 0;
11105		}
11106
11107		this.offset = this.helper.offset();
11108		this.position = { left: curleft, top: curtop };
11109
11110		this.size = this._helper ? {
11111				width: this.helper.width(),
11112				height: this.helper.height()
11113			} : {
11114				width: el.width(),
11115				height: el.height()
11116			};
11117
11118		this.originalSize = this._helper ? {
11119				width: el.outerWidth(),
11120				height: el.outerHeight()
11121			} : {
11122				width: el.width(),
11123				height: el.height()
11124			};
11125
11126		this.sizeDiff = {
11127			width: el.outerWidth() - el.width(),
11128			height: el.outerHeight() - el.height()
11129		};
11130
11131		this.originalPosition = { left: curleft, top: curtop };
11132		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11133
11134		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11135			o.aspectRatio :
11136			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11137
11138		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11139		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11140
11141		this._addClass( "ui-resizable-resizing" );
11142		this._propagate( "start", event );
11143		return true;
11144	},
11145
11146	_mouseDrag: function( event ) {
11147
11148		var data, props,
11149			smp = this.originalMousePosition,
11150			a = this.axis,
11151			dx = ( event.pageX - smp.left ) || 0,
11152			dy = ( event.pageY - smp.top ) || 0,
11153			trigger = this._change[ a ];
11154
11155		this._updatePrevProperties();
11156
11157		if ( !trigger ) {
11158			return false;
11159		}
11160
11161		data = trigger.apply( this, [ event, dx, dy ] );
11162
11163		this._updateVirtualBoundaries( event.shiftKey );
11164		if ( this._aspectRatio || event.shiftKey ) {
11165			data = this._updateRatio( data, event );
11166		}
11167
11168		data = this._respectSize( data, event );
11169
11170		this._updateCache( data );
11171
11172		this._propagate( "resize", event );
11173
11174		props = this._applyChanges();
11175
11176		if ( !this._helper && this._proportionallyResizeElements.length ) {
11177			this._proportionallyResize();
11178		}
11179
11180		if ( !$.isEmptyObject( props ) ) {
11181			this._updatePrevProperties();
11182			this._trigger( "resize", event, this.ui() );
11183			this._applyChanges();
11184		}
11185
11186		return false;
11187	},
11188
11189	_mouseStop: function( event ) {
11190
11191		this.resizing = false;
11192		var pr, ista, soffseth, soffsetw, s, left, top,
11193			o = this.options, that = this;
11194
11195		if ( this._helper ) {
11196
11197			pr = this._proportionallyResizeElements;
11198			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11199			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11200			soffsetw = ista ? 0 : that.sizeDiff.width;
11201
11202			s = {
11203				width: ( that.helper.width()  - soffsetw ),
11204				height: ( that.helper.height() - soffseth )
11205			};
11206			left = ( parseFloat( that.element.css( "left" ) ) +
11207				( that.position.left - that.originalPosition.left ) ) || null;
11208			top = ( parseFloat( that.element.css( "top" ) ) +
11209				( that.position.top - that.originalPosition.top ) ) || null;
11210
11211			if ( !o.animate ) {
11212				this.element.css( $.extend( s, { top: top, left: left } ) );
11213			}
11214
11215			that.helper.height( that.size.height );
11216			that.helper.width( that.size.width );
11217
11218			if ( this._helper && !o.animate ) {
11219				this._proportionallyResize();
11220			}
11221		}
11222
11223		$( "body" ).css( "cursor", "auto" );
11224
11225		this._removeClass( "ui-resizable-resizing" );
11226
11227		this._propagate( "stop", event );
11228
11229		if ( this._helper ) {
11230			this.helper.remove();
11231		}
11232
11233		return false;
11234
11235	},
11236
11237	_updatePrevProperties: function() {
11238		this.prevPosition = {
11239			top: this.position.top,
11240			left: this.position.left
11241		};
11242		this.prevSize = {
11243			width: this.size.width,
11244			height: this.size.height
11245		};
11246	},
11247
11248	_applyChanges: function() {
11249		var props = {};
11250
11251		if ( this.position.top !== this.prevPosition.top ) {
11252			props.top = this.position.top + "px";
11253		}
11254		if ( this.position.left !== this.prevPosition.left ) {
11255			props.left = this.position.left + "px";
11256		}
11257		if ( this.size.width !== this.prevSize.width ) {
11258			props.width = this.size.width + "px";
11259		}
11260		if ( this.size.height !== this.prevSize.height ) {
11261			props.height = this.size.height + "px";
11262		}
11263
11264		this.helper.css( props );
11265
11266		return props;
11267	},
11268
11269	_updateVirtualBoundaries: function( forceAspectRatio ) {
11270		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11271			o = this.options;
11272
11273		b = {
11274			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11275			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11276			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11277			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11278		};
11279
11280		if ( this._aspectRatio || forceAspectRatio ) {
11281			pMinWidth = b.minHeight * this.aspectRatio;
11282			pMinHeight = b.minWidth / this.aspectRatio;
11283			pMaxWidth = b.maxHeight * this.aspectRatio;
11284			pMaxHeight = b.maxWidth / this.aspectRatio;
11285
11286			if ( pMinWidth > b.minWidth ) {
11287				b.minWidth = pMinWidth;
11288			}
11289			if ( pMinHeight > b.minHeight ) {
11290				b.minHeight = pMinHeight;
11291			}
11292			if ( pMaxWidth < b.maxWidth ) {
11293				b.maxWidth = pMaxWidth;
11294			}
11295			if ( pMaxHeight < b.maxHeight ) {
11296				b.maxHeight = pMaxHeight;
11297			}
11298		}
11299		this._vBoundaries = b;
11300	},
11301
11302	_updateCache: function( data ) {
11303		this.offset = this.helper.offset();
11304		if ( this._isNumber( data.left ) ) {
11305			this.position.left = data.left;
11306		}
11307		if ( this._isNumber( data.top ) ) {
11308			this.position.top = data.top;
11309		}
11310		if ( this._isNumber( data.height ) ) {
11311			this.size.height = data.height;
11312		}
11313		if ( this._isNumber( data.width ) ) {
11314			this.size.width = data.width;
11315		}
11316	},
11317
11318	_updateRatio: function( data ) {
11319
11320		var cpos = this.position,
11321			csize = this.size,
11322			a = this.axis;
11323
11324		if ( this._isNumber( data.height ) ) {
11325			data.width = ( data.height * this.aspectRatio );
11326		} else if ( this._isNumber( data.width ) ) {
11327			data.height = ( data.width / this.aspectRatio );
11328		}
11329
11330		if ( a === "sw" ) {
11331			data.left = cpos.left + ( csize.width - data.width );
11332			data.top = null;
11333		}
11334		if ( a === "nw" ) {
11335			data.top = cpos.top + ( csize.height - data.height );
11336			data.left = cpos.left + ( csize.width - data.width );
11337		}
11338
11339		return data;
11340	},
11341
11342	_respectSize: function( data ) {
11343
11344		var o = this._vBoundaries,
11345			a = this.axis,
11346			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11347			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11348			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11349			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11350			dw = this.originalPosition.left + this.originalSize.width,
11351			dh = this.originalPosition.top + this.originalSize.height,
11352			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11353		if ( isminw ) {
11354			data.width = o.minWidth;
11355		}
11356		if ( isminh ) {
11357			data.height = o.minHeight;
11358		}
11359		if ( ismaxw ) {
11360			data.width = o.maxWidth;
11361		}
11362		if ( ismaxh ) {
11363			data.height = o.maxHeight;
11364		}
11365
11366		if ( isminw && cw ) {
11367			data.left = dw - o.minWidth;
11368		}
11369		if ( ismaxw && cw ) {
11370			data.left = dw - o.maxWidth;
11371		}
11372		if ( isminh && ch ) {
11373			data.top = dh - o.minHeight;
11374		}
11375		if ( ismaxh && ch ) {
11376			data.top = dh - o.maxHeight;
11377		}
11378
11379		// Fixing jump error on top/left - bug #2330
11380		if ( !data.width && !data.height && !data.left && data.top ) {
11381			data.top = null;
11382		} else if ( !data.width && !data.height && !data.top && data.left ) {
11383			data.left = null;
11384		}
11385
11386		return data;
11387	},
11388
11389	_getPaddingPlusBorderDimensions: function( element ) {
11390		var i = 0,
11391			widths = [],
11392			borders = [
11393				element.css( "borderTopWidth" ),
11394				element.css( "borderRightWidth" ),
11395				element.css( "borderBottomWidth" ),
11396				element.css( "borderLeftWidth" )
11397			],
11398			paddings = [
11399				element.css( "paddingTop" ),
11400				element.css( "paddingRight" ),
11401				element.css( "paddingBottom" ),
11402				element.css( "paddingLeft" )
11403			];
11404
11405		for ( ; i < 4; i++ ) {
11406			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11407			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11408		}
11409
11410		return {
11411			height: widths[ 0 ] + widths[ 2 ],
11412			width: widths[ 1 ] + widths[ 3 ]
11413		};
11414	},
11415
11416	_proportionallyResize: function() {
11417
11418		if ( !this._proportionallyResizeElements.length ) {
11419			return;
11420		}
11421
11422		var prel,
11423			i = 0,
11424			element = this.helper || this.element;
11425
11426		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11427
11428			prel = this._proportionallyResizeElements[ i ];
11429
11430			// TODO: Seems like a bug to cache this.outerDimensions
11431			// considering that we are in a loop.
11432			if ( !this.outerDimensions ) {
11433				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11434			}
11435
11436			prel.css( {
11437				height: ( element.height() - this.outerDimensions.height ) || 0,
11438				width: ( element.width() - this.outerDimensions.width ) || 0
11439			} );
11440
11441		}
11442
11443	},
11444
11445	_renderProxy: function() {
11446
11447		var el = this.element, o = this.options;
11448		this.elementOffset = el.offset();
11449
11450		if ( this._helper ) {
11451
11452			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11453
11454			this._addClass( this.helper, this._helper );
11455			this.helper.css( {
11456				width: this.element.outerWidth(),
11457				height: this.element.outerHeight(),
11458				position: "absolute",
11459				left: this.elementOffset.left + "px",
11460				top: this.elementOffset.top + "px",
11461				zIndex: ++o.zIndex //TODO: Don't modify option
11462			} );
11463
11464			this.helper
11465				.appendTo( "body" )
11466				.disableSelection();
11467
11468		} else {
11469			this.helper = this.element;
11470		}
11471
11472	},
11473
11474	_change: {
11475		e: function( event, dx ) {
11476			return { width: this.originalSize.width + dx };
11477		},
11478		w: function( event, dx ) {
11479			var cs = this.originalSize, sp = this.originalPosition;
11480			return { left: sp.left + dx, width: cs.width - dx };
11481		},
11482		n: function( event, dx, dy ) {
11483			var cs = this.originalSize, sp = this.originalPosition;
11484			return { top: sp.top + dy, height: cs.height - dy };
11485		},
11486		s: function( event, dx, dy ) {
11487			return { height: this.originalSize.height + dy };
11488		},
11489		se: function( event, dx, dy ) {
11490			return $.extend( this._change.s.apply( this, arguments ),
11491				this._change.e.apply( this, [ event, dx, dy ] ) );
11492		},
11493		sw: function( event, dx, dy ) {
11494			return $.extend( this._change.s.apply( this, arguments ),
11495				this._change.w.apply( this, [ event, dx, dy ] ) );
11496		},
11497		ne: function( event, dx, dy ) {
11498			return $.extend( this._change.n.apply( this, arguments ),
11499				this._change.e.apply( this, [ event, dx, dy ] ) );
11500		},
11501		nw: function( event, dx, dy ) {
11502			return $.extend( this._change.n.apply( this, arguments ),
11503				this._change.w.apply( this, [ event, dx, dy ] ) );
11504		}
11505	},
11506
11507	_propagate: function( n, event ) {
11508		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11509		( n !== "resize" && this._trigger( n, event, this.ui() ) );
11510	},
11511
11512	plugins: {},
11513
11514	ui: function() {
11515		return {
11516			originalElement: this.originalElement,
11517			element: this.element,
11518			helper: this.helper,
11519			position: this.position,
11520			size: this.size,
11521			originalSize: this.originalSize,
11522			originalPosition: this.originalPosition
11523		};
11524	}
11525
11526} );
11527
11528/*
11529 * Resizable Extensions
11530 */
11531
11532$.ui.plugin.add( "resizable", "animate", {
11533
11534	stop: function( event ) {
11535		var that = $( this ).resizable( "instance" ),
11536			o = that.options,
11537			pr = that._proportionallyResizeElements,
11538			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11539			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11540			soffsetw = ista ? 0 : that.sizeDiff.width,
11541			style = {
11542				width: ( that.size.width - soffsetw ),
11543				height: ( that.size.height - soffseth )
11544			},
11545			left = ( parseFloat( that.element.css( "left" ) ) +
11546				( that.position.left - that.originalPosition.left ) ) || null,
11547			top = ( parseFloat( that.element.css( "top" ) ) +
11548				( that.position.top - that.originalPosition.top ) ) || null;
11549
11550		that.element.animate(
11551			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11552				duration: o.animateDuration,
11553				easing: o.animateEasing,
11554				step: function() {
11555
11556					var data = {
11557						width: parseFloat( that.element.css( "width" ) ),
11558						height: parseFloat( that.element.css( "height" ) ),
11559						top: parseFloat( that.element.css( "top" ) ),
11560						left: parseFloat( that.element.css( "left" ) )
11561					};
11562
11563					if ( pr && pr.length ) {
11564						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11565					}
11566
11567					// Propagating resize, and updating values for each animation step
11568					that._updateCache( data );
11569					that._propagate( "resize", event );
11570
11571				}
11572			}
11573		);
11574	}
11575
11576} );
11577
11578$.ui.plugin.add( "resizable", "containment", {
11579
11580	start: function() {
11581		var element, p, co, ch, cw, width, height,
11582			that = $( this ).resizable( "instance" ),
11583			o = that.options,
11584			el = that.element,
11585			oc = o.containment,
11586			ce = ( oc instanceof $ ) ?
11587				oc.get( 0 ) :
11588				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11589
11590		if ( !ce ) {
11591			return;
11592		}
11593
11594		that.containerElement = $( ce );
11595
11596		if ( /document/.test( oc ) || oc === document ) {
11597			that.containerOffset = {
11598				left: 0,
11599				top: 0
11600			};
11601			that.containerPosition = {
11602				left: 0,
11603				top: 0
11604			};
11605
11606			that.parentData = {
11607				element: $( document ),
11608				left: 0,
11609				top: 0,
11610				width: $( document ).width(),
11611				height: $( document ).height() || document.body.parentNode.scrollHeight
11612			};
11613		} else {
11614			element = $( ce );
11615			p = [];
11616			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11617				p[ i ] = that._num( element.css( "padding" + name ) );
11618			} );
11619
11620			that.containerOffset = element.offset();
11621			that.containerPosition = element.position();
11622			that.containerSize = {
11623				height: ( element.innerHeight() - p[ 3 ] ),
11624				width: ( element.innerWidth() - p[ 1 ] )
11625			};
11626
11627			co = that.containerOffset;
11628			ch = that.containerSize.height;
11629			cw = that.containerSize.width;
11630			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11631			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11632
11633			that.parentData = {
11634				element: ce,
11635				left: co.left,
11636				top: co.top,
11637				width: width,
11638				height: height
11639			};
11640		}
11641	},
11642
11643	resize: function( event ) {
11644		var woset, hoset, isParent, isOffsetRelative,
11645			that = $( this ).resizable( "instance" ),
11646			o = that.options,
11647			co = that.containerOffset,
11648			cp = that.position,
11649			pRatio = that._aspectRatio || event.shiftKey,
11650			cop = {
11651				top: 0,
11652				left: 0
11653			},
11654			ce = that.containerElement,
11655			continueResize = true;
11656
11657		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11658			cop = co;
11659		}
11660
11661		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11662			that.size.width = that.size.width +
11663				( that._helper ?
11664					( that.position.left - co.left ) :
11665					( that.position.left - cop.left ) );
11666
11667			if ( pRatio ) {
11668				that.size.height = that.size.width / that.aspectRatio;
11669				continueResize = false;
11670			}
11671			that.position.left = o.helper ? co.left : 0;
11672		}
11673
11674		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11675			that.size.height = that.size.height +
11676				( that._helper ?
11677					( that.position.top - co.top ) :
11678					that.position.top );
11679
11680			if ( pRatio ) {
11681				that.size.width = that.size.height * that.aspectRatio;
11682				continueResize = false;
11683			}
11684			that.position.top = that._helper ? co.top : 0;
11685		}
11686
11687		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11688		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11689
11690		if ( isParent && isOffsetRelative ) {
11691			that.offset.left = that.parentData.left + that.position.left;
11692			that.offset.top = that.parentData.top + that.position.top;
11693		} else {
11694			that.offset.left = that.element.offset().left;
11695			that.offset.top = that.element.offset().top;
11696		}
11697
11698		woset = Math.abs( that.sizeDiff.width +
11699			( that._helper ?
11700				that.offset.left - cop.left :
11701				( that.offset.left - co.left ) ) );
11702
11703		hoset = Math.abs( that.sizeDiff.height +
11704			( that._helper ?
11705				that.offset.top - cop.top :
11706				( that.offset.top - co.top ) ) );
11707
11708		if ( woset + that.size.width >= that.parentData.width ) {
11709			that.size.width = that.parentData.width - woset;
11710			if ( pRatio ) {
11711				that.size.height = that.size.width / that.aspectRatio;
11712				continueResize = false;
11713			}
11714		}
11715
11716		if ( hoset + that.size.height >= that.parentData.height ) {
11717			that.size.height = that.parentData.height - hoset;
11718			if ( pRatio ) {
11719				that.size.width = that.size.height * that.aspectRatio;
11720				continueResize = false;
11721			}
11722		}
11723
11724		if ( !continueResize ) {
11725			that.position.left = that.prevPosition.left;
11726			that.position.top = that.prevPosition.top;
11727			that.size.width = that.prevSize.width;
11728			that.size.height = that.prevSize.height;
11729		}
11730	},
11731
11732	stop: function() {
11733		var that = $( this ).resizable( "instance" ),
11734			o = that.options,
11735			co = that.containerOffset,
11736			cop = that.containerPosition,
11737			ce = that.containerElement,
11738			helper = $( that.helper ),
11739			ho = helper.offset(),
11740			w = helper.outerWidth() - that.sizeDiff.width,
11741			h = helper.outerHeight() - that.sizeDiff.height;
11742
11743		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11744			$( this ).css( {
11745				left: ho.left - cop.left - co.left,
11746				width: w,
11747				height: h
11748			} );
11749		}
11750
11751		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11752			$( this ).css( {
11753				left: ho.left - cop.left - co.left,
11754				width: w,
11755				height: h
11756			} );
11757		}
11758	}
11759} );
11760
11761$.ui.plugin.add( "resizable", "alsoResize", {
11762
11763	start: function() {
11764		var that = $( this ).resizable( "instance" ),
11765			o = that.options;
11766
11767		$( o.alsoResize ).each( function() {
11768			var el = $( this );
11769			el.data( "ui-resizable-alsoresize", {
11770				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11771				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11772			} );
11773		} );
11774	},
11775
11776	resize: function( event, ui ) {
11777		var that = $( this ).resizable( "instance" ),
11778			o = that.options,
11779			os = that.originalSize,
11780			op = that.originalPosition,
11781			delta = {
11782				height: ( that.size.height - os.height ) || 0,
11783				width: ( that.size.width - os.width ) || 0,
11784				top: ( that.position.top - op.top ) || 0,
11785				left: ( that.position.left - op.left ) || 0
11786			};
11787
11788			$( o.alsoResize ).each( function() {
11789				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11790					css = el.parents( ui.originalElement[ 0 ] ).length ?
11791							[ "width", "height" ] :
11792							[ "width", "height", "top", "left" ];
11793
11794				$.each( css, function( i, prop ) {
11795					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11796					if ( sum && sum >= 0 ) {
11797						style[ prop ] = sum || null;
11798					}
11799				} );
11800
11801				el.css( style );
11802			} );
11803	},
11804
11805	stop: function() {
11806		$( this ).removeData( "ui-resizable-alsoresize" );
11807	}
11808} );
11809
11810$.ui.plugin.add( "resizable", "ghost", {
11811
11812	start: function() {
11813
11814		var that = $( this ).resizable( "instance" ), cs = that.size;
11815
11816		that.ghost = that.originalElement.clone();
11817		that.ghost.css( {
11818			opacity: 0.25,
11819			display: "block",
11820			position: "relative",
11821			height: cs.height,
11822			width: cs.width,
11823			margin: 0,
11824			left: 0,
11825			top: 0
11826		} );
11827
11828		that._addClass( that.ghost, "ui-resizable-ghost" );
11829
11830		// DEPRECATED
11831		// TODO: remove after 1.12
11832		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11833
11834			// Ghost option
11835			that.ghost.addClass( this.options.ghost );
11836		}
11837
11838		that.ghost.appendTo( that.helper );
11839
11840	},
11841
11842	resize: function() {
11843		var that = $( this ).resizable( "instance" );
11844		if ( that.ghost ) {
11845			that.ghost.css( {
11846				position: "relative",
11847				height: that.size.height,
11848				width: that.size.width
11849			} );
11850		}
11851	},
11852
11853	stop: function() {
11854		var that = $( this ).resizable( "instance" );
11855		if ( that.ghost && that.helper ) {
11856			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11857		}
11858	}
11859
11860} );
11861
11862$.ui.plugin.add( "resizable", "grid", {
11863
11864	resize: function() {
11865		var outerDimensions,
11866			that = $( this ).resizable( "instance" ),
11867			o = that.options,
11868			cs = that.size,
11869			os = that.originalSize,
11870			op = that.originalPosition,
11871			a = that.axis,
11872			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11873			gridX = ( grid[ 0 ] || 1 ),
11874			gridY = ( grid[ 1 ] || 1 ),
11875			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11876			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11877			newWidth = os.width + ox,
11878			newHeight = os.height + oy,
11879			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11880			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11881			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11882			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11883
11884		o.grid = grid;
11885
11886		if ( isMinWidth ) {
11887			newWidth += gridX;
11888		}
11889		if ( isMinHeight ) {
11890			newHeight += gridY;
11891		}
11892		if ( isMaxWidth ) {
11893			newWidth -= gridX;
11894		}
11895		if ( isMaxHeight ) {
11896			newHeight -= gridY;
11897		}
11898
11899		if ( /^(se|s|e)$/.test( a ) ) {
11900			that.size.width = newWidth;
11901			that.size.height = newHeight;
11902		} else if ( /^(ne)$/.test( a ) ) {
11903			that.size.width = newWidth;
11904			that.size.height = newHeight;
11905			that.position.top = op.top - oy;
11906		} else if ( /^(sw)$/.test( a ) ) {
11907			that.size.width = newWidth;
11908			that.size.height = newHeight;
11909			that.position.left = op.left - ox;
11910		} else {
11911			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11912				outerDimensions = that._getPaddingPlusBorderDimensions( this );
11913			}
11914
11915			if ( newHeight - gridY > 0 ) {
11916				that.size.height = newHeight;
11917				that.position.top = op.top - oy;
11918			} else {
11919				newHeight = gridY - outerDimensions.height;
11920				that.size.height = newHeight;
11921				that.position.top = op.top + os.height - newHeight;
11922			}
11923			if ( newWidth - gridX > 0 ) {
11924				that.size.width = newWidth;
11925				that.position.left = op.left - ox;
11926			} else {
11927				newWidth = gridX - outerDimensions.width;
11928				that.size.width = newWidth;
11929				that.position.left = op.left + os.width - newWidth;
11930			}
11931		}
11932	}
11933
11934} );
11935
11936var widgetsResizable = $.ui.resizable;
11937
11938
11939/*!
11940 * jQuery UI Dialog 1.12.0
11941 * http://jqueryui.com
11942 *
11943 * Copyright jQuery Foundation and other contributors
11944 * Released under the MIT license.
11945 * http://jquery.org/license
11946 */
11947
11948//>>label: Dialog
11949//>>group: Widgets
11950//>>description: Displays customizable dialog windows.
11951//>>docs: http://api.jqueryui.com/dialog/
11952//>>demos: http://jqueryui.com/dialog/
11953//>>css.structure: ../../themes/base/core.css
11954//>>css.structure: ../../themes/base/dialog.css
11955//>>css.theme: ../../themes/base/theme.css
11956
11957
11958
11959$.widget( "ui.dialog", {
11960	version: "1.12.0",
11961	options: {
11962		appendTo: "body",
11963		autoOpen: true,
11964		buttons: [],
11965		classes: {
11966			"ui-dialog": "ui-corner-all",
11967			"ui-dialog-titlebar": "ui-corner-all"
11968		},
11969		closeOnEscape: true,
11970		closeText: "Close",
11971		draggable: true,
11972		hide: null,
11973		height: "auto",
11974		maxHeight: null,
11975		maxWidth: null,
11976		minHeight: 150,
11977		minWidth: 150,
11978		modal: false,
11979		position: {
11980			my: "center",
11981			at: "center",
11982			of: window,
11983			collision: "fit",
11984
11985			// Ensure the titlebar is always visible
11986			using: function( pos ) {
11987				var topOffset = $( this ).css( pos ).offset().top;
11988				if ( topOffset < 0 ) {
11989					$( this ).css( "top", pos.top - topOffset );
11990				}
11991			}
11992		},
11993		resizable: true,
11994		show: null,
11995		title: null,
11996		width: 300,
11997
11998		// Callbacks
11999		beforeClose: null,
12000		close: null,
12001		drag: null,
12002		dragStart: null,
12003		dragStop: null,
12004		focus: null,
12005		open: null,
12006		resize: null,
12007		resizeStart: null,
12008		resizeStop: null
12009	},
12010
12011	sizeRelatedOptions: {
12012		buttons: true,
12013		height: true,
12014		maxHeight: true,
12015		maxWidth: true,
12016		minHeight: true,
12017		minWidth: true,
12018		width: true
12019	},
12020
12021	resizableRelatedOptions: {
12022		maxHeight: true,
12023		maxWidth: true,
12024		minHeight: true,
12025		minWidth: true
12026	},
12027
12028	_create: function() {
12029		this.originalCss = {
12030			display: this.element[ 0 ].style.display,
12031			width: this.element[ 0 ].style.width,
12032			minHeight: this.element[ 0 ].style.minHeight,
12033			maxHeight: this.element[ 0 ].style.maxHeight,
12034			height: this.element[ 0 ].style.height
12035		};
12036		this.originalPosition = {
12037			parent: this.element.parent(),
12038			index: this.element.parent().children().index( this.element )
12039		};
12040		this.originalTitle = this.element.attr( "title" );
12041		if ( this.options.title == null && this.originalTitle != null ) {
12042			this.options.title = this.originalTitle;
12043		}
12044
12045		// Dialogs can't be disabled
12046		if ( this.options.disabled ) {
12047			this.options.disabled = false;
12048		}
12049
12050		this._createWrapper();
12051
12052		this.element
12053			.show()
12054			.removeAttr( "title" )
12055			.appendTo( this.uiDialog );
12056
12057		this._addClass( "ui-dialog-content", "ui-widget-content" );
12058
12059		this._createTitlebar();
12060		this._createButtonPane();
12061
12062		if ( this.options.draggable && $.fn.draggable ) {
12063			this._makeDraggable();
12064		}
12065		if ( this.options.resizable && $.fn.resizable ) {
12066			this._makeResizable();
12067		}
12068
12069		this._isOpen = false;
12070
12071		this._trackFocus();
12072	},
12073
12074	_init: function() {
12075		if ( this.options.autoOpen ) {
12076			this.open();
12077		}
12078	},
12079
12080	_appendTo: function() {
12081		var element = this.options.appendTo;
12082		if ( element && ( element.jquery || element.nodeType ) ) {
12083			return $( element );
12084		}
12085		return this.document.find( element || "body" ).eq( 0 );
12086	},
12087
12088	_destroy: function() {
12089		var next,
12090			originalPosition = this.originalPosition;
12091
12092		this._untrackInstance();
12093		this._destroyOverlay();
12094
12095		this.element
12096			.removeUniqueId()
12097			.css( this.originalCss )
12098
12099			// Without detaching first, the following becomes really slow
12100			.detach();
12101
12102		this.uiDialog.remove();
12103
12104		if ( this.originalTitle ) {
12105			this.element.attr( "title", this.originalTitle );
12106		}
12107
12108		next = originalPosition.parent.children().eq( originalPosition.index );
12109
12110		// Don't try to place the dialog next to itself (#8613)
12111		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12112			next.before( this.element );
12113		} else {
12114			originalPosition.parent.append( this.element );
12115		}
12116	},
12117
12118	widget: function() {
12119		return this.uiDialog;
12120	},
12121
12122	disable: $.noop,
12123	enable: $.noop,
12124
12125	close: function( event ) {
12126		var that = this;
12127
12128		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12129			return;
12130		}
12131
12132		this._isOpen = false;
12133		this._focusedElement = null;
12134		this._destroyOverlay();
12135		this._untrackInstance();
12136
12137		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12138
12139			// Hiding a focused element doesn't trigger blur in WebKit
12140			// so in case we have nothing to focus on, explicitly blur the active element
12141			// https://bugs.webkit.org/show_bug.cgi?id=47182
12142			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12143		}
12144
12145		this._hide( this.uiDialog, this.options.hide, function() {
12146			that._trigger( "close", event );
12147		} );
12148	},
12149
12150	isOpen: function() {
12151		return this._isOpen;
12152	},
12153
12154	moveToTop: function() {
12155		this._moveToTop();
12156	},
12157
12158	_moveToTop: function( event, silent ) {
12159		var moved = false,
12160			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12161				return +$( this ).css( "z-index" );
12162			} ).get(),
12163			zIndexMax = Math.max.apply( null, zIndices );
12164
12165		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12166			this.uiDialog.css( "z-index", zIndexMax + 1 );
12167			moved = true;
12168		}
12169
12170		if ( moved && !silent ) {
12171			this._trigger( "focus", event );
12172		}
12173		return moved;
12174	},
12175
12176	open: function() {
12177		var that = this;
12178		if ( this._isOpen ) {
12179			if ( this._moveToTop() ) {
12180				this._focusTabbable();
12181			}
12182			return;
12183		}
12184
12185		this._isOpen = true;
12186		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12187
12188		this._size();
12189		this._position();
12190		this._createOverlay();
12191		this._moveToTop( null, true );
12192
12193		// Ensure the overlay is moved to the top with the dialog, but only when
12194		// opening. The overlay shouldn't move after the dialog is open so that
12195		// modeless dialogs opened after the modal dialog stack properly.
12196		if ( this.overlay ) {
12197			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12198		}
12199
12200		this._show( this.uiDialog, this.options.show, function() {
12201			that._focusTabbable();
12202			that._trigger( "focus" );
12203		} );
12204
12205		// Track the dialog immediately upon openening in case a focus event
12206		// somehow occurs outside of the dialog before an element inside the
12207		// dialog is focused (#10152)
12208		this._makeFocusTarget();
12209
12210		this._trigger( "open" );
12211	},
12212
12213	_focusTabbable: function() {
12214
12215		// Set focus to the first match:
12216		// 1. An element that was focused previously
12217		// 2. First element inside the dialog matching [autofocus]
12218		// 3. Tabbable element inside the content element
12219		// 4. Tabbable element inside the buttonpane
12220		// 5. The close button
12221		// 6. The dialog itself
12222		var hasFocus = this._focusedElement;
12223		if ( !hasFocus ) {
12224			hasFocus = this.element.find( "[autofocus]" );
12225		}
12226		if ( !hasFocus.length ) {
12227			hasFocus = this.element.find( ":tabbable" );
12228		}
12229		if ( !hasFocus.length ) {
12230			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12231		}
12232		if ( !hasFocus.length ) {
12233			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12234		}
12235		if ( !hasFocus.length ) {
12236			hasFocus = this.uiDialog;
12237		}
12238		hasFocus.eq( 0 ).trigger( "focus" );
12239	},
12240
12241	_keepFocus: function( event ) {
12242		function checkFocus() {
12243			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12244				isActive = this.uiDialog[ 0 ] === activeElement ||
12245					$.contains( this.uiDialog[ 0 ], activeElement );
12246			if ( !isActive ) {
12247				this._focusTabbable();
12248			}
12249		}
12250		event.preventDefault();
12251		checkFocus.call( this );
12252
12253		// support: IE
12254		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12255		// so we check again later
12256		this._delay( checkFocus );
12257	},
12258
12259	_createWrapper: function() {
12260		this.uiDialog = $( "<div>" )
12261			.hide()
12262			.attr( {
12263
12264				// Setting tabIndex makes the div focusable
12265				tabIndex: -1,
12266				role: "dialog"
12267			} )
12268			.appendTo( this._appendTo() );
12269
12270		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12271		this._on( this.uiDialog, {
12272			keydown: function( event ) {
12273				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12274						event.keyCode === $.ui.keyCode.ESCAPE ) {
12275					event.preventDefault();
12276					this.close( event );
12277					return;
12278				}
12279
12280				// Prevent tabbing out of dialogs
12281				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12282					return;
12283				}
12284				var tabbables = this.uiDialog.find( ":tabbable" ),
12285					first = tabbables.filter( ":first" ),
12286					last = tabbables.filter( ":last" );
12287
12288				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12289						!event.shiftKey ) {
12290					this._delay( function() {
12291						first.trigger( "focus" );
12292					} );
12293					event.preventDefault();
12294				} else if ( ( event.target === first[ 0 ] ||
12295						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12296					this._delay( function() {
12297						last.trigger( "focus" );
12298					} );
12299					event.preventDefault();
12300				}
12301			},
12302			mousedown: function( event ) {
12303				if ( this._moveToTop( event ) ) {
12304					this._focusTabbable();
12305				}
12306			}
12307		} );
12308
12309		// We assume that any existing aria-describedby attribute means
12310		// that the dialog content is marked up properly
12311		// otherwise we brute force the content as the description
12312		if ( !this.element.find( "[aria-describedby]" ).length ) {
12313			this.uiDialog.attr( {
12314				"aria-describedby": this.element.uniqueId().attr( "id" )
12315			} );
12316		}
12317	},
12318
12319	_createTitlebar: function() {
12320		var uiDialogTitle;
12321
12322		this.uiDialogTitlebar = $( "<div>" );
12323		this._addClass( this.uiDialogTitlebar,
12324			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12325		this._on( this.uiDialogTitlebar, {
12326			mousedown: function( event ) {
12327
12328				// Don't prevent click on close button (#8838)
12329				// Focusing a dialog that is partially scrolled out of view
12330				// causes the browser to scroll it into view, preventing the click event
12331				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12332
12333					// Dialog isn't getting focus when dragging (#8063)
12334					this.uiDialog.trigger( "focus" );
12335				}
12336			}
12337		} );
12338
12339		// Support: IE
12340		// Use type="button" to prevent enter keypresses in textboxes from closing the
12341		// dialog in IE (#9312)
12342		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12343			.button( {
12344				label: $( "<a>" ).text( this.options.closeText ).html(),
12345				icon: "ui-icon-closethick",
12346				showLabel: false
12347			} )
12348			.appendTo( this.uiDialogTitlebar );
12349
12350		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12351		this._on( this.uiDialogTitlebarClose, {
12352			click: function( event ) {
12353				event.preventDefault();
12354				this.close( event );
12355			}
12356		} );
12357
12358		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12359		this._addClass( uiDialogTitle, "ui-dialog-title" );
12360		this._title( uiDialogTitle );
12361
12362		this.uiDialogTitlebar.prependTo( this.uiDialog );
12363
12364		this.uiDialog.attr( {
12365			"aria-labelledby": uiDialogTitle.attr( "id" )
12366		} );
12367	},
12368
12369	_title: function( title ) {
12370		if ( this.options.title ) {
12371			title.text( this.options.title );
12372		} else {
12373			title.html( "&#160;" );
12374		}
12375	},
12376
12377	_createButtonPane: function() {
12378		this.uiDialogButtonPane = $( "<div>" );
12379		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12380			"ui-widget-content ui-helper-clearfix" );
12381
12382		this.uiButtonSet = $( "<div>" )
12383			.appendTo( this.uiDialogButtonPane );
12384		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12385
12386		this._createButtons();
12387	},
12388
12389	_createButtons: function() {
12390		var that = this,
12391			buttons = this.options.buttons;
12392
12393		// If we already have a button pane, remove it
12394		this.uiDialogButtonPane.remove();
12395		this.uiButtonSet.empty();
12396
12397		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12398			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12399			return;
12400		}
12401
12402		$.each( buttons, function( name, props ) {
12403			var click, buttonOptions;
12404			props = $.isFunction( props ) ?
12405				{ click: props, text: name } :
12406				props;
12407
12408			// Default to a non-submitting button
12409			props = $.extend( { type: "button" }, props );
12410
12411			// Change the context for the click callback to be the main element
12412			click = props.click;
12413			buttonOptions = {
12414				icon: props.icon,
12415				iconPosition: props.iconPosition,
12416				showLabel: props.showLabel
12417			};
12418
12419			delete props.click;
12420			delete props.icon;
12421			delete props.iconPosition;
12422			delete props.showLabel;
12423
12424			$( "<button></button>", props )
12425				.button( buttonOptions )
12426				.appendTo( that.uiButtonSet )
12427				.on( "click", function() {
12428					click.apply( that.element[ 0 ], arguments );
12429				} );
12430		} );
12431		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12432		this.uiDialogButtonPane.appendTo( this.uiDialog );
12433	},
12434
12435	_makeDraggable: function() {
12436		var that = this,
12437			options = this.options;
12438
12439		function filteredUi( ui ) {
12440			return {
12441				position: ui.position,
12442				offset: ui.offset
12443			};
12444		}
12445
12446		this.uiDialog.draggable( {
12447			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12448			handle: ".ui-dialog-titlebar",
12449			containment: "document",
12450			start: function( event, ui ) {
12451				that._addClass( $( this ), "ui-dialog-dragging" );
12452				that._blockFrames();
12453				that._trigger( "dragStart", event, filteredUi( ui ) );
12454			},
12455			drag: function( event, ui ) {
12456				that._trigger( "drag", event, filteredUi( ui ) );
12457			},
12458			stop: function( event, ui ) {
12459				var left = ui.offset.left - that.document.scrollLeft(),
12460					top = ui.offset.top - that.document.scrollTop();
12461
12462				options.position = {
12463					my: "left top",
12464					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12465						"top" + ( top >= 0 ? "+" : "" ) + top,
12466					of: that.window
12467				};
12468				that._removeClass( $( this ), "ui-dialog-dragging" );
12469				that._unblockFrames();
12470				that._trigger( "dragStop", event, filteredUi( ui ) );
12471			}
12472		} );
12473	},
12474
12475	_makeResizable: function() {
12476		var that = this,
12477			options = this.options,
12478			handles = options.resizable,
12479
12480			// .ui-resizable has position: relative defined in the stylesheet
12481			// but dialogs have to use absolute or fixed positioning
12482			position = this.uiDialog.css( "position" ),
12483			resizeHandles = typeof handles === "string" ?
12484				handles :
12485				"n,e,s,w,se,sw,ne,nw";
12486
12487		function filteredUi( ui ) {
12488			return {
12489				originalPosition: ui.originalPosition,
12490				originalSize: ui.originalSize,
12491				position: ui.position,
12492				size: ui.size
12493			};
12494		}
12495
12496		this.uiDialog.resizable( {
12497			cancel: ".ui-dialog-content",
12498			containment: "document",
12499			alsoResize: this.element,
12500			maxWidth: options.maxWidth,
12501			maxHeight: options.maxHeight,
12502			minWidth: options.minWidth,
12503			minHeight: this._minHeight(),
12504			handles: resizeHandles,
12505			start: function( event, ui ) {
12506				that._addClass( $( this ), "ui-dialog-resizing" );
12507				that._blockFrames();
12508				that._trigger( "resizeStart", event, filteredUi( ui ) );
12509			},
12510			resize: function( event, ui ) {
12511				that._trigger( "resize", event, filteredUi( ui ) );
12512			},
12513			stop: function( event, ui ) {
12514				var offset = that.uiDialog.offset(),
12515					left = offset.left - that.document.scrollLeft(),
12516					top = offset.top - that.document.scrollTop();
12517
12518				options.height = that.uiDialog.height();
12519				options.width = that.uiDialog.width();
12520				options.position = {
12521					my: "left top",
12522					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12523						"top" + ( top >= 0 ? "+" : "" ) + top,
12524					of: that.window
12525				};
12526				that._removeClass( $( this ), "ui-dialog-resizing" );
12527				that._unblockFrames();
12528				that._trigger( "resizeStop", event, filteredUi( ui ) );
12529			}
12530		} )
12531			.css( "position", position );
12532	},
12533
12534	_trackFocus: function() {
12535		this._on( this.widget(), {
12536			focusin: function( event ) {
12537				this._makeFocusTarget();
12538				this._focusedElement = $( event.target );
12539			}
12540		} );
12541	},
12542
12543	_makeFocusTarget: function() {
12544		this._untrackInstance();
12545		this._trackingInstances().unshift( this );
12546	},
12547
12548	_untrackInstance: function() {
12549		var instances = this._trackingInstances(),
12550			exists = $.inArray( this, instances );
12551		if ( exists !== -1 ) {
12552			instances.splice( exists, 1 );
12553		}
12554	},
12555
12556	_trackingInstances: function() {
12557		var instances = this.document.data( "ui-dialog-instances" );
12558		if ( !instances ) {
12559			instances = [];
12560			this.document.data( "ui-dialog-instances", instances );
12561		}
12562		return instances;
12563	},
12564
12565	_minHeight: function() {
12566		var options = this.options;
12567
12568		return options.height === "auto" ?
12569			options.minHeight :
12570			Math.min( options.minHeight, options.height );
12571	},
12572
12573	_position: function() {
12574
12575		// Need to show the dialog to get the actual offset in the position plugin
12576		var isVisible = this.uiDialog.is( ":visible" );
12577		if ( !isVisible ) {
12578			this.uiDialog.show();
12579		}
12580		this.uiDialog.position( this.options.position );
12581		if ( !isVisible ) {
12582			this.uiDialog.hide();
12583		}
12584	},
12585
12586	_setOptions: function( options ) {
12587		var that = this,
12588			resize = false,
12589			resizableOptions = {};
12590
12591		$.each( options, function( key, value ) {
12592			that._setOption( key, value );
12593
12594			if ( key in that.sizeRelatedOptions ) {
12595				resize = true;
12596			}
12597			if ( key in that.resizableRelatedOptions ) {
12598				resizableOptions[ key ] = value;
12599			}
12600		} );
12601
12602		if ( resize ) {
12603			this._size();
12604			this._position();
12605		}
12606		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12607			this.uiDialog.resizable( "option", resizableOptions );
12608		}
12609	},
12610
12611	_setOption: function( key, value ) {
12612		var isDraggable, isResizable,
12613			uiDialog = this.uiDialog;
12614
12615		if ( key === "disabled" ) {
12616			return;
12617		}
12618
12619		this._super( key, value );
12620
12621		if ( key === "appendTo" ) {
12622			this.uiDialog.appendTo( this._appendTo() );
12623		}
12624
12625		if ( key === "buttons" ) {
12626			this._createButtons();
12627		}
12628
12629		if ( key === "closeText" ) {
12630			this.uiDialogTitlebarClose.button( {
12631
12632				// Ensure that we always pass a string
12633				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12634			} );
12635		}
12636
12637		if ( key === "draggable" ) {
12638			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12639			if ( isDraggable && !value ) {
12640				uiDialog.draggable( "destroy" );
12641			}
12642
12643			if ( !isDraggable && value ) {
12644				this._makeDraggable();
12645			}
12646		}
12647
12648		if ( key === "position" ) {
12649			this._position();
12650		}
12651
12652		if ( key === "resizable" ) {
12653
12654			// currently resizable, becoming non-resizable
12655			isResizable = uiDialog.is( ":data(ui-resizable)" );
12656			if ( isResizable && !value ) {
12657				uiDialog.resizable( "destroy" );
12658			}
12659
12660			// Currently resizable, changing handles
12661			if ( isResizable && typeof value === "string" ) {
12662				uiDialog.resizable( "option", "handles", value );
12663			}
12664
12665			// Currently non-resizable, becoming resizable
12666			if ( !isResizable && value !== false ) {
12667				this._makeResizable();
12668			}
12669		}
12670
12671		if ( key === "title" ) {
12672			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12673		}
12674	},
12675
12676	_size: function() {
12677
12678		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12679		// divs will both have width and height set, so we need to reset them
12680		var nonContentHeight, minContentHeight, maxContentHeight,
12681			options = this.options;
12682
12683		// Reset content sizing
12684		this.element.show().css( {
12685			width: "auto",
12686			minHeight: 0,
12687			maxHeight: "none",
12688			height: 0
12689		} );
12690
12691		if ( options.minWidth > options.width ) {
12692			options.width = options.minWidth;
12693		}
12694
12695		// Reset wrapper sizing
12696		// determine the height of all the non-content elements
12697		nonContentHeight = this.uiDialog.css( {
12698			height: "auto",
12699			width: options.width
12700		} )
12701			.outerHeight();
12702		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12703		maxContentHeight = typeof options.maxHeight === "number" ?
12704			Math.max( 0, options.maxHeight - nonContentHeight ) :
12705			"none";
12706
12707		if ( options.height === "auto" ) {
12708			this.element.css( {
12709				minHeight: minContentHeight,
12710				maxHeight: maxContentHeight,
12711				height: "auto"
12712			} );
12713		} else {
12714			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12715		}
12716
12717		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12718			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12719		}
12720	},
12721
12722	_blockFrames: function() {
12723		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12724			var iframe = $( this );
12725
12726			return $( "<div>" )
12727				.css( {
12728					position: "absolute",
12729					width: iframe.outerWidth(),
12730					height: iframe.outerHeight()
12731				} )
12732				.appendTo( iframe.parent() )
12733				.offset( iframe.offset() )[ 0 ];
12734		} );
12735	},
12736
12737	_unblockFrames: function() {
12738		if ( this.iframeBlocks ) {
12739			this.iframeBlocks.remove();
12740			delete this.iframeBlocks;
12741		}
12742	},
12743
12744	_allowInteraction: function( event ) {
12745		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12746			return true;
12747		}
12748
12749		// TODO: Remove hack when datepicker implements
12750		// the .ui-front logic (#8989)
12751		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12752	},
12753
12754	_createOverlay: function() {
12755		if ( !this.options.modal ) {
12756			return;
12757		}
12758
12759		// We use a delay in case the overlay is created from an
12760		// event that we're going to be cancelling (#2804)
12761		var isOpening = true;
12762		this._delay( function() {
12763			isOpening = false;
12764		} );
12765
12766		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12767
12768			// Prevent use of anchors and inputs
12769			// Using _on() for an event handler shared across many instances is
12770			// safe because the dialogs stack and must be closed in reverse order
12771			this._on( this.document, {
12772				focusin: function( event ) {
12773					if ( isOpening ) {
12774						return;
12775					}
12776
12777					if ( !this._allowInteraction( event ) ) {
12778						event.preventDefault();
12779						this._trackingInstances()[ 0 ]._focusTabbable();
12780					}
12781				}
12782			} );
12783		}
12784
12785		this.overlay = $( "<div>" )
12786			.appendTo( this._appendTo() );
12787
12788		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12789		this._on( this.overlay, {
12790			mousedown: "_keepFocus"
12791		} );
12792		this.document.data( "ui-dialog-overlays",
12793			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12794	},
12795
12796	_destroyOverlay: function() {
12797		if ( !this.options.modal ) {
12798			return;
12799		}
12800
12801		if ( this.overlay ) {
12802			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12803
12804			if ( !overlays ) {
12805				this._off( this.document, "focusin" );
12806				this.document.removeData( "ui-dialog-overlays" );
12807			} else {
12808				this.document.data( "ui-dialog-overlays", overlays );
12809			}
12810
12811			this.overlay.remove();
12812			this.overlay = null;
12813		}
12814	}
12815} );
12816
12817// DEPRECATED
12818// TODO: switch return back to widget declaration at top of file when this is removed
12819if ( $.uiBackCompat !== false ) {
12820
12821	// Backcompat for dialogClass option
12822	$.widget( "ui.dialog", $.ui.dialog, {
12823		options: {
12824			dialogClass: ""
12825		},
12826		_createWrapper: function() {
12827			this._super();
12828			this.uiDialog.addClass( this.options.dialogClass );
12829		},
12830		_setOption: function( key, value ) {
12831			if ( key === "dialogClass" ) {
12832				this.uiDialog
12833					.removeClass( this.options.dialogClass )
12834					.addClass( value );
12835			}
12836			this._superApply( arguments );
12837		}
12838	} );
12839}
12840
12841var widgetsDialog = $.ui.dialog;
12842
12843
12844/*!
12845 * jQuery UI Droppable 1.12.0
12846 * http://jqueryui.com
12847 *
12848 * Copyright jQuery Foundation and other contributors
12849 * Released under the MIT license.
12850 * http://jquery.org/license
12851 */
12852
12853//>>label: Droppable
12854//>>group: Interactions
12855//>>description: Enables drop targets for draggable elements.
12856//>>docs: http://api.jqueryui.com/droppable/
12857//>>demos: http://jqueryui.com/droppable/
12858
12859
12860
12861$.widget( "ui.droppable", {
12862	version: "1.12.0",
12863	widgetEventPrefix: "drop",
12864	options: {
12865		accept: "*",
12866		addClasses: true,
12867		greedy: false,
12868		scope: "default",
12869		tolerance: "intersect",
12870
12871		// Callbacks
12872		activate: null,
12873		deactivate: null,
12874		drop: null,
12875		out: null,
12876		over: null
12877	},
12878	_create: function() {
12879
12880		var proportions,
12881			o = this.options,
12882			accept = o.accept;
12883
12884		this.isover = false;
12885		this.isout = true;
12886
12887		this.accept = $.isFunction( accept ) ? accept : function( d ) {
12888			return d.is( accept );
12889		};
12890
12891		this.proportions = function( /* valueToWrite */ ) {
12892			if ( arguments.length ) {
12893
12894				// Store the droppable's proportions
12895				proportions = arguments[ 0 ];
12896			} else {
12897
12898				// Retrieve or derive the droppable's proportions
12899				return proportions ?
12900					proportions :
12901					proportions = {
12902						width: this.element[ 0 ].offsetWidth,
12903						height: this.element[ 0 ].offsetHeight
12904					};
12905			}
12906		};
12907
12908		this._addToManager( o.scope );
12909
12910		o.addClasses && this._addClass( "ui-droppable" );
12911
12912	},
12913
12914	_addToManager: function( scope ) {
12915
12916		// Add the reference and positions to the manager
12917		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12918		$.ui.ddmanager.droppables[ scope ].push( this );
12919	},
12920
12921	_splice: function( drop ) {
12922		var i = 0;
12923		for ( ; i < drop.length; i++ ) {
12924			if ( drop[ i ] === this ) {
12925				drop.splice( i, 1 );
12926			}
12927		}
12928	},
12929
12930	_destroy: function() {
12931		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12932
12933		this._splice( drop );
12934	},
12935
12936	_setOption: function( key, value ) {
12937
12938		if ( key === "accept" ) {
12939			this.accept = $.isFunction( value ) ? value : function( d ) {
12940				return d.is( value );
12941			};
12942		} else if ( key === "scope" ) {
12943			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12944
12945			this._splice( drop );
12946			this._addToManager( value );
12947		}
12948
12949		this._super( key, value );
12950	},
12951
12952	_activate: function( event ) {
12953		var draggable = $.ui.ddmanager.current;
12954
12955		this._addActiveClass();
12956		if ( draggable ) {
12957			this._trigger( "activate", event, this.ui( draggable ) );
12958		}
12959	},
12960
12961	_deactivate: function( event ) {
12962		var draggable = $.ui.ddmanager.current;
12963
12964		this._removeActiveClass();
12965		if ( draggable ) {
12966			this._trigger( "deactivate", event, this.ui( draggable ) );
12967		}
12968	},
12969
12970	_over: function( event ) {
12971
12972		var draggable = $.ui.ddmanager.current;
12973
12974		// Bail if draggable and droppable are same element
12975		if ( !draggable || ( draggable.currentItem ||
12976				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12977			return;
12978		}
12979
12980		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12981				draggable.element ) ) ) {
12982			this._addHoverClass();
12983			this._trigger( "over", event, this.ui( draggable ) );
12984		}
12985
12986	},
12987
12988	_out: function( event ) {
12989
12990		var draggable = $.ui.ddmanager.current;
12991
12992		// Bail if draggable and droppable are same element
12993		if ( !draggable || ( draggable.currentItem ||
12994				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12995			return;
12996		}
12997
12998		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12999				draggable.element ) ) ) {
13000			this._removeHoverClass();
13001			this._trigger( "out", event, this.ui( draggable ) );
13002		}
13003
13004	},
13005
13006	_drop: function( event, custom ) {
13007
13008		var draggable = custom || $.ui.ddmanager.current,
13009			childrenIntersection = false;
vendor: 4,744 bytes, lines 13010-13182
13010
13011		// Bail if draggable and droppable are same element
13012		if ( !draggable || ( draggable.currentItem ||
13013				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13014			return false;
13015		}
13016
13017		this.element
13018			.find( ":data(ui-droppable)" )
13019			.not( ".ui-draggable-dragging" )
13020			.each( function() {
13021				var inst = $( this ).droppable( "instance" );
13022				if (
13023					inst.options.greedy &&
13024					!inst.options.disabled &&
13025					inst.options.scope === draggable.options.scope &&
13026					inst.accept.call(
13027						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13028					) &&
13029					intersect(
13030						draggable,
13031						$.extend( inst, { offset: inst.element.offset() } ),
13032						inst.options.tolerance, event
13033					)
13034				) {
13035					childrenIntersection = true;
13036					return false; }
13037			} );
13038		if ( childrenIntersection ) {
13039			return false;
13040		}
13041
13042		if ( this.accept.call( this.element[ 0 ],
13043				( draggable.currentItem || draggable.element ) ) ) {
13044			this._removeActiveClass();
13045			this._removeHoverClass();
13046
13047			this._trigger( "drop", event, this.ui( draggable ) );
13048			return this.element;
13049		}
13050
13051		return false;
13052
13053	},
13054
13055	ui: function( c ) {
13056		return {
13057			draggable: ( c.currentItem || c.element ),
13058			helper: c.helper,
13059			position: c.position,
13060			offset: c.positionAbs
13061		};
13062	},
13063
13064	// Extension points just to make backcompat sane and avoid duplicating logic
13065	// TODO: Remove in 1.13 along with call to it below
13066	_addHoverClass: function() {
13067		this._addClass( "ui-droppable-hover" );
13068	},
13069
13070	_removeHoverClass: function() {
13071		this._removeClass( "ui-droppable-hover" );
13072	},
13073
13074	_addActiveClass: function() {
13075		this._addClass( "ui-droppable-active" );
13076	},
13077
13078	_removeActiveClass: function() {
13079		this._removeClass( "ui-droppable-active" );
13080	}
13081} );
13082
13083var intersect = $.ui.intersect = ( function() {
13084	function isOverAxis( x, reference, size ) {
13085		return ( x >= reference ) && ( x < ( reference + size ) );
13086	}
13087
13088	return function( draggable, droppable, toleranceMode, event ) {
13089
13090		if ( !droppable.offset ) {
13091			return false;
13092		}
13093
13094		var x1 = ( draggable.positionAbs ||
13095				draggable.position.absolute ).left + draggable.margins.left,
13096			y1 = ( draggable.positionAbs ||
13097				draggable.position.absolute ).top + draggable.margins.top,
13098			x2 = x1 + draggable.helperProportions.width,
13099			y2 = y1 + draggable.helperProportions.height,
13100			l = droppable.offset.left,
13101			t = droppable.offset.top,
13102			r = l + droppable.proportions().width,
13103			b = t + droppable.proportions().height;
13104
13105		switch ( toleranceMode ) {
13106		case "fit":
13107			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13108		case "intersect":
13109			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13110				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13111				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13112				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13113		case "pointer":
13114			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13115				isOverAxis( event.pageX, l, droppable.proportions().width );
13116		case "touch":
13117			return (
13118				( y1 >= t && y1 <= b ) || // Top edge touching
13119				( y2 >= t && y2 <= b ) || // Bottom edge touching
13120				( y1 < t && y2 > b ) // Surrounded vertically
13121			) && (
13122				( x1 >= l && x1 <= r ) || // Left edge touching
13123				( x2 >= l && x2 <= r ) || // Right edge touching
13124				( x1 < l && x2 > r ) // Surrounded horizontally
13125			);
13126		default:
13127			return false;
13128		}
13129	};
13130} )();
13131
13132/*
13133	This manager tracks offsets of draggables and droppables
13134*/
13135$.ui.ddmanager = {
13136	current: null,
13137	droppables: { "default": [] },
13138	prepareOffsets: function( t, event ) {
13139
13140		var i, j,
13141			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13142			type = event ? event.type : null, // workaround for #2317
13143			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13144
13145		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13146
13147			// No disabled and non-accepted
13148			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13149					( t.currentItem || t.element ) ) ) ) {
13150				continue;
13151			}
13152
13153			// Filter out elements in the current dragged item
13154			for ( j = 0; j < list.length; j++ ) {
13155				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13156					m[ i ].proportions().height = 0;
13157					continue droppablesLoop;
13158				}
13159			}
13160
13161			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13162			if ( !m[ i ].visible ) {
13163				continue;
13164			}
13165
13166			// Activate the droppable if used directly from draggables
13167			if ( type === "mousedown" ) {
13168				m[ i ]._activate.call( m[ i ], event );
13169			}
13170
13171			m[ i ].offset = m[ i ].element.offset();
13172			m[ i ].proportions( {
13173				width: m[ i ].element[ 0 ].offsetWidth,
13174				height: m[ i ].element[ 0 ].offsetHeight
13175			} );
13176
13177		}
13178
13179	},
13180	drop: function( draggable, event ) {
13181
13182		var dropped = false;
vendor: 4,444 bytes, lines 13183-13337
13183
13184		// Create a copy of the droppables in case the list changes during the drop (#9116)
13185		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13186
13187			if ( !this.options ) {
13188				return;
13189			}
13190			if ( !this.options.disabled && this.visible &&
13191					intersect( draggable, this, this.options.tolerance, event ) ) {
13192				dropped = this._drop.call( this, event ) || dropped;
13193			}
13194
13195			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13196					( draggable.currentItem || draggable.element ) ) ) {
13197				this.isout = true;
13198				this.isover = false;
13199				this._deactivate.call( this, event );
13200			}
13201
13202		} );
13203		return dropped;
13204
13205	},
13206	dragStart: function( draggable, event ) {
13207
13208		// Listen for scrolling so that if the dragging causes scrolling the position of the
13209		// droppables can be recalculated (see #5003)
13210		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13211			if ( !draggable.options.refreshPositions ) {
13212				$.ui.ddmanager.prepareOffsets( draggable, event );
13213			}
13214		} );
13215	},
13216	drag: function( draggable, event ) {
13217
13218		// If you have a highly dynamic page, you might try this option. It renders positions
13219		// every time you move the mouse.
13220		if ( draggable.options.refreshPositions ) {
13221			$.ui.ddmanager.prepareOffsets( draggable, event );
13222		}
13223
13224		// Run through all droppables and check their positions based on specific tolerance options
13225		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13226
13227			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13228				return;
13229			}
13230
13231			var parentInstance, scope, parent,
13232				intersects = intersect( draggable, this, this.options.tolerance, event ),
13233				c = !intersects && this.isover ?
13234					"isout" :
13235					( intersects && !this.isover ? "isover" : null );
13236			if ( !c ) {
13237				return;
13238			}
13239
13240			if ( this.options.greedy ) {
13241
13242				// find droppable parents with same scope
13243				scope = this.options.scope;
13244				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13245					return $( this ).droppable( "instance" ).options.scope === scope;
13246				} );
13247
13248				if ( parent.length ) {
13249					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13250					parentInstance.greedyChild = ( c === "isover" );
13251				}
13252			}
13253
13254			// We just moved into a greedy child
13255			if ( parentInstance && c === "isover" ) {
13256				parentInstance.isover = false;
13257				parentInstance.isout = true;
13258				parentInstance._out.call( parentInstance, event );
13259			}
13260
13261			this[ c ] = true;
13262			this[ c === "isout" ? "isover" : "isout" ] = false;
13263			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13264
13265			// We just moved out of a greedy child
13266			if ( parentInstance && c === "isout" ) {
13267				parentInstance.isout = false;
13268				parentInstance.isover = true;
13269				parentInstance._over.call( parentInstance, event );
13270			}
13271		} );
13272
13273	},
13274	dragStop: function( draggable, event ) {
13275		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13276
13277		// Call prepareOffsets one final time since IE does not fire return scroll events when
13278		// overflow was caused by drag (see #5003)
13279		if ( !draggable.options.refreshPositions ) {
13280			$.ui.ddmanager.prepareOffsets( draggable, event );
13281		}
13282	}
13283};
13284
13285// DEPRECATED
13286// TODO: switch return back to widget declaration at top of file when this is removed
13287if ( $.uiBackCompat !== false ) {
13288
13289	// Backcompat for activeClass and hoverClass options
13290	$.widget( "ui.droppable", $.ui.droppable, {
13291		options: {
13292			hoverClass: false,
13293			activeClass: false
13294		},
13295		_addActiveClass: function() {
13296			this._super();
13297			if ( this.options.activeClass ) {
13298				this.element.addClass( this.options.activeClass );
13299			}
13300		},
13301		_removeActiveClass: function() {
13302			this._super();
13303			if ( this.options.activeClass ) {
13304				this.element.removeClass( this.options.activeClass );
13305			}
13306		},
13307		_addHoverClass: function() {
13308			this._super();
13309			if ( this.options.hoverClass ) {
13310				this.element.addClass( this.options.hoverClass );
13311			}
13312		},
13313		_removeHoverClass: function() {
13314			this._super();
13315			if ( this.options.hoverClass ) {
13316				this.element.removeClass( this.options.hoverClass );
13317			}
13318		}
13319	} );
13320}
13321
13322var widgetsDroppable = $.ui.droppable;
13323
13324
13325/*!
13326 * jQuery UI Progressbar 1.12.0
13327 * http://jqueryui.com
13328 *
13329 * Copyright jQuery Foundation and other contributors
13330 * Released under the MIT license.
13331 * http://jquery.org/license
13332 */
13333
13334//>>label: Progressbar
13335//>>group: Widgets
13336// jscs:disable maximumLineLength
13337//>>
vendor: 15,214 bytes, lines 13337-13930
13337description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13338// jscs:enable maximumLineLength
13339//>>docs: http://api.jqueryui.com/progressbar/
13340//>>demos: http://jqueryui.com/progressbar/
13341//>>css.structure: ../../themes/base/core.css
13342//>>css.structure: ../../themes/base/progressbar.css
13343//>>css.theme: ../../themes/base/theme.css
13344
13345
13346
13347var widgetsProgressbar = $.widget( "ui.progressbar", {
13348	version: "1.12.0",
13349	options: {
13350		classes: {
13351			"ui-progressbar": "ui-corner-all",
13352			"ui-progressbar-value": "ui-corner-left",
13353			"ui-progressbar-complete": "ui-corner-right"
13354		},
13355		max: 100,
13356		value: 0,
13357
13358		change: null,
13359		complete: null
13360	},
13361
13362	min: 0,
13363
13364	_create: function() {
13365
13366		// Constrain initial value
13367		this.oldValue = this.options.value = this._constrainedValue();
13368
13369		this.element.attr( {
13370
13371			// Only set static values; aria-valuenow and aria-valuemax are
13372			// set inside _refreshValue()
13373			role: "progressbar",
13374			"aria-valuemin": this.min
13375		} );
13376		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13377
13378		this.valueDiv = $( "<div>" ).appendTo( this.element );
13379		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13380		this._refreshValue();
13381	},
13382
13383	_destroy: function() {
13384		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13385
13386		this.valueDiv.remove();
13387	},
13388
13389	value: function( newValue ) {
13390		if ( newValue === undefined ) {
13391			return this.options.value;
13392		}
13393
13394		this.options.value = this._constrainedValue( newValue );
13395		this._refreshValue();
13396	},
13397
13398	_constrainedValue: function( newValue ) {
13399		if ( newValue === undefined ) {
13400			newValue = this.options.value;
13401		}
13402
13403		this.indeterminate = newValue === false;
13404
13405		// Sanitize value
13406		if ( typeof newValue !== "number" ) {
13407			newValue = 0;
13408		}
13409
13410		return this.indeterminate ? false :
13411			Math.min( this.options.max, Math.max( this.min, newValue ) );
13412	},
13413
13414	_setOptions: function( options ) {
13415
13416		// Ensure "value" option is set after other values (like max)
13417		var value = options.value;
13418		delete options.value;
13419
13420		this._super( options );
13421
13422		this.options.value = this._constrainedValue( value );
13423		this._refreshValue();
13424	},
13425
13426	_setOption: function( key, value ) {
13427		if ( key === "max" ) {
13428
13429			// Don't allow a max less than min
13430			value = Math.max( this.min, value );
13431		}
13432		this._super( key, value );
13433	},
13434
13435	_setOptionDisabled: function( value ) {
13436		this._super( value );
13437
13438		this.element.attr( "aria-disabled", value );
13439		this._toggleClass( null, "ui-state-disabled", !!value );
13440	},
13441
13442	_percentage: function() {
13443		return this.indeterminate ?
13444			100 :
13445			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13446	},
13447
13448	_refreshValue: function() {
13449		var value = this.options.value,
13450			percentage = this._percentage();
13451
13452		this.valueDiv
13453			.toggle( this.indeterminate || value > this.min )
13454			.width( percentage.toFixed( 0 ) + "%" );
13455
13456		this
13457			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13458				value === this.options.max )
13459			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13460
13461		if ( this.indeterminate ) {
13462			this.element.removeAttr( "aria-valuenow" );
13463			if ( !this.overlayDiv ) {
13464				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13465				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13466			}
13467		} else {
13468			this.element.attr( {
13469				"aria-valuemax": this.options.max,
13470				"aria-valuenow": value
13471			} );
13472			if ( this.overlayDiv ) {
13473				this.overlayDiv.remove();
13474				this.overlayDiv = null;
13475			}
13476		}
13477
13478		if ( this.oldValue !== value ) {
13479			this.oldValue = value;
13480			this._trigger( "change" );
13481		}
13482		if ( value === this.options.max ) {
13483			this._trigger( "complete" );
13484		}
13485	}
13486} );
13487
13488
13489/*!
13490 * jQuery UI Selectable 1.12.0
13491 * http://jqueryui.com
13492 *
13493 * Copyright jQuery Foundation and other contributors
13494 * Released under the MIT license.
13495 * http://jquery.org/license
13496 */
13497
13498//>>label: Selectable
13499//>>group: Interactions
13500//>>description: Allows groups of elements to be selected with the mouse.
13501//>>docs: http://api.jqueryui.com/selectable/
13502//>>demos: http://jqueryui.com/selectable/
13503//>>css.structure: ../../themes/base/selectable.css
13504
13505
13506
13507var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13508	version: "1.12.0",
13509	options: {
13510		appendTo: "body",
13511		autoRefresh: true,
13512		distance: 0,
13513		filter: "*",
13514		tolerance: "touch",
13515
13516		// Callbacks
13517		selected: null,
13518		selecting: null,
13519		start: null,
13520		stop: null,
13521		unselected: null,
13522		unselecting: null
13523	},
13524	_create: function() {
13525		var that = this;
13526
13527		this._addClass( "ui-selectable" );
13528
13529		this.dragged = false;
13530
13531		// Cache selectee children based on filter
13532		this.refresh = function() {
13533			that.elementPos = $( that.element[ 0 ] ).offset();
13534			that.selectees = $( that.options.filter, that.element[ 0 ] );
13535			that._addClass( that.selectees, "ui-selectee" );
13536			that.selectees.each( function() {
13537				var $this = $( this ),
13538					selecteeOffset = $this.offset(),
13539					pos = {
13540						left: selecteeOffset.left - that.elementPos.left,
13541						top: selecteeOffset.top - that.elementPos.top
13542					};
13543				$.data( this, "selectable-item", {
13544					element: this,
13545					$element: $this,
13546					left: pos.left,
13547					top: pos.top,
13548					right: pos.left + $this.outerWidth(),
13549					bottom: pos.top + $this.outerHeight(),
13550					startselected: false,
13551					selected: $this.hasClass( "ui-selected" ),
13552					selecting: $this.hasClass( "ui-selecting" ),
13553					unselecting: $this.hasClass( "ui-unselecting" )
13554				} );
13555			} );
13556		};
13557		this.refresh();
13558
13559		this._mouseInit();
13560
13561		this.helper = $( "<div>" );
13562		this._addClass( this.helper, "ui-selectable-helper" );
13563	},
13564
13565	_destroy: function() {
13566		this.selectees.removeData( "selectable-item" );
13567		this._mouseDestroy();
13568	},
13569
13570	_mouseStart: function( event ) {
13571		var that = this,
13572			options = this.options;
13573
13574		this.opos = [ event.pageX, event.pageY ];
13575		this.elementPos = $( this.element[ 0 ] ).offset();
13576
13577		if ( this.options.disabled ) {
13578			return;
13579		}
13580
13581		this.selectees = $( options.filter, this.element[ 0 ] );
13582
13583		this._trigger( "start", event );
13584
13585		$( options.appendTo ).append( this.helper );
13586
13587		// position helper (lasso)
13588		this.helper.css( {
13589			"left": event.pageX,
13590			"top": event.pageY,
13591			"width": 0,
13592			"height": 0
13593		} );
13594
13595		if ( options.autoRefresh ) {
13596			this.refresh();
13597		}
13598
13599		this.selectees.filter( ".ui-selected" ).each( function() {
13600			var selectee = $.data( this, "selectable-item" );
13601			selectee.startselected = true;
13602			if ( !event.metaKey && !event.ctrlKey ) {
13603				that._removeClass( selectee.$element, "ui-selected" );
13604				selectee.selected = false;
13605				that._addClass( selectee.$element, "ui-unselecting" );
13606				selectee.unselecting = true;
13607
13608				// selectable UNSELECTING callback
13609				that._trigger( "unselecting", event, {
13610					unselecting: selectee.element
13611				} );
13612			}
13613		} );
13614
13615		$( event.target ).parents().addBack().each( function() {
13616			var doSelect,
13617				selectee = $.data( this, "selectable-item" );
13618			if ( selectee ) {
13619				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13620					!selectee.$element.hasClass( "ui-selected" );
13621				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13622					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13623				selectee.unselecting = !doSelect;
13624				selectee.selecting = doSelect;
13625				selectee.selected = doSelect;
13626
13627				// selectable (UN)SELECTING callback
13628				if ( doSelect ) {
13629					that._trigger( "selecting", event, {
13630						selecting: selectee.element
13631					} );
13632				} else {
13633					that._trigger( "unselecting", event, {
13634						unselecting: selectee.element
13635					} );
13636				}
13637				return false;
13638			}
13639		} );
13640
13641	},
13642
13643	_mouseDrag: function( event ) {
13644
13645		this.dragged = true;
13646
13647		if ( this.options.disabled ) {
13648			return;
13649		}
13650
13651		var tmp,
13652			that = this,
13653			options = this.options,
13654			x1 = this.opos[ 0 ],
13655			y1 = this.opos[ 1 ],
13656			x2 = event.pageX,
13657			y2 = event.pageY;
13658
13659		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13660		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13661		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13662
13663		this.selectees.each( function() {
13664			var selectee = $.data( this, "selectable-item" ),
13665				hit = false,
13666				offset = {};
13667
13668			//prevent helper from being selected if appendTo: selectable
13669			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13670				return;
13671			}
13672
13673			offset.left   = selectee.left   + that.elementPos.left;
13674			offset.right  = selectee.right  + that.elementPos.left;
13675			offset.top    = selectee.top    + that.elementPos.top;
13676			offset.bottom = selectee.bottom + that.elementPos.top;
13677
13678			if ( options.tolerance === "touch" ) {
13679				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13680                    offset.bottom < y1 ) );
13681			} else if ( options.tolerance === "fit" ) {
13682				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13683                    offset.bottom < y2 );
13684			}
13685
13686			if ( hit ) {
13687
13688				// SELECT
13689				if ( selectee.selected ) {
13690					that._removeClass( selectee.$element, "ui-selected" );
13691					selectee.selected = false;
13692				}
13693				if ( selectee.unselecting ) {
13694					that._removeClass( selectee.$element, "ui-unselecting" );
13695					selectee.unselecting = false;
13696				}
13697				if ( !selectee.selecting ) {
13698					that._addClass( selectee.$element, "ui-selecting" );
13699					selectee.selecting = true;
13700
13701					// selectable SELECTING callback
13702					that._trigger( "selecting", event, {
13703						selecting: selectee.element
13704					} );
13705				}
13706			} else {
13707
13708				// UNSELECT
13709				if ( selectee.selecting ) {
13710					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13711						that._removeClass( selectee.$element, "ui-selecting" );
13712						selectee.selecting = false;
13713						that._addClass( selectee.$element, "ui-selected" );
13714						selectee.selected = true;
13715					} else {
13716						that._removeClass( selectee.$element, "ui-selecting" );
13717						selectee.selecting = false;
13718						if ( selectee.startselected ) {
13719							that._addClass( selectee.$element, "ui-unselecting" );
13720							selectee.unselecting = true;
13721						}
13722
13723						// selectable UNSELECTING callback
13724						that._trigger( "unselecting", event, {
13725							unselecting: selectee.element
13726						} );
13727					}
13728				}
13729				if ( selectee.selected ) {
13730					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13731						that._removeClass( selectee.$element, "ui-selected" );
13732						selectee.selected = false;
13733
13734						that._addClass( selectee.$element, "ui-unselecting" );
13735						selectee.unselecting = true;
13736
13737						// selectable UNSELECTING callback
13738						that._trigger( "unselecting", event, {
13739							unselecting: selectee.element
13740						} );
13741					}
13742				}
13743			}
13744		} );
13745
13746		return false;
13747	},
13748
13749	_mouseStop: function( event ) {
13750		var that = this;
13751
13752		this.dragged = false;
13753
13754		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13755			var selectee = $.data( this, "selectable-item" );
13756			that._removeClass( selectee.$element, "ui-unselecting" );
13757			selectee.unselecting = false;
13758			selectee.startselected = false;
13759			that._trigger( "unselected", event, {
13760				unselected: selectee.element
13761			} );
13762		} );
13763		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13764			var selectee = $.data( this, "selectable-item" );
13765			that._removeClass( selectee.$element, "ui-selecting" )
13766				._addClass( selectee.$element, "ui-selected" );
13767			selectee.selecting = false;
13768			selectee.selected = true;
13769			selectee.startselected = true;
13770			that._trigger( "selected", event, {
13771				selected: selectee.element
13772			} );
13773		} );
13774		this._trigger( "stop", event );
13775
13776		this.helper.remove();
13777
13778		return false;
13779	}
13780
13781} );
13782
13783
13784/*!
13785 * jQuery UI Selectmenu 1.12.0
13786 * http://jqueryui.com
13787 *
13788 * Copyright jQuery Foundation and other contributors
13789 * Released under the MIT license.
13790 * http://jquery.org/license
13791 */
13792
13793//>>label: Selectmenu
13794//>>group: Widgets
13795// jscs:disable maximumLineLength
13796//>>description: Duplicates and extends the functionality of a native HTML select element, allowing it to be customizable in behavior and appearance far beyond the limitations of a native select.
13797// jscs:enable maximumLineLength
13798//>>docs: http://api.jqueryui.com/selectmenu/
13799//>>demos: http://jqueryui.com/selectmenu/
13800//>>css.structure: ../../themes/base/core.css
13801//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13802//>>css.theme: ../../themes/base/theme.css
13803
13804
13805
13806var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13807	version: "1.12.0",
13808	defaultElement: "<select>",
13809	options: {
13810		appendTo: null,
13811		classes: {
13812			"ui-selectmenu-button-open": "ui-corner-top",
13813			"ui-selectmenu-button-closed": "ui-corner-all"
13814		},
13815		disabled: null,
13816		icons: {
13817			button: "ui-icon-triangle-1-s"
13818		},
13819		position: {
13820			my: "left top",
13821			at: "left bottom",
13822			collision: "none"
13823		},
13824		width: false,
13825
13826		// Callbacks
13827		change: null,
13828		close: null,
13829		focus: null,
13830		open: null,
13831		select: null
13832	},
13833
13834	_create: function() {
13835		var selectmenuId = this.element.uniqueId().attr( "id" );
13836		this.ids = {
13837			element: selectmenuId,
13838			button: selectmenuId + "-button",
13839			menu: selectmenuId + "-menu"
13840		};
13841
13842		this._drawButton();
13843		this._drawMenu();
13844		this._bindFormResetHandler();
13845
13846		this._rendered = false;
13847		this.menuItems = $();
13848	},
13849
13850	_drawButton: function() {
13851		var icon,
13852			that = this,
13853			item = this._parseOption(
13854				this.element.find( "option:selected" ),
13855				this.element[ 0 ].selectedIndex
13856			);
13857
13858		// Associate existing label with the new button
13859		this.labels = this.element.labels().attr( "for", this.ids.button );
13860		this._on( this.labels, {
13861			click: function( event ) {
13862				this.button.focus();
13863				event.preventDefault();
13864			}
13865		} );
13866
13867		// Hide original select element
13868		this.element.hide();
13869
13870		// Create button
13871		this.button = $( "<span>", {
13872			tabindex: this.options.disabled ? -1 : 0,
13873			id: this.ids.button,
13874			role: "combobox",
13875			"aria-expanded": "false",
13876			"aria-autocomplete": "list",
13877			"aria-owns": this.ids.menu,
13878			"aria-haspopup": "true",
13879			title: this.element.attr( "title" )
13880		} )
13881			.insertAfter( this.element );
13882
13883		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13884			"ui-button ui-widget" );
13885
13886		icon = $( "<span>" ).appendTo( this.button );
13887		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13888		this.buttonItem = this._renderButtonItem( item )
13889			.appendTo( this.button );
13890
13891		if ( this.options.width !== false ) {
13892			this._resizeButton();
13893		}
13894
13895		this._on( this.button, this._buttonEvents );
13896		this.button.one( "focusin", function() {
13897
13898			// Delay rendering the menu items until the button receives focus.
13899			// The menu may have already been rendered via a programmatic open.
13900			if ( !that._rendered ) {
13901				that._refreshMenu();
13902			}
13903		} );
13904	},
13905
13906	_drawMenu: function() {
13907		var that = this;
13908
13909		// Create menu
13910		this.menu = $( "<ul>", {
13911			"aria-hidden": "true",
13912			"aria-labelledby": this.ids.button,
13913			id: this.ids.menu
13914		} );
13915
13916		// Wrap menu
13917		this.menuWrap = $( "<div>" ).append( this.menu );
13918		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13919		this.menuWrap.appendTo( this._appendTo() );
13920
13921		// Initialize menu widget
13922		this.menuInstance = this.menu
13923			.menu( {
13924				classes: {
13925					"ui-menu": "ui-corner-bottom"
13926				},
13927				role: "listbox",
13928				select: function( event, ui ) {
13929					event.preventDefault();
13930
vendor: 5,595 bytes, lines 13931-14171
13931					// Support: IE8
13932					// If the item was selected via a click, the text selection
13933					// will be destroyed in IE
13934					that._setSelection();
13935
13936					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13937				},
13938				focus: function( event, ui ) {
13939					var item = ui.item.data( "ui-selectmenu-item" );
13940
13941					// Prevent inital focus from firing and check if its a newly focused item
13942					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13943						that._trigger( "focus", event, { item: item } );
13944						if ( !that.isOpen ) {
13945							that._select( item, event );
13946						}
13947					}
13948					that.focusIndex = item.index;
13949
13950					that.button.attr( "aria-activedescendant",
13951						that.menuItems.eq( item.index ).attr( "id" ) );
13952				}
13953			} )
13954			.menu( "instance" );
13955
13956		// Don't close the menu on mouseleave
13957		this.menuInstance._off( this.menu, "mouseleave" );
13958
13959		// Cancel the menu's collapseAll on document click
13960		this.menuInstance._closeOnDocumentClick = function() {
13961			return false;
13962		};
13963
13964		// Selects often contain empty items, but never contain dividers
13965		this.menuInstance._isDivider = function() {
13966			return false;
13967		};
13968	},
13969
13970	refresh: function() {
13971		this._refreshMenu();
13972		this.buttonItem.replaceWith(
13973			this.buttonItem = this._renderButtonItem(
13974
13975				// Fall back to an empty object in case there are no options
13976				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13977			)
13978		);
13979		if ( this.options.width === null ) {
13980			this._resizeButton();
13981		}
13982	},
13983
13984	_refreshMenu: function() {
13985		var item,
13986			options = this.element.find( "option" );
13987
13988		this.menu.empty();
13989
13990		this._parseOptions( options );
13991		this._renderMenu( this.menu, this.items );
13992
13993		this.menuInstance.refresh();
13994		this.menuItems = this.menu.find( "li" )
13995			.not( ".ui-selectmenu-optgroup" )
13996				.find( ".ui-menu-item-wrapper" );
13997
13998		this._rendered = true;
13999
14000		if ( !options.length ) {
14001			return;
14002		}
14003
14004		item = this._getSelectedItem();
14005
14006		// Update the menu to have the correct item focused
14007		this.menuInstance.focus( null, item );
14008		this._setAria( item.data( "ui-selectmenu-item" ) );
14009
14010		// Set disabled state
14011		this._setOption( "disabled", this.element.prop( "disabled" ) );
14012	},
14013
14014	open: function( event ) {
14015		if ( this.options.disabled ) {
14016			return;
14017		}
14018
14019		// If this is the first time the menu is being opened, render the items
14020		if ( !this._rendered ) {
14021			this._refreshMenu();
14022		} else {
14023
14024			// Menu clears focus on close, reset focus to selected item
14025			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14026			this.menuInstance.focus( null, this._getSelectedItem() );
14027		}
14028
14029		// If there are no options, don't open the menu
14030		if ( !this.menuItems.length ) {
14031			return;
14032		}
14033
14034		this.isOpen = true;
14035		this._toggleAttr();
14036		this._resizeMenu();
14037		this._position();
14038
14039		this._on( this.document, this._documentClick );
14040
14041		this._trigger( "open", event );
14042	},
14043
14044	_position: function() {
14045		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14046	},
14047
14048	close: function( event ) {
14049		if ( !this.isOpen ) {
14050			return;
14051		}
14052
14053		this.isOpen = false;
14054		this._toggleAttr();
14055
14056		this.range = null;
14057		this._off( this.document );
14058
14059		this._trigger( "close", event );
14060	},
14061
14062	widget: function() {
14063		return this.button;
14064	},
14065
14066	menuWidget: function() {
14067		return this.menu;
14068	},
14069
14070	_renderButtonItem: function( item ) {
14071		var buttonItem = $( "<span>" );
14072
14073		this._setText( buttonItem, item.label );
14074		this._addClass( buttonItem, "ui-selectmenu-text" );
14075
14076		return buttonItem;
14077	},
14078
14079	_renderMenu: function( ul, items ) {
14080		var that = this,
14081			currentOptgroup = "";
14082
14083		$.each( items, function( index, item ) {
14084			var li;
14085
14086			if ( item.optgroup !== currentOptgroup ) {
14087				li = $( "<li>", {
14088					text: item.optgroup
14089				} );
14090				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14091					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14092						" ui-state-disabled" :
14093						"" ) );
14094
14095				li.appendTo( ul );
14096
14097				currentOptgroup = item.optgroup;
14098			}
14099
14100			that._renderItemData( ul, item );
14101		} );
14102	},
14103
14104	_renderItemData: function( ul, item ) {
14105		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14106	},
14107
14108	_renderItem: function( ul, item ) {
14109		var li = $( "<li>" ),
14110			wrapper = $( "<div>", {
14111				title: item.element.attr( "title" )
14112			} );
14113
14114		if ( item.disabled ) {
14115			this._addClass( li, null, "ui-state-disabled" );
14116		}
14117		this._setText( wrapper, item.label );
14118
14119		return li.append( wrapper ).appendTo( ul );
14120	},
14121
14122	_setText: function( element, value ) {
14123		if ( value ) {
14124			element.text( value );
14125		} else {
14126			element.html( "&#160;" );
14127		}
14128	},
14129
14130	_move: function( direction, event ) {
14131		var item, next,
14132			filter = ".ui-menu-item";
14133
14134		if ( this.isOpen ) {
14135			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14136		} else {
14137			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14138			filter += ":not(.ui-state-disabled)";
14139		}
14140
14141		if ( direction === "first" || direction === "last" ) {
14142			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14143		} else {
14144			next = item[ direction + "All" ]( filter ).eq( 0 );
14145		}
14146
14147		if ( next.length ) {
14148			this.menuInstance.focus( event, next );
14149		}
14150	},
14151
14152	_getSelectedItem: function() {
14153		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14154	},
14155
14156	_toggle: function( event ) {
14157		this[ this.isOpen ? "close" : "open" ]( event );
14158	},
14159
14160	_setSelection: function() {
14161		var selection;
14162
14163		if ( !this.range ) {
14164			return;
14165		}
14166
14167		if ( window.getSelection ) {
14168			selection = window.getSelection();
14169			selection.removeAllRanges();
14170			selection.addRange( this.range );
14171
14172		// Support: IE8
14173		} else {
14174			this.range.select();
14175		}
14176
14177		// Support: IE
14178		// Setting the text selection kills the button focus in IE, but
14179		// restoring the focus doesn't kill the selection.
14180		this.button.focus();
14181	},
14182
14183	_documentClick: {
14184		mousedown: function( event ) {
14185			if ( !this.isOpen ) {
14186				return;
14187			}
14188
14189			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14190					$.ui
vendor: 5,768 bytes, lines 14190-14434
14190.escapeSelector( this.ids.button ) ).length ) {
14191				this.close( event );
14192			}
14193		}
14194	},
14195
14196	_buttonEvents: {
14197
14198		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14199		mousedown: function() {
14200			var selection;
14201
14202			if ( window.getSelection ) {
14203				selection = window.getSelection();
14204				if ( selection.rangeCount ) {
14205					this.range = selection.getRangeAt( 0 );
14206				}
14207
14208			// Support: IE8
14209			} else {
14210				this.range = document.selection.createRange();
14211			}
14212		},
14213
14214		click: function( event ) {
14215			this._setSelection();
14216			this._toggle( event );
14217		},
14218
14219		keydown: function( event ) {
14220			var preventDefault = true;
14221			switch ( event.keyCode ) {
14222			case $.ui.keyCode.TAB:
14223			case $.ui.keyCode.ESCAPE:
14224				this.close( event );
14225				preventDefault = false;
14226				break;
14227			case $.ui.keyCode.ENTER:
14228				if ( this.isOpen ) {
14229					this._selectFocusedItem( event );
14230				}
14231				break;
14232			case $.ui.keyCode.UP:
14233				if ( event.altKey ) {
14234					this._toggle( event );
14235				} else {
14236					this._move( "prev", event );
14237				}
14238				break;
14239			case $.ui.keyCode.DOWN:
14240				if ( event.altKey ) {
14241					this._toggle( event );
14242				} else {
14243					this._move( "next", event );
14244				}
14245				break;
14246			case $.ui.keyCode.SPACE:
14247				if ( this.isOpen ) {
14248					this._selectFocusedItem( event );
14249				} else {
14250					this._toggle( event );
14251				}
14252				break;
14253			case $.ui.keyCode.LEFT:
14254				this._move( "prev", event );
14255				break;
14256			case $.ui.keyCode.RIGHT:
14257				this._move( "next", event );
14258				break;
14259			case $.ui.keyCode.HOME:
14260			case $.ui.keyCode.PAGE_UP:
14261				this._move( "first", event );
14262				break;
14263			case $.ui.keyCode.END:
14264			case $.ui.keyCode.PAGE_DOWN:
14265				this._move( "last", event );
14266				break;
14267			default:
14268				this.menu.trigger( event );
14269				preventDefault = false;
14270			}
14271
14272			if ( preventDefault ) {
14273				event.preventDefault();
14274			}
14275		}
14276	},
14277
14278	_selectFocusedItem: function( event ) {
14279		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14280		if ( !item.hasClass( "ui-state-disabled" ) ) {
14281			this._select( item.data( "ui-selectmenu-item" ), event );
14282		}
14283	},
14284
14285	_select: function( item, event ) {
14286		var oldIndex = this.element[ 0 ].selectedIndex;
14287
14288		// Change native select element
14289		this.element[ 0 ].selectedIndex = item.index;
14290		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14291		this._setAria( item );
14292		this._trigger( "select", event, { item: item } );
14293
14294		if ( item.index !== oldIndex ) {
14295			this._trigger( "change", event, { item: item } );
14296		}
14297
14298		this.close( event );
14299	},
14300
14301	_setAria: function( item ) {
14302		var id = this.menuItems.eq( item.index ).attr( "id" );
14303
14304		this.button.attr( {
14305			"aria-labelledby": id,
14306			"aria-activedescendant": id
14307		} );
14308		this.menu.attr( "aria-activedescendant", id );
14309	},
14310
14311	_setOption: function( key, value ) {
14312		if ( key === "icons" ) {
14313			var icon = this.button.find( "span.ui-icon" );
14314			this._removeClass( icon, null, this.options.icons.button )
14315				._addClass( icon, null, value.button );
14316		}
14317
14318		this._super( key, value );
14319
14320		if ( key === "appendTo" ) {
14321			this.menuWrap.appendTo( this._appendTo() );
14322		}
14323
14324		if ( key === "width" ) {
14325			this._resizeButton();
14326		}
14327	},
14328
14329	_setOptionDisabled: function( value ) {
14330		this._super( value );
14331
14332		this.menuInstance.option( "disabled", value );
14333		this.button.attr( "aria-disabled", value );
14334		this._toggleClass( this.button, null, "ui-state-disabled", value );
14335
14336		this.element.prop( "disabled", value );
14337		if ( value ) {
14338			this.button.attr( "tabindex", -1 );
14339			this.close();
14340		} else {
14341			this.button.attr( "tabindex", 0 );
14342		}
14343	},
14344
14345	_appendTo: function() {
14346		var element = this.options.appendTo;
14347
14348		if ( element ) {
14349			element = element.jquery || element.nodeType ?
14350				$( element ) :
14351				this.document.find( element ).eq( 0 );
14352		}
14353
14354		if ( !element || !element[ 0 ] ) {
14355			element = this.element.closest( ".ui-front, dialog" );
14356		}
14357
14358		if ( !element.length ) {
14359			element = this.document[ 0 ].body;
14360		}
14361
14362		return element;
14363	},
14364
14365	_toggleAttr: function() {
14366		this.button.attr( "aria-expanded", this.isOpen );
14367
14368		// We can't use two _toggleClass() calls here, because we need to make sure
14369		// we always remove classes first and add them second, otherwise if both classes have the
14370		// same theme class, it will be removed after we add it.
14371		this._removeClass( this.button, "ui-selectmenu-button-" +
14372			( this.isOpen ? "closed" : "open" ) )
14373			._addClass( this.button, "ui-selectmenu-button-" +
14374				( this.isOpen ? "open" : "closed" ) )
14375			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14376
14377		this.menu.attr( "aria-hidden", !this.isOpen );
14378	},
14379
14380	_resizeButton: function() {
14381		var width = this.options.width;
14382
14383		// For `width: false`, just remove inline style and stop
14384		if ( width === false ) {
14385			this.button.css( "width", "" );
14386			return;
14387		}
14388
14389		// For `width: null`, match the width of the original element
14390		if ( width === null ) {
14391			width = this.element.show().outerWidth();
14392			this.element.hide();
14393		}
14394
14395		this.button.outerWidth( width );
14396	},
14397
14398	_resizeMenu: function() {
14399		this.menu.outerWidth( Math.max(
14400			this.button.outerWidth(),
14401
14402			// Support: IE10
14403			// IE10 wraps long text (possibly a rounding bug)
14404			// so we add 1px to avoid the wrapping
14405			this.menu.width( "" ).outerWidth() + 1
14406		) );
14407	},
14408
14409	_getCreateOptions: function() {
14410		var options = this._super();
14411
14412		options.disabled = this.element.prop( "disabled" );
14413
14414		return options;
14415	},
14416
14417	_parseOptions: function( options ) {
14418		var that = this,
14419			data = [];
14420		options.each( function( index, item ) {
14421			data.push( that._parseOption( $( item ), index ) );
14422		} );
14423		this.items = data;
14424	},
14425
14426	_parseOption: function( option, index ) {
14427		var optgroup = option.parent( "optgroup" );
14428
14429		return {
14430			element: option,
14431			index: index,
14432			value: option.val(),
14433			label: option.text(),
14434			
vendor: 3,316 bytes, lines 14434-14566
14434optgroup: optgroup.attr( "label" ) || "",
14435			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14436		};
14437	},
14438
14439	_destroy: function() {
14440		this._unbindFormResetHandler();
14441		this.menuWrap.remove();
14442		this.button.remove();
14443		this.element.show();
14444		this.element.removeUniqueId();
14445		this.labels.attr( "for", this.ids.element );
14446	}
14447} ] );
14448
14449
14450/*!
14451 * jQuery UI Slider 1.12.0
14452 * http://jqueryui.com
14453 *
14454 * Copyright jQuery Foundation and other contributors
14455 * Released under the MIT license.
14456 * http://jquery.org/license
14457 */
14458
14459//>>label: Slider
14460//>>group: Widgets
14461//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14462//>>docs: http://api.jqueryui.com/slider/
14463//>>demos: http://jqueryui.com/slider/
14464//>>css.structure: ../../themes/base/core.css
14465//>>css.structure: ../../themes/base/slider.css
14466//>>css.theme: ../../themes/base/theme.css
14467
14468
14469
14470var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14471	version: "1.12.0",
14472	widgetEventPrefix: "slide",
14473
14474	options: {
14475		animate: false,
14476		classes: {
14477			"ui-slider": "ui-corner-all",
14478			"ui-slider-handle": "ui-corner-all",
14479
14480			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14481			// element, but worked best visually with a variety of themes
14482			"ui-slider-range": "ui-corner-all ui-widget-header"
14483		},
14484		distance: 0,
14485		max: 100,
14486		min: 0,
14487		orientation: "horizontal",
14488		range: false,
14489		step: 1,
14490		value: 0,
14491		values: null,
14492
14493		// Callbacks
14494		change: null,
14495		slide: null,
14496		start: null,
14497		stop: null
14498	},
14499
14500	// Number of pages in a slider
14501	// (how many times can you page up/down to go through the whole range)
14502	numPages: 5,
14503
14504	_create: function() {
14505		this._keySliding = false;
14506		this._mouseSliding = false;
14507		this._animateOff = true;
14508		this._handleIndex = null;
14509		this._detectOrientation();
14510		this._mouseInit();
14511		this._calculateNewMax();
14512
14513		this._addClass( "ui-slider ui-slider-" + this.orientation,
14514			"ui-widget ui-widget-content" );
14515
14516		this._refresh();
14517
14518		this._animateOff = false;
14519	},
14520
14521	_refresh: function() {
14522		this._createRange();
14523		this._createHandles();
14524		this._setupEvents();
14525		this._refreshValue();
14526	},
14527
14528	_createHandles: function() {
14529		var i, handleCount,
14530			options = this.options,
14531			existingHandles = this.element.find( ".ui-slider-handle" ),
14532			handle = "<span tabindex='0'></span>",
14533			handles = [];
14534
14535		handleCount = ( options.values && options.values.length ) || 1;
14536
14537		if ( existingHandles.length > handleCount ) {
14538			existingHandles.slice( handleCount ).remove();
14539			existingHandles = existingHandles.slice( 0, handleCount );
14540		}
14541
14542		for ( i = existingHandles.length; i < handleCount; i++ ) {
14543			handles.push( handle );
14544		}
14545
14546		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14547
14548		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14549
14550		this.handle = this.handles.eq( 0 );
14551
14552		this.handles.each( function( i ) {
14553			$( this ).data( "ui-slider-handle-index", i );
14554		} );
14555	},
14556
14557	_createRange: function() {
14558		var options = this.options;
14559
14560		if ( options.range ) {
14561			if ( options.range === true ) {
14562				if ( !options.values ) {
14563					options.values = [ this._valueMin(), this._valueMin() ];
14564				} else if ( options.values.length && options.values.length !== 2 ) {
14565					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14566				} else if ( $
vendor: 6,653 bytes, lines 14566-14829
14566.isArray( options.values ) ) {
14567					options.values = options.values.slice( 0 );
14568				}
14569			}
14570
14571			if ( !this.range || !this.range.length ) {
14572				this.range = $( "<div>" )
14573					.appendTo( this.element );
14574
14575				this._addClass( this.range, "ui-slider-range" );
14576			} else {
14577				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14578
14579				// Handle range switching from true to min/max
14580				this.range.css( {
14581					"left": "",
14582					"bottom": ""
14583				} );
14584			}
14585			if ( options.range === "min" || options.range === "max" ) {
14586				this._addClass( this.range, "ui-slider-range-" + options.range );
14587			}
14588		} else {
14589			if ( this.range ) {
14590				this.range.remove();
14591			}
14592			this.range = null;
14593		}
14594	},
14595
14596	_setupEvents: function() {
14597		this._off( this.handles );
14598		this._on( this.handles, this._handleEvents );
14599		this._hoverable( this.handles );
14600		this._focusable( this.handles );
14601	},
14602
14603	_destroy: function() {
14604		this.handles.remove();
14605		if ( this.range ) {
14606			this.range.remove();
14607		}
14608
14609		this._mouseDestroy();
14610	},
14611
14612	_mouseCapture: function( event ) {
14613		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14614			that = this,
14615			o = this.options;
14616
14617		if ( o.disabled ) {
14618			return false;
14619		}
14620
14621		this.elementSize = {
14622			width: this.element.outerWidth(),
14623			height: this.element.outerHeight()
14624		};
14625		this.elementOffset = this.element.offset();
14626
14627		position = { x: event.pageX, y: event.pageY };
14628		normValue = this._normValueFromMouse( position );
14629		distance = this._valueMax() - this._valueMin() + 1;
14630		this.handles.each( function( i ) {
14631			var thisDistance = Math.abs( normValue - that.values( i ) );
14632			if ( ( distance > thisDistance ) ||
14633				( distance === thisDistance &&
14634					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14635				distance = thisDistance;
14636				closestHandle = $( this );
14637				index = i;
14638			}
14639		} );
14640
14641		allowed = this._start( event, index );
14642		if ( allowed === false ) {
14643			return false;
14644		}
14645		this._mouseSliding = true;
14646
14647		this._handleIndex = index;
14648
14649		this._addClass( closestHandle, null, "ui-state-active" );
14650		closestHandle.trigger( "focus" );
14651
14652		offset = closestHandle.offset();
14653		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14654		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14655			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14656			top: event.pageY - offset.top -
14657				( closestHandle.height() / 2 ) -
14658				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14659				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14660				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14661		};
14662
14663		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14664			this._slide( event, index, normValue );
14665		}
14666		this._animateOff = true;
14667		return true;
14668	},
14669
14670	_mouseStart: function() {
14671		return true;
14672	},
14673
14674	_mouseDrag: function( event ) {
14675		var position = { x: event.pageX, y: event.pageY },
14676			normValue = this._normValueFromMouse( position );
14677
14678		this._slide( event, this._handleIndex, normValue );
14679
14680		return false;
14681	},
14682
14683	_mouseStop: function( event ) {
14684		this._removeClass( this.handles, null, "ui-state-active" );
14685		this._mouseSliding = false;
14686
14687		this._stop( event, this._handleIndex );
14688		this._change( event, this._handleIndex );
14689
14690		this._handleIndex = null;
14691		this._clickOffset = null;
14692		this._animateOff = false;
14693
14694		return false;
14695	},
14696
14697	_detectOrientation: function() {
14698		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14699	},
14700
14701	_normValueFromMouse: function( position ) {
14702		var pixelTotal,
14703			pixelMouse,
14704			percentMouse,
14705			valueTotal,
14706			valueMouse;
14707
14708		if ( this.orientation === "horizontal" ) {
14709			pixelTotal = this.elementSize.width;
14710			pixelMouse = position.x - this.elementOffset.left -
14711				( this._clickOffset ? this._clickOffset.left : 0 );
14712		} else {
14713			pixelTotal = this.elementSize.height;
14714			pixelMouse = position.y - this.elementOffset.top -
14715				( this._clickOffset ? this._clickOffset.top : 0 );
14716		}
14717
14718		percentMouse = ( pixelMouse / pixelTotal );
14719		if ( percentMouse > 1 ) {
14720			percentMouse = 1;
14721		}
14722		if ( percentMouse < 0 ) {
14723			percentMouse = 0;
14724		}
14725		if ( this.orientation === "vertical" ) {
14726			percentMouse = 1 - percentMouse;
14727		}
14728
14729		valueTotal = this._valueMax() - this._valueMin();
14730		valueMouse = this._valueMin() + percentMouse * valueTotal;
14731
14732		return this._trimAlignValue( valueMouse );
14733	},
14734
14735	_uiHash: function( index, value, values ) {
14736		var uiHash = {
14737			handle: this.handles[ index ],
14738			handleIndex: index,
14739			value: value !== undefined ? value : this.value()
14740		};
14741
14742		if ( this._hasMultipleValues() ) {
14743			uiHash.value = value !== undefined ? value : this.values( index );
14744			uiHash.values = values || this.values();
14745		}
14746
14747		return uiHash;
14748	},
14749
14750	_hasMultipleValues: function() {
14751		return this.options.values && this.options.values.length;
14752	},
14753
14754	_start: function( event, index ) {
14755		return this._trigger( "start", event, this._uiHash( index ) );
14756	},
14757
14758	_slide: function( event, index, newVal ) {
14759		var allowed, otherVal,
14760			currentValue = this.value(),
14761			newValues = this.values();
14762
14763		if ( this._hasMultipleValues() ) {
14764			otherVal = this.values( index ? 0 : 1 );
14765			currentValue = this.values( index );
14766
14767			if ( this.options.values.length === 2 && this.options.range === true ) {
14768				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14769			}
14770
14771			newValues[ index ] = newVal;
14772		}
14773
14774		if ( newVal === currentValue ) {
14775			return;
14776		}
14777
14778		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14779
14780		// A slide can be canceled by returning false from the slide callback
14781		if ( allowed === false ) {
14782			return;
14783		}
14784
14785		if ( this._hasMultipleValues() ) {
14786			this.values( index, newVal );
14787		} else {
14788			this.value( newVal );
14789		}
14790	},
14791
14792	_stop: function( event, index ) {
14793		this._trigger( "stop", event, this._uiHash( index ) );
14794	},
14795
14796	_change: function( event, index ) {
14797		if ( !this._keySliding && !this._mouseSliding ) {
14798
14799			//store the last changed value index for reference when handles overlap
14800			this._lastChangedValue = index;
14801			this._trigger( "change", event, this._uiHash( index ) );
14802		}
14803	},
14804
14805	value: function( newValue ) {
14806		if ( arguments.length ) {
14807			this.options.value = this._trimAlignValue( newValue );
14808			this._refreshValue();
14809			this._change( null, 0 );
14810			return;
14811		}
14812
14813		return this._value();
14814	},
14815
14816	values: function( index, newValue ) {
14817		var vals,
14818			newValues,
14819			i;
14820
14821		if ( arguments.length > 1 ) {
14822			this.options.values[ index ] = this._trimAlignValue( newValue );
14823			this._refreshValue();
14824			this._change( null, index );
14825			return;
14826		}
14827
14828		if ( arguments.length ) {
14829			if ( 
vendor: 829 bytes, lines 14829-14863
14829$.isArray( arguments[ 0 ] ) ) {
14830				vals = this.options.values;
14831				newValues = arguments[ 0 ];
14832				for ( i = 0; i < vals.length; i += 1 ) {
14833					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14834					this._change( null, i );
14835				}
14836				this._refreshValue();
14837			} else {
14838				if ( this._hasMultipleValues() ) {
14839					return this._values( index );
14840				} else {
14841					return this.value();
14842				}
14843			}
14844		} else {
14845			return this._values();
14846		}
14847	},
14848
14849	_setOption: function( key, value ) {
14850		var i,
14851			valsLength = 0;
14852
14853		if ( key === "range" && this.options.range === true ) {
14854			if ( value === "min" ) {
14855				this.options.value = this._values( 0 );
14856				this.options.values = null;
14857			} else if ( value === "max" ) {
14858				this.options.value = this._values( this.options.values.length - 1 );
14859				this.options.values = null;
14860			}
14861		}
14862
14863		if ( $
vendor: 8,805 bytes, lines 14863-15185
14863.isArray( this.options.values ) ) {
14864			valsLength = this.options.values.length;
14865		}
14866
14867		this._super( key, value );
14868
14869		switch ( key ) {
14870			case "orientation":
14871				this._detectOrientation();
14872				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14873					._addClass( "ui-slider-" + this.orientation );
14874				this._refreshValue();
14875				if ( this.options.range ) {
14876					this._refreshRange( value );
14877				}
14878
14879				// Reset positioning from previous orientation
14880				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14881				break;
14882			case "value":
14883				this._animateOff = true;
14884				this._refreshValue();
14885				this._change( null, 0 );
14886				this._animateOff = false;
14887				break;
14888			case "values":
14889				this._animateOff = true;
14890				this._refreshValue();
14891
14892				// Start from the last handle to prevent unreachable handles (#9046)
14893				for ( i = valsLength - 1; i >= 0; i-- ) {
14894					this._change( null, i );
14895				}
14896				this._animateOff = false;
14897				break;
14898			case "step":
14899			case "min":
14900			case "max":
14901				this._animateOff = true;
14902				this._calculateNewMax();
14903				this._refreshValue();
14904				this._animateOff = false;
14905				break;
14906			case "range":
14907				this._animateOff = true;
14908				this._refresh();
14909				this._animateOff = false;
14910				break;
14911		}
14912	},
14913
14914	_setOptionDisabled: function( value ) {
14915		this._super( value );
14916
14917		this._toggleClass( null, "ui-state-disabled", !!value );
14918	},
14919
14920	//internal value getter
14921	// _value() returns value trimmed by min and max, aligned by step
14922	_value: function() {
14923		var val = this.options.value;
14924		val = this._trimAlignValue( val );
14925
14926		return val;
14927	},
14928
14929	//internal values getter
14930	// _values() returns array of values trimmed by min and max, aligned by step
14931	// _values( index ) returns single value trimmed by min and max, aligned by step
14932	_values: function( index ) {
14933		var val,
14934			vals,
14935			i;
14936
14937		if ( arguments.length ) {
14938			val = this.options.values[ index ];
14939			val = this._trimAlignValue( val );
14940
14941			return val;
14942		} else if ( this._hasMultipleValues() ) {
14943
14944			// .slice() creates a copy of the array
14945			// this copy gets trimmed by min and max and then returned
14946			vals = this.options.values.slice();
14947			for ( i = 0; i < vals.length; i += 1 ) {
14948				vals[ i ] = this._trimAlignValue( vals[ i ] );
14949			}
14950
14951			return vals;
14952		} else {
14953			return [];
14954		}
14955	},
14956
14957	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14958	_trimAlignValue: function( val ) {
14959		if ( val <= this._valueMin() ) {
14960			return this._valueMin();
14961		}
14962		if ( val >= this._valueMax() ) {
14963			return this._valueMax();
14964		}
14965		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14966			valModStep = ( val - this._valueMin() ) % step,
14967			alignValue = val - valModStep;
14968
14969		if ( Math.abs( valModStep ) * 2 >= step ) {
14970			alignValue += ( valModStep > 0 ) ? step : ( -step );
14971		}
14972
14973		// Since JavaScript has problems with large floats, round
14974		// the final value to 5 digits after the decimal point (see #4124)
14975		return parseFloat( alignValue.toFixed( 5 ) );
14976	},
14977
14978	_calculateNewMax: function() {
14979		var max = this.options.max,
14980			min = this._valueMin(),
14981			step = this.options.step,
14982			aboveMin = Math.round( ( max - min ) / step ) * step;
14983		max = aboveMin + min;
14984		if ( max > this.options.max ) {
14985
14986			//If max is not divisible by step, rounding off may increase its value
14987			max -= step;
14988		}
14989		this.max = parseFloat( max.toFixed( this._precision() ) );
14990	},
14991
14992	_precision: function() {
14993		var precision = this._precisionOf( this.options.step );
14994		if ( this.options.min !== null ) {
14995			precision = Math.max( precision, this._precisionOf( this.options.min ) );
14996		}
14997		return precision;
14998	},
14999
15000	_precisionOf: function( num ) {
15001		var str = num.toString(),
15002			decimal = str.indexOf( "." );
15003		return decimal === -1 ? 0 : str.length - decimal - 1;
15004	},
15005
15006	_valueMin: function() {
15007		return this.options.min;
15008	},
15009
15010	_valueMax: function() {
15011		return this.max;
15012	},
15013
15014	_refreshRange: function( orientation ) {
15015		if ( orientation === "vertical" ) {
15016			this.range.css( { "width": "", "left": "" } );
15017		}
15018		if ( orientation === "horizontal" ) {
15019			this.range.css( { "height": "", "bottom": "" } );
15020		}
15021	},
15022
15023	_refreshValue: function() {
15024		var lastValPercent, valPercent, value, valueMin, valueMax,
15025			oRange = this.options.range,
15026			o = this.options,
15027			that = this,
15028			animate = ( !this._animateOff ) ? o.animate : false,
15029			_set = {};
15030
15031		if ( this._hasMultipleValues() ) {
15032			this.handles.each( function( i ) {
15033				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15034					that._valueMin() ) * 100;
15035				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15036				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15037				if ( that.options.range === true ) {
15038					if ( that.orientation === "horizontal" ) {
15039						if ( i === 0 ) {
15040							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15041								left: valPercent + "%"
15042							}, o.animate );
15043						}
15044						if ( i === 1 ) {
15045							that.range[ animate ? "animate" : "css" ]( {
15046								width: ( valPercent - lastValPercent ) + "%"
15047							}, {
15048								queue: false,
15049								duration: o.animate
15050							} );
15051						}
15052					} else {
15053						if ( i === 0 ) {
15054							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15055								bottom: ( valPercent ) + "%"
15056							}, o.animate );
15057						}
15058						if ( i === 1 ) {
15059							that.range[ animate ? "animate" : "css" ]( {
15060								height: ( valPercent - lastValPercent ) + "%"
15061							}, {
15062								queue: false,
15063								duration: o.animate
15064							} );
15065						}
15066					}
15067				}
15068				lastValPercent = valPercent;
15069			} );
15070		} else {
15071			value = this.value();
15072			valueMin = this._valueMin();
15073			valueMax = this._valueMax();
15074			valPercent = ( valueMax !== valueMin ) ?
15075					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15076					0;
15077			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15078			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15079
15080			if ( oRange === "min" && this.orientation === "horizontal" ) {
15081				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15082					width: valPercent + "%"
15083				}, o.animate );
15084			}
15085			if ( oRange === "max" && this.orientation === "horizontal" ) {
15086				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15087					width: ( 100 - valPercent ) + "%"
15088				}, o.animate );
15089			}
15090			if ( oRange === "min" && this.orientation === "vertical" ) {
15091				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15092					height: valPercent + "%"
15093				}, o.animate );
15094			}
15095			if ( oRange === "max" && this.orientation === "vertical" ) {
15096				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15097					height: ( 100 - valPercent ) + "%"
15098				}, o.animate );
15099			}
15100		}
15101	},
15102
15103	_handleEvents: {
15104		keydown: function( event ) {
15105			var allowed, curVal, newVal, step,
15106				index = $( event.target ).data( "ui-slider-handle-index" );
15107
15108			switch ( event.keyCode ) {
15109				case $.ui.keyCode.HOME:
15110				case $.ui.keyCode.END:
15111				case $.ui.keyCode.PAGE_UP:
15112				case $.ui.keyCode.PAGE_DOWN:
15113				case $.ui.keyCode.UP:
15114				case $.ui.keyCode.RIGHT:
15115				case $.ui.keyCode.DOWN:
15116				case $.ui.keyCode.LEFT:
15117					event.preventDefault();
15118					if ( !this._keySliding ) {
15119						this._keySliding = true;
15120						this._addClass( $( event.target ), null, "ui-state-active" );
15121						allowed = this._start( event, index );
15122						if ( allowed === false ) {
15123							return;
15124						}
15125					}
15126					break;
15127			}
15128
15129			step = this.options.step;
15130			if ( this._hasMultipleValues() ) {
15131				curVal = newVal = this.values( index );
15132			} else {
15133				curVal = newVal = this.value();
15134			}
15135
15136			switch ( event.keyCode ) {
15137				case $.ui.keyCode.HOME:
15138					newVal = this._valueMin();
15139					break;
15140				case $.ui.keyCode.END:
15141					newVal = this._valueMax();
15142					break;
15143				case $.ui.keyCode.PAGE_UP:
15144					newVal = this._trimAlignValue(
15145						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15146					);
15147					break;
15148				case $.ui.keyCode.PAGE_DOWN:
15149					newVal = this._trimAlignValue(
15150						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15151					break;
15152				case $.ui.keyCode.UP:
15153				case $.ui.keyCode.RIGHT:
15154					if ( curVal === this._valueMax() ) {
15155						return;
15156					}
15157					newVal = this._trimAlignValue( curVal + step );
15158					break;
15159				case $.ui.keyCode.DOWN:
15160				case $.ui.keyCode.LEFT:
15161					if ( curVal === this._valueMin() ) {
15162						return;
15163					}
15164					newVal = this._trimAlignValue( curVal - step );
15165					break;
15166			}
15167
15168			this._slide( event, index, newVal );
15169		},
15170		keyup: function( event ) {
15171			var index = $( event.target ).data( "ui-slider-handle-index" );
15172
15173			if ( this._keySliding ) {
15174				this._keySliding = false;
15175				this._stop( event, index );
15176				this._change( event, index );
15177				this._removeClass( $( event.target ), null, "ui-state-active" );
15178			}
15179		}
15180	}
15181} );
15182
15183
15184/*!
15185 * jQuery UI Sortable 1.1
vendor: 3,492 bytes, lines 15185-15342
151852.0
15186 * http://jqueryui.com
15187 *
15188 * Copyright jQuery Foundation and other contributors
15189 * Released under the MIT license.
15190 * http://jquery.org/license
15191 */
15192
15193//>>label: Sortable
15194//>>group: Interactions
15195//>>description: Enables items in a list to be sorted using the mouse.
15196//>>docs: http://api.jqueryui.com/sortable/
15197//>>demos: http://jqueryui.com/sortable/
15198//>>css.structure: ../../themes/base/sortable.css
15199
15200
15201
15202var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15203	version: "1.12.0",
15204	widgetEventPrefix: "sort",
15205	ready: false,
15206	options: {
15207		appendTo: "parent",
15208		axis: false,
15209		connectWith: false,
15210		containment: false,
15211		cursor: "auto",
15212		cursorAt: false,
15213		dropOnEmpty: true,
15214		forcePlaceholderSize: false,
15215		forceHelperSize: false,
15216		grid: false,
15217		handle: false,
15218		helper: "original",
15219		items: "> *",
15220		opacity: false,
15221		placeholder: false,
15222		revert: false,
15223		scroll: true,
15224		scrollSensitivity: 20,
15225		scrollSpeed: 20,
15226		scope: "default",
15227		tolerance: "intersect",
15228		zIndex: 1000,
15229
15230		// Callbacks
15231		activate: null,
15232		beforeStop: null,
15233		change: null,
15234		deactivate: null,
15235		out: null,
15236		over: null,
15237		receive: null,
15238		remove: null,
15239		sort: null,
15240		start: null,
15241		stop: null,
15242		update: null
15243	},
15244
15245	_isOverAxis: function( x, reference, size ) {
15246		return ( x >= reference ) && ( x < ( reference + size ) );
15247	},
15248
15249	_isFloating: function( item ) {
15250		return ( /left|right/ ).test( item.css( "float" ) ) ||
15251			( /inline|table-cell/ ).test( item.css( "display" ) );
15252	},
15253
15254	_create: function() {
15255		this.containerCache = {};
15256		this._addClass( "ui-sortable" );
15257
15258		//Get the items
15259		this.refresh();
15260
15261		//Let's determine the parent's offset
15262		this.offset = this.element.offset();
15263
15264		//Initialize mouse events for interaction
15265		this._mouseInit();
15266
15267		this._setHandleClassName();
15268
15269		//We're ready to go
15270		this.ready = true;
15271
15272	},
15273
15274	_setOption: function( key, value ) {
15275		this._super( key, value );
15276
15277		if ( key === "handle" ) {
15278			this._setHandleClassName();
15279		}
15280	},
15281
15282	_setHandleClassName: function() {
15283		var that = this;
15284		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15285		$.each( this.items, function() {
15286			that._addClass(
15287				this.instance.options.handle ?
15288					this.item.find( this.instance.options.handle ) :
15289					this.item,
15290				"ui-sortable-handle"
15291			);
15292		} );
15293	},
15294
15295	_destroy: function() {
15296		this._mouseDestroy();
15297
15298		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15299			this.items[ i ].item.removeData( this.widgetName + "-item" );
15300		}
15301
15302		return this;
15303	},
15304
15305	_mouseCapture: function( event, overrideHandle ) {
15306		var currentItem = null,
15307			validHandle = false,
15308			that = this;
15309
15310		if ( this.reverting ) {
15311			return false;
15312		}
15313
15314		if ( this.options.disabled || this.options.type === "static" ) {
15315			return false;
15316		}
15317
15318		//We have to refresh the items data once first
15319		this._refreshItems( event );
15320
15321		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15322		$( event.target ).parents().each( function() {
15323			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15324				currentItem = $( this );
15325				return false;
15326			}
15327		} );
15328		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15329			currentItem = $( event.target );
15330		}
15331
15332		if ( !currentItem ) {
15333			return false;
15334		}
15335		if ( this.options.handle && !overrideHandle ) {
15336			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15337				if ( this === event.target ) {
15338					validHandle = true;
15339				}
15340			} );
15341			if ( !validHandle ) {
15342				return false;
vendor: 8,708 bytes, lines 15343-15631
15343			}
15344		}
15345
15346		this.currentItem = currentItem;
15347		this._removeCurrentsFromItems();
15348		return true;
15349
15350	},
15351
15352	_mouseStart: function( event, overrideHandle, noActivation ) {
15353
15354		var i, body,
15355			o = this.options;
15356
15357		this.currentContainer = this;
15358
15359		//We only need to call refreshPositions, because the refreshItems call has been moved to
15360		// mouseCapture
15361		this.refreshPositions();
15362
15363		//Create and append the visible helper
15364		this.helper = this._createHelper( event );
15365
15366		//Cache the helper size
15367		this._cacheHelperProportions();
15368
15369		/*
15370		 * - Position generation -
15371		 * This block generates everything position related - it's the core of draggables.
15372		 */
15373
15374		//Cache the margins of the original element
15375		this._cacheMargins();
15376
15377		//Get the next scrolling parent
15378		this.scrollParent = this.helper.scrollParent();
15379
15380		//The element's absolute position on the page minus margins
15381		this.offset = this.currentItem.offset();
15382		this.offset = {
15383			top: this.offset.top - this.margins.top,
15384			left: this.offset.left - this.margins.left
15385		};
15386
15387		$.extend( this.offset, {
15388			click: { //Where the click happened, relative to the element
15389				left: event.pageX - this.offset.left,
15390				top: event.pageY - this.offset.top
15391			},
15392			parent: this._getParentOffset(),
15393
15394			// This is a relative to absolute position minus the actual position calculation -
15395			// only used for relative positioned helper
15396			relative: this._getRelativeOffset()
15397		} );
15398
15399		// Only after we got the offset, we can change the helper's position to absolute
15400		// TODO: Still need to figure out a way to make relative sorting possible
15401		this.helper.css( "position", "absolute" );
15402		this.cssPosition = this.helper.css( "position" );
15403
15404		//Generate the original position
15405		this.originalPosition = this._generatePosition( event );
15406		this.originalPageX = event.pageX;
15407		this.originalPageY = event.pageY;
15408
15409		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15410		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15411
15412		//Cache the former DOM position
15413		this.domPosition = {
15414			prev: this.currentItem.prev()[ 0 ],
15415			parent: this.currentItem.parent()[ 0 ]
15416		};
15417
15418		// If the helper is not the original, hide the original so it's not playing any role during
15419		// the drag, won't cause anything bad this way
15420		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15421			this.currentItem.hide();
15422		}
15423
15424		//Create the placeholder
15425		this._createPlaceholder();
15426
15427		//Set a containment if given in the options
15428		if ( o.containment ) {
15429			this._setContainment();
15430		}
15431
15432		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15433			body = this.document.find( "body" );
15434
15435			// Support: IE
15436			this.storedCursor = body.css( "cursor" );
15437			body.css( "cursor", o.cursor );
15438
15439			this.storedStylesheet =
15440				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15441		}
15442
15443		if ( o.opacity ) { // opacity option
15444			if ( this.helper.css( "opacity" ) ) {
15445				this._storedOpacity = this.helper.css( "opacity" );
15446			}
15447			this.helper.css( "opacity", o.opacity );
15448		}
15449
15450		if ( o.zIndex ) { // zIndex option
15451			if ( this.helper.css( "zIndex" ) ) {
15452				this._storedZIndex = this.helper.css( "zIndex" );
15453			}
15454			this.helper.css( "zIndex", o.zIndex );
15455		}
15456
15457		//Prepare scrolling
15458		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15459				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15460			this.overflowOffset = this.scrollParent.offset();
15461		}
15462
15463		//Call callbacks
15464		this._trigger( "start", event, this._uiHash() );
15465
15466		//Recache the helper size
15467		if ( !this._preserveHelperProportions ) {
15468			this._cacheHelperProportions();
15469		}
15470
15471		//Post "activate" events to possible containers
15472		if ( !noActivation ) {
15473			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15474				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15475			}
15476		}
15477
15478		//Prepare possible droppables
15479		if ( $.ui.ddmanager ) {
15480			$.ui.ddmanager.current = this;
15481		}
15482
15483		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15484			$.ui.ddmanager.prepareOffsets( this, event );
15485		}
15486
15487		this.dragging = true;
15488
15489		this._addClass( this.helper, "ui-sortable-helper" );
15490
15491		// Execute the drag once - this causes the helper not to be visiblebefore getting its
15492		// correct position
15493		this._mouseDrag( event );
15494		return true;
15495
15496	},
15497
15498	_mouseDrag: function( event ) {
15499		var i, item, itemElement, intersection,
15500			o = this.options,
15501			scrolled = false;
15502
15503		//Compute the helpers position
15504		this.position = this._generatePosition( event );
15505		this.positionAbs = this._convertPositionTo( "absolute" );
15506
15507		if ( !this.lastPositionAbs ) {
15508			this.lastPositionAbs = this.positionAbs;
15509		}
15510
15511		//Do scrolling
15512		if ( this.options.scroll ) {
15513			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15514					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15515
15516				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15517						event.pageY < o.scrollSensitivity ) {
15518					this.scrollParent[ 0 ].scrollTop =
15519						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15520				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15521					this.scrollParent[ 0 ].scrollTop =
15522						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15523				}
15524
15525				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15526						event.pageX < o.scrollSensitivity ) {
15527					this.scrollParent[ 0 ].scrollLeft = scrolled =
15528						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15529				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15530					this.scrollParent[ 0 ].scrollLeft = scrolled =
15531						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15532				}
15533
15534			} else {
15535
15536				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15537					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15538				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15539						o.scrollSensitivity ) {
15540					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15541				}
15542
15543				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15544					scrolled = this.document.scrollLeft(
15545						this.document.scrollLeft() - o.scrollSpeed
15546					);
15547				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15548						o.scrollSensitivity ) {
15549					scrolled = this.document.scrollLeft(
15550						this.document.scrollLeft() + o.scrollSpeed
15551					);
15552				}
15553
15554			}
15555
15556			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15557				$.ui.ddmanager.prepareOffsets( this, event );
15558			}
15559		}
15560
15561		//Regenerate the absolute position used for position checks
15562		this.positionAbs = this._convertPositionTo( "absolute" );
15563
15564		//Set the helper position
15565		if ( !this.options.axis || this.options.axis !== "y" ) {
15566			this.helper[ 0 ].style.left = this.position.left + "px";
15567		}
15568		if ( !this.options.axis || this.options.axis !== "x" ) {
15569			this.helper[ 0 ].style.top = this.position.top + "px";
15570		}
15571
15572		//Rearrange
15573		for ( i = this.items.length - 1; i >= 0; i-- ) {
15574
15575			//Cache variables and intersection, continue if no intersection
15576			item = this.items[ i ];
15577			itemElement = item.item[ 0 ];
15578			intersection = this._intersectsWithPointer( item );
15579			if ( !intersection ) {
15580				continue;
15581			}
15582
15583			// Only put the placeholder inside the current Container, skip all
15584			// items from other containers. This works because when moving
15585			// an item from one container to another the
15586			// currentContainer is switched before the placeholder is moved.
15587			//
15588			// Without this, moving items in "sub-sortables" can cause
15589			// the placeholder to jitter between the outer and inner container.
15590			if ( item.instance !== this.currentContainer ) {
15591				continue;
15592			}
15593
15594			// Cannot intersect with itself
15595			// no useless actions that have been done before
15596			// no action if the item moved is the parent of the item checked
15597			if ( itemElement !== this.currentItem[ 0 ] &&
15598				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15599				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15600				( this.options.type === "semi-dynamic" ?
15601					!$.contains( this.element[ 0 ], itemElement ) :
15602					true
15603				)
15604			) {
15605
15606				this.direction = intersection === 1 ? "down" : "up";
15607
15608				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
15609					this._rearrange( event, item );
15610				} else {
15611					break;
15612				}
15613
15614				this._trigger( "change", event, this._uiHash() );
15615				break;
15616			}
15617		}
15618
15619		//Post events to containers
15620		this._contactContainers( event );
15621
15622		//Interconnect with droppables
15623		if ( $.ui.ddmanager ) {
15624			$.ui.ddmanager.drag( this, event );
15625		}
15626
15627		//Call callbacks
15628		this._trigger( "sort", event, this._uiHash() );
15629
15630		this.lastPositionAbs = this.positionAbs;
15631		return false;
vendor: 5,037 bytes, lines 15632-15821
15632
15633	},
15634
15635	_mouseStop: function( event, noPropagation ) {
15636
15637		if ( !event ) {
15638			return;
15639		}
15640
15641		//If we are using droppables, inform the manager about the drop
15642		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15643			$.ui.ddmanager.drop( this, event );
15644		}
15645
15646		if ( this.options.revert ) {
15647			var that = this,
15648				cur = this.placeholder.offset(),
15649				axis = this.options.axis,
15650				animation = {};
15651
15652			if ( !axis || axis === "x" ) {
15653				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15654					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15655						0 :
15656						this.offsetParent[ 0 ].scrollLeft
15657					);
15658			}
15659			if ( !axis || axis === "y" ) {
15660				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15661					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15662						0 :
15663						this.offsetParent[ 0 ].scrollTop
15664					);
15665			}
15666			this.reverting = true;
15667			$( this.helper ).animate(
15668				animation,
15669				parseInt( this.options.revert, 10 ) || 500,
15670				function() {
15671					that._clear( event );
15672				}
15673			);
15674		} else {
15675			this._clear( event, noPropagation );
15676		}
15677
15678		return false;
15679
15680	},
15681
15682	cancel: function() {
15683
15684		if ( this.dragging ) {
15685
15686			this._mouseUp( { target: null } );
15687
15688			if ( this.options.helper === "original" ) {
15689				this.currentItem.css( this._storedCSS );
15690				this._removeClass( this.currentItem, "ui-sortable-helper" );
15691			} else {
15692				this.currentItem.show();
15693			}
15694
15695			//Post deactivating events to containers
15696			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15697				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15698				if ( this.containers[ i ].containerCache.over ) {
15699					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15700					this.containers[ i ].containerCache.over = 0;
15701				}
15702			}
15703
15704		}
15705
15706		if ( this.placeholder ) {
15707
15708			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15709			// it unbinds ALL events from the original node!
15710			if ( this.placeholder[ 0 ].parentNode ) {
15711				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15712			}
15713			if ( this.options.helper !== "original" && this.helper &&
15714					this.helper[ 0 ].parentNode ) {
15715				this.helper.remove();
15716			}
15717
15718			$.extend( this, {
15719				helper: null,
15720				dragging: false,
15721				reverting: false,
15722				_noFinalSort: null
15723			} );
15724
15725			if ( this.domPosition.prev ) {
15726				$( this.domPosition.prev ).after( this.currentItem );
15727			} else {
15728				$( this.domPosition.parent ).prepend( this.currentItem );
15729			}
15730		}
15731
15732		return this;
15733
15734	},
15735
15736	serialize: function( o ) {
15737
15738		var items = this._getItemsAsjQuery( o && o.connected ),
15739			str = [];
15740		o = o || {};
15741
15742		$( items ).each( function() {
15743			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15744				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15745			if ( res ) {
15746				str.push(
15747					( o.key || res[ 1 ] + "[]" ) +
15748					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15749			}
15750		} );
15751
15752		if ( !str.length && o.key ) {
15753			str.push( o.key + "=" );
15754		}
15755
15756		return str.join( "&" );
15757
15758	},
15759
15760	toArray: function( o ) {
15761
15762		var items = this._getItemsAsjQuery( o && o.connected ),
15763			ret = [];
15764
15765		o = o || {};
15766
15767		items.each( function() {
15768			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15769		} );
15770		return ret;
15771
15772	},
15773
15774	/* Be careful with the following core functions */
15775	_intersectsWith: function( item ) {
15776
15777		var x1 = this.positionAbs.left,
15778			x2 = x1 + this.helperProportions.width,
15779			y1 = this.positionAbs.top,
15780			y2 = y1 + this.helperProportions.height,
15781			l = item.left,
15782			r = l + item.width,
15783			t = item.top,
15784			b = t + item.height,
15785			dyClick = this.offset.click.top,
15786			dxClick = this.offset.click.left,
15787			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15788				( y1 + dyClick ) < b ),
15789			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15790				( x1 + dxClick ) < r ),
15791			isOverElement = isOverElementHeight && isOverElementWidth;
15792
15793		if ( this.options.tolerance === "pointer" ||
15794			this.options.forcePointerForContainers ||
15795			( this.options.tolerance !== "pointer" &&
15796				this.helperProportions[ this.floating ? "width" : "height" ] >
15797				item[ this.floating ? "width" : "height" ] )
15798		) {
15799			return isOverElement;
15800		} else {
15801
15802			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15803				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15804				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15805				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15806
15807		}
15808	},
15809
15810	_intersectsWithPointer: function( item ) {
15811		var verticalDirection, horizontalDirection,
15812			isOverElementHeight = ( this.options.axis === "x" ) ||
15813				this._isOverAxis(
15814					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15815			isOverElementWidth = ( this.options.axis === "y" ) ||
15816				this._isOverAxis(
15817					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15818			isOverElement = isOverElementHeight && isOverElementWidth;
15819
15820		if ( !isOverElement ) {
15821			return false;
vendor: 13,838 bytes, lines 15822-16271
15822		}
15823
15824		verticalDirection = this._getDragVerticalDirection();
15825		horizontalDirection = this._getDragHorizontalDirection();
15826
15827		return this.floating ?
15828			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15829			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15830
15831	},
15832
15833	_intersectsWithSides: function( item ) {
15834
15835		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15836				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15837			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15838				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15839			verticalDirection = this._getDragVerticalDirection(),
15840			horizontalDirection = this._getDragHorizontalDirection();
15841
15842		if ( this.floating && horizontalDirection ) {
15843			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15844				( horizontalDirection === "left" && !isOverRightHalf ) );
15845		} else {
15846			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15847				( verticalDirection === "up" && !isOverBottomHalf ) );
15848		}
15849
15850	},
15851
15852	_getDragVerticalDirection: function() {
15853		var delta = this.positionAbs.top - this.lastPositionAbs.top;
15854		return delta !== 0 && ( delta > 0 ? "down" : "up" );
15855	},
15856
15857	_getDragHorizontalDirection: function() {
15858		var delta = this.positionAbs.left - this.lastPositionAbs.left;
15859		return delta !== 0 && ( delta > 0 ? "right" : "left" );
15860	},
15861
15862	refresh: function( event ) {
15863		this._refreshItems( event );
15864		this._setHandleClassName();
15865		this.refreshPositions();
15866		return this;
15867	},
15868
15869	_connectWith: function() {
15870		var options = this.options;
15871		return options.connectWith.constructor === String ?
15872			[ options.connectWith ] :
15873			options.connectWith;
15874	},
15875
15876	_getItemsAsjQuery: function( connected ) {
15877
15878		var i, j, cur, inst,
15879			items = [],
15880			queries = [],
15881			connectWith = this._connectWith();
15882
15883		if ( connectWith && connected ) {
15884			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15885				cur = $( connectWith[ i ], this.document[ 0 ] );
15886				for ( j = cur.length - 1; j >= 0; j-- ) {
15887					inst = $.data( cur[ j ], this.widgetFullName );
15888					if ( inst && inst !== this && !inst.options.disabled ) {
15889						queries.push( [ $.isFunction( inst.options.items ) ?
15890							inst.options.items.call( inst.element ) :
15891							$( inst.options.items, inst.element )
15892								.not( ".ui-sortable-helper" )
15893								.not( ".ui-sortable-placeholder" ), inst ] );
15894					}
15895				}
15896			}
15897		}
15898
15899		queries.push( [ $.isFunction( this.options.items ) ?
15900			this.options.items
15901				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15902			$( this.options.items, this.element )
15903				.not( ".ui-sortable-helper" )
15904				.not( ".ui-sortable-placeholder" ), this ] );
15905
15906		function addItems() {
15907			items.push( this );
15908		}
15909		for ( i = queries.length - 1; i >= 0; i-- ) {
15910			queries[ i ][ 0 ].each( addItems );
15911		}
15912
15913		return $( items );
15914
15915	},
15916
15917	_removeCurrentsFromItems: function() {
15918
15919		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15920
15921		this.items = $.grep( this.items, function( item ) {
15922			for ( var j = 0; j < list.length; j++ ) {
15923				if ( list[ j ] === item.item[ 0 ] ) {
15924					return false;
15925				}
15926			}
15927			return true;
15928		} );
15929
15930	},
15931
15932	_refreshItems: function( event ) {
15933
15934		this.items = [];
15935		this.containers = [ this ];
15936
15937		var i, j, cur, inst, targetData, _queries, item, queriesLength,
15938			items = this.items,
15939			queries = [ [ $.isFunction( this.options.items ) ?
15940				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15941				$( this.options.items, this.element ), this ] ],
15942			connectWith = this._connectWith();
15943
15944		//Shouldn't be run the first time through due to massive slow-down
15945		if ( connectWith && this.ready ) {
15946			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15947				cur = $( connectWith[ i ], this.document[ 0 ] );
15948				for ( j = cur.length - 1; j >= 0; j-- ) {
15949					inst = $.data( cur[ j ], this.widgetFullName );
15950					if ( inst && inst !== this && !inst.options.disabled ) {
15951						queries.push( [ $.isFunction( inst.options.items ) ?
15952							inst.options.items
15953								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15954							$( inst.options.items, inst.element ), inst ] );
15955						this.containers.push( inst );
15956					}
15957				}
15958			}
15959		}
15960
15961		for ( i = queries.length - 1; i >= 0; i-- ) {
15962			targetData = queries[ i ][ 1 ];
15963			_queries = queries[ i ][ 0 ];
15964
15965			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15966				item = $( _queries[ j ] );
15967
15968				// Data for target checking (mouse manager)
15969				item.data( this.widgetName + "-item", targetData );
15970
15971				items.push( {
15972					item: item,
15973					instance: targetData,
15974					width: 0, height: 0,
15975					left: 0, top: 0
15976				} );
15977			}
15978		}
15979
15980	},
15981
15982	refreshPositions: function( fast ) {
15983
15984		// Determine whether items are being displayed horizontally
15985		this.floating = this.items.length ?
15986			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
15987			false;
15988
15989		//This has to be redone because due to the item being moved out/into the offsetParent,
15990		// the offsetParent's position will change
15991		if ( this.offsetParent && this.helper ) {
15992			this.offset.parent = this._getParentOffset();
15993		}
15994
15995		var i, item, t, p;
15996
15997		for ( i = this.items.length - 1; i >= 0; i-- ) {
15998			item = this.items[ i ];
15999
16000			//We ignore calculating positions of all connected containers when we're not over them
16001			if ( item.instance !== this.currentContainer && this.currentContainer &&
16002					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16003				continue;
16004			}
16005
16006			t = this.options.toleranceElement ?
16007				$( this.options.toleranceElement, item.item ) :
16008				item.item;
16009
16010			if ( !fast ) {
16011				item.width = t.outerWidth();
16012				item.height = t.outerHeight();
16013			}
16014
16015			p = t.offset();
16016			item.left = p.left;
16017			item.top = p.top;
16018		}
16019
16020		if ( this.options.custom && this.options.custom.refreshContainers ) {
16021			this.options.custom.refreshContainers.call( this );
16022		} else {
16023			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16024				p = this.containers[ i ].element.offset();
16025				this.containers[ i ].containerCache.left = p.left;
16026				this.containers[ i ].containerCache.top = p.top;
16027				this.containers[ i ].containerCache.width =
16028					this.containers[ i ].element.outerWidth();
16029				this.containers[ i ].containerCache.height =
16030					this.containers[ i ].element.outerHeight();
16031			}
16032		}
16033
16034		return this;
16035	},
16036
16037	_createPlaceholder: function( that ) {
16038		that = that || this;
16039		var className,
16040			o = that.options;
16041
16042		if ( !o.placeholder || o.placeholder.constructor === String ) {
16043			className = o.placeholder;
16044			o.placeholder = {
16045				element: function() {
16046
16047					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16048						element = $( "<" + nodeName + ">", that.document[ 0 ] );
16049
16050						that._addClass( element, "ui-sortable-placeholder",
16051								className || that.currentItem[ 0 ].className )
16052							._removeClass( element, "ui-sortable-helper" );
16053
16054					if ( nodeName === "tbody" ) {
16055						that._createTrPlaceholder(
16056							that.currentItem.find( "tr" ).eq( 0 ),
16057							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16058						);
16059					} else if ( nodeName === "tr" ) {
16060						that._createTrPlaceholder( that.currentItem, element );
16061					} else if ( nodeName === "img" ) {
16062						element.attr( "src", that.currentItem.attr( "src" ) );
16063					}
16064
16065					if ( !className ) {
16066						element.css( "visibility", "hidden" );
16067					}
16068
16069					return element;
16070				},
16071				update: function( container, p ) {
16072
16073					// 1. If a className is set as 'placeholder option, we don't force sizes -
16074					// the class is responsible for that
16075					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16076					// class name is specified
16077					if ( className && !o.forcePlaceholderSize ) {
16078						return;
16079					}
16080
16081					//If the element doesn't have a actual height by itself (without styles coming
16082					// from a stylesheet), it receives the inline height from the dragged item
16083					if ( !p.height() ) {
16084						p.height(
16085							that.currentItem.innerHeight() -
16086							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16087							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16088					}
16089					if ( !p.width() ) {
16090						p.width(
16091							that.currentItem.innerWidth() -
16092							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16093							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16094					}
16095				}
16096			};
16097		}
16098
16099		//Create the placeholder
16100		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16101
16102		//Append it after the actual current item
16103		that.currentItem.after( that.placeholder );
16104
16105		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16106		o.placeholder.update( that, that.placeholder );
16107
16108	},
16109
16110	_createTrPlaceholder: function( sourceTr, targetTr ) {
16111		var that = this;
16112
16113		sourceTr.children().each( function() {
16114			$( "<td>&#160;</td>", that.document[ 0 ] )
16115				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16116				.appendTo( targetTr );
16117		} );
16118	},
16119
16120	_contactContainers: function( event ) {
16121		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16122			floating, axis,
16123			innermostContainer = null,
16124			innermostIndex = null;
16125
16126		// Get innermost container that intersects with item
16127		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16128
16129			// Never consider a container that's located within the item itself
16130			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16131				continue;
16132			}
16133
16134			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16135
16136				// If we've already found a container and it's more "inner" than this, then continue
16137				if ( innermostContainer &&
16138						$.contains(
16139							this.containers[ i ].element[ 0 ],
16140							innermostContainer.element[ 0 ] ) ) {
16141					continue;
16142				}
16143
16144				innermostContainer = this.containers[ i ];
16145				innermostIndex = i;
16146
16147			} else {
16148
16149				// container doesn't intersect. trigger "out" event if necessary
16150				if ( this.containers[ i ].containerCache.over ) {
16151					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16152					this.containers[ i ].containerCache.over = 0;
16153				}
16154			}
16155
16156		}
16157
16158		// If no intersecting containers found, return
16159		if ( !innermostContainer ) {
16160			return;
16161		}
16162
16163		// Move the item into the container if it's not there already
16164		if ( this.containers.length === 1 ) {
16165			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16166				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16167				this.containers[ innermostIndex ].containerCache.over = 1;
16168			}
16169		} else {
16170
16171			// When entering a new container, we will find the item with the least distance and
16172			// append our item near it
16173			dist = 10000;
16174			itemWithLeastDistance = null;
16175			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16176			posProperty = floating ? "left" : "top";
16177			sizeProperty = floating ? "width" : "height";
16178			axis = floating ? "pageX" : "pageY";
16179
16180			for ( j = this.items.length - 1; j >= 0; j-- ) {
16181				if ( !$.contains(
16182						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16183				) {
16184					continue;
16185				}
16186				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16187					continue;
16188				}
16189
16190				cur = this.items[ j ].item.offset()[ posProperty ];
16191				nearBottom = false;
16192				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16193					nearBottom = true;
16194				}
16195
16196				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16197					dist = Math.abs( event[ axis ] - cur );
16198					itemWithLeastDistance = this.items[ j ];
16199					this.direction = nearBottom ? "up" : "down";
16200				}
16201			}
16202
16203			//Check if dropOnEmpty is enabled
16204			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16205				return;
16206			}
16207
16208			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16209				if ( !this.currentContainer.containerCache.over ) {
16210					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16211					this.currentContainer.containerCache.over = 1;
16212				}
16213				return;
16214			}
16215
16216			itemWithLeastDistance ?
16217				this._rearrange( event, itemWithLeastDistance, null, true ) :
16218				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16219			this._trigger( "change", event, this._uiHash() );
16220			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16221			this.currentContainer = this.containers[ innermostIndex ];
16222
16223			//Update the placeholder
16224			this.options.placeholder.update( this.currentContainer, this.placeholder );
16225
16226			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16227			this.containers[ innermostIndex ].containerCache.over = 1;
16228		}
16229
16230	},
16231
16232	_createHelper: function( event ) {
16233
16234		var o = this.options,
16235			helper = $.isFunction( o.helper ) ?
16236				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16237				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16238
16239		//Add the helper to the DOM if that didn't happen already
16240		if ( !helper.parents( "body" ).length ) {
16241			$( o.appendTo !== "parent" ?
16242				o.appendTo :
16243				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16244		}
16245
16246		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16247			this._storedCSS = {
16248				width: this.currentItem[ 0 ].style.width,
16249				height: this.currentItem[ 0 ].style.height,
16250				position: this.currentItem.css( "position" ),
16251				top: this.currentItem.css( "top" ),
16252				left: this.currentItem.css( "left" )
16253			};
16254		}
16255
16256		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16257			helper.width( this.currentItem.width() );
16258		}
16259		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16260			helper.height( this.currentItem.height() );
16261		}
16262
16263		return helper;
16264
16265	},
16266
16267	_adjustOffsetFromHelper: function( obj ) {
16268		if ( typeof obj === "string" ) {
16269			obj = obj.split( " " );
16270		}
16271		if ( $
vendor: 9,476 bytes, lines 16271-16551
16271.isArray( obj ) ) {
16272			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16273		}
16274		if ( "left" in obj ) {
16275			this.offset.click.left = obj.left + this.margins.left;
16276		}
16277		if ( "right" in obj ) {
16278			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16279		}
16280		if ( "top" in obj ) {
16281			this.offset.click.top = obj.top + this.margins.top;
16282		}
16283		if ( "bottom" in obj ) {
16284			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16285		}
16286	},
16287
16288	_getParentOffset: function() {
16289
16290		//Get the offsetParent and cache its position
16291		this.offsetParent = this.helper.offsetParent();
16292		var po = this.offsetParent.offset();
16293
16294		// This is a special case where we need to modify a offset calculated on start, since the
16295		// following happened:
16296		// 1. The position of the helper is absolute, so it's position is calculated based on the
16297		// next positioned parent
16298		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16299		// the document, which means that the scroll is included in the initial calculation of the
16300		// offset of the parent, and never recalculated upon drag
16301		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16302				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16303			po.left += this.scrollParent.scrollLeft();
16304			po.top += this.scrollParent.scrollTop();
16305		}
16306
16307		// This needs to be actually done for all browsers, since pageX/pageY includes this
16308		// information with an ugly IE fix
16309		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16310				( this.offsetParent[ 0 ].tagName &&
16311				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16312			po = { top: 0, left: 0 };
16313		}
16314
16315		return {
16316			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16317			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16318		};
16319
16320	},
16321
16322	_getRelativeOffset: function() {
16323
16324		if ( this.cssPosition === "relative" ) {
16325			var p = this.currentItem.position();
16326			return {
16327				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16328					this.scrollParent.scrollTop(),
16329				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16330					this.scrollParent.scrollLeft()
16331			};
16332		} else {
16333			return { top: 0, left: 0 };
16334		}
16335
16336	},
16337
16338	_cacheMargins: function() {
16339		this.margins = {
16340			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16341			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16342		};
16343	},
16344
16345	_cacheHelperProportions: function() {
16346		this.helperProportions = {
16347			width: this.helper.outerWidth(),
16348			height: this.helper.outerHeight()
16349		};
16350	},
16351
16352	_setContainment: function() {
16353
16354		var ce, co, over,
16355			o = this.options;
16356		if ( o.containment === "parent" ) {
16357			o.containment = this.helper[ 0 ].parentNode;
16358		}
16359		if ( o.containment === "document" || o.containment === "window" ) {
16360			this.containment = [
16361				0 - this.offset.relative.left - this.offset.parent.left,
16362				0 - this.offset.relative.top - this.offset.parent.top,
16363				o.containment === "document" ?
16364					this.document.width() :
16365					this.window.width() - this.helperProportions.width - this.margins.left,
16366				( o.containment === "document" ?
16367					( this.document.height() || document.body.parentNode.scrollHeight ) :
16368					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16369				) - this.helperProportions.height - this.margins.top
16370			];
16371		}
16372
16373		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16374			ce = $( o.containment )[ 0 ];
16375			co = $( o.containment ).offset();
16376			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16377
16378			this.containment = [
16379				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16380					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16381				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16382					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16383				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16384					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16385					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16386					this.helperProportions.width - this.margins.left,
16387				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16388					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16389					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16390					this.helperProportions.height - this.margins.top
16391			];
16392		}
16393
16394	},
16395
16396	_convertPositionTo: function( d, pos ) {
16397
16398		if ( !pos ) {
16399			pos = this.position;
16400		}
16401		var mod = d === "absolute" ? 1 : -1,
16402			scroll = this.cssPosition === "absolute" &&
16403				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16404				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16405					this.offsetParent :
16406					this.scrollParent,
16407			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16408
16409		return {
16410			top: (
16411
16412				// The absolute mouse position
16413				pos.top	+
16414
16415				// Only for relative positioned nodes: Relative offset from element to offset parent
16416				this.offset.relative.top * mod +
16417
16418				// The offsetParent's offset without borders (offset + border)
16419				this.offset.parent.top * mod -
16420				( ( this.cssPosition === "fixed" ?
16421					-this.scrollParent.scrollTop() :
16422					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16423			),
16424			left: (
16425
16426				// The absolute mouse position
16427				pos.left +
16428
16429				// Only for relative positioned nodes: Relative offset from element to offset parent
16430				this.offset.relative.left * mod +
16431
16432				// The offsetParent's offset without borders (offset + border)
16433				this.offset.parent.left * mod	-
16434				( ( this.cssPosition === "fixed" ?
16435					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16436					scroll.scrollLeft() ) * mod )
16437			)
16438		};
16439
16440	},
16441
16442	_generatePosition: function( event ) {
16443
16444		var top, left,
16445			o = this.options,
16446			pageX = event.pageX,
16447			pageY = event.pageY,
16448			scroll = this.cssPosition === "absolute" &&
16449				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16450				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16451					this.offsetParent :
16452					this.scrollParent,
16453				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16454
16455		// This is another very weird special case that only happens for relative elements:
16456		// 1. If the css position is relative
16457		// 2. and the scroll parent is the document or similar to the offset parent
16458		// we have to refresh the relative offset during the scroll so there are no jumps
16459		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16460				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16461			this.offset.relative = this._getRelativeOffset();
16462		}
16463
16464		/*
16465		 * - Position constraining -
16466		 * Constrain the position to a mix of grid, containment.
16467		 */
16468
16469		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16470
16471			if ( this.containment ) {
16472				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16473					pageX = this.containment[ 0 ] + this.offset.click.left;
16474				}
16475				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16476					pageY = this.containment[ 1 ] + this.offset.click.top;
16477				}
16478				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16479					pageX = this.containment[ 2 ] + this.offset.click.left;
16480				}
16481				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16482					pageY = this.containment[ 3 ] + this.offset.click.top;
16483				}
16484			}
16485
16486			if ( o.grid ) {
16487				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16488					o.grid[ 1 ] ) * o.grid[ 1 ];
16489				pageY = this.containment ?
16490					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16491						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16492							top :
16493							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16494								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16495								top;
16496
16497				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16498					o.grid[ 0 ] ) * o.grid[ 0 ];
16499				pageX = this.containment ?
16500					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16501						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16502							left :
16503							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16504								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16505								left;
16506			}
16507
16508		}
16509
16510		return {
16511			top: (
16512
16513				// The absolute mouse position
16514				pageY -
16515
16516				// Click offset (relative to the element)
16517				this.offset.click.top -
16518
16519				// Only for relative positioned nodes: Relative offset from element to offset parent
16520				this.offset.relative.top -
16521
16522				// The offsetParent's offset without borders (offset + border)
16523				this.offset.parent.top +
16524				( ( this.cssPosition === "fixed" ?
16525					-this.scrollParent.scrollTop() :
16526					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16527			),
16528			left: (
16529
16530				// The absolute mouse position
16531				pageX -
16532
16533				// Click offset (relative to the element)
16534				this.offset.click.left -
16535
16536				// Only for relative positioned nodes: Relative offset from element to offset parent
16537				this.offset.relative.left -
16538
16539				// The offsetParent's offset without borders (offset + border)
16540				this.offset.parent.left +
16541				( ( this.cssPosition === "fixed" ?
16542					-this.scrollParent.scrollLeft() :
16543					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16544			)
16545		};
16546
16547	},
16548
16549	_rearrange: function( event, i, a, hardRefresh ) {
16550
16551		
16551a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16552			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16553				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
vendor: 5,013 bytes, lines 16553-16721
16553
16554
16555		//Various things done here to improve the performance:
16556		// 1. we create a setTimeout, that calls refreshPositions
16557		// 2. on the instance, we have a counter variable, that get's higher after every append
16558		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16559		// if it's still the same
16560		// 4. this lets only the last addition to the timeout stack through
16561		this.counter = this.counter ? ++this.counter : 1;
16562		var counter = this.counter;
16563
16564		this._delay( function() {
16565			if ( counter === this.counter ) {
16566
16567				//Precompute after each DOM insertion, NOT on mousemove
16568				this.refreshPositions( !hardRefresh );
16569			}
16570		} );
16571
16572	},
16573
16574	_clear: function( event, noPropagation ) {
16575
16576		this.reverting = false;
16577
16578		// We delay all events that have to be triggered to after the point where the placeholder
16579		// has been removed and everything else normalized again
16580		var i,
16581			delayedTriggers = [];
16582
16583		// We first have to update the dom position of the actual currentItem
16584		// Note: don't do it if the current item is already removed (by a user), or it gets
16585		// reappended (see #4088)
16586		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16587			this.placeholder.before( this.currentItem );
16588		}
16589		this._noFinalSort = null;
16590
16591		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16592			for ( i in this._storedCSS ) {
16593				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16594					this._storedCSS[ i ] = "";
16595				}
16596			}
16597			this.currentItem.css( this._storedCSS );
16598			this._removeClass( this.currentItem, "ui-sortable-helper" );
16599		} else {
16600			this.currentItem.show();
16601		}
16602
16603		if ( this.fromOutside && !noPropagation ) {
16604			delayedTriggers.push( function( event ) {
16605				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16606			} );
16607		}
16608		if ( ( this.fromOutside ||
16609				this.domPosition.prev !==
16610				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16611				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16612
16613			// Trigger update callback if the DOM position has changed
16614			delayedTriggers.push( function( event ) {
16615				this._trigger( "update", event, this._uiHash() );
16616			} );
16617		}
16618
16619		// Check if the items Container has Changed and trigger appropriate
16620		// events.
16621		if ( this !== this.currentContainer ) {
16622			if ( !noPropagation ) {
16623				delayedTriggers.push( function( event ) {
16624					this._trigger( "remove", event, this._uiHash() );
16625				} );
16626				delayedTriggers.push( ( function( c ) {
16627					return function( event ) {
16628						c._trigger( "receive", event, this._uiHash( this ) );
16629					};
16630				} ).call( this, this.currentContainer ) );
16631				delayedTriggers.push( ( function( c ) {
16632					return function( event ) {
16633						c._trigger( "update", event, this._uiHash( this ) );
16634					};
16635				} ).call( this, this.currentContainer ) );
16636			}
16637		}
16638
16639		//Post events to containers
16640		function delayEvent( type, instance, container ) {
16641			return function( event ) {
16642				container._trigger( type, event, instance._uiHash( instance ) );
16643			};
16644		}
16645		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16646			if ( !noPropagation ) {
16647				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16648			}
16649			if ( this.containers[ i ].containerCache.over ) {
16650				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16651				this.containers[ i ].containerCache.over = 0;
16652			}
16653		}
16654
16655		//Do what was originally in plugins
16656		if ( this.storedCursor ) {
16657			this.document.find( "body" ).css( "cursor", this.storedCursor );
16658			this.storedStylesheet.remove();
16659		}
16660		if ( this._storedOpacity ) {
16661			this.helper.css( "opacity", this._storedOpacity );
16662		}
16663		if ( this._storedZIndex ) {
16664			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16665		}
16666
16667		this.dragging = false;
16668
16669		if ( !noPropagation ) {
16670			this._trigger( "beforeStop", event, this._uiHash() );
16671		}
16672
16673		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16674		// it unbinds ALL events from the original node!
16675		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16676
16677		if ( !this.cancelHelperRemoval ) {
16678			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16679				this.helper.remove();
16680			}
16681			this.helper = null;
16682		}
16683
16684		if ( !noPropagation ) {
16685			for ( i = 0; i < delayedTriggers.length; i++ ) {
16686
16687				// Trigger all delayed events
16688				delayedTriggers[ i ].call( this, event );
16689			}
16690			this._trigger( "stop", event, this._uiHash() );
16691		}
16692
16693		this.fromOutside = false;
16694		return !this.cancelHelperRemoval;
16695
16696	},
16697
16698	_trigger: function() {
16699		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16700			this.cancel();
16701		}
16702	},
16703
16704	_uiHash: function( _inst ) {
16705		var inst = _inst || this;
16706		return {
16707			helper: inst.helper,
16708			placeholder: inst.placeholder || $( [] ),
16709			position: inst.position,
16710			originalPosition: inst.originalPosition,
16711			offset: inst.positionAbs,
16712			item: inst.currentItem,
16713			sender: _inst ? _inst.element : null
16714		};
16715	}
16716
16717} );
16718
16719
16720/*!
16721 * jQuery UI Spinner 1.1
vendor: 26,644 bytes, lines 16721-17765
167212.0
16722 * http://jqueryui.com
16723 *
16724 * Copyright jQuery Foundation and other contributors
16725 * Released under the MIT license.
16726 * http://jquery.org/license
16727 */
16728
16729//>>label: Spinner
16730//>>group: Widgets
16731//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16732//>>docs: http://api.jqueryui.com/spinner/
16733//>>demos: http://jqueryui.com/spinner/
16734//>>css.structure: ../../themes/base/core.css
16735//>>css.structure: ../../themes/base/spinner.css
16736//>>css.theme: ../../themes/base/theme.css
16737
16738
16739
16740function spinnerModifer( fn ) {
16741	return function() {
16742		var previous = this.element.val();
16743		fn.apply( this, arguments );
16744		this._refresh();
16745		if ( previous !== this.element.val() ) {
16746			this._trigger( "change" );
16747		}
16748	};
16749}
16750
16751$.widget( "ui.spinner", {
16752	version: "1.12.0",
16753	defaultElement: "<input>",
16754	widgetEventPrefix: "spin",
16755	options: {
16756		classes: {
16757			"ui-spinner": "ui-corner-all",
16758			"ui-spinner-down": "ui-corner-br",
16759			"ui-spinner-up": "ui-corner-tr"
16760		},
16761		culture: null,
16762		icons: {
16763			down: "ui-icon-triangle-1-s",
16764			up: "ui-icon-triangle-1-n"
16765		},
16766		incremental: true,
16767		max: null,
16768		min: null,
16769		numberFormat: null,
16770		page: 10,
16771		step: 1,
16772
16773		change: null,
16774		spin: null,
16775		start: null,
16776		stop: null
16777	},
16778
16779	_create: function() {
16780
16781		// handle string values that need to be parsed
16782		this._setOption( "max", this.options.max );
16783		this._setOption( "min", this.options.min );
16784		this._setOption( "step", this.options.step );
16785
16786		// Only format if there is a value, prevents the field from being marked
16787		// as invalid in Firefox, see #9573.
16788		if ( this.value() !== "" ) {
16789
16790			// Format the value, but don't constrain.
16791			this._value( this.element.val(), true );
16792		}
16793
16794		this._draw();
16795		this._on( this._events );
16796		this._refresh();
16797
16798		// Turning off autocomplete prevents the browser from remembering the
16799		// value when navigating through history, so we re-enable autocomplete
16800		// if the page is unloaded before the widget is destroyed. #7790
16801		this._on( this.window, {
16802			beforeunload: function() {
16803				this.element.removeAttr( "autocomplete" );
16804			}
16805		} );
16806	},
16807
16808	_getCreateOptions: function() {
16809		var options = this._super();
16810		var element = this.element;
16811
16812		$.each( [ "min", "max", "step" ], function( i, option ) {
16813			var value = element.attr( option );
16814			if ( value != null && value.length ) {
16815				options[ option ] = value;
16816			}
16817		} );
16818
16819		return options;
16820	},
16821
16822	_events: {
16823		keydown: function( event ) {
16824			if ( this._start( event ) && this._keydown( event ) ) {
16825				event.preventDefault();
16826			}
16827		},
16828		keyup: "_stop",
16829		focus: function() {
16830			this.previous = this.element.val();
16831		},
16832		blur: function( event ) {
16833			if ( this.cancelBlur ) {
16834				delete this.cancelBlur;
16835				return;
16836			}
16837
16838			this._stop();
16839			this._refresh();
16840			if ( this.previous !== this.element.val() ) {
16841				this._trigger( "change", event );
16842			}
16843		},
16844		mousewheel: function( event, delta ) {
16845			if ( !delta ) {
16846				return;
16847			}
16848			if ( !this.spinning && !this._start( event ) ) {
16849				return false;
16850			}
16851
16852			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16853			clearTimeout( this.mousewheelTimer );
16854			this.mousewheelTimer = this._delay( function() {
16855				if ( this.spinning ) {
16856					this._stop( event );
16857				}
16858			}, 100 );
16859			event.preventDefault();
16860		},
16861		"mousedown .ui-spinner-button": function( event ) {
16862			var previous;
16863
16864			// We never want the buttons to have focus; whenever the user is
16865			// interacting with the spinner, the focus should be on the input.
16866			// If the input is focused then this.previous is properly set from
16867			// when the input first received focus. If the input is not focused
16868			// then we need to set this.previous based on the value before spinning.
16869			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16870				this.previous : this.element.val();
16871			function checkFocus() {
16872				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16873				if ( !isActive ) {
16874					this.element.trigger( "focus" );
16875					this.previous = previous;
16876
16877					// support: IE
16878					// IE sets focus asynchronously, so we need to check if focus
16879					// moved off of the input because the user clicked on the button.
16880					this._delay( function() {
16881						this.previous = previous;
16882					} );
16883				}
16884			}
16885
16886			// Ensure focus is on (or stays on) the text field
16887			event.preventDefault();
16888			checkFocus.call( this );
16889
16890			// Support: IE
16891			// IE doesn't prevent moving focus even with event.preventDefault()
16892			// so we set a flag to know when we should ignore the blur event
16893			// and check (again) if focus moved off of the input.
16894			this.cancelBlur = true;
16895			this._delay( function() {
16896				delete this.cancelBlur;
16897				checkFocus.call( this );
16898			} );
16899
16900			if ( this._start( event ) === false ) {
16901				return;
16902			}
16903
16904			this._repeat( null, $( event.currentTarget )
16905				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16906		},
16907		"mouseup .ui-spinner-button": "_stop",
16908		"mouseenter .ui-spinner-button": function( event ) {
16909
16910			// button will add ui-state-active if mouse was down while mouseleave and kept down
16911			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16912				return;
16913			}
16914
16915			if ( this._start( event ) === false ) {
16916				return false;
16917			}
16918			this._repeat( null, $( event.currentTarget )
16919				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16920		},
16921
16922		// TODO: do we really want to consider this a stop?
16923		// shouldn't we just stop the repeater and wait until mouseup before
16924		// we trigger the stop event?
16925		"mouseleave .ui-spinner-button": "_stop"
16926	},
16927
16928	// Support mobile enhanced option and make backcompat more sane
16929	_enhance: function() {
16930		this.uiSpinner = this.element
16931			.attr( "autocomplete", "off" )
16932			.wrap( "<span>" )
16933			.parent()
16934
16935				// Add buttons
16936				.append(
16937					"<a></a><a></a>"
16938				);
16939	},
16940
16941	_draw: function() {
16942		this._enhance();
16943
16944		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16945		this._addClass( "ui-spinner-input" );
16946
16947		this.element.attr( "role", "spinbutton" );
16948
16949		// Button bindings
16950		this.buttons = this.uiSpinner.children( "a" )
16951			.attr( "tabIndex", -1 )
16952			.attr( "aria-hidden", true )
16953			.button( {
16954				classes: {
16955					"ui-button": ""
16956				}
16957			} );
16958
16959		// TODO: Right now button does not support classes this is already updated in button PR
16960		this._removeClass( this.buttons, "ui-corner-all" );
16961
16962		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16963		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16964		this.buttons.first().button( {
16965			"icon": this.options.icons.up,
16966			"showLabel": false
16967		} );
16968		this.buttons.last().button( {
16969			"icon": this.options.icons.down,
16970			"showLabel": false
16971		} );
16972
16973		// IE 6 doesn't understand height: 50% for the buttons
16974		// unless the wrapper has an explicit height
16975		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16976				this.uiSpinner.height() > 0 ) {
16977			this.uiSpinner.height( this.uiSpinner.height() );
16978		}
16979	},
16980
16981	_keydown: function( event ) {
16982		var options = this.options,
16983			keyCode = $.ui.keyCode;
16984
16985		switch ( event.keyCode ) {
16986		case keyCode.UP:
16987			this._repeat( null, 1, event );
16988			return true;
16989		case keyCode.DOWN:
16990			this._repeat( null, -1, event );
16991			return true;
16992		case keyCode.PAGE_UP:
16993			this._repeat( null, options.page, event );
16994			return true;
16995		case keyCode.PAGE_DOWN:
16996			this._repeat( null, -options.page, event );
16997			return true;
16998		}
16999
17000		return false;
17001	},
17002
17003	_start: function( event ) {
17004		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17005			return false;
17006		}
17007
17008		if ( !this.counter ) {
17009			this.counter = 1;
17010		}
17011		this.spinning = true;
17012		return true;
17013	},
17014
17015	_repeat: function( i, steps, event ) {
17016		i = i || 500;
17017
17018		clearTimeout( this.timer );
17019		this.timer = this._delay( function() {
17020			this._repeat( 40, steps, event );
17021		}, i );
17022
17023		this._spin( steps * this.options.step, event );
17024	},
17025
17026	_spin: function( step, event ) {
17027		var value = this.value() || 0;
17028
17029		if ( !this.counter ) {
17030			this.counter = 1;
17031		}
17032
17033		value = this._adjustValue( value + step * this._increment( this.counter ) );
17034
17035		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17036			this._value( value );
17037			this.counter++;
17038		}
17039	},
17040
17041	_increment: function( i ) {
17042		var incremental = this.options.incremental;
17043
17044		if ( incremental ) {
17045			return $.isFunction( incremental ) ?
17046				incremental( i ) :
17047				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17048		}
17049
17050		return 1;
17051	},
17052
17053	_precision: function() {
17054		var precision = this._precisionOf( this.options.step );
17055		if ( this.options.min !== null ) {
17056			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17057		}
17058		return precision;
17059	},
17060
17061	_precisionOf: function( num ) {
17062		var str = num.toString(),
17063			decimal = str.indexOf( "." );
17064		return decimal === -1 ? 0 : str.length - decimal - 1;
17065	},
17066
17067	_adjustValue: function( value ) {
17068		var base, aboveMin,
17069			options = this.options;
17070
17071		// Make sure we're at a valid step
17072		// - find out where we are relative to the base (min or 0)
17073		base = options.min !== null ? options.min : 0;
17074		aboveMin = value - base;
17075
17076		// - round to the nearest step
17077		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17078
17079		// - rounding is based on 0, so adjust back to our base
17080		value = base + aboveMin;
17081
17082		// Fix precision from bad JS floating point math
17083		value = parseFloat( value.toFixed( this._precision() ) );
17084
17085		// Clamp the value
17086		if ( options.max !== null && value > options.max ) {
17087			return options.max;
17088		}
17089		if ( options.min !== null && value < options.min ) {
17090			return options.min;
17091		}
17092
17093		return value;
17094	},
17095
17096	_stop: function( event ) {
17097		if ( !this.spinning ) {
17098			return;
17099		}
17100
17101		clearTimeout( this.timer );
17102		clearTimeout( this.mousewheelTimer );
17103		this.counter = 0;
17104		this.spinning = false;
17105		this._trigger( "stop", event );
17106	},
17107
17108	_setOption: function( key, value ) {
17109		var prevValue, first, last;
17110
17111		if ( key === "culture" || key === "numberFormat" ) {
17112			prevValue = this._parse( this.element.val() );
17113			this.options[ key ] = value;
17114			this.element.val( this._format( prevValue ) );
17115			return;
17116		}
17117
17118		if ( key === "max" || key === "min" || key === "step" ) {
17119			if ( typeof value === "string" ) {
17120				value = this._parse( value );
17121			}
17122		}
17123		if ( key === "icons" ) {
17124			first = this.buttons.first().find( ".ui-icon" );
17125			this._removeClass( first, null, this.options.icons.up );
17126			this._addClass( first, null, value.up );
17127			last = this.buttons.last().find( ".ui-icon" );
17128			this._removeClass( last, null, this.options.icons.down );
17129			this._addClass( last, null, value.down );
17130		}
17131
17132		this._super( key, value );
17133	},
17134
17135	_setOptionDisabled: function( value ) {
17136		this._super( value );
17137
17138		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17139		this.element.prop( "disabled", !!value );
17140		this.buttons.button( value ? "disable" : "enable" );
17141	},
17142
17143	_setOptions: spinnerModifer( function( options ) {
17144		this._super( options );
17145	} ),
17146
17147	_parse: function( val ) {
17148		if ( typeof val === "string" && val !== "" ) {
17149			val = window.Globalize && this.options.numberFormat ?
17150				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17151		}
17152		return val === "" || isNaN( val ) ? null : val;
17153	},
17154
17155	_format: function( value ) {
17156		if ( value === "" ) {
17157			return "";
17158		}
17159		return window.Globalize && this.options.numberFormat ?
17160			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17161			value;
17162	},
17163
17164	_refresh: function() {
17165		this.element.attr( {
17166			"aria-valuemin": this.options.min,
17167			"aria-valuemax": this.options.max,
17168
17169			// TODO: what should we do with values that can't be parsed?
17170			"aria-valuenow": this._parse( this.element.val() )
17171		} );
17172	},
17173
17174	isValid: function() {
17175		var value = this.value();
17176
17177		// Null is invalid
17178		if ( value === null ) {
17179			return false;
17180		}
17181
17182		// If value gets adjusted, it's invalid
17183		return value === this._adjustValue( value );
17184	},
17185
17186	// Update the value without triggering change
17187	_value: function( value, allowAny ) {
17188		var parsed;
17189		if ( value !== "" ) {
17190			parsed = this._parse( value );
17191			if ( parsed !== null ) {
17192				if ( !allowAny ) {
17193					parsed = this._adjustValue( parsed );
17194				}
17195				value = this._format( parsed );
17196			}
17197		}
17198		this.element.val( value );
17199		this._refresh();
17200	},
17201
17202	_destroy: function() {
17203		this.element
17204			.prop( "disabled", false )
17205			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17206
17207		this.uiSpinner.replaceWith( this.element );
17208	},
17209
17210	stepUp: spinnerModifer( function( steps ) {
17211		this._stepUp( steps );
17212	} ),
17213	_stepUp: function( steps ) {
17214		if ( this._start() ) {
17215			this._spin( ( steps || 1 ) * this.options.step );
17216			this._stop();
17217		}
17218	},
17219
17220	stepDown: spinnerModifer( function( steps ) {
17221		this._stepDown( steps );
17222	} ),
17223	_stepDown: function( steps ) {
17224		if ( this._start() ) {
17225			this._spin( ( steps || 1 ) * -this.options.step );
17226			this._stop();
17227		}
17228	},
17229
17230	pageUp: spinnerModifer( function( pages ) {
17231		this._stepUp( ( pages || 1 ) * this.options.page );
17232	} ),
17233
17234	pageDown: spinnerModifer( function( pages ) {
17235		this._stepDown( ( pages || 1 ) * this.options.page );
17236	} ),
17237
17238	value: function( newVal ) {
17239		if ( !arguments.length ) {
17240			return this._parse( this.element.val() );
17241		}
17242		spinnerModifer( this._value ).call( this, newVal );
17243	},
17244
17245	widget: function() {
17246		return this.uiSpinner;
17247	}
17248} );
17249
17250// DEPRECATED
17251// TODO: switch return back to widget declaration at top of file when this is removed
17252if ( $.uiBackCompat !== false ) {
17253
17254	// Backcompat for spinner html extension points
17255	$.widget( "ui.spinner", $.ui.spinner, {
17256		_enhance: function() {
17257			this.uiSpinner = this.element
17258				.attr( "autocomplete", "off" )
17259				.wrap( this._uiSpinnerHtml() )
17260				.parent()
17261
17262					// Add buttons
17263					.append( this._buttonHtml() );
17264		},
17265		_uiSpinnerHtml: function() {
17266			return "<span>";
17267		},
17268
17269		_buttonHtml: function() {
17270			return "<a></a><a></a>";
17271		}
17272	} );
17273}
17274
17275var widgetsSpinner = $.ui.spinner;
17276
17277
17278/*!
17279 * jQuery UI Tabs 1.12.0
17280 * http://jqueryui.com
17281 *
17282 * Copyright jQuery Foundation and other contributors
17283 * Released under the MIT license.
17284 * http://jquery.org/license
17285 */
17286
17287//>>label: Tabs
17288//>>group: Widgets
17289//>>description: Transforms a set of container elements into a tab structure.
17290//>>docs: http://api.jqueryui.com/tabs/
17291//>>demos: http://jqueryui.com/tabs/
17292//>>css.structure: ../../themes/base/core.css
17293//>>css.structure: ../../themes/base/tabs.css
17294//>>css.theme: ../../themes/base/theme.css
17295
17296
17297
17298$.widget( "ui.tabs", {
17299	version: "1.12.0",
17300	delay: 300,
17301	options: {
17302		active: null,
17303		classes: {
17304			"ui-tabs": "ui-corner-all",
17305			"ui-tabs-nav": "ui-corner-all",
17306			"ui-tabs-panel": "ui-corner-bottom",
17307			"ui-tabs-tab": "ui-corner-top"
17308		},
17309		collapsible: false,
17310		event: "click",
17311		heightStyle: "content",
17312		hide: null,
17313		show: null,
17314
17315		// Callbacks
17316		activate: null,
17317		beforeActivate: null,
17318		beforeLoad: null,
17319		load: null
17320	},
17321
17322	_isLocal: ( function() {
17323		var rhash = /#.*$/;
17324
17325		return function( anchor ) {
17326			var anchorUrl, locationUrl;
17327
17328			anchorUrl = anchor.href.replace( rhash, "" );
17329			locationUrl = location.href.replace( rhash, "" );
17330
17331			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17332			try {
17333				anchorUrl = decodeURIComponent( anchorUrl );
17334			} catch ( error ) {}
17335			try {
17336				locationUrl = decodeURIComponent( locationUrl );
17337			} catch ( error ) {}
17338
17339			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17340		};
17341	} )(),
17342
17343	_create: function() {
17344		var that = this,
17345			options = this.options;
17346
17347		this.running = false;
17348
17349		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17350		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17351
17352		this._processTabs();
17353		options.active = this._initialActive();
17354
17355		// Take disabling tabs via class attribute from HTML
17356		// into account and update option properly.
17357		if ( $.isArray( options.disabled ) ) {
17358			options.disabled = $.unique( options.disabled.concat(
17359				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17360					return that.tabs.index( li );
17361				} )
17362			) ).sort();
17363		}
17364
17365		// Check for length avoids error when initializing empty list
17366		if ( this.options.active !== false && this.anchors.length ) {
17367			this.active = this._findActive( options.active );
17368		} else {
17369			this.active = $();
17370		}
17371
17372		this._refresh();
17373
17374		if ( this.active.length ) {
17375			this.load( options.active );
17376		}
17377	},
17378
17379	_initialActive: function() {
17380		var active = this.options.active,
17381			collapsible = this.options.collapsible,
17382			locationHash = location.hash.substring( 1 );
17383
17384		if ( active === null ) {
17385
17386			// check the fragment identifier in the URL
17387			if ( locationHash ) {
17388				this.tabs.each( function( i, tab ) {
17389					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17390						active = i;
17391						return false;
17392					}
17393				} );
17394			}
17395
17396			// Check for a tab marked active via a class
17397			if ( active === null ) {
17398				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17399			}
17400
17401			// No active tab, set to false
17402			if ( active === null || active === -1 ) {
17403				active = this.tabs.length ? 0 : false;
17404			}
17405		}
17406
17407		// Handle numbers: negative, out of range
17408		if ( active !== false ) {
17409			active = this.tabs.index( this.tabs.eq( active ) );
17410			if ( active === -1 ) {
17411				active = collapsible ? false : 0;
17412			}
17413		}
17414
17415		// Don't allow collapsible: false and active: false
17416		if ( !collapsible && active === false && this.anchors.length ) {
17417			active = 0;
17418		}
17419
17420		return active;
17421	},
17422
17423	_getCreateEventData: function() {
17424		return {
17425			tab: this.active,
17426			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17427		};
17428	},
17429
17430	_tabKeydown: function( event ) {
17431		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17432			selectedIndex = this.tabs.index( focusedTab ),
17433			goingForward = true;
17434
17435		if ( this._handlePageNav( event ) ) {
17436			return;
17437		}
17438
17439		switch ( event.keyCode ) {
17440		case $.ui.keyCode.RIGHT:
17441		case $.ui.keyCode.DOWN:
17442			selectedIndex++;
17443			break;
17444		case $.ui.keyCode.UP:
17445		case $.ui.keyCode.LEFT:
17446			goingForward = false;
17447			selectedIndex--;
17448			break;
17449		case $.ui.keyCode.END:
17450			selectedIndex = this.anchors.length - 1;
17451			break;
17452		case $.ui.keyCode.HOME:
17453			selectedIndex = 0;
17454			break;
17455		case $.ui.keyCode.SPACE:
17456
17457			// Activate only, no collapsing
17458			event.preventDefault();
17459			clearTimeout( this.activating );
17460			this._activate( selectedIndex );
17461			return;
17462		case $.ui.keyCode.ENTER:
17463
17464			// Toggle (cancel delayed activation, allow collapsing)
17465			event.preventDefault();
17466			clearTimeout( this.activating );
17467
17468			// Determine if we should collapse or activate
17469			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17470			return;
17471		default:
17472			return;
17473		}
17474
17475		// Focus the appropriate tab, based on which key was pressed
17476		event.preventDefault();
17477		clearTimeout( this.activating );
17478		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17479
17480		// Navigating with control/command key will prevent automatic activation
17481		if ( !event.ctrlKey && !event.metaKey ) {
17482
17483			// Update aria-selected immediately so that AT think the tab is already selected.
17484			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17485			// but the tab will already be activated by the time the announcement finishes.
17486			focusedTab.attr( "aria-selected", "false" );
17487			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17488
17489			this.activating = this._delay( function() {
17490				this.option( "active", selectedIndex );
17491			}, this.delay );
17492		}
17493	},
17494
17495	_panelKeydown: function( event ) {
17496		if ( this._handlePageNav( event ) ) {
17497			return;
17498		}
17499
17500		// Ctrl+up moves focus to the current tab
17501		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17502			event.preventDefault();
17503			this.active.trigger( "focus" );
17504		}
17505	},
17506
17507	// Alt+page up/down moves focus to the previous/next tab (and activates)
17508	_handlePageNav: function( event ) {
17509		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17510			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17511			return true;
17512		}
17513		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17514			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17515			return true;
17516		}
17517	},
17518
17519	_findNextTab: function( index, goingForward ) {
17520		var lastTabIndex = this.tabs.length - 1;
17521
17522		function constrain() {
17523			if ( index > lastTabIndex ) {
17524				index = 0;
17525			}
17526			if ( index < 0 ) {
17527				index = lastTabIndex;
17528			}
17529			return index;
17530		}
17531
17532		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17533			index = goingForward ? index + 1 : index - 1;
17534		}
17535
17536		return index;
17537	},
17538
17539	_focusNextTab: function( index, goingForward ) {
17540		index = this._findNextTab( index, goingForward );
17541		this.tabs.eq( index ).trigger( "focus" );
17542		return index;
17543	},
17544
17545	_setOption: function( key, value ) {
17546		if ( key === "active" ) {
17547
17548			// _activate() will handle invalid values and update this.options
17549			this._activate( value );
17550			return;
17551		}
17552
17553		this._super( key, value );
17554
17555		if ( key === "collapsible" ) {
17556			this._toggleClass( "ui-tabs-collapsible", null, value );
17557
17558			// Setting collapsible: false while collapsed; open first panel
17559			if ( !value && this.options.active === false ) {
17560				this._activate( 0 );
17561			}
17562		}
17563
17564		if ( key === "event" ) {
17565			this._setupEvents( value );
17566		}
17567
17568		if ( key === "heightStyle" ) {
17569			this._setupHeightStyle( value );
17570		}
17571	},
17572
17573	_sanitizeSelector: function( hash ) {
17574		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17575	},
17576
17577	refresh: function() {
17578		var options = this.options,
17579			lis = this.tablist.children( ":has(a[href])" );
17580
17581		// Get disabled tabs from class attribute from HTML
17582		// this will get converted to a boolean if needed in _refresh()
17583		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17584			return lis.index( tab );
17585		} );
17586
17587		this._processTabs();
17588
17589		// Was collapsed or no tabs
17590		if ( options.active === false || !this.anchors.length ) {
17591			options.active = false;
17592			this.active = $();
17593
17594		// was active, but active tab is gone
17595		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17596
17597			// all remaining tabs are disabled
17598			if ( this.tabs.length === options.disabled.length ) {
17599				options.active = false;
17600				this.active = $();
17601
17602			// activate previous tab
17603			} else {
17604				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17605			}
17606
17607		// was active, active tab still exists
17608		} else {
17609
17610			// make sure active index is correct
17611			options.active = this.tabs.index( this.active );
17612		}
17613
17614		this._refresh();
17615	},
17616
17617	_refresh: function() {
17618		this._setOptionDisabled( this.options.disabled );
17619		this._setupEvents( this.options.event );
17620		this._setupHeightStyle( this.options.heightStyle );
17621
17622		this.tabs.not( this.active ).attr( {
17623			"aria-selected": "false",
17624			"aria-expanded": "false",
17625			tabIndex: -1
17626		} );
17627		this.panels.not( this._getPanelForTab( this.active ) )
17628			.hide()
17629			.attr( {
17630				"aria-hidden": "true"
17631			} );
17632
17633		// Make sure one tab is in the tab order
17634		if ( !this.active.length ) {
17635			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17636		} else {
17637			this.active
17638				.attr( {
17639					"aria-selected": "true",
17640					"aria-expanded": "true",
17641					tabIndex: 0
17642				} );
17643			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17644			this._getPanelForTab( this.active )
17645				.show()
17646				.attr( {
17647					"aria-hidden": "false"
17648				} );
17649		}
17650	},
17651
17652	_processTabs: function() {
17653		var that = this,
17654			prevTabs = this.tabs,
17655			prevAnchors = this.anchors,
17656			prevPanels = this.panels;
17657
17658		this.tablist = this._getList().attr( "role", "tablist" );
17659		this._addClass( this.tablist, "ui-tabs-nav",
17660			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17661
17662		// Prevent users from focusing disabled tabs via click
17663		this.tablist
17664			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17665				if ( $( this ).is( ".ui-state-disabled" ) ) {
17666					event.preventDefault();
17667				}
17668			} )
17669
17670			// Support: IE <9
17671			// Preventing the default action in mousedown doesn't prevent IE
17672			// from focusing the element, so if the anchor gets focused, blur.
17673			// We don't have to worry about focusing the previously focused
17674			// element since clicking on a non-focusable element should focus
17675			// the body anyway.
17676			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17677				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17678					this.blur();
17679				}
17680			} );
17681
17682		this.tabs = this.tablist.find( "> li:has(a[href])" )
17683			.attr( {
17684				role: "tab",
17685				tabIndex: -1
17686			} );
17687		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17688
17689		this.anchors = this.tabs.map( function() {
17690			return $( "a", this )[ 0 ];
17691		} )
17692			.attr( {
17693				role: "presentation",
17694				tabIndex: -1
17695			} );
17696		this._addClass( this.anchors, "ui-tabs-anchor" );
17697
17698		this.panels = $();
17699
17700		this.anchors.each( function( i, anchor ) {
17701			var selector, panel, panelId,
17702				anchorId = $( anchor ).uniqueId().attr( "id" ),
17703				tab = $( anchor ).closest( "li" ),
17704				originalAriaControls = tab.attr( "aria-controls" );
17705
17706			// Inline tab
17707			if ( that._isLocal( anchor ) ) {
17708				selector = anchor.hash;
17709				panelId = selector.substring( 1 );
17710				panel = that.element.find( that._sanitizeSelector( selector ) );
17711
17712			// remote tab
17713			} else {
17714
17715				// If the tab doesn't already have aria-controls,
17716				// generate an id by using a throw-away element
17717				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17718				selector = "#" + panelId;
17719				panel = that.element.find( selector );
17720				if ( !panel.length ) {
17721					panel = that._createPanel( panelId );
17722					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17723				}
17724				panel.attr( "aria-live", "polite" );
17725			}
17726
17727			if ( panel.length ) {
17728				that.panels = that.panels.add( panel );
17729			}
17730			if ( originalAriaControls ) {
17731				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17732			}
17733			tab.attr( {
17734				"aria-controls": panelId,
17735				"aria-labelledby": anchorId
17736			} );
17737			panel.attr( "aria-labelledby", anchorId );
17738		} );
17739
17740		this.panels.attr( "role", "tabpanel" );
17741		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17742
17743		// Avoid memory leaks (#10056)
17744		if ( prevTabs ) {
17745			this._off( prevTabs.not( this.tabs ) );
17746			this._off( prevAnchors.not( this.anchors ) );
17747			this._off( prevPanels.not( this.panels ) );
17748		}
17749	},
17750
17751	// Allow overriding how to find the list for rare usage scenarios (#7715)
17752	_getList: function() {
17753		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17754	},
17755
17756	_createPanel: function( id ) {
17757		return $( "<div>" )
17758			.attr( "id", id )
17759			.data( "ui-tabs-destroy", true );
17760	},
17761
17762	_setOptionDisabled: function( disabled ) {
17763		var currentItem, li, i;
17764
17765		if ( $
vendor: 6,224 bytes, lines 17765-17996
17765.isArray( disabled ) ) {
17766			if ( !disabled.length ) {
17767				disabled = false;
17768			} else if ( disabled.length === this.anchors.length ) {
17769				disabled = true;
17770			}
17771		}
17772
17773		// Disable tabs
17774		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17775			currentItem = $( li );
17776			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17777				currentItem.attr( "aria-disabled", "true" );
17778				this._addClass( currentItem, null, "ui-state-disabled" );
17779			} else {
17780				currentItem.removeAttr( "aria-disabled" );
17781				this._removeClass( currentItem, null, "ui-state-disabled" );
17782			}
17783		}
17784
17785		this.options.disabled = disabled;
17786
17787		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17788			disabled === true );
17789	},
17790
17791	_setupEvents: function( event ) {
17792		var events = {};
17793		if ( event ) {
17794			$.each( event.split( " " ), function( index, eventName ) {
17795				events[ eventName ] = "_eventHandler";
17796			} );
17797		}
17798
17799		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17800
17801		// Always prevent the default action, even when disabled
17802		this._on( true, this.anchors, {
17803			click: function( event ) {
17804				event.preventDefault();
17805			}
17806		} );
17807		this._on( this.anchors, events );
17808		this._on( this.tabs, { keydown: "_tabKeydown" } );
17809		this._on( this.panels, { keydown: "_panelKeydown" } );
17810
17811		this._focusable( this.tabs );
17812		this._hoverable( this.tabs );
17813	},
17814
17815	_setupHeightStyle: function( heightStyle ) {
17816		var maxHeight,
17817			parent = this.element.parent();
17818
17819		if ( heightStyle === "fill" ) {
17820			maxHeight = parent.height();
17821			maxHeight -= this.element.outerHeight() - this.element.height();
17822
17823			this.element.siblings( ":visible" ).each( function() {
17824				var elem = $( this ),
17825					position = elem.css( "position" );
17826
17827				if ( position === "absolute" || position === "fixed" ) {
17828					return;
17829				}
17830				maxHeight -= elem.outerHeight( true );
17831			} );
17832
17833			this.element.children().not( this.panels ).each( function() {
17834				maxHeight -= $( this ).outerHeight( true );
17835			} );
17836
17837			this.panels.each( function() {
17838				$( this ).height( Math.max( 0, maxHeight -
17839					$( this ).innerHeight() + $( this ).height() ) );
17840			} )
17841				.css( "overflow", "auto" );
17842		} else if ( heightStyle === "auto" ) {
17843			maxHeight = 0;
17844			this.panels.each( function() {
17845				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17846			} ).height( maxHeight );
17847		}
17848	},
17849
17850	_eventHandler: function( event ) {
17851		var options = this.options,
17852			active = this.active,
17853			anchor = $( event.currentTarget ),
17854			tab = anchor.closest( "li" ),
17855			clickedIsActive = tab[ 0 ] === active[ 0 ],
17856			collapsing = clickedIsActive && options.collapsible,
17857			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17858			toHide = !active.length ? $() : this._getPanelForTab( active ),
17859			eventData = {
17860				oldTab: active,
17861				oldPanel: toHide,
17862				newTab: collapsing ? $() : tab,
17863				newPanel: toShow
17864			};
17865
17866		event.preventDefault();
17867
17868		if ( tab.hasClass( "ui-state-disabled" ) ||
17869
17870				// tab is already loading
17871				tab.hasClass( "ui-tabs-loading" ) ||
17872
17873				// can't switch durning an animation
17874				this.running ||
17875
17876				// click on active header, but not collapsible
17877				( clickedIsActive && !options.collapsible ) ||
17878
17879				// allow canceling activation
17880				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17881			return;
17882		}
17883
17884		options.active = collapsing ? false : this.tabs.index( tab );
17885
17886		this.active = clickedIsActive ? $() : tab;
17887		if ( this.xhr ) {
17888			this.xhr.abort();
17889		}
17890
17891		if ( !toHide.length && !toShow.length ) {
17892			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17893		}
17894
17895		if ( toShow.length ) {
17896			this.load( this.tabs.index( tab ), event );
17897		}
17898		this._toggle( event, eventData );
17899	},
17900
17901	// Handles show/hide for selecting tabs
17902	_toggle: function( event, eventData ) {
17903		var that = this,
17904			toShow = eventData.newPanel,
17905			toHide = eventData.oldPanel;
17906
17907		this.running = true;
17908
17909		function complete() {
17910			that.running = false;
17911			that._trigger( "activate", event, eventData );
17912		}
17913
17914		function show() {
17915			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17916
17917			if ( toShow.length && that.options.show ) {
17918				that._show( toShow, that.options.show, complete );
17919			} else {
17920				toShow.show();
17921				complete();
17922			}
17923		}
17924
17925		// Start out by hiding, then showing, then completing
17926		if ( toHide.length && this.options.hide ) {
17927			this._hide( toHide, this.options.hide, function() {
17928				that._removeClass( eventData.oldTab.closest( "li" ),
17929					"ui-tabs-active", "ui-state-active" );
17930				show();
17931			} );
17932		} else {
17933			this._removeClass( eventData.oldTab.closest( "li" ),
17934				"ui-tabs-active", "ui-state-active" );
17935			toHide.hide();
17936			show();
17937		}
17938
17939		toHide.attr( "aria-hidden", "true" );
17940		eventData.oldTab.attr( {
17941			"aria-selected": "false",
17942			"aria-expanded": "false"
17943		} );
17944
17945		// If we're switching tabs, remove the old tab from the tab order.
17946		// If we're opening from collapsed state, remove the previous tab from the tab order.
17947		// If we're collapsing, then keep the collapsing tab in the tab order.
17948		if ( toShow.length && toHide.length ) {
17949			eventData.oldTab.attr( "tabIndex", -1 );
17950		} else if ( toShow.length ) {
17951			this.tabs.filter( function() {
17952				return $( this ).attr( "tabIndex" ) === 0;
17953			} )
17954				.attr( "tabIndex", -1 );
17955		}
17956
17957		toShow.attr( "aria-hidden", "false" );
17958		eventData.newTab.attr( {
17959			"aria-selected": "true",
17960			"aria-expanded": "true",
17961			tabIndex: 0
17962		} );
17963	},
17964
17965	_activate: function( index ) {
17966		var anchor,
17967			active = this._findActive( index );
17968
17969		// Trying to activate the already active panel
17970		if ( active[ 0 ] === this.active[ 0 ] ) {
17971			return;
17972		}
17973
17974		// Trying to collapse, simulate a click on the current active header
17975		if ( !active.length ) {
17976			active = this.active;
17977		}
17978
17979		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17980		this._eventHandler( {
17981			target: anchor,
17982			currentTarget: anchor,
17983			preventDefault: $.noop
17984		} );
17985	},
17986
17987	_findActive: function( index ) {
17988		return index === false ? $() : this.tabs.eq( index );
17989	},
17990
17991	_getIndex: function( index ) {
17992
17993		// meta-function to give users option to provide a href string instead of a numerical index.
17994		if ( typeof index === "string" ) {
17995			index = this.anchors.index( this.anchors.filter( "[href$='" +
17996				$.
vendor: 11,467 bytes, lines 17996-18444
17996ui.escapeSelector( index ) + "']" ) );
17997		}
17998
17999		return index;
18000	},
18001
18002	_destroy: function() {
18003		if ( this.xhr ) {
18004			this.xhr.abort();
18005		}
18006
18007		this.tablist
18008			.removeAttr( "role" )
18009			.off( this.eventNamespace );
18010
18011		this.anchors
18012			.removeAttr( "role tabIndex" )
18013			.removeUniqueId();
18014
18015		this.tabs.add( this.panels ).each( function() {
18016			if ( $.data( this, "ui-tabs-destroy" ) ) {
18017				$( this ).remove();
18018			} else {
18019				$( this ).removeAttr( "role tabIndex " +
18020					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18021			}
18022		} );
18023
18024		this.tabs.each( function() {
18025			var li = $( this ),
18026				prev = li.data( "ui-tabs-aria-controls" );
18027			if ( prev ) {
18028				li
18029					.attr( "aria-controls", prev )
18030					.removeData( "ui-tabs-aria-controls" );
18031			} else {
18032				li.removeAttr( "aria-controls" );
18033			}
18034		} );
18035
18036		this.panels.show();
18037
18038		if ( this.options.heightStyle !== "content" ) {
18039			this.panels.css( "height", "" );
18040		}
18041	},
18042
18043	enable: function( index ) {
18044		var disabled = this.options.disabled;
18045		if ( disabled === false ) {
18046			return;
18047		}
18048
18049		if ( index === undefined ) {
18050			disabled = false;
18051		} else {
18052			index = this._getIndex( index );
18053			if ( $.isArray( disabled ) ) {
18054				disabled = $.map( disabled, function( num ) {
18055					return num !== index ? num : null;
18056				} );
18057			} else {
18058				disabled = $.map( this.tabs, function( li, num ) {
18059					return num !== index ? num : null;
18060				} );
18061			}
18062		}
18063		this._setOptionDisabled( disabled );
18064	},
18065
18066	disable: function( index ) {
18067		var disabled = this.options.disabled;
18068		if ( disabled === true ) {
18069			return;
18070		}
18071
18072		if ( index === undefined ) {
18073			disabled = true;
18074		} else {
18075			index = this._getIndex( index );
18076			if ( $.inArray( index, disabled ) !== -1 ) {
18077				return;
18078			}
18079			if ( $.isArray( disabled ) ) {
18080				disabled = $.merge( [ index ], disabled ).sort();
18081			} else {
18082				disabled = [ index ];
18083			}
18084		}
18085		this._setOptionDisabled( disabled );
18086	},
18087
18088	load: function( index, event ) {
18089		index = this._getIndex( index );
18090		var that = this,
18091			tab = this.tabs.eq( index ),
18092			anchor = tab.find( ".ui-tabs-anchor" ),
18093			panel = this._getPanelForTab( tab ),
18094			eventData = {
18095				tab: tab,
18096				panel: panel
18097			},
18098			complete = function( jqXHR, status ) {
18099				if ( status === "abort" ) {
18100					that.panels.stop( false, true );
18101				}
18102
18103				that._removeClass( tab, "ui-tabs-loading" );
18104				panel.removeAttr( "aria-busy" );
18105
18106				if ( jqXHR === that.xhr ) {
18107					delete that.xhr;
18108				}
18109			};
18110
18111		// Not remote
18112		if ( this._isLocal( anchor[ 0 ] ) ) {
18113			return;
18114		}
18115
18116		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18117
18118		// Support: jQuery <1.8
18119		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18120		// but as of 1.8, $.ajax() always returns a jqXHR object.
18121		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18122			this._addClass( tab, "ui-tabs-loading" );
18123			panel.attr( "aria-busy", "true" );
18124
18125			this.xhr
18126				.done( function( response, status, jqXHR ) {
18127
18128					// support: jQuery <1.8
18129					// http://bugs.jquery.com/ticket/11778
18130					setTimeout( function() {
18131						panel.html( response );
18132						that._trigger( "load", event, eventData );
18133
18134						complete( jqXHR, status );
18135					}, 1 );
18136				} )
18137				.fail( function( jqXHR, status ) {
18138
18139					// support: jQuery <1.8
18140					// http://bugs.jquery.com/ticket/11778
18141					setTimeout( function() {
18142						complete( jqXHR, status );
18143					}, 1 );
18144				} );
18145		}
18146	},
18147
18148	_ajaxSettings: function( anchor, event, eventData ) {
18149		var that = this;
18150		return {
18151			url: anchor.attr( "href" ),
18152			beforeSend: function( jqXHR, settings ) {
18153				return that._trigger( "beforeLoad", event,
18154					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18155			}
18156		};
18157	},
18158
18159	_getPanelForTab: function( tab ) {
18160		var id = $( tab ).attr( "aria-controls" );
18161		return this.element.find( this._sanitizeSelector( "#" + id ) );
18162	}
18163} );
18164
18165// DEPRECATED
18166// TODO: Switch return back to widget declaration at top of file when this is removed
18167if ( $.uiBackCompat !== false ) {
18168
18169	// Backcompat for ui-tab class (now ui-tabs-tab)
18170	$.widget( "ui.tabs", $.ui.tabs, {
18171		_processTabs: function() {
18172			this._superApply( arguments );
18173			this._addClass( this.tabs, "ui-tab" );
18174		}
18175	} );
18176}
18177
18178var widgetsTabs = $.ui.tabs;
18179
18180
18181/*!
18182 * jQuery UI Tooltip 1.12.0
18183 * http://jqueryui.com
18184 *
18185 * Copyright jQuery Foundation and other contributors
18186 * Released under the MIT license.
18187 * http://jquery.org/license
18188 */
18189
18190//>>label: Tooltip
18191//>>group: Widgets
18192//>>description: Shows additional information for any element on hover or focus.
18193//>>docs: http://api.jqueryui.com/tooltip/
18194//>>demos: http://jqueryui.com/tooltip/
18195//>>css.structure: ../../themes/base/core.css
18196//>>css.structure: ../../themes/base/tooltip.css
18197//>>css.theme: ../../themes/base/theme.css
18198
18199
18200
18201$.widget( "ui.tooltip", {
18202	version: "1.12.0",
18203	options: {
18204		classes: {
18205			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18206		},
18207		content: function() {
18208
18209			// support: IE<9, Opera in jQuery <1.7
18210			// .text() can't accept undefined, so coerce to a string
18211			var title = $( this ).attr( "title" ) || "";
18212
18213			// Escape title, since we're going from an attribute to raw HTML
18214			return $( "<a>" ).text( title ).html();
18215		},
18216		hide: true,
18217
18218		// Disabled elements have inconsistent behavior across browsers (#8661)
18219		items: "[title]:not([disabled])",
18220		position: {
18221			my: "left top+15",
18222			at: "left bottom",
18223			collision: "flipfit flip"
18224		},
18225		show: true,
18226		track: false,
18227
18228		// Callbacks
18229		close: null,
18230		open: null
18231	},
18232
18233	_addDescribedBy: function( elem, id ) {
18234		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18235		describedby.push( id );
18236		elem
18237			.data( "ui-tooltip-id", id )
18238			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18239	},
18240
18241	_removeDescribedBy: function( elem ) {
18242		var id = elem.data( "ui-tooltip-id" ),
18243			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18244			index = $.inArray( id, describedby );
18245
18246		if ( index !== -1 ) {
18247			describedby.splice( index, 1 );
18248		}
18249
18250		elem.removeData( "ui-tooltip-id" );
18251		describedby = $.trim( describedby.join( " " ) );
18252		if ( describedby ) {
18253			elem.attr( "aria-describedby", describedby );
18254		} else {
18255			elem.removeAttr( "aria-describedby" );
18256		}
18257	},
18258
18259	_create: function() {
18260		this._on( {
18261			mouseover: "open",
18262			focusin: "open"
18263		} );
18264
18265		// IDs of generated tooltips, needed for destroy
18266		this.tooltips = {};
18267
18268		// IDs of parent tooltips where we removed the title attribute
18269		this.parents = {};
18270
18271		// Append the aria-live region so tooltips announce correctly
18272		this.liveRegion = $( "<div>" )
18273			.attr( {
18274				role: "log",
18275				"aria-live": "assertive",
18276				"aria-relevant": "additions"
18277			} )
18278			.appendTo( this.document[ 0 ].body );
18279		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18280
18281		this.disabledTitles = $( [] );
18282	},
18283
18284	_setOption: function( key, value ) {
18285		var that = this;
18286
18287		this._super( key, value );
18288
18289		if ( key === "content" ) {
18290			$.each( this.tooltips, function( id, tooltipData ) {
18291				that._updateContent( tooltipData.element );
18292			} );
18293		}
18294	},
18295
18296	_setOptionDisabled: function( value ) {
18297		this[ value ? "_disable" : "_enable" ]();
18298	},
18299
18300	_disable: function() {
18301		var that = this;
18302
18303		// Close open tooltips
18304		$.each( this.tooltips, function( id, tooltipData ) {
18305			var event = $.Event( "blur" );
18306			event.target = event.currentTarget = tooltipData.element[ 0 ];
18307			that.close( event, true );
18308		} );
18309
18310		// Remove title attributes to prevent native tooltips
18311		this.disabledTitles = this.disabledTitles.add(
18312			this.element.find( this.options.items ).addBack()
18313				.filter( function() {
18314					var element = $( this );
18315					if ( element.is( "[title]" ) ) {
18316						return element
18317							.data( "ui-tooltip-title", element.attr( "title" ) )
18318							.removeAttr( "title" );
18319					}
18320				} )
18321		);
18322	},
18323
18324	_enable: function() {
18325
18326		// restore title attributes
18327		this.disabledTitles.each( function() {
18328			var element = $( this );
18329			if ( element.data( "ui-tooltip-title" ) ) {
18330				element.attr( "title", element.data( "ui-tooltip-title" ) );
18331			}
18332		} );
18333		this.disabledTitles = $( [] );
18334	},
18335
18336	open: function( event ) {
18337		var that = this,
18338			target = $( event ? event.target : this.element )
18339
18340				// we need closest here due to mouseover bubbling,
18341				// but always pointing at the same event target
18342				.closest( this.options.items );
18343
18344		// No element to show a tooltip for or the tooltip is already open
18345		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18346			return;
18347		}
18348
18349		if ( target.attr( "title" ) ) {
18350			target.data( "ui-tooltip-title", target.attr( "title" ) );
18351		}
18352
18353		target.data( "ui-tooltip-open", true );
18354
18355		// Kill parent tooltips, custom or native, for hover
18356		if ( event && event.type === "mouseover" ) {
18357			target.parents().each( function() {
18358				var parent = $( this ),
18359					blurEvent;
18360				if ( parent.data( "ui-tooltip-open" ) ) {
18361					blurEvent = $.Event( "blur" );
18362					blurEvent.target = blurEvent.currentTarget = this;
18363					that.close( blurEvent, true );
18364				}
18365				if ( parent.attr( "title" ) ) {
18366					parent.uniqueId();
18367					that.parents[ this.id ] = {
18368						element: this,
18369						title: parent.attr( "title" )
18370					};
18371					parent.attr( "title", "" );
18372				}
18373			} );
18374		}
18375
18376		this._registerCloseHandlers( event, target );
18377		this._updateContent( target, event );
18378	},
18379
18380	_updateContent: function( target, event ) {
18381		var content,
18382			contentOption = this.options.content,
18383			that = this,
18384			eventType = event ? event.type : null;
18385
18386		if ( typeof contentOption === "string" || contentOption.nodeType ||
18387				contentOption.jquery ) {
18388			return this._open( event, target, contentOption );
18389		}
18390
18391		content = contentOption.call( target[ 0 ], function( response ) {
18392
18393			// IE may instantly serve a cached response for ajax requests
18394			// delay this call to _open so the other call to _open runs first
18395			that._delay( function() {
18396
18397				// Ignore async response if tooltip was closed already
18398				if ( !target.data( "ui-tooltip-open" ) ) {
18399					return;
18400				}
18401
18402				// JQuery creates a special event for focusin when it doesn't
18403				// exist natively. To improve performance, the native event
18404				// object is reused and the type is changed. Therefore, we can't
18405				// rely on the type being correct after the event finished
18406				// bubbling, so we set it back to the previous value. (#8740)
18407				if ( event ) {
18408					event.type = eventType;
18409				}
18410				this._open( event, target, response );
18411			} );
18412		} );
18413		if ( content ) {
18414			this._open( event, target, content );
18415		}
18416	},
18417
18418	_open: function( event, target, content ) {
18419		var tooltipData, tooltip, delayedShow, a11yContent,
18420			positionOption = $.extend( {}, this.options.position );
18421
18422		if ( !content ) {
18423			return;
18424		}
18425
18426		// Content can be updated multiple times. If the tooltip already
18427		// exists, then just update the content and bail.
18428		tooltipData = this._find( target );
18429		if ( tooltipData ) {
18430			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18431			return;
18432		}
18433
18434		// If we have a title, clear it to prevent the native tooltip
18435		// we have to check first to avoid defining a title if none exists
18436		// (we don't want to cause an element to start matching [title])
18437		//
18438		// We use removeAttr only for key events, to allow IE to export the correct
18439		// accessible attributes. For mouse events, set to empty string to avoid
18440		// native tooltip showing up (happens only when removing inside mouseover).
18441		if ( target.is( "[title]" ) ) {
18442			if ( event && event.type === "mouseover" ) {
18443				target.attr( "title", "" );
18444			} else {
vendor: 4,621 bytes, lines 18445-18592
18445				target.removeAttr( "title" );
18446			}
18447		}
18448
18449		tooltipData = this._tooltip( target );
18450		tooltip = tooltipData.tooltip;
18451		this._addDescribedBy( target, tooltip.attr( "id" ) );
18452		tooltip.find( ".ui-tooltip-content" ).html( content );
18453
18454		// Support: Voiceover on OS X, JAWS on IE <= 9
18455		// JAWS announces deletions even when aria-relevant="additions"
18456		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18457		this.liveRegion.children().hide();
18458		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18459		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18460		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18461		a11yContent.appendTo( this.liveRegion );
18462
18463		function position( event ) {
18464			positionOption.of = event;
18465			if ( tooltip.is( ":hidden" ) ) {
18466				return;
18467			}
18468			tooltip.position( positionOption );
18469		}
18470		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18471			this._on( this.document, {
18472				mousemove: position
18473			} );
18474
18475			// trigger once to override element-relative positioning
18476			position( event );
18477		} else {
18478			tooltip.position( $.extend( {
18479				of: target
18480			}, this.options.position ) );
18481		}
18482
18483		tooltip.hide();
18484
18485		this._show( tooltip, this.options.show );
18486
18487		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18488		// as the tooltip is visible, position the tooltip using the most recent
18489		// event.
18490		// Adds the check to add the timers only when both delay and track options are set (#14682)
18491		if ( this.options.track && this.options.show && this.options.show.delay ) {
18492			delayedShow = this.delayedShow = setInterval( function() {
18493				if ( tooltip.is( ":visible" ) ) {
18494					position( positionOption.of );
18495					clearInterval( delayedShow );
18496				}
18497			}, $.fx.interval );
18498		}
18499
18500		this._trigger( "open", event, { tooltip: tooltip } );
18501	},
18502
18503	_registerCloseHandlers: function( event, target ) {
18504		var events = {
18505			keyup: function( event ) {
18506				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18507					var fakeEvent = $.Event( event );
18508					fakeEvent.currentTarget = target[ 0 ];
18509					this.close( fakeEvent, true );
18510				}
18511			}
18512		};
18513
18514		// Only bind remove handler for delegated targets. Non-delegated
18515		// tooltips will handle this in destroy.
18516		if ( target[ 0 ] !== this.element[ 0 ] ) {
18517			events.remove = function() {
18518				this._removeTooltip( this._find( target ).tooltip );
18519			};
18520		}
18521
18522		if ( !event || event.type === "mouseover" ) {
18523			events.mouseleave = "close";
18524		}
18525		if ( !event || event.type === "focusin" ) {
18526			events.focusout = "close";
18527		}
18528		this._on( true, target, events );
18529	},
18530
18531	close: function( event ) {
18532		var tooltip,
18533			that = this,
18534			target = $( event ? event.currentTarget : this.element ),
18535			tooltipData = this._find( target );
18536
18537		// The tooltip may already be closed
18538		if ( !tooltipData ) {
18539
18540			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18541			// additional data once there's actually content to show (in _open()). So even if the
18542			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18543			// the period between open() and _open().
18544			target.removeData( "ui-tooltip-open" );
18545			return;
18546		}
18547
18548		tooltip = tooltipData.tooltip;
18549
18550		// Disabling closes the tooltip, so we need to track when we're closing
18551		// to avoid an infinite loop in case the tooltip becomes disabled on close
18552		if ( tooltipData.closing ) {
18553			return;
18554		}
18555
18556		// Clear the interval for delayed tracking tooltips
18557		clearInterval( this.delayedShow );
18558
18559		// Only set title if we had one before (see comment in _open())
18560		// If the title attribute has changed since open(), don't restore
18561		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18562			target.attr( "title", target.data( "ui-tooltip-title" ) );
18563		}
18564
18565		this._removeDescribedBy( target );
18566
18567		tooltipData.hiding = true;
18568		tooltip.stop( true );
18569		this._hide( tooltip, this.options.hide, function() {
18570			that._removeTooltip( $( this ) );
18571		} );
18572
18573		target.removeData( "ui-tooltip-open" );
18574		this._off( target, "mouseleave focusout keyup" );
18575
18576		// Remove 'remove' binding only on delegated targets
18577		if ( target[ 0 ] !== this.element[ 0 ] ) {
18578			this._off( target, "remove" );
18579		}
18580		this._off( this.document, "mousemove" );
18581
18582		if ( event && event.type === "mouseleave" ) {
18583			$.each( this.parents, function( id, parent ) {
18584				$( parent.element ).attr( "title", parent.title );
18585				delete that.parents[ id ];
18586			} );
18587		}
18588
18589		tooltipData.closing = true;
18590		this._trigger( "close", event, { tooltip: tooltip } );
18591		if ( !tooltipData.hiding ) {
18592			tooltipData.closing = false;
vendor: 2,177 bytes, lines 18593-18686
18593		}
18594	},
18595
18596	_tooltip: function( element ) {
18597		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18598			content = $( "<div>" ).appendTo( tooltip ),
18599			id = tooltip.uniqueId().attr( "id" );
18600
18601		this._addClass( content, "ui-tooltip-content" );
18602		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18603
18604		tooltip.appendTo( this._appendTo( element ) );
18605
18606		return this.tooltips[ id ] = {
18607			element: element,
18608			tooltip: tooltip
18609		};
18610	},
18611
18612	_find: function( target ) {
18613		var id = target.data( "ui-tooltip-id" );
18614		return id ? this.tooltips[ id ] : null;
18615	},
18616
18617	_removeTooltip: function( tooltip ) {
18618		tooltip.remove();
18619		delete this.tooltips[ tooltip.attr( "id" ) ];
18620	},
18621
18622	_appendTo: function( target ) {
18623		var element = target.closest( ".ui-front, dialog" );
18624
18625		if ( !element.length ) {
18626			element = this.document[ 0 ].body;
18627		}
18628
18629		return element;
18630	},
18631
18632	_destroy: function() {
18633		var that = this;
18634
18635		// Close open tooltips
18636		$.each( this.tooltips, function( id, tooltipData ) {
18637
18638			// Delegate to close method to handle common cleanup
18639			var event = $.Event( "blur" ),
18640				element = tooltipData.element;
18641			event.target = event.currentTarget = element[ 0 ];
18642			that.close( event, true );
18643
18644			// Remove immediately; destroying an open tooltip doesn't use the
18645			// hide animation
18646			$( "#" + id ).remove();
18647
18648			// Restore the title
18649			if ( element.data( "ui-tooltip-title" ) ) {
18650
18651				// If the title attribute has changed since open(), don't restore
18652				if ( !element.attr( "title" ) ) {
18653					element.attr( "title", element.data( "ui-tooltip-title" ) );
18654				}
18655				element.removeData( "ui-tooltip-title" );
18656			}
18657		} );
18658		this.liveRegion.remove();
18659	}
18660} );
18661
18662// DEPRECATED
18663// TODO: Switch return back to widget declaration at top of file when this is removed
18664if ( $.uiBackCompat !== false ) {
18665
18666	// Backcompat for tooltipClass option
18667	$.widget( "ui.tooltip", $.ui.tooltip, {
18668		options: {
18669			tooltipClass: null
18670		},
18671		_tooltip: function() {
18672			var tooltipData = this._superApply( arguments );
18673			if ( this.options.tooltipClass ) {
18674				tooltipData.tooltip.addClass( this.options.tooltipClass );
18675			}
18676			return tooltipData;
18677		}
18678	} );
18679}
18680
18681var widgetsTooltip = $.ui.tooltip;
18682
18683
18684
18685
18686}));

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.