PageSourceSearch

https://search.dongguk.edu/resources/js/jquery-ui.js

js dongguk.edu collected 2026-09-24 09:28:01 UTC 520,714 bytes, 18,706 lines download raw bytes

vendor: 4,756 bytes, lines 1-143
1/*! jQuery UI - v1.12.1 - 2016-09-14
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.1";
21
22
23/*!
24 * jQuery UI Widget 1.12.1
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: 5,120 bytes, lines 144-330
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
231			// If this is an empty collection, we need to have the instance method
232			// return undefined instead of the jQuery instance
233			if ( !this.length && options === "instance" ) {
234				returnValue = undefined;
235			} else {
236				this.each( function() {
237					var methodValue;
238					var instance = $.data( this, fullName );
239
240					if ( options === "instance" ) {
241						returnValue = instance;
242						return false;
243					}
244
245					if ( !instance ) {
246						return $.error( "cannot call methods on " + name +
247							" prior to initialization; " +
248							"attempted to call method '" + options + "'" );
249					}
250
251					if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
252						return $.error( "no such method '" + options + "' for " + name +
253							" widget instance" );
254					}
255
256					methodValue = instance[ options ].apply( instance, args );
257
258					if ( methodValue !== instance && methodValue !== undefined ) {
259						returnValue = methodValue && methodValue.jquery ?
260							returnValue.pushStack( methodValue.get() ) :
261							methodValue;
262						return false;
263					}
264				} );
265			}
266		} else {
267
268			// Allow multiple hashes to be passed on init
269			if ( args.length ) {
270				options = $.widget.extend.apply( null, [ options ].concat( args ) );
271			}
272
273			this.each( function() {
274				var instance = $.data( this, fullName );
275				if ( instance ) {
276					instance.option( options || {} );
277					if ( instance._init ) {
278						instance._init();
279					}
280				} else {
281					$.data( this, fullName, new object( options, this ) );
282				}
283			} );
284		}
285
286		return returnValue;
287	};
288};
289
290$.Widget = function( /* options, element */ ) {};
291$.Widget._childConstructors = [];
292
293$.Widget.prototype = {
294	widgetName: "widget",
295	widgetEventPrefix: "",
296	defaultElement: "<div>",
297
298	options: {
299		classes: {},
300		disabled: false,
301
302		// Callbacks
303		create: null
304	},
305
306	_createWidget: function( options, element ) {
307		element = $( element || this.defaultElement || this )[ 0 ];
308		this.element = $( element );
309		this.uuid = widgetUuid++;
310		this.eventNamespace = "." + this.widgetName + this.uuid;
311
312		this.bindings = $();
313		this.hoverable = $();
314		this.focusable = $();
315		this.classesElementLookup = {};
316
317		if ( element !== this ) {
318			$.data( element, this.widgetFullName, this );
319			this._on( true, this.element, {
320				remove: function( event ) {
321					if ( event.target === element ) {
322						this.destroy();
323					}
324				}
325			} );
326			this.document = $( element.style ?
327
328				// Element within the document
329				element.ownerDocument :
330
vendor: 6,494 bytes, lines 331-581
331				// Element is window or document
332				element.document || element );
333			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
334		}
335
336		this.options = $.widget.extend( {},
337			this.options,
338			this._getCreateOptions(),
339			options );
340
341		this._create();
342
343		if ( this.options.disabled ) {
344			this._setOptionDisabled( this.options.disabled );
345		}
346
347		this._trigger( "create", null, this._getCreateEventData() );
348		this._init();
349	},
350
351	_getCreateOptions: function() {
352		return {};
353	},
354
355	_getCreateEventData: $.noop,
356
357	_create: $.noop,
358
359	_init: $.noop,
360
361	destroy: function() {
362		var that = this;
363
364		this._destroy();
365		$.each( this.classesElementLookup, function( key, value ) {
366			that._removeClass( value, key );
367		} );
368
369		// We can probably remove the unbind calls in 2.0
370		// all event bindings should go through this._on()
371		this.element
372			.off( this.eventNamespace )
373			.removeData( this.widgetFullName );
374		this.widget()
375			.off( this.eventNamespace )
376			.removeAttr( "aria-disabled" );
377
378		// Clean up events and states
379		this.bindings.off( this.eventNamespace );
380	},
381
382	_destroy: $.noop,
383
384	widget: function() {
385		return this.element;
386	},
387
388	option: function( key, value ) {
389		var options = key;
390		var parts;
391		var curOption;
392		var i;
393
394		if ( arguments.length === 0 ) {
395
396			// Don't return a reference to the internal hash
397			return $.widget.extend( {}, this.options );
398		}
399
400		if ( typeof key === "string" ) {
401
402			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
403			options = {};
404			parts = key.split( "." );
405			key = parts.shift();
406			if ( parts.length ) {
407				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
408				for ( i = 0; i < parts.length - 1; i++ ) {
409					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
410					curOption = curOption[ parts[ i ] ];
411				}
412				key = parts.pop();
413				if ( arguments.length === 1 ) {
414					return curOption[ key ] === undefined ? null : curOption[ key ];
415				}
416				curOption[ key ] = value;
417			} else {
418				if ( arguments.length === 1 ) {
419					return this.options[ key ] === undefined ? null : this.options[ key ];
420				}
421				options[ key ] = value;
422			}
423		}
424
425		this._setOptions( options );
426
427		return this;
428	},
429
430	_setOptions: function( options ) {
431		var key;
432
433		for ( key in options ) {
434			this._setOption( key, options[ key ] );
435		}
436
437		return this;
438	},
439
440	_setOption: function( key, value ) {
441		if ( key === "classes" ) {
442			this._setOptionClasses( value );
443		}
444
445		this.options[ key ] = value;
446
447		if ( key === "disabled" ) {
448			this._setOptionDisabled( value );
449		}
450
451		return this;
452	},
453
454	_setOptionClasses: function( value ) {
455		var classKey, elements, currentElements;
456
457		for ( classKey in value ) {
458			currentElements = this.classesElementLookup[ classKey ];
459			if ( value[ classKey ] === this.options.classes[ classKey ] ||
460					!currentElements ||
461					!currentElements.length ) {
462				continue;
463			}
464
465			// We are doing this to create a new jQuery object because the _removeClass() call
466			// on the next line is going to destroy the reference to the current elements being
467			// tracked. We need to save a copy of this collection so that we can add the new classes
468			// below.
469			elements = $( currentElements.get() );
470			this._removeClass( currentElements, classKey );
471
472			// We don't use _addClass() here, because that uses this.options.classes
473			// for generating the string of classes. We want to use the value passed in from
474			// _setOption(), this is the new value of the classes option which was passed to
475			// _setOption(). We pass this value directly to _classes().
476			elements.addClass( this._classes( {
477				element: elements,
478				keys: classKey,
479				classes: value,
480				add: true
481			} ) );
482		}
483	},
484
485	_setOptionDisabled: function( value ) {
486		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
487
488		// If the widget is becoming disabled, then nothing is interactive
489		if ( value ) {
490			this._removeClass( this.hoverable, null, "ui-state-hover" );
491			this._removeClass( this.focusable, null, "ui-state-focus" );
492		}
493	},
494
495	enable: function() {
496		return this._setOptions( { disabled: false } );
497	},
498
499	disable: function() {
500		return this._setOptions( { disabled: true } );
501	},
502
503	_classes: function( options ) {
504		var full = [];
505		var that = this;
506
507		options = $.extend( {
508			element: this.element,
509			classes: this.options.classes || {}
510		}, options );
511
512		function processClassString( classes, checkOption ) {
513			var current, i;
514			for ( i = 0; i < classes.length; i++ ) {
515				current = that.classesElementLookup[ classes[ i ] ] || $();
516				if ( options.add ) {
517					current = $( $.unique( current.get().concat( options.element.get() ) ) );
518				} else {
519					current = $( current.not( options.element ).get() );
520				}
521				that.classesElementLookup[ classes[ i ] ] = current;
522				full.push( classes[ i ] );
523				if ( checkOption && options.classes[ classes[ i ] ] ) {
524					full.push( options.classes[ classes[ i ] ] );
525				}
526			}
527		}
528
529		this._on( options.element, {
530			"remove": "_untrackClassesElement"
531		} );
532
533		if ( options.keys ) {
534			processClassString( options.keys.match( /\S+/g ) || [], true );
535		}
536		if ( options.extra ) {
537			processClassString( options.extra.match( /\S+/g ) || [] );
538		}
539
540		return full.join( " " );
541	},
542
543	_untrackClassesElement: function( event ) {
544		var that = this;
545		$.each( that.classesElementLookup, function( key, value ) {
546			if ( $.inArray( event.target, value ) !== -1 ) {
547				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
548			}
549		} );
550	},
551
552	_removeClass: function( element, keys, extra ) {
553		return this._toggleClass( element, keys, extra, false );
554	},
555
556	_addClass: function( element, keys, extra ) {
557		return this._toggleClass( element, keys, extra, true );
558	},
559
560	_toggleClass: function( element, keys, extra, add ) {
561		add = ( typeof add === "boolean" ) ? add : extra;
562		var shift = ( typeof element === "string" || element === null ),
563			options = {
564				extra: shift ? keys : extra,
565				keys: shift ? element : keys,
566				element: shift ? this.element : element,
567				add: add
568			};
569		options.element.toggleClass( this._classes( options ), add );
570		return this;
571	},
572
573	_on: function( suppressDisabledCheck, element, handlers ) {
574		var delegateElement;
575		var instance = this;
576
577		// No suppressDisabledCheck flag, shuffle arguments
578		if ( typeof suppressDisabledCheck !== "boolean" ) {
579			handlers = element;
580			element = suppressDisabledCheck;
581			suppressDisabledCheck = false;
vendor: 4,288 bytes, lines 582-729
582		}
583
584		// No element argument, shuffle and use this.element
585		if ( !handlers ) {
586			handlers = element;
587			element = this.element;
588			delegateElement = this.widget();
589		} else {
590			element = delegateElement = $( element );
591			this.bindings = this.bindings.add( element );
592		}
593
594		$.each( handlers, function( event, handler ) {
595			function handlerProxy() {
596
597				// Allow widgets to customize the disabled handling
598				// - disabled as an array instead of boolean
599				// - disabled class as method for disabling individual parts
600				if ( !suppressDisabledCheck &&
601						( instance.options.disabled === true ||
602						$( this ).hasClass( "ui-state-disabled" ) ) ) {
603					return;
604				}
605				return ( typeof handler === "string" ? instance[ handler ] : handler )
606					.apply( instance, arguments );
607			}
608
609			// Copy the guid so direct unbinding works
610			if ( typeof handler !== "string" ) {
611				handlerProxy.guid = handler.guid =
612					handler.guid || handlerProxy.guid || $.guid++;
613			}
614
615			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
616			var eventName = match[ 1 ] + instance.eventNamespace;
617			var selector = match[ 2 ];
618
619			if ( selector ) {
620				delegateElement.on( eventName, selector, handlerProxy );
621			} else {
622				element.on( eventName, handlerProxy );
623			}
624		} );
625	},
626
627	_off: function( element, eventName ) {
628		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
629			this.eventNamespace;
630		element.off( eventName ).off( eventName );
631
632		// Clear the stack to avoid memory leaks (#10056)
633		this.bindings = $( this.bindings.not( element ).get() );
634		this.focusable = $( this.focusable.not( element ).get() );
635		this.hoverable = $( this.hoverable.not( element ).get() );
636	},
637
638	_delay: function( handler, delay ) {
639		function handlerProxy() {
640			return ( typeof handler === "string" ? instance[ handler ] : handler )
641				.apply( instance, arguments );
642		}
643		var instance = this;
644		return setTimeout( handlerProxy, delay || 0 );
645	},
646
647	_hoverable: function( element ) {
648		this.hoverable = this.hoverable.add( element );
649		this._on( element, {
650			mouseenter: function( event ) {
651				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
652			},
653			mouseleave: function( event ) {
654				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
655			}
656		} );
657	},
658
659	_focusable: function( element ) {
660		this.focusable = this.focusable.add( element );
661		this._on( element, {
662			focusin: function( event ) {
663				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
664			},
665			focusout: function( event ) {
666				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
667			}
668		} );
669	},
670
671	_trigger: function( type, event, data ) {
672		var prop, orig;
673		var callback = this.options[ type ];
674
675		data = data || {};
676		event = $.Event( event );
677		event.type = ( type === this.widgetEventPrefix ?
678			type :
679			this.widgetEventPrefix + type ).toLowerCase();
680
681		// The original event may come from any element
682		// so we need to reset the target on the new event
683		event.target = this.element[ 0 ];
684
685		// Copy original event properties over to the new event
686		orig = event.originalEvent;
687		if ( orig ) {
688			for ( prop in orig ) {
689				if ( !( prop in event ) ) {
690					event[ prop ] = orig[ prop ];
691				}
692			}
693		}
694
695		this.element.trigger( event, data );
696		return !( $.isFunction( callback ) &&
697			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
698			event.isDefaultPrevented() );
699	}
700};
701
702$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
703	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
704		if ( typeof options === "string" ) {
705			options = { effect: options };
706		}
707
708		var hasOptions;
709		var effectName = !options ?
710			method :
711			options === true || typeof options === "number" ?
712				defaultEffect :
713				options.effect || defaultEffect;
714
715		options = options || {};
716		if ( typeof options === "number" ) {
717			options = { duration: options };
718		}
719
720		hasOptions = !$.isEmptyObject( options );
721		options.complete = callback;
722
723		if ( options.delay ) {
724			element.delay( options.delay );
725		}
726
727		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
728			element[ method ]( options );
729		} else if ( effectName !== method && element[ effectName ] ) {
vendor: 3,939 bytes, lines 730-882
730			element[ effectName ]( options.duration, options.easing, callback );
731		} else {
732			element.queue( function( next ) {
733				$( this )[ method ]();
734				if ( callback ) {
735					callback.call( element[ 0 ] );
736				}
737				next();
738			} );
739		}
740	};
741} );
742
743var widget = $.widget;
744
745
746/*!
747 * jQuery UI Position 1.12.1
748 * http://jqueryui.com
749 *
750 * Copyright jQuery Foundation and other contributors
751 * Released under the MIT license.
752 * http://jquery.org/license
753 *
754 * http://api.jqueryui.com/position/
755 */
756
757//>>label: Position
758//>>group: Core
759//>>description: Positions elements relative to other elements.
760//>>docs: http://api.jqueryui.com/position/
761//>>demos: http://jqueryui.com/position/
762
763
764( function() {
765var cachedScrollbarWidth,
766	max = Math.max,
767	abs = Math.abs,
768	rhorizontal = /left|center|right/,
769	rvertical = /top|center|bottom/,
770	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
771	rposition = /^\w+/,
772	rpercent = /%$/,
773	_position = $.fn.position;
774
775function getOffsets( offsets, width, height ) {
776	return [
777		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
778		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
779	];
780}
781
782function parseCss( element, property ) {
783	return parseInt( $.css( element, property ), 10 ) || 0;
784}
785
786function getDimensions( elem ) {
787	var raw = elem[ 0 ];
788	if ( raw.nodeType === 9 ) {
789		return {
790			width: elem.width(),
791			height: elem.height(),
792			offset: { top: 0, left: 0 }
793		};
794	}
795	if ( $.isWindow( raw ) ) {
796		return {
797			width: elem.width(),
798			height: elem.height(),
799			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
800		};
801	}
802	if ( raw.preventDefault ) {
803		return {
804			width: 0,
805			height: 0,
806			offset: { top: raw.pageY, left: raw.pageX }
807		};
808	}
809	return {
810		width: elem.outerWidth(),
811		height: elem.outerHeight(),
812		offset: elem.offset()
813	};
814}
815
816$.position = {
817	scrollbarWidth: function() {
818		if ( cachedScrollbarWidth !== undefined ) {
819			return cachedScrollbarWidth;
820		}
821		var w1, w2,
822			div = $( "<div " +
823				"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>" +
824				"<div style='height:100px;width:auto;'></div></div>" ),
825			innerDiv = div.children()[ 0 ];
826
827		$( "body" ).append( div );
828		w1 = innerDiv.offsetWidth;
829		div.css( "overflow", "scroll" );
830
831		w2 = innerDiv.offsetWidth;
832
833		if ( w1 === w2 ) {
834			w2 = div[ 0 ].clientWidth;
835		}
836
837		div.remove();
838
839		return ( cachedScrollbarWidth = w1 - w2 );
840	},
841	getScrollInfo: function( within ) {
842		var overflowX = within.isWindow || within.isDocument ? "" :
843				within.element.css( "overflow-x" ),
844			overflowY = within.isWindow || within.isDocument ? "" :
845				within.element.css( "overflow-y" ),
846			hasOverflowX = overflowX === "scroll" ||
847				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
848			hasOverflowY = overflowY === "scroll" ||
849				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
850		return {
851			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
852			height: hasOverflowX ? $.position.scrollbarWidth() : 0
853		};
854	},
855	getWithinInfo: function( element ) {
856		var withinElement = $( element || window ),
857			isWindow = $.isWindow( withinElement[ 0 ] ),
858			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
859			hasOffset = !isWindow && !isDocument;
860		return {
861			element: withinElement,
862			isWindow: isWindow,
863			isDocument: isDocument,
864			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
865			scrollLeft: withinElement.scrollLeft(),
866			scrollTop: withinElement.scrollTop(),
867			width: withinElement.outerWidth(),
868			height: withinElement.outerHeight()
869		};
870	}
871};
872
873$.fn.position = function( options ) {
874	if ( !options || !options.of ) {
875		return _position.apply( this, arguments );
876	}
877
878	// Make a copy, we don't want to modify arguments
879	options = $.extend( {}, options );
880
881	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
882		target = $( options.of ),
vendor: 10,983 bytes, lines 882-1235
882
883		within = $.position.getWithinInfo( options.within ),
884		scrollInfo = $.position.getScrollInfo( within ),
885		collision = ( options.collision || "flip" ).split( " " ),
886		offsets = {};
887
888	dimensions = getDimensions( target );
889	if ( target[ 0 ].preventDefault ) {
890
891		// Force left top to allow flipping
892		options.at = "left top";
893	}
894	targetWidth = dimensions.width;
895	targetHeight = dimensions.height;
896	targetOffset = dimensions.offset;
897
898	// Clone to reuse original targetOffset later
899	basePosition = $.extend( {}, targetOffset );
900
901	// Force my and at to have valid horizontal and vertical positions
902	// if a value is missing or invalid, it will be converted to center
903	$.each( [ "my", "at" ], function() {
904		var pos = ( options[ this ] || "" ).split( " " ),
905			horizontalOffset,
906			verticalOffset;
907
908		if ( pos.length === 1 ) {
909			pos = rhorizontal.test( pos[ 0 ] ) ?
910				pos.concat( [ "center" ] ) :
911				rvertical.test( pos[ 0 ] ) ?
912					[ "center" ].concat( pos ) :
913					[ "center", "center" ];
914		}
915		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
916		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
917
918		// Calculate offsets
919		horizontalOffset = roffset.exec( pos[ 0 ] );
920		verticalOffset = roffset.exec( pos[ 1 ] );
921		offsets[ this ] = [
922			horizontalOffset ? horizontalOffset[ 0 ] : 0,
923			verticalOffset ? verticalOffset[ 0 ] : 0
924		];
925
926		// Reduce to just the positions without the offsets
927		options[ this ] = [
928			rposition.exec( pos[ 0 ] )[ 0 ],
929			rposition.exec( pos[ 1 ] )[ 0 ]
930		];
931	} );
932
933	// Normalize collision option
934	if ( collision.length === 1 ) {
935		collision[ 1 ] = collision[ 0 ];
936	}
937
938	if ( options.at[ 0 ] === "right" ) {
939		basePosition.left += targetWidth;
940	} else if ( options.at[ 0 ] === "center" ) {
941		basePosition.left += targetWidth / 2;
942	}
943
944	if ( options.at[ 1 ] === "bottom" ) {
945		basePosition.top += targetHeight;
946	} else if ( options.at[ 1 ] === "center" ) {
947		basePosition.top += targetHeight / 2;
948	}
949
950	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
951	basePosition.left += atOffset[ 0 ];
952	basePosition.top += atOffset[ 1 ];
953
954	return this.each( function() {
955		var collisionPosition, using,
956			elem = $( this ),
957			elemWidth = elem.outerWidth(),
958			elemHeight = elem.outerHeight(),
959			marginLeft = parseCss( this, "marginLeft" ),
960			marginTop = parseCss( this, "marginTop" ),
961			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
962				scrollInfo.width,
963			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
964				scrollInfo.height,
965			position = $.extend( {}, basePosition ),
966			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
967
968		if ( options.my[ 0 ] === "right" ) {
969			position.left -= elemWidth;
970		} else if ( options.my[ 0 ] === "center" ) {
971			position.left -= elemWidth / 2;
972		}
973
974		if ( options.my[ 1 ] === "bottom" ) {
975			position.top -= elemHeight;
976		} else if ( options.my[ 1 ] === "center" ) {
977			position.top -= elemHeight / 2;
978		}
979
980		position.left += myOffset[ 0 ];
981		position.top += myOffset[ 1 ];
982
983		collisionPosition = {
984			marginLeft: marginLeft,
985			marginTop: marginTop
986		};
987
988		$.each( [ "left", "top" ], function( i, dir ) {
989			if ( $.ui.position[ collision[ i ] ] ) {
990				$.ui.position[ collision[ i ] ][ dir ]( position, {
991					targetWidth: targetWidth,
992					targetHeight: targetHeight,
993					elemWidth: elemWidth,
994					elemHeight: elemHeight,
995					collisionPosition: collisionPosition,
996					collisionWidth: collisionWidth,
997					collisionHeight: collisionHeight,
998					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
999					my: options.my,
1000					at: options.at,
1001					within: within,
1002					elem: elem
1003				} );
1004			}
1005		} );
1006
1007		if ( options.using ) {
1008
1009			// Adds feedback as second argument to using callback, if present
1010			using = function( props ) {
1011				var left = targetOffset.left - position.left,
1012					right = left + targetWidth - elemWidth,
1013					top = targetOffset.top - position.top,
1014					bottom = top + targetHeight - elemHeight,
1015					feedback = {
1016						target: {
1017							element: target,
1018							left: targetOffset.left,
1019							top: targetOffset.top,
1020							width: targetWidth,
1021							height: targetHeight
1022						},
1023						element: {
1024							element: elem,
1025							left: position.left,
1026							top: position.top,
1027							width: elemWidth,
1028							height: elemHeight
1029						},
1030						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1031						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1032					};
1033				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1034					feedback.horizontal = "center";
1035				}
1036				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1037					feedback.vertical = "middle";
1038				}
1039				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1040					feedback.important = "horizontal";
1041				} else {
1042					feedback.important = "vertical";
1043				}
1044				options.using.call( this, props, feedback );
1045			};
1046		}
1047
1048		elem.offset( $.extend( position, { using: using } ) );
1049	} );
1050};
1051
1052$.ui.position = {
1053	fit: {
1054		left: function( position, data ) {
1055			var within = data.within,
1056				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1057				outerWidth = within.width,
1058				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1059				overLeft = withinOffset - collisionPosLeft,
1060				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1061				newOverRight;
1062
1063			// Element is wider than within
1064			if ( data.collisionWidth > outerWidth ) {
1065
1066				// Element is initially over the left side of within
1067				if ( overLeft > 0 && overRight <= 0 ) {
1068					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1069						withinOffset;
1070					position.left += overLeft - newOverRight;
1071
1072				// Element is initially over right side of within
1073				} else if ( overRight > 0 && overLeft <= 0 ) {
1074					position.left = withinOffset;
1075
1076				// Element is initially over both left and right sides of within
1077				} else {
1078					if ( overLeft > overRight ) {
1079						position.left = withinOffset + outerWidth - data.collisionWidth;
1080					} else {
1081						position.left = withinOffset;
1082					}
1083				}
1084
1085			// Too far left -> align with left edge
1086			} else if ( overLeft > 0 ) {
1087				position.left += overLeft;
1088
1089			// Too far right -> align with right edge
1090			} else if ( overRight > 0 ) {
1091				position.left -= overRight;
1092
1093			// Adjust based on position and margin
1094			} else {
1095				position.left = max( position.left - collisionPosLeft, position.left );
1096			}
1097		},
1098		top: function( position, data ) {
1099			var within = data.within,
1100				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1101				outerHeight = data.within.height,
1102				collisionPosTop = position.top - data.collisionPosition.marginTop,
1103				overTop = withinOffset - collisionPosTop,
1104				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1105				newOverBottom;
1106
1107			// Element is taller than within
1108			if ( data.collisionHeight > outerHeight ) {
1109
1110				// Element is initially over the top of within
1111				if ( overTop > 0 && overBottom <= 0 ) {
1112					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1113						withinOffset;
1114					position.top += overTop - newOverBottom;
1115
1116				// Element is initially over bottom of within
1117				} else if ( overBottom > 0 && overTop <= 0 ) {
1118					position.top = withinOffset;
1119
1120				// Element is initially over both top and bottom of within
1121				} else {
1122					if ( overTop > overBottom ) {
1123						position.top = withinOffset + outerHeight - data.collisionHeight;
1124					} else {
1125						position.top = withinOffset;
1126					}
1127				}
1128
1129			// Too far up -> align with top
1130			} else if ( overTop > 0 ) {
1131				position.top += overTop;
1132
1133			// Too far down -> align with bottom edge
1134			} else if ( overBottom > 0 ) {
1135				position.top -= overBottom;
1136
1137			// Adjust based on position and margin
1138			} else {
1139				position.top = max( position.top - collisionPosTop, position.top );
1140			}
1141		}
1142	},
1143	flip: {
1144		left: function( position, data ) {
1145			var within = data.within,
1146				withinOffset = within.offset.left + within.scrollLeft,
1147				outerWidth = within.width,
1148				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1149				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1150				overLeft = collisionPosLeft - offsetLeft,
1151				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1152				myOffset = data.my[ 0 ] === "left" ?
1153					-data.elemWidth :
1154					data.my[ 0 ] === "right" ?
1155						data.elemWidth :
1156						0,
1157				atOffset = data.at[ 0 ] === "left" ?
1158					data.targetWidth :
1159					data.at[ 0 ] === "right" ?
1160						-data.targetWidth :
1161						0,
1162				offset = -2 * data.offset[ 0 ],
1163				newOverRight,
1164				newOverLeft;
1165
1166			if ( overLeft < 0 ) {
1167				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1168					outerWidth - withinOffset;
1169				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1170					position.left += myOffset + atOffset + offset;
1171				}
1172			} else if ( overRight > 0 ) {
1173				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1174					atOffset + offset - offsetLeft;
1175				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1176					position.left += myOffset + atOffset + offset;
1177				}
1178			}
1179		},
1180		top: function( position, data ) {
1181			var within = data.within,
1182				withinOffset = within.offset.top + within.scrollTop,
1183				outerHeight = within.height,
1184				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1185				collisionPosTop = position.top - data.collisionPosition.marginTop,
1186				overTop = collisionPosTop - offsetTop,
1187				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1188				top = data.my[ 1 ] === "top",
1189				myOffset = top ?
1190					-data.elemHeight :
1191					data.my[ 1 ] === "bottom" ?
1192						data.elemHeight :
1193						0,
1194				atOffset = data.at[ 1 ] === "top" ?
1195					data.targetHeight :
1196					data.at[ 1 ] === "bottom" ?
1197						-data.targetHeight :
1198						0,
1199				offset = -2 * data.offset[ 1 ],
1200				newOverTop,
1201				newOverBottom;
1202			if ( overTop < 0 ) {
1203				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1204					outerHeight - withinOffset;
1205				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1206					position.top += myOffset + atOffset + offset;
1207				}
1208			} else if ( overBottom > 0 ) {
1209				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1210					offset - offsetTop;
1211				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1212					position.top += myOffset + atOffset + offset;
1213				}
1214			}
1215		}
1216	},
1217	flipfit: {
1218		left: function() {
1219			$.ui.position.flip.left.apply( this, arguments );
1220			$.ui.position.fit.left.apply( this, arguments );
1221		},
1222		top: function() {
1223			$.ui.position.flip.top.apply( this, arguments );
1224			$.ui.position.fit.top.apply( this, arguments );
1225		}
1226	}
1227};
1228
1229} )();
1230
1231var position = $.ui.position;
1232
1233
1234/*!
1235 * jQuery UI 
1235:data 1.12.1
1236 * http://jqueryui.com
1237 *
1238 * Copyright jQuery Foundation and other contributors
1239 * Released under the MIT license.
1240 * http://jquery.org/license
1241 */
1242
1243//>>label: :data Selector
vendor: 23,364 bytes, lines 1244-2199
1244//>>group: Core
1245//>>description: Selects elements which have data stored under the specified key.
1246//>>docs: http://api.jqueryui.com/data-selector/
1247
1248
1249var data = $.extend( $.expr[ ":" ], {
1250	data: $.expr.createPseudo ?
1251		$.expr.createPseudo( function( dataName ) {
1252			return function( elem ) {
1253				return !!$.data( elem, dataName );
1254			};
1255		} ) :
1256
1257		// Support: jQuery <1.8
1258		function( elem, i, match ) {
1259			return !!$.data( elem, match[ 3 ] );
1260		}
1261} );
1262
1263/*!
1264 * jQuery UI Disable Selection 1.12.1
1265 * http://jqueryui.com
1266 *
1267 * Copyright jQuery Foundation and other contributors
1268 * Released under the MIT license.
1269 * http://jquery.org/license
1270 */
1271
1272//>>label: disableSelection
1273//>>group: Core
1274//>>description: Disable selection of text content within the set of matched elements.
1275//>>docs: http://api.jqueryui.com/disableSelection/
1276
1277// This file is deprecated
1278
1279
1280var disableSelection = $.fn.extend( {
1281	disableSelection: ( function() {
1282		var eventType = "onselectstart" in document.createElement( "div" ) ?
1283			"selectstart" :
1284			"mousedown";
1285
1286		return function() {
1287			return this.on( eventType + ".ui-disableSelection", function( event ) {
1288				event.preventDefault();
1289			} );
1290		};
1291	} )(),
1292
1293	enableSelection: function() {
1294		return this.off( ".ui-disableSelection" );
1295	}
1296} );
1297
1298
1299/*!
1300 * jQuery UI Effects 1.12.1
1301 * http://jqueryui.com
1302 *
1303 * Copyright jQuery Foundation and other contributors
1304 * Released under the MIT license.
1305 * http://jquery.org/license
1306 */
1307
1308//>>label: Effects Core
1309//>>group: Effects
1310// jscs:disable maximumLineLength
1311//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
1312// jscs:enable maximumLineLength
1313//>>docs: http://api.jqueryui.com/category/effects-core/
1314//>>demos: http://jqueryui.com/effect/
1315
1316
1317
1318var dataSpace = "ui-effects-",
1319	dataSpaceStyle = "ui-effects-style",
1320	dataSpaceAnimated = "ui-effects-animated",
1321
1322	// Create a local jQuery because jQuery Color relies on it and the
1323	// global may not exist with AMD and a custom build (#10199)
1324	jQuery = $;
1325
1326$.effects = {
1327	effect: {}
1328};
1329
1330/*!
1331 * jQuery Color Animations v2.1.2
1332 * https://github.com/jquery/jquery-color
1333 *
1334 * Copyright 2014 jQuery Foundation and other contributors
1335 * Released under the MIT license.
1336 * http://jquery.org/license
1337 *
1338 * Date: Wed Jan 16 08:47:09 2013 -0600
1339 */
1340( function( jQuery, undefined ) {
1341
1342	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1343		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1344
1345	// Plusequals test for += 100 -= 100
1346	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1347
1348	// A set of RE's that can match strings and generate color tuples.
1349	stringParsers = [ {
1350			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1351			parse: function( execResult ) {
1352				return [
1353					execResult[ 1 ],
1354					execResult[ 2 ],
1355					execResult[ 3 ],
1356					execResult[ 4 ]
1357				];
1358			}
1359		}, {
1360			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1361			parse: function( execResult ) {
1362				return [
1363					execResult[ 1 ] * 2.55,
1364					execResult[ 2 ] * 2.55,
1365					execResult[ 3 ] * 2.55,
1366					execResult[ 4 ]
1367				];
1368			}
1369		}, {
1370
1371			// This regex ignores A-F because it's compared against an already lowercased string
1372			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
1373			parse: function( execResult ) {
1374				return [
1375					parseInt( execResult[ 1 ], 16 ),
1376					parseInt( execResult[ 2 ], 16 ),
1377					parseInt( execResult[ 3 ], 16 )
1378				];
1379			}
1380		}, {
1381
1382			// This regex ignores A-F because it's compared against an already lowercased string
1383			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
1384			parse: function( execResult ) {
1385				return [
1386					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1387					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1388					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
1389				];
1390			}
1391		}, {
1392			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1393			space: "hsla",
1394			parse: function( execResult ) {
1395				return [
1396					execResult[ 1 ],
1397					execResult[ 2 ] / 100,
1398					execResult[ 3 ] / 100,
1399					execResult[ 4 ]
1400				];
1401			}
1402		} ],
1403
1404	// JQuery.Color( )
1405	color = jQuery.Color = function( color, green, blue, alpha ) {
1406		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1407	},
1408	spaces = {
1409		rgba: {
1410			props: {
1411				red: {
1412					idx: 0,
1413					type: "byte"
1414				},
1415				green: {
1416					idx: 1,
1417					type: "byte"
1418				},
1419				blue: {
1420					idx: 2,
1421					type: "byte"
1422				}
1423			}
1424		},
1425
1426		hsla: {
1427			props: {
1428				hue: {
1429					idx: 0,
1430					type: "degrees"
1431				},
1432				saturation: {
1433					idx: 1,
1434					type: "percent"
1435				},
1436				lightness: {
1437					idx: 2,
1438					type: "percent"
1439				}
1440			}
1441		}
1442	},
1443	propTypes = {
1444		"byte": {
1445			floor: true,
1446			max: 255
1447		},
1448		"percent": {
1449			max: 1
1450		},
1451		"degrees": {
1452			mod: 360,
1453			floor: true
1454		}
1455	},
1456	support = color.support = {},
1457
1458	// Element for support tests
1459	supportElem = jQuery( "<p>" )[ 0 ],
1460
1461	// Colors = jQuery.Color.names
1462	colors,
1463
1464	// Local aliases of functions called often
1465	each = jQuery.each;
1466
1467// Determine rgba support immediately
1468supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
1469support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
1470
1471// Define cache name and alpha properties
1472// for rgba and hsla spaces
1473each( spaces, function( spaceName, space ) {
1474	space.cache = "_" + spaceName;
1475	space.props.alpha = {
1476		idx: 3,
1477		type: "percent",
1478		def: 1
1479	};
1480} );
1481
1482function clamp( value, prop, allowEmpty ) {
1483	var type = propTypes[ prop.type ] || {};
1484
1485	if ( value == null ) {
1486		return ( allowEmpty || !prop.def ) ? null : prop.def;
1487	}
1488
1489	// ~~ is an short way of doing floor for positive numbers
1490	value = type.floor ? ~~value : parseFloat( value );
1491
1492	// IE will pass in empty strings as value for alpha,
1493	// which will hit this case
1494	if ( isNaN( value ) ) {
1495		return prop.def;
1496	}
1497
1498	if ( type.mod ) {
1499
1500		// We add mod before modding to make sure that negatives values
1501		// get converted properly: -10 -> 350
1502		return ( value + type.mod ) % type.mod;
1503	}
1504
1505	// For now all property types without mod have min and max
1506	return 0 > value ? 0 : type.max < value ? type.max : value;
1507}
1508
1509function stringParse( string ) {
1510	var inst = color(),
1511		rgba = inst._rgba = [];
1512
1513	string = string.toLowerCase();
1514
1515	each( stringParsers, function( i, parser ) {
1516		var parsed,
1517			match = parser.re.exec( string ),
1518			values = match && parser.parse( match ),
1519			spaceName = parser.space || "rgba";
1520
1521		if ( values ) {
1522			parsed = inst[ spaceName ]( values );
1523
1524			// If this was an rgba parse the assignment might happen twice
1525			// oh well....
1526			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1527			rgba = inst._rgba = parsed._rgba;
1528
1529			// Exit each( stringParsers ) here because we matched
1530			return false;
1531		}
1532	} );
1533
1534	// Found a stringParser that handled it
1535	if ( rgba.length ) {
1536
1537		// If this came from a parsed string, force "transparent" when alpha is 0
1538		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1539		if ( rgba.join() === "0,0,0,0" ) {
1540			jQuery.extend( rgba, colors.transparent );
1541		}
1542		return inst;
1543	}
1544
1545	// Named colors
1546	return colors[ string ];
1547}
1548
1549color.fn = jQuery.extend( color.prototype, {
1550	parse: function( red, green, blue, alpha ) {
1551		if ( red === undefined ) {
1552			this._rgba = [ null, null, null, null ];
1553			return this;
1554		}
1555		if ( red.jquery || red.nodeType ) {
1556			red = jQuery( red ).css( green );
1557			green = undefined;
1558		}
1559
1560		var inst = this,
1561			type = jQuery.type( red ),
1562			rgba = this._rgba = [];
1563
1564		// More than 1 argument specified - assume ( red, green, blue, alpha )
1565		if ( green !== undefined ) {
1566			red = [ red, green, blue, alpha ];
1567			type = "array";
1568		}
1569
1570		if ( type === "string" ) {
1571			return this.parse( stringParse( red ) || colors._default );
1572		}
1573
1574		if ( type === "array" ) {
1575			each( spaces.rgba.props, function( key, prop ) {
1576				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1577			} );
1578			return this;
1579		}
1580
1581		if ( type === "object" ) {
1582			if ( red instanceof color ) {
1583				each( spaces, function( spaceName, space ) {
1584					if ( red[ space.cache ] ) {
1585						inst[ space.cache ] = red[ space.cache ].slice();
1586					}
1587				} );
1588			} else {
1589				each( spaces, function( spaceName, space ) {
1590					var cache = space.cache;
1591					each( space.props, function( key, prop ) {
1592
1593						// If the cache doesn't exist, and we know how to convert
1594						if ( !inst[ cache ] && space.to ) {
1595
1596							// If the value was null, we don't need to copy it
1597							// if the key was alpha, we don't need to copy it either
1598							if ( key === "alpha" || red[ key ] == null ) {
1599								return;
1600							}
1601							inst[ cache ] = space.to( inst._rgba );
1602						}
1603
1604						// This is the only case where we allow nulls for ALL properties.
1605						// call clamp with alwaysAllowEmpty
1606						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1607					} );
1608
1609					// Everything defined but alpha?
1610					if ( inst[ cache ] &&
1611							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
1612
1613						// Use the default of 1
1614						inst[ cache ][ 3 ] = 1;
1615						if ( space.from ) {
1616							inst._rgba = space.from( inst[ cache ] );
1617						}
1618					}
1619				} );
1620			}
1621			return this;
1622		}
1623	},
1624	is: function( compare ) {
1625		var is = color( compare ),
1626			same = true,
1627			inst = this;
1628
1629		each( spaces, function( _, space ) {
1630			var localCache,
1631				isCache = is[ space.cache ];
1632			if ( isCache ) {
1633				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1634				each( space.props, function( _, prop ) {
1635					if ( isCache[ prop.idx ] != null ) {
1636						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1637						return same;
1638					}
1639				} );
1640			}
1641			return same;
1642		} );
1643		return same;
1644	},
1645	_space: function() {
1646		var used = [],
1647			inst = this;
1648		each( spaces, function( spaceName, space ) {
1649			if ( inst[ space.cache ] ) {
1650				used.push( spaceName );
1651			}
1652		} );
1653		return used.pop();
1654	},
1655	transition: function( other, distance ) {
1656		var end = color( other ),
1657			spaceName = end._space(),
1658			space = spaces[ spaceName ],
1659			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1660			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1661			result = start.slice();
1662
1663		end = end[ space.cache ];
1664		each( space.props, function( key, prop ) {
1665			var index = prop.idx,
1666				startValue = start[ index ],
1667				endValue = end[ index ],
1668				type = propTypes[ prop.type ] || {};
1669
1670			// If null, don't override start value
1671			if ( endValue === null ) {
1672				return;
1673			}
1674
1675			// If null - use end
1676			if ( startValue === null ) {
1677				result[ index ] = endValue;
1678			} else {
1679				if ( type.mod ) {
1680					if ( endValue - startValue > type.mod / 2 ) {
1681						startValue += type.mod;
1682					} else if ( startValue - endValue > type.mod / 2 ) {
1683						startValue -= type.mod;
1684					}
1685				}
1686				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1687			}
1688		} );
1689		return this[ spaceName ]( result );
1690	},
1691	blend: function( opaque ) {
1692
1693		// If we are already opaque - return ourself
1694		if ( this._rgba[ 3 ] === 1 ) {
1695			return this;
1696		}
1697
1698		var rgb = this._rgba.slice(),
1699			a = rgb.pop(),
1700			blend = color( opaque )._rgba;
1701
1702		return color( jQuery.map( rgb, function( v, i ) {
1703			return ( 1 - a ) * blend[ i ] + a * v;
1704		} ) );
1705	},
1706	toRgbaString: function() {
1707		var prefix = "rgba(",
1708			rgba = jQuery.map( this._rgba, function( v, i ) {
1709				return v == null ? ( i > 2 ? 1 : 0 ) : v;
1710			} );
1711
1712		if ( rgba[ 3 ] === 1 ) {
1713			rgba.pop();
1714			prefix = "rgb(";
1715		}
1716
1717		return prefix + rgba.join() + ")";
1718	},
1719	toHslaString: function() {
1720		var prefix = "hsla(",
1721			hsla = jQuery.map( this.hsla(), function( v, i ) {
1722				if ( v == null ) {
1723					v = i > 2 ? 1 : 0;
1724				}
1725
1726				// Catch 1 and 2
1727				if ( i && i < 3 ) {
1728					v = Math.round( v * 100 ) + "%";
1729				}
1730				return v;
1731			} );
1732
1733		if ( hsla[ 3 ] === 1 ) {
1734			hsla.pop();
1735			prefix = "hsl(";
1736		}
1737		return prefix + hsla.join() + ")";
1738	},
1739	toHexString: function( includeAlpha ) {
1740		var rgba = this._rgba.slice(),
1741			alpha = rgba.pop();
1742
1743		if ( includeAlpha ) {
1744			rgba.push( ~~( alpha * 255 ) );
1745		}
1746
1747		return "#" + jQuery.map( rgba, function( v ) {
1748
1749			// Default to 0 when nulls exist
1750			v = ( v || 0 ).toString( 16 );
1751			return v.length === 1 ? "0" + v : v;
1752		} ).join( "" );
1753	},
1754	toString: function() {
1755		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
1756	}
1757} );
1758color.fn.parse.prototype = color.fn;
1759
1760// Hsla conversions adapted from:
1761// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1762
1763function hue2rgb( p, q, h ) {
1764	h = ( h + 1 ) % 1;
1765	if ( h * 6 < 1 ) {
1766		return p + ( q - p ) * h * 6;
1767	}
1768	if ( h * 2 < 1 ) {
1769		return q;
1770	}
1771	if ( h * 3 < 2 ) {
1772		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1773	}
1774	return p;
1775}
1776
1777spaces.hsla.to = function( rgba ) {
1778	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1779		return [ null, null, null, rgba[ 3 ] ];
1780	}
1781	var r = rgba[ 0 ] / 255,
1782		g = rgba[ 1 ] / 255,
1783		b = rgba[ 2 ] / 255,
1784		a = rgba[ 3 ],
1785		max = Math.max( r, g, b ),
1786		min = Math.min( r, g, b ),
1787		diff = max - min,
1788		add = max + min,
1789		l = add * 0.5,
1790		h, s;
1791
1792	if ( min === max ) {
1793		h = 0;
1794	} else if ( r === max ) {
1795		h = ( 60 * ( g - b ) / diff ) + 360;
1796	} else if ( g === max ) {
1797		h = ( 60 * ( b - r ) / diff ) + 120;
1798	} else {
1799		h = ( 60 * ( r - g ) / diff ) + 240;
1800	}
1801
1802	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1803	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1804	if ( diff === 0 ) {
1805		s = 0;
1806	} else if ( l <= 0.5 ) {
1807		s = diff / add;
1808	} else {
1809		s = diff / ( 2 - add );
1810	}
1811	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1812};
1813
1814spaces.hsla.from = function( hsla ) {
1815	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1816		return [ null, null, null, hsla[ 3 ] ];
1817	}
1818	var h = hsla[ 0 ] / 360,
1819		s = hsla[ 1 ],
1820		l = hsla[ 2 ],
1821		a = hsla[ 3 ],
1822		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1823		p = 2 * l - q;
1824
1825	return [
1826		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1827		Math.round( hue2rgb( p, q, h ) * 255 ),
1828		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1829		a
1830	];
1831};
1832
1833each( spaces, function( spaceName, space ) {
1834	var props = space.props,
1835		cache = space.cache,
1836		to = space.to,
1837		from = space.from;
1838
1839	// Makes rgba() and hsla()
1840	color.fn[ spaceName ] = function( value ) {
1841
1842		// Generate a cache for this space if it doesn't exist
1843		if ( to && !this[ cache ] ) {
1844			this[ cache ] = to( this._rgba );
1845		}
1846		if ( value === undefined ) {
1847			return this[ cache ].slice();
1848		}
1849
1850		var ret,
1851			type = jQuery.type( value ),
1852			arr = ( type === "array" || type === "object" ) ? value : arguments,
1853			local = this[ cache ].slice();
1854
1855		each( props, function( key, prop ) {
1856			var val = arr[ type === "object" ? key : prop.idx ];
1857			if ( val == null ) {
1858				val = local[ prop.idx ];
1859			}
1860			local[ prop.idx ] = clamp( val, prop );
1861		} );
1862
1863		if ( from ) {
1864			ret = color( from( local ) );
1865			ret[ cache ] = local;
1866			return ret;
1867		} else {
1868			return color( local );
1869		}
1870	};
1871
1872	// Makes red() green() blue() alpha() hue() saturation() lightness()
1873	each( props, function( key, prop ) {
1874
1875		// Alpha is included in more than one space
1876		if ( color.fn[ key ] ) {
1877			return;
1878		}
1879		color.fn[ key ] = function( value ) {
1880			var vtype = jQuery.type( value ),
1881				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
1882				local = this[ fn ](),
1883				cur = local[ prop.idx ],
1884				match;
1885
1886			if ( vtype === "undefined" ) {
1887				return cur;
1888			}
1889
1890			if ( vtype === "function" ) {
1891				value = value.call( this, cur );
1892				vtype = jQuery.type( value );
1893			}
1894			if ( value == null && prop.empty ) {
1895				return this;
1896			}
1897			if ( vtype === "string" ) {
1898				match = rplusequals.exec( value );
1899				if ( match ) {
1900					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1901				}
1902			}
1903			local[ prop.idx ] = value;
1904			return this[ fn ]( local );
1905		};
1906	} );
1907} );
1908
1909// Add cssHook and .fx.step function for each named hook.
1910// accept a space separated string of properties
1911color.hook = function( hook ) {
1912	var hooks = hook.split( " " );
1913	each( hooks, function( i, hook ) {
1914		jQuery.cssHooks[ hook ] = {
1915			set: function( elem, value ) {
1916				var parsed, curElem,
1917					backgroundColor = "";
1918
1919				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
1920						( parsed = stringParse( value ) ) ) ) {
1921					value = color( parsed || value );
1922					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
1923						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
1924						while (
1925							( backgroundColor === "" || backgroundColor === "transparent" ) &&
1926							curElem && curElem.style
1927						) {
1928							try {
1929								backgroundColor = jQuery.css( curElem, "backgroundColor" );
1930								curElem = curElem.parentNode;
1931							} catch ( e ) {
1932							}
1933						}
1934
1935						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
1936							backgroundColor :
1937							"_default" );
1938					}
1939
1940					value = value.toRgbaString();
1941				}
1942				try {
1943					elem.style[ hook ] = value;
1944				} catch ( e ) {
1945
1946					// Wrapped to prevent IE from throwing errors on "invalid" values like
1947					// 'auto' or 'inherit'
1948				}
1949			}
1950		};
1951		jQuery.fx.step[ hook ] = function( fx ) {
1952			if ( !fx.colorInit ) {
1953				fx.start = color( fx.elem, hook );
1954				fx.end = color( fx.end );
1955				fx.colorInit = true;
1956			}
1957			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1958		};
1959	} );
1960
1961};
1962
1963color.hook( stepHooks );
1964
1965jQuery.cssHooks.borderColor = {
1966	expand: function( value ) {
1967		var expanded = {};
1968
1969		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
1970			expanded[ "border" + part + "Color" ] = value;
1971		} );
1972		return expanded;
1973	}
1974};
1975
1976// Basic color names only.
1977// Usage of any of the other color names requires adding yourself or including
1978// jquery.color.svg-names.js.
1979colors = jQuery.Color.names = {
1980
1981	// 4.1. Basic color keywords
1982	aqua: "#00ffff",
1983	black: "#000000",
1984	blue: "#0000ff",
1985	fuchsia: "#ff00ff",
1986	gray: "#808080",
1987	green: "#008000",
1988	lime: "#00ff00",
1989	maroon: "#800000",
1990	navy: "#000080",
1991	olive: "#808000",
1992	purple: "#800080",
1993	red: "#ff0000",
1994	silver: "#c0c0c0",
1995	teal: "#008080",
1996	white: "#ffffff",
1997	yellow: "#ffff00",
1998
1999	// 4.2.3. "transparent" color keyword
2000	transparent: [ null, null, null, 0 ],
2001
2002	_default: "#ffffff"
2003};
2004
2005} )( jQuery );
2006
2007/******************************************************************************/
2008/****************************** CLASS ANIMATIONS ******************************/
2009/******************************************************************************/
2010( function() {
2011
2012var classAnimationActions = [ "add", "remove", "toggle" ],
2013	shorthandStyles = {
2014		border: 1,
2015		borderBottom: 1,
2016		borderColor: 1,
2017		borderLeft: 1,
2018		borderRight: 1,
2019		borderTop: 1,
2020		borderWidth: 1,
2021		margin: 1,
2022		padding: 1
2023	};
2024
2025$.each(
2026	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2027	function( _, prop ) {
2028		$.fx.step[ prop ] = function( fx ) {
2029			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2030				jQuery.style( fx.elem, prop, fx.end );
2031				fx.setAttr = true;
2032			}
2033		};
2034	}
2035);
2036
2037function getElementStyles( elem ) {
2038	var key, len,
2039		style = elem.ownerDocument.defaultView ?
2040			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
2041			elem.currentStyle,
2042		styles = {};
2043
2044	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
2045		len = style.length;
2046		while ( len-- ) {
2047			key = style[ len ];
2048			if ( typeof style[ key ] === "string" ) {
2049				styles[ $.camelCase( key ) ] = style[ key ];
2050			}
2051		}
2052
2053	// Support: Opera, IE <9
2054	} else {
2055		for ( key in style ) {
2056			if ( typeof style[ key ] === "string" ) {
2057				styles[ key ] = style[ key ];
2058			}
2059		}
2060	}
2061
2062	return styles;
2063}
2064
2065function styleDifference( oldStyle, newStyle ) {
2066	var diff = {},
2067		name, value;
2068
2069	for ( name in newStyle ) {
2070		value = newStyle[ name ];
2071		if ( oldStyle[ name ] !== value ) {
2072			if ( !shorthandStyles[ name ] ) {
2073				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2074					diff[ name ] = value;
2075				}
2076			}
2077		}
2078	}
2079
2080	return diff;
2081}
2082
2083// Support: jQuery <1.8
2084if ( !$.fn.addBack ) {
2085	$.fn.addBack = function( selector ) {
2086		return this.add( selector == null ?
2087			this.prevObject : this.prevObject.filter( selector )
2088		);
2089	};
2090}
2091
2092$.effects.animateClass = function( value, duration, easing, callback ) {
2093	var o = $.speed( duration, easing, callback );
2094
2095	return this.queue( function() {
2096		var animated = $( this ),
2097			baseClass = animated.attr( "class" ) || "",
2098			applyClassChange,
2099			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2100
2101		// Map the animated objects to store the original styles.
2102		allAnimations = allAnimations.map( function() {
2103			var el = $( this );
2104			return {
2105				el: el,
2106				start: getElementStyles( this )
2107			};
2108		} );
2109
2110		// Apply class change
2111		applyClassChange = function() {
2112			$.each( classAnimationActions, function( i, action ) {
2113				if ( value[ action ] ) {
2114					animated[ action + "Class" ]( value[ action ] );
2115				}
2116			} );
2117		};
2118		applyClassChange();
2119
2120		// Map all animated objects again - calculate new styles and diff
2121		allAnimations = allAnimations.map( function() {
2122			this.end = getElementStyles( this.el[ 0 ] );
2123			this.diff = styleDifference( this.start, this.end );
2124			return this;
2125		} );
2126
2127		// Apply original class
2128		animated.attr( "class", baseClass );
2129
2130		// Map all animated objects again - this time collecting a promise
2131		allAnimations = allAnimations.map( function() {
2132			var styleInfo = this,
2133				dfd = $.Deferred(),
2134				opts = $.extend( {}, o, {
2135					queue: false,
2136					complete: function() {
2137						dfd.resolve( styleInfo );
2138					}
2139				} );
2140
2141			this.el.animate( this.diff, opts );
2142			return dfd.promise();
2143		} );
2144
2145		// Once all animations have completed:
2146		$.when.apply( $, allAnimations.get() ).done( function() {
2147
2148			// Set the final class
2149			applyClassChange();
2150
2151			// For each animated element,
2152			// clear all css properties that were animated
2153			$.each( arguments, function() {
2154				var el = this.el;
2155				$.each( this.diff, function( key ) {
2156					el.css( key, "" );
2157				} );
2158			} );
2159
2160			// This is guarnteed to be there if you use jQuery.speed()
2161			// it also handles dequeuing the next anim...
2162			o.complete.call( animated[ 0 ] );
2163		} );
2164	} );
2165};
2166
2167$.fn.extend( {
2168	addClass: ( function( orig ) {
2169		return function( classNames, speed, easing, callback ) {
2170			return speed ?
2171				$.effects.animateClass.call( this,
2172					{ add: classNames }, speed, easing, callback ) :
2173				orig.apply( this, arguments );
2174		};
2175	} )( $.fn.addClass ),
2176
2177	removeClass: ( function( orig ) {
2178		return function( classNames, speed, easing, callback ) {
2179			return arguments.length > 1 ?
2180				$.effects.animateClass.call( this,
2181					{ remove: classNames }, speed, easing, callback ) :
2182				orig.apply( this, arguments );
2183		};
2184	} )( $.fn.removeClass ),
2185
2186	toggleClass: ( function( orig ) {
2187		return function( classNames, force, speed, easing, callback ) {
2188			if ( typeof force === "boolean" || force === undefined ) {
2189				if ( !speed ) {
2190
2191					// Without speed parameter
2192					return orig.apply( this, arguments );
2193				} else {
2194					return $.effects.animateClass.call( this,
2195						( force ? { add: classNames } : { remove: classNames } ),
2196						speed, easing, callback );
2197				}
2198			} else {
2199
vendor: 6,240 bytes, lines 2200-2454
2200				// Without force parameter
2201				return $.effects.animateClass.call( this,
2202					{ toggle: classNames }, force, speed, easing );
2203			}
2204		};
2205	} )( $.fn.toggleClass ),
2206
2207	switchClass: function( remove, add, speed, easing, callback ) {
2208		return $.effects.animateClass.call( this, {
2209			add: add,
2210			remove: remove
2211		}, speed, easing, callback );
2212	}
2213} );
2214
2215} )();
2216
2217/******************************************************************************/
2218/*********************************** EFFECTS **********************************/
2219/******************************************************************************/
2220
2221( function() {
2222
2223if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
2224	$.expr.filters.animated = ( function( orig ) {
2225		return function( elem ) {
2226			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2227		};
2228	} )( $.expr.filters.animated );
2229}
2230
2231if ( $.uiBackCompat !== false ) {
2232	$.extend( $.effects, {
2233
2234		// Saves a set of properties in a data storage
2235		save: function( element, set ) {
2236			var i = 0, length = set.length;
2237			for ( ; i < length; i++ ) {
2238				if ( set[ i ] !== null ) {
2239					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2240				}
2241			}
2242		},
2243
2244		// Restores a set of previously saved properties from a data storage
2245		restore: function( element, set ) {
2246			var val, i = 0, length = set.length;
2247			for ( ; i < length; i++ ) {
2248				if ( set[ i ] !== null ) {
2249					val = element.data( dataSpace + set[ i ] );
2250					element.css( set[ i ], val );
2251				}
2252			}
2253		},
2254
2255		setMode: function( el, mode ) {
2256			if ( mode === "toggle" ) {
2257				mode = el.is( ":hidden" ) ? "show" : "hide";
2258			}
2259			return mode;
2260		},
2261
2262		// Wraps the element around a wrapper that copies position properties
2263		createWrapper: function( element ) {
2264
2265			// If the element is already wrapped, return it
2266			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2267				return element.parent();
2268			}
2269
2270			// Wrap the element
2271			var props = {
2272					width: element.outerWidth( true ),
2273					height: element.outerHeight( true ),
2274					"float": element.css( "float" )
2275				},
2276				wrapper = $( "<div></div>" )
2277					.addClass( "ui-effects-wrapper" )
2278					.css( {
2279						fontSize: "100%",
2280						background: "transparent",
2281						border: "none",
2282						margin: 0,
2283						padding: 0
2284					} ),
2285
2286				// Store the size in case width/height are defined in % - Fixes #5245
2287				size = {
2288					width: element.width(),
2289					height: element.height()
2290				},
2291				active = document.activeElement;
2292
2293			// Support: Firefox
2294			// Firefox incorrectly exposes anonymous content
2295			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2296			try {
2297				active.id;
2298			} catch ( e ) {
2299				active = document.body;
2300			}
2301
2302			element.wrap( wrapper );
2303
2304			// Fixes #7595 - Elements lose focus when wrapped.
2305			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2306				$( active ).trigger( "focus" );
2307			}
2308
2309			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2310			// lose the reference to the wrapped element
2311			wrapper = element.parent();
2312
2313			// Transfer positioning properties to the wrapper
2314			if ( element.css( "position" ) === "static" ) {
2315				wrapper.css( { position: "relative" } );
2316				element.css( { position: "relative" } );
2317			} else {
2318				$.extend( props, {
2319					position: element.css( "position" ),
2320					zIndex: element.css( "z-index" )
2321				} );
2322				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2323					props[ pos ] = element.css( pos );
2324					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2325						props[ pos ] = "auto";
2326					}
2327				} );
2328				element.css( {
2329					position: "relative",
2330					top: 0,
2331					left: 0,
2332					right: "auto",
2333					bottom: "auto"
2334				} );
2335			}
2336			element.css( size );
2337
2338			return wrapper.css( props ).show();
2339		},
2340
2341		removeWrapper: function( element ) {
2342			var active = document.activeElement;
2343
2344			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2345				element.parent().replaceWith( element );
2346
2347				// Fixes #7595 - Elements lose focus when wrapped.
2348				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2349					$( active ).trigger( "focus" );
2350				}
2351			}
2352
2353			return element;
2354		}
2355	} );
2356}
2357
2358$.extend( $.effects, {
2359	version: "1.12.1",
2360
2361	define: function( name, mode, effect ) {
2362		if ( !effect ) {
2363			effect = mode;
2364			mode = "effect";
2365		}
2366
2367		$.effects.effect[ name ] = effect;
2368		$.effects.effect[ name ].mode = mode;
2369
2370		return effect;
2371	},
2372
2373	scaledDimensions: function( element, percent, direction ) {
2374		if ( percent === 0 ) {
2375			return {
2376				height: 0,
2377				width: 0,
2378				outerHeight: 0,
2379				outerWidth: 0
2380			};
2381		}
2382
2383		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2384			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2385
2386		return {
2387			height: element.height() * y,
2388			width: element.width() * x,
2389			outerHeight: element.outerHeight() * y,
2390			outerWidth: element.outerWidth() * x
2391		};
2392
2393	},
2394
2395	clipToBox: function( animation ) {
2396		return {
2397			width: animation.clip.right - animation.clip.left,
2398			height: animation.clip.bottom - animation.clip.top,
2399			left: animation.clip.left,
2400			top: animation.clip.top
2401		};
2402	},
2403
2404	// Injects recently queued functions to be first in line (after "inprogress")
2405	unshift: function( element, queueLength, count ) {
2406		var queue = element.queue();
2407
2408		if ( queueLength > 1 ) {
2409			queue.splice.apply( queue,
2410				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2411		}
2412		element.dequeue();
2413	},
2414
2415	saveStyle: function( element ) {
2416		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2417	},
2418
2419	restoreStyle: function( element ) {
2420		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2421		element.removeData( dataSpaceStyle );
2422	},
2423
2424	mode: function( element, mode ) {
2425		var hidden = element.is( ":hidden" );
2426
2427		if ( mode === "toggle" ) {
2428			mode = hidden ? "show" : "hide";
2429		}
2430		if ( hidden ? mode === "hide" : mode === "show" ) {
2431			mode = "none";
2432		}
2433		return mode;
2434	},
2435
2436	// Translates a [top,left] array into a baseline value
2437	getBaseline: function( origin, original ) {
2438		var y, x;
2439
2440		switch ( origin[ 0 ] ) {
2441		case "top":
2442			y = 0;
2443			break;
2444		case "middle":
2445			y = 0.5;
2446			break;
2447		case "bottom":
2448			y = 1;
2449			break;
2450		default:
2451			y = origin[ 0 ] / original.height;
2452		}
2453
2454		switch ( origin[ 1 ] ) {
vendor: 4,228 bytes, lines 2455-2627
2455		case "left":
2456			x = 0;
2457			break;
2458		case "center":
2459			x = 0.5;
2460			break;
2461		case "right":
2462			x = 1;
2463			break;
2464		default:
2465			x = origin[ 1 ] / original.width;
2466		}
2467
2468		return {
2469			x: x,
2470			y: y
2471		};
2472	},
2473
2474	// Creates a placeholder element so that the original element can be made absolute
2475	createPlaceholder: function( element ) {
2476		var placeholder,
2477			cssPosition = element.css( "position" ),
2478			position = element.position();
2479
2480		// Lock in margins first to account for form elements, which
2481		// will change margin if you explicitly set height
2482		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2483		// Support: Safari
2484		element.css( {
2485			marginTop: element.css( "marginTop" ),
2486			marginBottom: element.css( "marginBottom" ),
2487			marginLeft: element.css( "marginLeft" ),
2488			marginRight: element.css( "marginRight" )
2489		} )
2490		.outerWidth( element.outerWidth() )
2491		.outerHeight( element.outerHeight() );
2492
2493		if ( /^(static|relative)/.test( cssPosition ) ) {
2494			cssPosition = "absolute";
2495
2496			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2497
2498				// Convert inline to inline block to account for inline elements
2499				// that turn to inline block based on content (like img)
2500				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2501					"inline-block" :
2502					"block",
2503				visibility: "hidden",
2504
2505				// Margins need to be set to account for margin collapse
2506				marginTop: element.css( "marginTop" ),
2507				marginBottom: element.css( "marginBottom" ),
2508				marginLeft: element.css( "marginLeft" ),
2509				marginRight: element.css( "marginRight" ),
2510				"float": element.css( "float" )
2511			} )
2512			.outerWidth( element.outerWidth() )
2513			.outerHeight( element.outerHeight() )
2514			.addClass( "ui-effects-placeholder" );
2515
2516			element.data( dataSpace + "placeholder", placeholder );
2517		}
2518
2519		element.css( {
2520			position: cssPosition,
2521			left: position.left,
2522			top: position.top
2523		} );
2524
2525		return placeholder;
2526	},
2527
2528	removePlaceholder: function( element ) {
2529		var dataKey = dataSpace + "placeholder",
2530				placeholder = element.data( dataKey );
2531
2532		if ( placeholder ) {
2533			placeholder.remove();
2534			element.removeData( dataKey );
2535		}
2536	},
2537
2538	// Removes a placeholder if it exists and restores
2539	// properties that were modified during placeholder creation
2540	cleanUp: function( element ) {
2541		$.effects.restoreStyle( element );
2542		$.effects.removePlaceholder( element );
2543	},
2544
2545	setTransition: function( element, list, factor, value ) {
2546		value = value || {};
2547		$.each( list, function( i, x ) {
2548			var unit = element.cssUnit( x );
2549			if ( unit[ 0 ] > 0 ) {
2550				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2551			}
2552		} );
2553		return value;
2554	}
2555} );
2556
2557// Return an effect options object for the given parameters:
2558function _normalizeArguments( effect, options, speed, callback ) {
2559
2560	// Allow passing all options as the first parameter
2561	if ( $.isPlainObject( effect ) ) {
2562		options = effect;
2563		effect = effect.effect;
2564	}
2565
2566	// Convert to an object
2567	effect = { effect: effect };
2568
2569	// Catch (effect, null, ...)
2570	if ( options == null ) {
2571		options = {};
2572	}
2573
2574	// Catch (effect, callback)
2575	if ( $.isFunction( options ) ) {
2576		callback = options;
2577		speed = null;
2578		options = {};
2579	}
2580
2581	// Catch (effect, speed, ?)
2582	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2583		callback = speed;
2584		speed = options;
2585		options = {};
2586	}
2587
2588	// Catch (effect, options, callback)
2589	if ( $.isFunction( speed ) ) {
2590		callback = speed;
2591		speed = null;
2592	}
2593
2594	// Add options to effect
2595	if ( options ) {
2596		$.extend( effect, options );
2597	}
2598
2599	speed = speed || options.duration;
2600	effect.duration = $.fx.off ? 0 :
2601		typeof speed === "number" ? speed :
2602		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2603		$.fx.speeds._default;
2604
2605	effect.complete = callback || options.complete;
2606
2607	return effect;
2608}
2609
2610function standardAnimationOption( option ) {
2611
2612	// Valid standard speeds (nothing, number, named speed)
2613	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2614		return true;
2615	}
2616
2617	// Invalid strings - treat as "normal" speed
2618	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2619		return true;
2620	}
2621
2622	// Complete callback
2623	if ( $.isFunction( option ) ) {
2624		return true;
2625	}
2626
2627	// Options hash (but not naming an effect)
vendor: 4,796 bytes, lines 2628-2811
2628	if ( typeof option === "object" && !option.effect ) {
2629		return true;
2630	}
2631
2632	// Didn't match any standard API
2633	return false;
2634}
2635
2636$.fn.extend( {
2637	effect: function( /* effect, options, speed, callback */ ) {
2638		var args = _normalizeArguments.apply( this, arguments ),
2639			effectMethod = $.effects.effect[ args.effect ],
2640			defaultMode = effectMethod.mode,
2641			queue = args.queue,
2642			queueName = queue || "fx",
2643			complete = args.complete,
2644			mode = args.mode,
2645			modes = [],
2646			prefilter = function( next ) {
2647				var el = $( this ),
2648					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2649
2650				// Sentinel for duck-punching the :animated psuedo-selector
2651				el.data( dataSpaceAnimated, true );
2652
2653				// Save effect mode for later use,
2654				// we can't just call $.effects.mode again later,
2655				// as the .show() below destroys the initial state
2656				modes.push( normalizedMode );
2657
2658				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
2659				if ( defaultMode && ( normalizedMode === "show" ||
2660						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2661					el.show();
2662				}
2663
2664				if ( !defaultMode || normalizedMode !== "none" ) {
2665					$.effects.saveStyle( el );
2666				}
2667
2668				if ( $.isFunction( next ) ) {
2669					next();
2670				}
2671			};
2672
2673		if ( $.fx.off || !effectMethod ) {
2674
2675			// Delegate to the original method (e.g., .show()) if possible
2676			if ( mode ) {
2677				return this[ mode ]( args.duration, complete );
2678			} else {
2679				return this.each( function() {
2680					if ( complete ) {
2681						complete.call( this );
2682					}
2683				} );
2684			}
2685		}
2686
2687		function run( next ) {
2688			var elem = $( this );
2689
2690			function cleanup() {
2691				elem.removeData( dataSpaceAnimated );
2692
2693				$.effects.cleanUp( elem );
2694
2695				if ( args.mode === "hide" ) {
2696					elem.hide();
2697				}
2698
2699				done();
2700			}
2701
2702			function done() {
2703				if ( $.isFunction( complete ) ) {
2704					complete.call( elem[ 0 ] );
2705				}
2706
2707				if ( $.isFunction( next ) ) {
2708					next();
2709				}
2710			}
2711
2712			// Override mode option on a per element basis,
2713			// as toggle can be either show or hide depending on element state
2714			args.mode = modes.shift();
2715
2716			if ( $.uiBackCompat !== false && !defaultMode ) {
2717				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2718
2719					// Call the core method to track "olddisplay" properly
2720					elem[ mode ]();
2721					done();
2722				} else {
2723					effectMethod.call( elem[ 0 ], args, done );
2724				}
2725			} else {
2726				if ( args.mode === "none" ) {
2727
2728					// Call the core method to track "olddisplay" properly
2729					elem[ mode ]();
2730					done();
2731				} else {
2732					effectMethod.call( elem[ 0 ], args, cleanup );
2733				}
2734			}
2735		}
2736
2737		// Run prefilter on all elements first to ensure that
2738		// any showing or hiding happens before placeholder creation,
2739		// which ensures that any layout changes are correctly captured.
2740		return queue === false ?
2741			this.each( prefilter ).each( run ) :
2742			this.queue( queueName, prefilter ).queue( queueName, run );
2743	},
2744
2745	show: ( function( orig ) {
2746		return function( option ) {
2747			if ( standardAnimationOption( option ) ) {
2748				return orig.apply( this, arguments );
2749			} else {
2750				var args = _normalizeArguments.apply( this, arguments );
2751				args.mode = "show";
2752				return this.effect.call( this, args );
2753			}
2754		};
2755	} )( $.fn.show ),
2756
2757	hide: ( function( orig ) {
2758		return function( option ) {
2759			if ( standardAnimationOption( option ) ) {
2760				return orig.apply( this, arguments );
2761			} else {
2762				var args = _normalizeArguments.apply( this, arguments );
2763				args.mode = "hide";
2764				return this.effect.call( this, args );
2765			}
2766		};
2767	} )( $.fn.hide ),
2768
2769	toggle: ( function( orig ) {
2770		return function( option ) {
2771			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2772				return orig.apply( this, arguments );
2773			} else {
2774				var args = _normalizeArguments.apply( this, arguments );
2775				args.mode = "toggle";
2776				return this.effect.call( this, args );
2777			}
2778		};
2779	} )( $.fn.toggle ),
2780
2781	cssUnit: function( key ) {
2782		var style = this.css( key ),
2783			val = [];
2784
2785		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2786			if ( style.indexOf( unit ) > 0 ) {
2787				val = [ parseFloat( style ), unit ];
2788			}
2789		} );
2790		return val;
2791	},
2792
2793	cssClip: function( clipObj ) {
2794		if ( clipObj ) {
2795			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2796				clipObj.bottom + "px " + clipObj.left + "px)" );
2797		}
2798		return parseClip( this.css( "clip" ), this );
2799	},
2800
2801	transfer: function( options, done ) {
2802		var element = $( this ),
2803			target = $( options.to ),
2804			targetFixed = target.css( "position" ) === "fixed",
2805			body = $( "body" ),
2806			fixTop = targetFixed ? body.scrollTop() : 0,
2807			fixLeft = targetFixed ? body.scrollLeft() : 0,
2808			endPosition = target.offset(),
2809			animation = {
2810				top: endPosition.top - fixTop,
2811				left: endPosition.left - fixLeft,
vendor: 27,020 bytes, lines 2812-3841
2812				height: target.innerHeight(),
2813				width: target.innerWidth()
2814			},
2815			startPosition = element.offset(),
2816			transfer = $( "<div class='ui-effects-transfer'></div>" )
2817				.appendTo( "body" )
2818				.addClass( options.className )
2819				.css( {
2820					top: startPosition.top - fixTop,
2821					left: startPosition.left - fixLeft,
2822					height: element.innerHeight(),
2823					width: element.innerWidth(),
2824					position: targetFixed ? "fixed" : "absolute"
2825				} )
2826				.animate( animation, options.duration, options.easing, function() {
2827					transfer.remove();
2828					if ( $.isFunction( done ) ) {
2829						done();
2830					}
2831				} );
2832	}
2833} );
2834
2835function parseClip( str, element ) {
2836		var outerWidth = element.outerWidth(),
2837			outerHeight = element.outerHeight(),
2838			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)\)$/,
2839			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2840
2841		return {
2842			top: parseFloat( values[ 1 ] ) || 0,
2843			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2844			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2845			left: parseFloat( values[ 4 ] ) || 0
2846		};
2847}
2848
2849$.fx.step.clip = function( fx ) {
2850	if ( !fx.clipInit ) {
2851		fx.start = $( fx.elem ).cssClip();
2852		if ( typeof fx.end === "string" ) {
2853			fx.end = parseClip( fx.end, fx.elem );
2854		}
2855		fx.clipInit = true;
2856	}
2857
2858	$( fx.elem ).cssClip( {
2859		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2860		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2861		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2862		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2863	} );
2864};
2865
2866} )();
2867
2868/******************************************************************************/
2869/*********************************** EASING ***********************************/
2870/******************************************************************************/
2871
2872( function() {
2873
2874// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2875
2876var baseEasings = {};
2877
2878$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2879	baseEasings[ name ] = function( p ) {
2880		return Math.pow( p, i + 2 );
2881	};
2882} );
2883
2884$.extend( baseEasings, {
2885	Sine: function( p ) {
2886		return 1 - Math.cos( p * Math.PI / 2 );
2887	},
2888	Circ: function( p ) {
2889		return 1 - Math.sqrt( 1 - p * p );
2890	},
2891	Elastic: function( p ) {
2892		return p === 0 || p === 1 ? p :
2893			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2894	},
2895	Back: function( p ) {
2896		return p * p * ( 3 * p - 2 );
2897	},
2898	Bounce: function( p ) {
2899		var pow2,
2900			bounce = 4;
2901
2902		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2903		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2904	}
2905} );
2906
2907$.each( baseEasings, function( name, easeIn ) {
2908	$.easing[ "easeIn" + name ] = easeIn;
2909	$.easing[ "easeOut" + name ] = function( p ) {
2910		return 1 - easeIn( 1 - p );
2911	};
2912	$.easing[ "easeInOut" + name ] = function( p ) {
2913		return p < 0.5 ?
2914			easeIn( p * 2 ) / 2 :
2915			1 - easeIn( p * -2 + 2 ) / 2;
2916	};
2917} );
2918
2919} )();
2920
2921var effect = $.effects;
2922
2923
2924/*!
2925 * jQuery UI Effects Blind 1.12.1
2926 * http://jqueryui.com
2927 *
2928 * Copyright jQuery Foundation and other contributors
2929 * Released under the MIT license.
2930 * http://jquery.org/license
2931 */
2932
2933//>>label: Blind Effect
2934//>>group: Effects
2935//>>description: Blinds the element.
2936//>>docs: http://api.jqueryui.com/blind-effect/
2937//>>demos: http://jqueryui.com/effect/
2938
2939
2940
2941var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2942	var map = {
2943			up: [ "bottom", "top" ],
2944			vertical: [ "bottom", "top" ],
2945			down: [ "top", "bottom" ],
2946			left: [ "right", "left" ],
2947			horizontal: [ "right", "left" ],
2948			right: [ "left", "right" ]
2949		},
2950		element = $( this ),
2951		direction = options.direction || "up",
2952		start = element.cssClip(),
2953		animate = { clip: $.extend( {}, start ) },
2954		placeholder = $.effects.createPlaceholder( element );
2955
2956	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2957
2958	if ( options.mode === "show" ) {
2959		element.cssClip( animate.clip );
2960		if ( placeholder ) {
2961			placeholder.css( $.effects.clipToBox( animate ) );
2962		}
2963
2964		animate.clip = start;
2965	}
2966
2967	if ( placeholder ) {
2968		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2969	}
2970
2971	element.animate( animate, {
2972		queue: false,
2973		duration: options.duration,
2974		easing: options.easing,
2975		complete: done
2976	} );
2977} );
2978
2979
2980/*!
2981 * jQuery UI Effects Bounce 1.12.1
2982 * http://jqueryui.com
2983 *
2984 * Copyright jQuery Foundation and other contributors
2985 * Released under the MIT license.
2986 * http://jquery.org/license
2987 */
2988
2989//>>label: Bounce Effect
2990//>>group: Effects
2991//>>description: Bounces an element horizontally or vertically n times.
2992//>>docs: http://api.jqueryui.com/bounce-effect/
2993//>>demos: http://jqueryui.com/effect/
2994
2995
2996
2997var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2998	var upAnim, downAnim, refValue,
2999		element = $( this ),
3000
3001		// Defaults:
3002		mode = options.mode,
3003		hide = mode === "hide",
3004		show = mode === "show",
3005		direction = options.direction || "up",
3006		distance = options.distance,
3007		times = options.times || 5,
3008
3009		// Number of internal animations
3010		anims = times * 2 + ( show || hide ? 1 : 0 ),
3011		speed = options.duration / anims,
3012		easing = options.easing,
3013
3014		// Utility:
3015		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3016		motion = ( direction === "up" || direction === "left" ),
3017		i = 0,
3018
3019		queuelen = element.queue().length;
3020
3021	$.effects.createPlaceholder( element );
3022
3023	refValue = element.css( ref );
3024
3025	// Default distance for the BIGGEST bounce is the outer Distance / 3
3026	if ( !distance ) {
3027		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3028	}
3029
3030	if ( show ) {
3031		downAnim = { opacity: 1 };
3032		downAnim[ ref ] = refValue;
3033
3034		// If we are showing, force opacity 0 and set the initial position
3035		// then do the "first" animation
3036		element
3037			.css( "opacity", 0 )
3038			.css( ref, motion ? -distance * 2 : distance * 2 )
3039			.animate( downAnim, speed, easing );
3040	}
3041
3042	// Start at the smallest distance if we are hiding
3043	if ( hide ) {
3044		distance = distance / Math.pow( 2, times - 1 );
3045	}
3046
3047	downAnim = {};
3048	downAnim[ ref ] = refValue;
3049
3050	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3051	for ( ; i < times; i++ ) {
3052		upAnim = {};
3053		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3054
3055		element
3056			.animate( upAnim, speed, easing )
3057			.animate( downAnim, speed, easing );
3058
3059		distance = hide ? distance * 2 : distance / 2;
3060	}
3061
3062	// Last Bounce when Hiding
3063	if ( hide ) {
3064		upAnim = { opacity: 0 };
3065		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3066
3067		element.animate( upAnim, speed, easing );
3068	}
3069
3070	element.queue( done );
3071
3072	$.effects.unshift( element, queuelen, anims + 1 );
3073} );
3074
3075
3076/*!
3077 * jQuery UI Effects Clip 1.12.1
3078 * http://jqueryui.com
3079 *
3080 * Copyright jQuery Foundation and other contributors
3081 * Released under the MIT license.
3082 * http://jquery.org/license
3083 */
3084
3085//>>label: Clip Effect
3086//>>group: Effects
3087//>>description: Clips the element on and off like an old TV.
3088//>>docs: http://api.jqueryui.com/clip-effect/
3089//>>demos: http://jqueryui.com/effect/
3090
3091
3092
3093var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3094	var start,
3095		animate = {},
3096		element = $( this ),
3097		direction = options.direction || "vertical",
3098		both = direction === "both",
3099		horizontal = both || direction === "horizontal",
3100		vertical = both || direction === "vertical";
3101
3102	start = element.cssClip();
3103	animate.clip = {
3104		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3105		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3106		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3107		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3108	};
3109
3110	$.effects.createPlaceholder( element );
3111
3112	if ( options.mode === "show" ) {
3113		element.cssClip( animate.clip );
3114		animate.clip = start;
3115	}
3116
3117	element.animate( animate, {
3118		queue: false,
3119		duration: options.duration,
3120		easing: options.easing,
3121		complete: done
3122	} );
3123
3124} );
3125
3126
3127/*!
3128 * jQuery UI Effects Drop 1.12.1
3129 * http://jqueryui.com
3130 *
3131 * Copyright jQuery Foundation and other contributors
3132 * Released under the MIT license.
3133 * http://jquery.org/license
3134 */
3135
3136//>>label: Drop Effect
3137//>>group: Effects
3138//>>description: Moves an element in one direction and hides it at the same time.
3139//>>docs: http://api.jqueryui.com/drop-effect/
3140//>>demos: http://jqueryui.com/effect/
3141
3142
3143
3144var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3145
3146	var distance,
3147		element = $( this ),
3148		mode = options.mode,
3149		show = mode === "show",
3150		direction = options.direction || "left",
3151		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3152		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3153		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3154		animation = {
3155			opacity: 0
3156		};
3157
3158	$.effects.createPlaceholder( element );
3159
3160	distance = options.distance ||
3161		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3162
3163	animation[ ref ] = motion + distance;
3164
3165	if ( show ) {
3166		element.css( animation );
3167
3168		animation[ ref ] = oppositeMotion + distance;
3169		animation.opacity = 1;
3170	}
3171
3172	// Animate
3173	element.animate( animation, {
3174		queue: false,
3175		duration: options.duration,
3176		easing: options.easing,
3177		complete: done
3178	} );
3179} );
3180
3181
3182/*!
3183 * jQuery UI Effects Explode 1.12.1
3184 * http://jqueryui.com
3185 *
3186 * Copyright jQuery Foundation and other contributors
3187 * Released under the MIT license.
3188 * http://jquery.org/license
3189 */
3190
3191//>>label: Explode Effect
3192//>>group: Effects
3193// jscs:disable maximumLineLength
3194//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3195// jscs:enable maximumLineLength
3196//>>docs: http://api.jqueryui.com/explode-effect/
3197//>>demos: http://jqueryui.com/effect/
3198
3199
3200
3201var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3202
3203	var i, j, left, top, mx, my,
3204		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3205		cells = rows,
3206		element = $( this ),
3207		mode = options.mode,
3208		show = mode === "show",
3209
3210		// Show and then visibility:hidden the element before calculating offset
3211		offset = element.show().css( "visibility", "hidden" ).offset(),
3212
3213		// Width and height of a piece
3214		width = Math.ceil( element.outerWidth() / cells ),
3215		height = Math.ceil( element.outerHeight() / rows ),
3216		pieces = [];
3217
3218	// Children animate complete:
3219	function childComplete() {
3220		pieces.push( this );
3221		if ( pieces.length === rows * cells ) {
3222			animComplete();
3223		}
3224	}
3225
3226	// Clone the element for each row and cell.
3227	for ( i = 0; i < rows; i++ ) { // ===>
3228		top = offset.top + i * height;
3229		my = i - ( rows - 1 ) / 2;
3230
3231		for ( j = 0; j < cells; j++ ) { // |||
3232			left = offset.left + j * width;
3233			mx = j - ( cells - 1 ) / 2;
3234
3235			// Create a clone of the now hidden main element that will be absolute positioned
3236			// within a wrapper div off the -left and -top equal to size of our pieces
3237			element
3238				.clone()
3239				.appendTo( "body" )
3240				.wrap( "<div></div>" )
3241				.css( {
3242					position: "absolute",
3243					visibility: "visible",
3244					left: -j * width,
3245					top: -i * height
3246				} )
3247
3248				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3249				// where the original was located +left and +top equal to the size of pieces
3250				.parent()
3251					.addClass( "ui-effects-explode" )
3252					.css( {
3253						position: "absolute",
3254						overflow: "hidden",
3255						width: width,
3256						height: height,
3257						left: left + ( show ? mx * width : 0 ),
3258						top: top + ( show ? my * height : 0 ),
3259						opacity: show ? 0 : 1
3260					} )
3261					.animate( {
3262						left: left + ( show ? 0 : mx * width ),
3263						top: top + ( show ? 0 : my * height ),
3264						opacity: show ? 1 : 0
3265					}, options.duration || 500, options.easing, childComplete );
3266		}
3267	}
3268
3269	function animComplete() {
3270		element.css( {
3271			visibility: "visible"
3272		} );
3273		$( pieces ).remove();
3274		done();
3275	}
3276} );
3277
3278
3279/*!
3280 * jQuery UI Effects Fade 1.12.1
3281 * http://jqueryui.com
3282 *
3283 * Copyright jQuery Foundation and other contributors
3284 * Released under the MIT license.
3285 * http://jquery.org/license
3286 */
3287
3288//>>label: Fade Effect
3289//>>group: Effects
3290//>>description: Fades the element.
3291//>>docs: http://api.jqueryui.com/fade-effect/
3292//>>demos: http://jqueryui.com/effect/
3293
3294
3295
3296var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3297	var show = options.mode === "show";
3298
3299	$( this )
3300		.css( "opacity", show ? 0 : 1 )
3301		.animate( {
3302			opacity: show ? 1 : 0
3303		}, {
3304			queue: false,
3305			duration: options.duration,
3306			easing: options.easing,
3307			complete: done
3308		} );
3309} );
3310
3311
3312/*!
3313 * jQuery UI Effects Fold 1.12.1
3314 * http://jqueryui.com
3315 *
3316 * Copyright jQuery Foundation and other contributors
3317 * Released under the MIT license.
3318 * http://jquery.org/license
3319 */
3320
3321//>>label: Fold Effect
3322//>>group: Effects
3323//>>description: Folds an element first horizontally and then vertically.
3324//>>docs: http://api.jqueryui.com/fold-effect/
3325//>>demos: http://jqueryui.com/effect/
3326
3327
3328
3329var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3330
3331	// Create element
3332	var element = $( this ),
3333		mode = options.mode,
3334		show = mode === "show",
3335		hide = mode === "hide",
3336		size = options.size || 15,
3337		percent = /([0-9]+)%/.exec( size ),
3338		horizFirst = !!options.horizFirst,
3339		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3340		duration = options.duration / 2,
3341
3342		placeholder = $.effects.createPlaceholder( element ),
3343
3344		start = element.cssClip(),
3345		animation1 = { clip: $.extend( {}, start ) },
3346		animation2 = { clip: $.extend( {}, start ) },
3347
3348		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3349
3350		queuelen = element.queue().length;
3351
3352	if ( percent ) {
3353		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3354	}
3355	animation1.clip[ ref[ 0 ] ] = size;
3356	animation2.clip[ ref[ 0 ] ] = size;
3357	animation2.clip[ ref[ 1 ] ] = 0;
3358
3359	if ( show ) {
3360		element.cssClip( animation2.clip );
3361		if ( placeholder ) {
3362			placeholder.css( $.effects.clipToBox( animation2 ) );
3363		}
3364
3365		animation2.clip = start;
3366	}
3367
3368	// Animate
3369	element
3370		.queue( function( next ) {
3371			if ( placeholder ) {
3372				placeholder
3373					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3374					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3375			}
3376
3377			next();
3378		} )
3379		.animate( animation1, duration, options.easing )
3380		.animate( animation2, duration, options.easing )
3381		.queue( done );
3382
3383	$.effects.unshift( element, queuelen, 4 );
3384} );
3385
3386
3387/*!
3388 * jQuery UI Effects Highlight 1.12.1
3389 * http://jqueryui.com
3390 *
3391 * Copyright jQuery Foundation and other contributors
3392 * Released under the MIT license.
3393 * http://jquery.org/license
3394 */
3395
3396//>>label: Highlight Effect
3397//>>group: Effects
3398//>>description: Highlights the background of an element in a defined color for a custom duration.
3399//>>docs: http://api.jqueryui.com/highlight-effect/
3400//>>demos: http://jqueryui.com/effect/
3401
3402
3403
3404var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3405	var element = $( this ),
3406		animation = {
3407			backgroundColor: element.css( "backgroundColor" )
3408		};
3409
3410	if ( options.mode === "hide" ) {
3411		animation.opacity = 0;
3412	}
3413
3414	$.effects.saveStyle( element );
3415
3416	element
3417		.css( {
3418			backgroundImage: "none",
3419			backgroundColor: options.color || "#ffff99"
3420		} )
3421		.animate( animation, {
3422			queue: false,
3423			duration: options.duration,
3424			easing: options.easing,
3425			complete: done
3426		} );
3427} );
3428
3429
3430/*!
3431 * jQuery UI Effects Size 1.12.1
3432 * http://jqueryui.com
3433 *
3434 * Copyright jQuery Foundation and other contributors
3435 * Released under the MIT license.
3436 * http://jquery.org/license
3437 */
3438
3439//>>label: Size Effect
3440//>>group: Effects
3441//>>description: Resize an element to a specified width and height.
3442//>>docs: http://api.jqueryui.com/size-effect/
3443//>>demos: http://jqueryui.com/effect/
3444
3445
3446
3447var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3448
3449	// Create element
3450	var baseline, factor, temp,
3451		element = $( this ),
3452
3453		// Copy for children
3454		cProps = [ "fontSize" ],
3455		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3456		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3457
3458		// Set options
3459		mode = options.mode,
3460		restore = mode !== "effect",
3461		scale = options.scale || "both",
3462		origin = options.origin || [ "middle", "center" ],
3463		position = element.css( "position" ),
3464		pos = element.position(),
3465		original = $.effects.scaledDimensions( element ),
3466		from = options.from || original,
3467		to = options.to || $.effects.scaledDimensions( element, 0 );
3468
3469	$.effects.createPlaceholder( element );
3470
3471	if ( mode === "show" ) {
3472		temp = from;
3473		from = to;
3474		to = temp;
3475	}
3476
3477	// Set scaling factor
3478	factor = {
3479		from: {
3480			y: from.height / original.height,
3481			x: from.width / original.width
3482		},
3483		to: {
3484			y: to.height / original.height,
3485			x: to.width / original.width
3486		}
3487	};
3488
3489	// Scale the css box
3490	if ( scale === "box" || scale === "both" ) {
3491
3492		// Vertical props scaling
3493		if ( factor.from.y !== factor.to.y ) {
3494			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3495			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3496		}
3497
3498		// Horizontal props scaling
3499		if ( factor.from.x !== factor.to.x ) {
3500			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3501			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3502		}
3503	}
3504
3505	// Scale the content
3506	if ( scale === "content" || scale === "both" ) {
3507
3508		// Vertical props scaling
3509		if ( factor.from.y !== factor.to.y ) {
3510			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3511			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3512		}
3513	}
3514
3515	// Adjust the position properties based on the provided origin points
3516	if ( origin ) {
3517		baseline = $.effects.getBaseline( origin, original );
3518		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3519		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3520		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3521		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3522	}
3523	element.css( from );
3524
3525	// Animate the children if desired
3526	if ( scale === "content" || scale === "both" ) {
3527
3528		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3529		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3530
3531		// Only animate children with width attributes specified
3532		// TODO: is this right? should we include anything with css width specified as well
3533		element.find( "*[width]" ).each( function() {
3534			var child = $( this ),
3535				childOriginal = $.effects.scaledDimensions( child ),
3536				childFrom = {
3537					height: childOriginal.height * factor.from.y,
3538					width: childOriginal.width * factor.from.x,
3539					outerHeight: childOriginal.outerHeight * factor.from.y,
3540					outerWidth: childOriginal.outerWidth * factor.from.x
3541				},
3542				childTo = {
3543					height: childOriginal.height * factor.to.y,
3544					width: childOriginal.width * factor.to.x,
3545					outerHeight: childOriginal.height * factor.to.y,
3546					outerWidth: childOriginal.width * factor.to.x
3547				};
3548
3549			// Vertical props scaling
3550			if ( factor.from.y !== factor.to.y ) {
3551				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3552				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3553			}
3554
3555			// Horizontal props scaling
3556			if ( factor.from.x !== factor.to.x ) {
3557				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3558				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3559			}
3560
3561			if ( restore ) {
3562				$.effects.saveStyle( child );
3563			}
3564
3565			// Animate children
3566			child.css( childFrom );
3567			child.animate( childTo, options.duration, options.easing, function() {
3568
3569				// Restore children
3570				if ( restore ) {
3571					$.effects.restoreStyle( child );
3572				}
3573			} );
3574		} );
3575	}
3576
3577	// Animate
3578	element.animate( to, {
3579		queue: false,
3580		duration: options.duration,
3581		easing: options.easing,
3582		complete: function() {
3583
3584			var offset = element.offset();
3585
3586			if ( to.opacity === 0 ) {
3587				element.css( "opacity", from.opacity );
3588			}
3589
3590			if ( !restore ) {
3591				element
3592					.css( "position", position === "static" ? "relative" : position )
3593					.offset( offset );
3594
3595				// Need to save style here so that automatic style restoration
3596				// doesn't restore to the original styles from before the animation.
3597				$.effects.saveStyle( element );
3598			}
3599
3600			done();
3601		}
3602	} );
3603
3604} );
3605
3606
3607/*!
3608 * jQuery UI Effects Scale 1.12.1
3609 * http://jqueryui.com
3610 *
3611 * Copyright jQuery Foundation and other contributors
3612 * Released under the MIT license.
3613 * http://jquery.org/license
3614 */
3615
3616//>>label: Scale Effect
3617//>>group: Effects
3618//>>description: Grows or shrinks an element and its content.
3619//>>docs: http://api.jqueryui.com/scale-effect/
3620//>>demos: http://jqueryui.com/effect/
3621
3622
3623
3624var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3625
3626	// Create element
3627	var el = $( this ),
3628		mode = options.mode,
3629		percent = parseInt( options.percent, 10 ) ||
3630			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3631
3632		newOptions = $.extend( true, {
3633			from: $.effects.scaledDimensions( el ),
3634			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3635			origin: options.origin || [ "middle", "center" ]
3636		}, options );
3637
3638	// Fade option to support puff
3639	if ( options.fade ) {
3640		newOptions.from.opacity = 1;
3641		newOptions.to.opacity = 0;
3642	}
3643
3644	$.effects.effect.size.call( this, newOptions, done );
3645} );
3646
3647
3648/*!
3649 * jQuery UI Effects Puff 1.12.1
3650 * http://jqueryui.com
3651 *
3652 * Copyright jQuery Foundation and other contributors
3653 * Released under the MIT license.
3654 * http://jquery.org/license
3655 */
3656
3657//>>label: Puff Effect
3658//>>group: Effects
3659//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3660//>>docs: http://api.jqueryui.com/puff-effect/
3661//>>demos: http://jqueryui.com/effect/
3662
3663
3664
3665var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3666	var newOptions = $.extend( true, {}, options, {
3667		fade: true,
3668		percent: parseInt( options.percent, 10 ) || 150
3669	} );
3670
3671	$.effects.effect.scale.call( this, newOptions, done );
3672} );
3673
3674
3675/*!
3676 * jQuery UI Effects Pulsate 1.12.1
3677 * http://jqueryui.com
3678 *
3679 * Copyright jQuery Foundation and other contributors
3680 * Released under the MIT license.
3681 * http://jquery.org/license
3682 */
3683
3684//>>label: Pulsate Effect
3685//>>group: Effects
3686//>>description: Pulsates an element n times by changing the opacity to zero and back.
3687//>>docs: http://api.jqueryui.com/pulsate-effect/
3688//>>demos: http://jqueryui.com/effect/
3689
3690
3691
3692var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3693	var element = $( this ),
3694		mode = options.mode,
3695		show = mode === "show",
3696		hide = mode === "hide",
3697		showhide = show || hide,
3698
3699		// Showing or hiding leaves off the "last" animation
3700		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3701		duration = options.duration / anims,
3702		animateTo = 0,
3703		i = 1,
3704		queuelen = element.queue().length;
3705
3706	if ( show || !element.is( ":visible" ) ) {
3707		element.css( "opacity", 0 ).show();
3708		animateTo = 1;
3709	}
3710
3711	// Anims - 1 opacity "toggles"
3712	for ( ; i < anims; i++ ) {
3713		element.animate( { opacity: animateTo }, duration, options.easing );
3714		animateTo = 1 - animateTo;
3715	}
3716
3717	element.animate( { opacity: animateTo }, duration, options.easing );
3718
3719	element.queue( done );
3720
3721	$.effects.unshift( element, queuelen, anims + 1 );
3722} );
3723
3724
3725/*!
3726 * jQuery UI Effects Shake 1.12.1
3727 * http://jqueryui.com
3728 *
3729 * Copyright jQuery Foundation and other contributors
3730 * Released under the MIT license.
3731 * http://jquery.org/license
3732 */
3733
3734//>>label: Shake Effect
3735//>>group: Effects
3736//>>description: Shakes an element horizontally or vertically n times.
3737//>>docs: http://api.jqueryui.com/shake-effect/
3738//>>demos: http://jqueryui.com/effect/
3739
3740
3741
3742var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3743
3744	var i = 1,
3745		element = $( this ),
3746		direction = options.direction || "left",
3747		distance = options.distance || 20,
3748		times = options.times || 3,
3749		anims = times * 2 + 1,
3750		speed = Math.round( options.duration / anims ),
3751		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3752		positiveMotion = ( direction === "up" || direction === "left" ),
3753		animation = {},
3754		animation1 = {},
3755		animation2 = {},
3756
3757		queuelen = element.queue().length;
3758
3759	$.effects.createPlaceholder( element );
3760
3761	// Animation
3762	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3763	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3764	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3765
3766	// Animate
3767	element.animate( animation, speed, options.easing );
3768
3769	// Shakes
3770	for ( ; i < times; i++ ) {
3771		element
3772			.animate( animation1, speed, options.easing )
3773			.animate( animation2, speed, options.easing );
3774	}
3775
3776	element
3777		.animate( animation1, speed, options.easing )
3778		.animate( animation, speed / 2, options.easing )
3779		.queue( done );
3780
3781	$.effects.unshift( element, queuelen, anims + 1 );
3782} );
3783
3784
3785/*!
3786 * jQuery UI Effects Slide 1.12.1
3787 * http://jqueryui.com
3788 *
3789 * Copyright jQuery Foundation and other contributors
3790 * Released under the MIT license.
3791 * http://jquery.org/license
3792 */
3793
3794//>>label: Slide Effect
3795//>>group: Effects
3796//>>description: Slides an element in and out of the viewport.
3797//>>docs: http://api.jqueryui.com/slide-effect/
3798//>>demos: http://jqueryui.com/effect/
3799
3800
3801
3802var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3803	var startClip, startRef,
3804		element = $( this ),
3805		map = {
3806			up: [ "bottom", "top" ],
3807			down: [ "top", "bottom" ],
3808			left: [ "right", "left" ],
3809			right: [ "left", "right" ]
3810		},
3811		mode = options.mode,
3812		direction = options.direction || "left",
3813		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3814		positiveMotion = ( direction === "up" || direction === "left" ),
3815		distance = options.distance ||
3816			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3817		animation = {};
3818
3819	$.effects.createPlaceholder( element );
3820
3821	startClip = element.cssClip();
3822	startRef = element.position()[ ref ];
3823
3824	// Define hide animation
3825	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3826	animation.clip = element.cssClip();
3827	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3828
3829	// Reverse the animation if we're showing
3830	if ( mode === "show" ) {
3831		element.cssClip( animation.clip );
3832		element.css( ref, animation[ ref ] );
3833		animation.clip = startClip;
3834		animation[ ref ] = startRef;
3835	}
3836
3837	// Actually animate
3838	element.animate( animation, {
3839		queue: false,
3840		duration: options.duration,
3841		easing: options.easing,
vendor: 4,900 bytes, lines 3842-4037
3842		complete: done
3843	} );
3844} );
3845
3846
3847/*!
3848 * jQuery UI Effects Transfer 1.12.1
3849 * http://jqueryui.com
3850 *
3851 * Copyright jQuery Foundation and other contributors
3852 * Released under the MIT license.
3853 * http://jquery.org/license
3854 */
3855
3856//>>label: Transfer Effect
3857//>>group: Effects
3858//>>description: Displays a transfer effect from one element to another.
3859//>>docs: http://api.jqueryui.com/transfer-effect/
3860//>>demos: http://jqueryui.com/effect/
3861
3862
3863
3864var effect;
3865if ( $.uiBackCompat !== false ) {
3866	effect = $.effects.define( "transfer", function( options, done ) {
3867		$( this ).transfer( options, done );
3868	} );
3869}
3870var effectsEffectTransfer = effect;
3871
3872
3873/*!
3874 * jQuery UI Focusable 1.12.1
3875 * http://jqueryui.com
3876 *
3877 * Copyright jQuery Foundation and other contributors
3878 * Released under the MIT license.
3879 * http://jquery.org/license
3880 */
3881
3882//>>label: :focusable Selector
3883//>>group: Core
3884//>>description: Selects elements which can be focused.
3885//>>docs: http://api.jqueryui.com/focusable-selector/
3886
3887
3888
3889// Selectors
3890$.ui.focusable = function( element, hasTabindex ) {
3891	var map, mapName, img, focusableIfVisible, fieldset,
3892		nodeName = element.nodeName.toLowerCase();
3893
3894	if ( "area" === nodeName ) {
3895		map = element.parentNode;
3896		mapName = map.name;
3897		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3898			return false;
3899		}
3900		img = $( "img[usemap='#" + mapName + "']" );
3901		return img.length > 0 && img.is( ":visible" );
3902	}
3903
3904	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3905		focusableIfVisible = !element.disabled;
3906
3907		if ( focusableIfVisible ) {
3908
3909			// Form controls within a disabled fieldset are disabled.
3910			// However, controls within the fieldset's legend do not get disabled.
3911			// Since controls generally aren't placed inside legends, we skip
3912			// this portion of the check.
3913			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3914			if ( fieldset ) {
3915				focusableIfVisible = !fieldset.disabled;
3916			}
3917		}
3918	} else if ( "a" === nodeName ) {
3919		focusableIfVisible = element.href || hasTabindex;
3920	} else {
3921		focusableIfVisible = hasTabindex;
3922	}
3923
3924	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3925};
3926
3927// Support: IE 8 only
3928// IE 8 doesn't resolve inherit to visible/hidden for computed values
3929function visible( element ) {
3930	var visibility = element.css( "visibility" );
3931	while ( visibility === "inherit" ) {
3932		element = element.parent();
3933		visibility = element.css( "visibility" );
3934	}
3935	return visibility !== "hidden";
3936}
3937
3938$.extend( $.expr[ ":" ], {
3939	focusable: function( element ) {
3940		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3941	}
3942} );
3943
3944var focusable = $.ui.focusable;
3945
3946
3947
3948
3949// Support: IE8 Only
3950// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3951// with a string, so we need to find the proper form.
3952var form = $.fn.form = function() {
3953	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3954};
3955
3956
3957/*!
3958 * jQuery UI Form Reset Mixin 1.12.1
3959 * http://jqueryui.com
3960 *
3961 * Copyright jQuery Foundation and other contributors
3962 * Released under the MIT license.
3963 * http://jquery.org/license
3964 */
3965
3966//>>label: Form Reset Mixin
3967//>>group: Core
3968//>>description: Refresh input widgets when their form is reset
3969//>>docs: http://api.jqueryui.com/form-reset-mixin/
3970
3971
3972
3973var formResetMixin = $.ui.formResetMixin = {
3974	_formResetHandler: function() {
3975		var form = $( this );
3976
3977		// Wait for the form reset to actually happen before refreshing
3978		setTimeout( function() {
3979			var instances = form.data( "ui-form-reset-instances" );
3980			$.each( instances, function() {
3981				this.refresh();
3982			} );
3983		} );
3984	},
3985
3986	_bindFormResetHandler: function() {
3987		this.form = this.element.form();
3988		if ( !this.form.length ) {
3989			return;
3990		}
3991
3992		var instances = this.form.data( "ui-form-reset-instances" ) || [];
3993		if ( !instances.length ) {
3994
3995			// We don't use _on() here because we use a single event handler per form
3996			this.form.on( "reset.ui-form-reset", this._formResetHandler );
3997		}
3998		instances.push( this );
3999		this.form.data( "ui-form-reset-instances", instances );
4000	},
4001
4002	_unbindFormResetHandler: function() {
4003		if ( !this.form.length ) {
4004			return;
4005		}
4006
4007		var instances = this.form.data( "ui-form-reset-instances" );
4008		instances.splice( $.inArray( this, instances ), 1 );
4009		if ( instances.length ) {
4010			this.form.data( "ui-form-reset-instances", instances );
4011		} else {
4012			this.form
4013				.removeData( "ui-form-reset-instances" )
4014				.off( "reset.ui-form-reset" );
4015		}
4016	}
4017};
4018
4019
4020/*!
4021 * jQuery UI Support for jQuery core 1.7.x 1.12.1
4022 * http://jqueryui.com
4023 *
4024 * Copyright jQuery Foundation and other contributors
4025 * Released under the MIT license.
4026 * http://jquery.org/license
4027 *
4028 */
4029
4030//>>label: jQuery 1.7 Support
4031//>>group: Core
4032//>>description: Support version 1.7.x of jQuery core
4033
4034
4035
4036// Support: jQuery 1.7 only
4037// Not a great way to check versions, but since we only support 
40371.7+ and only
4038// need to detect <1.8, this is a simple check that should suffice. Checking
4039// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4040// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4041// 1.7 anymore). See #11197 for why we're not using feature detection.
4042if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4043
4044	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4045	// Unlike jQuery Core 1.8+, these only support numeric values to set the
4046	// dimensions in pixels
4047	$.each( [ "Width", "Height" ], function( i, name ) {
4048		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4049			type = name.toLowerCase(),
4050			orig = {
4051				innerWidth: $.fn.innerWidth,
4052				innerHeight: $.fn.innerHeight,
4053				outerWidth: $.fn.outerWidth,
4054				outerHeight: $.fn.outerHeight
4055			};
4056
4057		function reduce( elem, size, border, margin ) {
4058			$.each( side, function() {
4059				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4060				if ( border ) {
4061					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4062				}
4063				if ( margin ) {
4064					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4065				}
4066			} );
4067			return size;
4068		}
4069
4070		$.fn[ "inner" + name ] = function( size ) {
4071			if ( size === undefined ) {
4072				return orig[ "inner" + name ].call( this );
4073			}
4074
4075			return this.each( function() {
4076				$( this ).css( type, reduce( this, size ) + "px" );
4077			} );
4078		};
4079
4080		$.fn[ "outer" + name ] = function( size, margin ) {
4081			if ( typeof size !== "number" ) {
4082				return orig[ "outer" + name ].call( this, size );
4083			}
4084
4085			return this.each( function() {
4086				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4087			} );
4088		};
4089	} );
4090
4091	$.fn.addBack = function( selector ) {
4092		return this.add( selector == null ?
4093			this.prevObject : this.prevObject.filter( selector )
4094		);
4095	};
4096}
4097
4098;
4099/*!
4100 * jQuery UI Keycode 1.12.1
4101 * http://jqueryui.com
4102 *
4103 * Copyright jQuery Foundation and other contributors
4104 * Released under the MIT license.
4105 * http://jquery.org/license
4106 */
4107
4108//>>label: Keycode
4109//>>group: Core
4110//>>description: Provide keycodes as keynames
4111//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4112
4113
4114var keycode = $.ui.keyCode = {
4115	BACKSPACE: 8,
4116	COMMA: 188,
4117	DELETE: 46,
4118	DOWN: 40,
4119	END: 35,
4120	ENTER: 13,
4121	ESCAPE: 27,
4122	HOME: 36,
4123	LEFT: 37,
4124	PAGE_DOWN: 34,
4125	PAGE_UP: 33,
4126	PERIOD: 190,
4127	RIGHT: 39,
4128	SPACE: 32,
4129	TAB: 9,
4130	UP: 38
4131};
4132
4133
4134
4135
4136// Internal use only
4137var escapeSelector = $.ui.escapeSelector = ( function() {
4138	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4139	return function( selector ) {
4140		return selector.replace( selectorEscape, "\\$1" );
4141	};
4142} )();
4143
4144
4145/*!
4146 * jQuery UI Labels 1.12.1
4147 * http://jqueryui.com
4148 *
4149 * Copyright jQuery Foundation and other contributors
4150 * Released under the MIT license.
4151 * http://jquery.org/license
4152 */
4153
4154//>>label: labels
4155//>>group: Core
4156//>>description: Find all the labels associated with a given input
4157//>>docs: http://api.jqueryui.com/labels/
4158
4159
4160
4161var labels = $.fn.labels = function() {
4162	var ancestor, selector, id, labels, ancestors;
4163
4164	// Check control.labels first
4165	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4166		return this.pushStack( this[ 0 ].labels );
4167	}
4168
4169	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4170	// Above browsers do not support control.labels. Everything below is to support them
4171	// as well as document fragments. control.labels does not work on document fragments
4172	labels = this.eq( 0 ).parents( "label" );
4173
4174	// Look for the label based on the id
4175	id = this.attr( "id" );
4176	if ( id ) {
4177
4178		// We don't search against the document in case the element
4179		// is disconnected from the DOM
4180		ancestor = this.eq( 0 ).parents().last();
4181
4182		// Get a full set of top level ancestors
4183		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4184
4185		// Create a selector for the label based on the id
4186		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4187
4188		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4189
4190	}
4191
4192	// Return whatever we have found for labels
4193	return this.pushStack( labels );
4194};
4195
4196
4197/*!
4198 * jQuery UI Scroll Parent 1.12.1
4199 * http://jqueryui.com
4200 *
4201 * Copyright jQuery Foundation and other contributors
4202 * Released under the MIT license.
4203 * http://jquery.org/license
4204 */
4205
4206//>>label: scrollParent
4207//>>group: Core
4208//>>description: Get the closest ancestor element that is scrollable.
4209//>>docs: http://api.jqueryui.com/scrollParent/
4210
4211
4212
4213var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4214	var position = this.css( "position" ),
4215		excludeStaticParent = position === "absolute",
4216		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4217		scrollParent = this.parents().filter( function() {
4218			var parent = $( this );
4219			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4220				return false;
vendor: 5,582 bytes, lines 4221-4464
4221			}
4222			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4223				parent.css( "overflow-x" ) );
4224		} ).eq( 0 );
4225
4226	return position === "fixed" || !scrollParent.length ?
4227		$( this[ 0 ].ownerDocument || document ) :
4228		scrollParent;
4229};
4230
4231
4232/*!
4233 * jQuery UI Tabbable 1.12.1
4234 * http://jqueryui.com
4235 *
4236 * Copyright jQuery Foundation and other contributors
4237 * Released under the MIT license.
4238 * http://jquery.org/license
4239 */
4240
4241//>>label: :tabbable Selector
4242//>>group: Core
4243//>>description: Selects elements which can be tabbed to.
4244//>>docs: http://api.jqueryui.com/tabbable-selector/
4245
4246
4247
4248var tabbable = $.extend( $.expr[ ":" ], {
4249	tabbable: function( element ) {
4250		var tabIndex = $.attr( element, "tabindex" ),
4251			hasTabindex = tabIndex != null;
4252		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4253	}
4254} );
4255
4256
4257/*!
4258 * jQuery UI Unique ID 1.12.1
4259 * http://jqueryui.com
4260 *
4261 * Copyright jQuery Foundation and other contributors
4262 * Released under the MIT license.
4263 * http://jquery.org/license
4264 */
4265
4266//>>label: uniqueId
4267//>>group: Core
4268//>>description: Functions to generate and remove uniqueId's
4269//>>docs: http://api.jqueryui.com/uniqueId/
4270
4271
4272
4273var uniqueId = $.fn.extend( {
4274	uniqueId: ( function() {
4275		var uuid = 0;
4276
4277		return function() {
4278			return this.each( function() {
4279				if ( !this.id ) {
4280					this.id = "ui-id-" + ( ++uuid );
4281				}
4282			} );
4283		};
4284	} )(),
4285
4286	removeUniqueId: function() {
4287		return this.each( function() {
4288			if ( /^ui-id-\d+$/.test( this.id ) ) {
4289				$( this ).removeAttr( "id" );
4290			}
4291		} );
4292	}
4293} );
4294
4295
4296/*!
4297 * jQuery UI Accordion 1.12.1
4298 * http://jqueryui.com
4299 *
4300 * Copyright jQuery Foundation and other contributors
4301 * Released under the MIT license.
4302 * http://jquery.org/license
4303 */
4304
4305//>>label: Accordion
4306//>>group: Widgets
4307// jscs:disable maximumLineLength
4308//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4309// jscs:enable maximumLineLength
4310//>>docs: http://api.jqueryui.com/accordion/
4311//>>demos: http://jqueryui.com/accordion/
4312//>>css.structure: ../../themes/base/core.css
4313//>>css.structure: ../../themes/base/accordion.css
4314//>>css.theme: ../../themes/base/theme.css
4315
4316
4317
4318var widgetsAccordion = $.widget( "ui.accordion", {
4319	version: "1.12.1",
4320	options: {
4321		active: 0,
4322		animate: {},
4323		classes: {
4324			"ui-accordion-header": "ui-corner-top",
4325			"ui-accordion-header-collapsed": "ui-corner-all",
4326			"ui-accordion-content": "ui-corner-bottom"
4327		},
4328		collapsible: false,
4329		event: "click",
4330		header: "> li > :first-child, > :not(li):even",
4331		heightStyle: "auto",
4332		icons: {
4333			activeHeader: "ui-icon-triangle-1-s",
4334			header: "ui-icon-triangle-1-e"
4335		},
4336
4337		// Callbacks
4338		activate: null,
4339		beforeActivate: null
4340	},
4341
4342	hideProps: {
4343		borderTopWidth: "hide",
4344		borderBottomWidth: "hide",
4345		paddingTop: "hide",
4346		paddingBottom: "hide",
4347		height: "hide"
4348	},
4349
4350	showProps: {
4351		borderTopWidth: "show",
4352		borderBottomWidth: "show",
4353		paddingTop: "show",
4354		paddingBottom: "show",
4355		height: "show"
4356	},
4357
4358	_create: function() {
4359		var options = this.options;
4360
4361		this.prevShow = this.prevHide = $();
4362		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4363		this.element.attr( "role", "tablist" );
4364
4365		// Don't allow collapsible: false and active: false / null
4366		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4367			options.active = 0;
4368		}
4369
4370		this._processPanels();
4371
4372		// handle negative values
4373		if ( options.active < 0 ) {
4374			options.active += this.headers.length;
4375		}
4376		this._refresh();
4377	},
4378
4379	_getCreateEventData: function() {
4380		return {
4381			header: this.active,
4382			panel: !this.active.length ? $() : this.active.next()
4383		};
4384	},
4385
4386	_createIcons: function() {
4387		var icon, children,
4388			icons = this.options.icons;
4389
4390		if ( icons ) {
4391			icon = $( "<span>" );
4392			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4393			icon.prependTo( this.headers );
4394			children = this.active.children( ".ui-accordion-header-icon" );
4395			this._removeClass( children, icons.header )
4396				._addClass( children, null, icons.activeHeader )
4397				._addClass( this.headers, "ui-accordion-icons" );
4398		}
4399	},
4400
4401	_destroyIcons: function() {
4402		this._removeClass( this.headers, "ui-accordion-icons" );
4403		this.headers.children( ".ui-accordion-header-icon" ).remove();
4404	},
4405
4406	_destroy: function() {
4407		var contents;
4408
4409		// Clean up main element
4410		this.element.removeAttr( "role" );
4411
4412		// Clean up headers
4413		this.headers
4414			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4415			.removeUniqueId();
4416
4417		this._destroyIcons();
4418
4419		// Clean up content panels
4420		contents = this.headers.next()
4421			.css( "display", "" )
4422			.removeAttr( "role aria-hidden aria-labelledby" )
4423			.removeUniqueId();
4424
4425		if ( this.options.heightStyle !== "content" ) {
4426			contents.css( "height", "" );
4427		}
4428	},
4429
4430	_setOption: function( key, value ) {
4431		if ( key === "active" ) {
4432
4433			// _activate() will handle invalid values and update this.options
4434			this._activate( value );
4435			return;
4436		}
4437
4438		if ( key === "event" ) {
4439			if ( this.options.event ) {
4440				this._off( this.headers, this.options.event );
4441			}
4442			this._setupEvents( value );
4443		}
4444
4445		this._super( key, value );
4446
4447		// Setting collapsible: false while collapsed; open first panel
4448		if ( key === "collapsible" && !value && this.options.active === false ) {
4449			this._activate( 0 );
4450		}
4451
4452		if ( key === "icons" ) {
4453			this._destroyIcons();
4454			if ( value ) {
4455				this._createIcons();
4456			}
4457		}
4458	},
4459
4460	_setOptionDisabled: function( value ) {
4461		this._super( value );
4462
4463		this.element.attr( "aria-disabled", value );
4464
vendor: 16,234 bytes, lines 4465-5064
4465		// Support: IE8 Only
4466		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4467		// so we need to add the disabled class to the headers and panels
4468		this._toggleClass( null, "ui-state-disabled", !!value );
4469		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4470			!!value );
4471	},
4472
4473	_keydown: function( event ) {
4474		if ( event.altKey || event.ctrlKey ) {
4475			return;
4476		}
4477
4478		var keyCode = $.ui.keyCode,
4479			length = this.headers.length,
4480			currentIndex = this.headers.index( event.target ),
4481			toFocus = false;
4482
4483		switch ( event.keyCode ) {
4484		case keyCode.RIGHT:
4485		case keyCode.DOWN:
4486			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4487			break;
4488		case keyCode.LEFT:
4489		case keyCode.UP:
4490			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4491			break;
4492		case keyCode.SPACE:
4493		case keyCode.ENTER:
4494			this._eventHandler( event );
4495			break;
4496		case keyCode.HOME:
4497			toFocus = this.headers[ 0 ];
4498			break;
4499		case keyCode.END:
4500			toFocus = this.headers[ length - 1 ];
4501			break;
4502		}
4503
4504		if ( toFocus ) {
4505			$( event.target ).attr( "tabIndex", -1 );
4506			$( toFocus ).attr( "tabIndex", 0 );
4507			$( toFocus ).trigger( "focus" );
4508			event.preventDefault();
4509		}
4510	},
4511
4512	_panelKeyDown: function( event ) {
4513		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4514			$( event.currentTarget ).prev().trigger( "focus" );
4515		}
4516	},
4517
4518	refresh: function() {
4519		var options = this.options;
4520		this._processPanels();
4521
4522		// Was collapsed or no panel
4523		if ( ( options.active === false && options.collapsible === true ) ||
4524				!this.headers.length ) {
4525			options.active = false;
4526			this.active = $();
4527
4528		// active false only when collapsible is true
4529		} else if ( options.active === false ) {
4530			this._activate( 0 );
4531
4532		// was active, but active panel is gone
4533		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4534
4535			// all remaining panel are disabled
4536			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4537				options.active = false;
4538				this.active = $();
4539
4540			// activate previous panel
4541			} else {
4542				this._activate( Math.max( 0, options.active - 1 ) );
4543			}
4544
4545		// was active, active panel still exists
4546		} else {
4547
4548			// make sure active index is correct
4549			options.active = this.headers.index( this.active );
4550		}
4551
4552		this._destroyIcons();
4553
4554		this._refresh();
4555	},
4556
4557	_processPanels: function() {
4558		var prevHeaders = this.headers,
4559			prevPanels = this.panels;
4560
4561		this.headers = this.element.find( this.options.header );
4562		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4563			"ui-state-default" );
4564
4565		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4566		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4567
4568		// Avoid memory leaks (#10056)
4569		if ( prevPanels ) {
4570			this._off( prevHeaders.not( this.headers ) );
4571			this._off( prevPanels.not( this.panels ) );
4572		}
4573	},
4574
4575	_refresh: function() {
4576		var maxHeight,
4577			options = this.options,
4578			heightStyle = options.heightStyle,
4579			parent = this.element.parent();
4580
4581		this.active = this._findActive( options.active );
4582		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4583			._removeClass( this.active, "ui-accordion-header-collapsed" );
4584		this._addClass( this.active.next(), "ui-accordion-content-active" );
4585		this.active.next().show();
4586
4587		this.headers
4588			.attr( "role", "tab" )
4589			.each( function() {
4590				var header = $( this ),
4591					headerId = header.uniqueId().attr( "id" ),
4592					panel = header.next(),
4593					panelId = panel.uniqueId().attr( "id" );
4594				header.attr( "aria-controls", panelId );
4595				panel.attr( "aria-labelledby", headerId );
4596			} )
4597			.next()
4598				.attr( "role", "tabpanel" );
4599
4600		this.headers
4601			.not( this.active )
4602				.attr( {
4603					"aria-selected": "false",
4604					"aria-expanded": "false",
4605					tabIndex: -1
4606				} )
4607				.next()
4608					.attr( {
4609						"aria-hidden": "true"
4610					} )
4611					.hide();
4612
4613		// Make sure at least one header is in the tab order
4614		if ( !this.active.length ) {
4615			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4616		} else {
4617			this.active.attr( {
4618				"aria-selected": "true",
4619				"aria-expanded": "true",
4620				tabIndex: 0
4621			} )
4622				.next()
4623					.attr( {
4624						"aria-hidden": "false"
4625					} );
4626		}
4627
4628		this._createIcons();
4629
4630		this._setupEvents( options.event );
4631
4632		if ( heightStyle === "fill" ) {
4633			maxHeight = parent.height();
4634			this.element.siblings( ":visible" ).each( function() {
4635				var elem = $( this ),
4636					position = elem.css( "position" );
4637
4638				if ( position === "absolute" || position === "fixed" ) {
4639					return;
4640				}
4641				maxHeight -= elem.outerHeight( true );
4642			} );
4643
4644			this.headers.each( function() {
4645				maxHeight -= $( this ).outerHeight( true );
4646			} );
4647
4648			this.headers.next()
4649				.each( function() {
4650					$( this ).height( Math.max( 0, maxHeight -
4651						$( this ).innerHeight() + $( this ).height() ) );
4652				} )
4653				.css( "overflow", "auto" );
4654		} else if ( heightStyle === "auto" ) {
4655			maxHeight = 0;
4656			this.headers.next()
4657				.each( function() {
4658					var isVisible = $( this ).is( ":visible" );
4659					if ( !isVisible ) {
4660						$( this ).show();
4661					}
4662					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4663					if ( !isVisible ) {
4664						$( this ).hide();
4665					}
4666				} )
4667				.height( maxHeight );
4668		}
4669	},
4670
4671	_activate: function( index ) {
4672		var active = this._findActive( index )[ 0 ];
4673
4674		// Trying to activate the already active panel
4675		if ( active === this.active[ 0 ] ) {
4676			return;
4677		}
4678
4679		// Trying to collapse, simulate a click on the currently active header
4680		active = active || this.active[ 0 ];
4681
4682		this._eventHandler( {
4683			target: active,
4684			currentTarget: active,
4685			preventDefault: $.noop
4686		} );
4687	},
4688
4689	_findActive: function( selector ) {
4690		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4691	},
4692
4693	_setupEvents: function( event ) {
4694		var events = {
4695			keydown: "_keydown"
4696		};
4697		if ( event ) {
4698			$.each( event.split( " " ), function( index, eventName ) {
4699				events[ eventName ] = "_eventHandler";
4700			} );
4701		}
4702
4703		this._off( this.headers.add( this.headers.next() ) );
4704		this._on( this.headers, events );
4705		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4706		this._hoverable( this.headers );
4707		this._focusable( this.headers );
4708	},
4709
4710	_eventHandler: function( event ) {
4711		var activeChildren, clickedChildren,
4712			options = this.options,
4713			active = this.active,
4714			clicked = $( event.currentTarget ),
4715			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4716			collapsing = clickedIsActive && options.collapsible,
4717			toShow = collapsing ? $() : clicked.next(),
4718			toHide = active.next(),
4719			eventData = {
4720				oldHeader: active,
4721				oldPanel: toHide,
4722				newHeader: collapsing ? $() : clicked,
4723				newPanel: toShow
4724			};
4725
4726		event.preventDefault();
4727
4728		if (
4729
4730				// click on active header, but not collapsible
4731				( clickedIsActive && !options.collapsible ) ||
4732
4733				// allow canceling activation
4734				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4735			return;
4736		}
4737
4738		options.active = collapsing ? false : this.headers.index( clicked );
4739
4740		// When the call to ._toggle() comes after the class changes
4741		// it causes a very odd bug in IE 8 (see #6720)
4742		this.active = clickedIsActive ? $() : clicked;
4743		this._toggle( eventData );
4744
4745		// Switch classes
4746		// corner classes on the previously active header stay after the animation
4747		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4748		if ( options.icons ) {
4749			activeChildren = active.children( ".ui-accordion-header-icon" );
4750			this._removeClass( activeChildren, null, options.icons.activeHeader )
4751				._addClass( activeChildren, null, options.icons.header );
4752		}
4753
4754		if ( !clickedIsActive ) {
4755			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4756				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4757			if ( options.icons ) {
4758				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4759				this._removeClass( clickedChildren, null, options.icons.header )
4760					._addClass( clickedChildren, null, options.icons.activeHeader );
4761			}
4762
4763			this._addClass( clicked.next(), "ui-accordion-content-active" );
4764		}
4765	},
4766
4767	_toggle: function( data ) {
4768		var toShow = data.newPanel,
4769			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4770
4771		// Handle activating a panel during the animation for another activation
4772		this.prevShow.add( this.prevHide ).stop( true, true );
4773		this.prevShow = toShow;
4774		this.prevHide = toHide;
4775
4776		if ( this.options.animate ) {
4777			this._animate( toShow, toHide, data );
4778		} else {
4779			toHide.hide();
4780			toShow.show();
4781			this._toggleComplete( data );
4782		}
4783
4784		toHide.attr( {
4785			"aria-hidden": "true"
4786		} );
4787		toHide.prev().attr( {
4788			"aria-selected": "false",
4789			"aria-expanded": "false"
4790		} );
4791
4792		// if we're switching panels, remove the old header from the tab order
4793		// if we're opening from collapsed state, remove the previous header from the tab order
4794		// if we're collapsing, then keep the collapsing header in the tab order
4795		if ( toShow.length && toHide.length ) {
4796			toHide.prev().attr( {
4797				"tabIndex": -1,
4798				"aria-expanded": "false"
4799			} );
4800		} else if ( toShow.length ) {
4801			this.headers.filter( function() {
4802				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4803			} )
4804				.attr( "tabIndex", -1 );
4805		}
4806
4807		toShow
4808			.attr( "aria-hidden", "false" )
4809			.prev()
4810				.attr( {
4811					"aria-selected": "true",
4812					"aria-expanded": "true",
4813					tabIndex: 0
4814				} );
4815	},
4816
4817	_animate: function( toShow, toHide, data ) {
4818		var total, easing, duration,
4819			that = this,
4820			adjust = 0,
4821			boxSizing = toShow.css( "box-sizing" ),
4822			down = toShow.length &&
4823				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4824			animate = this.options.animate || {},
4825			options = down && animate.down || animate,
4826			complete = function() {
4827				that._toggleComplete( data );
4828			};
4829
4830		if ( typeof options === "number" ) {
4831			duration = options;
4832		}
4833		if ( typeof options === "string" ) {
4834			easing = options;
4835		}
4836
4837		// fall back from options to animation in case of partial down settings
4838		easing = easing || options.easing || animate.easing;
4839		duration = duration || options.duration || animate.duration;
4840
4841		if ( !toHide.length ) {
4842			return toShow.animate( this.showProps, duration, easing, complete );
4843		}
4844		if ( !toShow.length ) {
4845			return toHide.animate( this.hideProps, duration, easing, complete );
4846		}
4847
4848		total = toShow.show().outerHeight();
4849		toHide.animate( this.hideProps, {
4850			duration: duration,
4851			easing: easing,
4852			step: function( now, fx ) {
4853				fx.now = Math.round( now );
4854			}
4855		} );
4856		toShow
4857			.hide()
4858			.animate( this.showProps, {
4859				duration: duration,
4860				easing: easing,
4861				complete: complete,
4862				step: function( now, fx ) {
4863					fx.now = Math.round( now );
4864					if ( fx.prop !== "height" ) {
4865						if ( boxSizing === "content-box" ) {
4866							adjust += fx.now;
4867						}
4868					} else if ( that.options.heightStyle !== "content" ) {
4869						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4870						adjust = 0;
4871					}
4872				}
4873			} );
4874	},
4875
4876	_toggleComplete: function( data ) {
4877		var toHide = data.oldPanel,
4878			prev = toHide.prev();
4879
4880		this._removeClass( toHide, "ui-accordion-content-active" );
4881		this._removeClass( prev, "ui-accordion-header-active" )
4882			._addClass( prev, "ui-accordion-header-collapsed" );
4883
4884		// Work around for rendering bug in IE (#5421)
4885		if ( toHide.length ) {
4886			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4887		}
4888		this._trigger( "activate", null, data );
4889	}
4890} );
4891
4892
4893
4894var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4895	var activeElement;
4896
4897	// Support: IE 9 only
4898	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4899	try {
4900		activeElement = document.activeElement;
4901	} catch ( error ) {
4902		activeElement = document.body;
4903	}
4904
4905	// Support: IE 9 - 11 only
4906	// IE may return null instead of an element
4907	// Interestingly, this only seems to occur when NOT in an iframe
4908	if ( !activeElement ) {
4909		activeElement = document.body;
4910	}
4911
4912	// Support: IE 11 only
4913	// IE11 returns a seemingly empty object in some cases when accessing
4914	// document.activeElement from an <iframe>
4915	if ( !activeElement.nodeName ) {
4916		activeElement = document.body;
4917	}
4918
4919	return activeElement;
4920};
4921
4922
4923/*!
4924 * jQuery UI Menu 1.12.1
4925 * http://jqueryui.com
4926 *
4927 * Copyright jQuery Foundation and other contributors
4928 * Released under the MIT license.
4929 * http://jquery.org/license
4930 */
4931
4932//>>label: Menu
4933//>>group: Widgets
4934//>>description: Creates nestable menus.
4935//>>docs: http://api.jqueryui.com/menu/
4936//>>demos: http://jqueryui.com/menu/
4937//>>css.structure: ../../themes/base/core.css
4938//>>css.structure: ../../themes/base/menu.css
4939//>>css.theme: ../../themes/base/theme.css
4940
4941
4942
4943var widgetsMenu = $.widget( "ui.menu", {
4944	version: "1.12.1",
4945	defaultElement: "<ul>",
4946	delay: 300,
4947	options: {
4948		icons: {
4949			submenu: "ui-icon-caret-1-e"
4950		},
4951		items: "> *",
4952		menus: "ul",
4953		position: {
4954			my: "left top",
4955			at: "right top"
4956		},
4957		role: "menu",
4958
4959		// Callbacks
4960		blur: null,
4961		focus: null,
4962		select: null
4963	},
4964
4965	_create: function() {
4966		this.activeMenu = this.element;
4967
4968		// Flag used to prevent firing of the click handler
4969		// as the event bubbles up through nested menus
4970		this.mouseHandled = false;
4971		this.element
4972			.uniqueId()
4973			.attr( {
4974				role: this.options.role,
4975				tabIndex: 0
4976			} );
4977
4978		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4979		this._on( {
4980
4981			// Prevent focus from sticking to links inside menu after clicking
4982			// them (focus should always stay on UL during navigation).
4983			"mousedown .ui-menu-item": function( event ) {
4984				event.preventDefault();
4985			},
4986			"click .ui-menu-item": function( event ) {
4987				var target = $( event.target );
4988				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4989				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4990					this.select( event );
4991
4992					// Only set the mouseHandled flag if the event will bubble, see #9469.
4993					if ( !event.isPropagationStopped() ) {
4994						this.mouseHandled = true;
4995					}
4996
4997					// Open submenu on click
4998					if ( target.has( ".ui-menu" ).length ) {
4999						this.expand( event );
5000					} else if ( !this.element.is( ":focus" ) &&
5001							active.closest( ".ui-menu" ).length ) {
5002
5003						// Redirect focus to the menu
5004						this.element.trigger( "focus", [ true ] );
5005
5006						// If the active item is on the top level, let it stay active.
5007						// Otherwise, blur the active item since it is no longer visible.
5008						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5009							clearTimeout( this.timer );
5010						}
5011					}
5012				}
5013			},
5014			"mouseenter .ui-menu-item": function( event ) {
5015
5016				// Ignore mouse events while typeahead is active, see #10458.
5017				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5018				// is over an item in the menu
5019				if ( this.previousFilter ) {
5020					return;
5021				}
5022
5023				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5024					target = $( event.currentTarget );
5025
5026				// Ignore bubbled events on parent items, see #11641
5027				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5028					return;
5029				}
5030
5031				// Remove ui-state-active class from siblings of the newly focused menu item
5032				// to avoid a jump caused by adjacent elements both having a class with a border
5033				this._removeClass( target.siblings().children( ".ui-state-active" ),
5034					null, "ui-state-active" );
5035				this.focus( event, target );
5036			},
5037			mouseleave: "collapseAll",
5038			"mouseleave .ui-menu": "collapseAll",
5039			focus: function( event, keepActiveItem ) {
5040
5041				// If there's already an active item, keep it active
5042				// If not, activate the first item
5043				var item = this.active || this.element.find( this.options.items ).eq( 0 );
5044
5045				if ( !keepActiveItem ) {
5046					this.focus( event, item );
5047				}
5048			},
5049			blur: function( event ) {
5050				this._delay( function() {
5051					var notContained = !$.contains(
5052						this.element[ 0 ],
5053						$.ui.safeActiveElement( this.document[ 0 ] )
5054					);
5055					if ( notContained ) {
5056						this.collapseAll( event );
5057					}
5058				} );
5059			},
5060			keydown: "_keydown"
5061		} );
5062
5063		this.refresh();
5064
5065		// Clicks outside of a menu collapse any open menus
5066		this._on( this.document, {
5067			click: function( event ) {
5068				if ( this._closeOnDocumentClick( event ) ) {
5069					this.collapseAll( event );
5070				}
5071
5072				// Reset the mouseHandled flag
5073				this.mouseHandled = false;
5074			}
5075		}
vendor: 9,131 bytes, lines 5075-5409
5075 );
5076	},
5077
5078	_destroy: function() {
5079		var items = this.element.find( ".ui-menu-item" )
5080				.removeAttr( "role aria-disabled" ),
5081			submenus = items.children( ".ui-menu-item-wrapper" )
5082				.removeUniqueId()
5083				.removeAttr( "tabIndex role aria-haspopup" );
5084
5085		// Destroy (sub)menus
5086		this.element
5087			.removeAttr( "aria-activedescendant" )
5088			.find( ".ui-menu" ).addBack()
5089				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5090					"tabIndex" )
5091				.removeUniqueId()
5092				.show();
5093
5094		submenus.children().each( function() {
5095			var elem = $( this );
5096			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5097				elem.remove();
5098			}
5099		} );
5100	},
5101
5102	_keydown: function( event ) {
5103		var match, prev, character, skip,
5104			preventDefault = true;
5105
5106		switch ( event.keyCode ) {
5107		case $.ui.keyCode.PAGE_UP:
5108			this.previousPage( event );
5109			break;
5110		case $.ui.keyCode.PAGE_DOWN:
5111			this.nextPage( event );
5112			break;
5113		case $.ui.keyCode.HOME:
5114			this._move( "first", "first", event );
5115			break;
5116		case $.ui.keyCode.END:
5117			this._move( "last", "last", event );
5118			break;
5119		case $.ui.keyCode.UP:
5120			this.previous( event );
5121			break;
5122		case $.ui.keyCode.DOWN:
5123			this.next( event );
5124			break;
5125		case $.ui.keyCode.LEFT:
5126			this.collapse( event );
5127			break;
5128		case $.ui.keyCode.RIGHT:
5129			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5130				this.expand( event );
5131			}
5132			break;
5133		case $.ui.keyCode.ENTER:
5134		case $.ui.keyCode.SPACE:
5135			this._activate( event );
5136			break;
5137		case $.ui.keyCode.ESCAPE:
5138			this.collapse( event );
5139			break;
5140		default:
5141			preventDefault = false;
5142			prev = this.previousFilter || "";
5143			skip = false;
5144
5145			// Support number pad values
5146			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5147				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5148
5149			clearTimeout( this.filterTimer );
5150
5151			if ( character === prev ) {
5152				skip = true;
5153			} else {
5154				character = prev + character;
5155			}
5156
5157			match = this._filterMenuItems( character );
5158			match = skip && match.index( this.active.next() ) !== -1 ?
5159				this.active.nextAll( ".ui-menu-item" ) :
5160				match;
5161
5162			// If no matches on the current filter, reset to the last character pressed
5163			// to move down the menu to the first item that starts with that character
5164			if ( !match.length ) {
5165				character = String.fromCharCode( event.keyCode );
5166				match = this._filterMenuItems( character );
5167			}
5168
5169			if ( match.length ) {
5170				this.focus( event, match );
5171				this.previousFilter = character;
5172				this.filterTimer = this._delay( function() {
5173					delete this.previousFilter;
5174				}, 1000 );
5175			} else {
5176				delete this.previousFilter;
5177			}
5178		}
5179
5180		if ( preventDefault ) {
5181			event.preventDefault();
5182		}
5183	},
5184
5185	_activate: function( event ) {
5186		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5187			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5188				this.expand( event );
5189			} else {
5190				this.select( event );
5191			}
5192		}
5193	},
5194
5195	refresh: function() {
5196		var menus, items, newSubmenus, newItems, newWrappers,
5197			that = this,
5198			icon = this.options.icons.submenu,
5199			submenus = this.element.find( this.options.menus );
5200
5201		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5202
5203		// Initialize nested menus
5204		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5205			.hide()
5206			.attr( {
5207				role: this.options.role,
5208				"aria-hidden": "true",
5209				"aria-expanded": "false"
5210			} )
5211			.each( function() {
5212				var menu = $( this ),
5213					item = menu.prev(),
5214					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5215
5216				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5217				item
5218					.attr( "aria-haspopup", "true" )
5219					.prepend( submenuCaret );
5220				menu.attr( "aria-labelledby", item.attr( "id" ) );
5221			} );
5222
5223		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5224
5225		menus = submenus.add( this.element );
5226		items = menus.find( this.options.items );
5227
5228		// Initialize menu-items containing spaces and/or dashes only as dividers
5229		items.not( ".ui-menu-item" ).each( function() {
5230			var item = $( this );
5231			if ( that._isDivider( item ) ) {
5232				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5233			}
5234		} );
5235
5236		// Don't refresh list items that are already adapted
5237		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5238		newWrappers = newItems.children()
5239			.not( ".ui-menu" )
5240				.uniqueId()
5241				.attr( {
5242					tabIndex: -1,
5243					role: this._itemRole()
5244				} );
5245		this._addClass( newItems, "ui-menu-item" )
5246			._addClass( newWrappers, "ui-menu-item-wrapper" );
5247
5248		// Add aria-disabled attribute to any disabled menu item
5249		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5250
5251		// If the active item has been removed, blur the menu
5252		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5253			this.blur();
5254		}
5255	},
5256
5257	_itemRole: function() {
5258		return {
5259			menu: "menuitem",
5260			listbox: "option"
5261		}[ this.options.role ];
5262	},
5263
5264	_setOption: function( key, value ) {
5265		if ( key === "icons" ) {
5266			var icons = this.element.find( ".ui-menu-icon" );
5267			this._removeClass( icons, null, this.options.icons.submenu )
5268				._addClass( icons, null, value.submenu );
5269		}
5270		this._super( key, value );
5271	},
5272
5273	_setOptionDisabled: function( value ) {
5274		this._super( value );
5275
5276		this.element.attr( "aria-disabled", String( value ) );
5277		this._toggleClass( null, "ui-state-disabled", !!value );
5278	},
5279
5280	focus: function( event, item ) {
5281		var nested, focused, activeParent;
5282		this.blur( event, event && event.type === "focus" );
5283
5284		this._scrollIntoView( item );
5285
5286		this.active = item.first();
5287
5288		focused = this.active.children( ".ui-menu-item-wrapper" );
5289		this._addClass( focused, null, "ui-state-active" );
5290
5291		// Only update aria-activedescendant if there's a role
5292		// otherwise we assume focus is managed elsewhere
5293		if ( this.options.role ) {
5294			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5295		}
5296
5297		// Highlight active parent menu item, if any
5298		activeParent = this.active
5299			.parent()
5300				.closest( ".ui-menu-item" )
5301					.children( ".ui-menu-item-wrapper" );
5302		this._addClass( activeParent, null, "ui-state-active" );
5303
5304		if ( event && event.type === "keydown" ) {
5305			this._close();
5306		} else {
5307			this.timer = this._delay( function() {
5308				this._close();
5309			}, this.delay );
5310		}
5311
5312		nested = item.children( ".ui-menu" );
5313		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5314			this._startOpening( nested );
5315		}
5316		this.activeMenu = item.parent();
5317
5318		this._trigger( "focus", event, { item: item } );
5319	},
5320
5321	_scrollIntoView: function( item ) {
5322		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5323		if ( this._hasScroll() ) {
5324			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5325			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5326			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5327			scroll = this.activeMenu.scrollTop();
5328			elementHeight = this.activeMenu.height();
5329			itemHeight = item.outerHeight();
5330
5331			if ( offset < 0 ) {
5332				this.activeMenu.scrollTop( scroll + offset );
5333			} else if ( offset + itemHeight > elementHeight ) {
5334				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5335			}
5336		}
5337	},
5338
5339	blur: function( event, fromFocus ) {
5340		if ( !fromFocus ) {
5341			clearTimeout( this.timer );
5342		}
5343
5344		if ( !this.active ) {
5345			return;
5346		}
5347
5348		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5349			null, "ui-state-active" );
5350
5351		this._trigger( "blur", event, { item: this.active } );
5352		this.active = null;
5353	},
5354
5355	_startOpening: function( submenu ) {
5356		clearTimeout( this.timer );
5357
5358		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5359		// shift in the submenu position when mousing over the caret icon
5360		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5361			return;
5362		}
5363
5364		this.timer = this._delay( function() {
5365			this._close();
5366			this._open( submenu );
5367		}, this.delay );
5368	},
5369
5370	_open: function( submenu ) {
5371		var position = $.extend( {
5372			of: this.active
5373		}, this.options.position );
5374
5375		clearTimeout( this.timer );
5376		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5377			.hide()
5378			.attr( "aria-hidden", "true" );
5379
5380		submenu
5381			.show()
5382			.removeAttr( "aria-hidden" )
5383			.attr( "aria-expanded", "true" )
5384			.position( position );
5385	},
5386
5387	collapseAll: function( event, all ) {
5388		clearTimeout( this.timer );
5389		this.timer = this._delay( function() {
5390
5391			// If we were passed an event, look for the submenu that contains the event
5392			var currentMenu = all ? this.element :
5393				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5394
5395			// If we found no valid submenu ancestor, use the main menu to close all
5396			// sub menus anyway
5397			if ( !currentMenu.length ) {
5398				currentMenu = this.element;
5399			}
5400
5401			this._close( currentMenu );
5402
5403			this.blur( event );
5404
5405			// Work around active item staying active after menu is blurred
5406			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5407
5408			this.activeMenu = currentMenu;
5409		}, 
vendor: 6,612 bytes, lines 5409-5661
5409this.delay );
5410	},
5411
5412	// With no arguments, closes the currently active menu - if nothing is active
5413	// it closes all menus.  If passed an argument, it will search for menus BELOW
5414	_close: function( startMenu ) {
5415		if ( !startMenu ) {
5416			startMenu = this.active ? this.active.parent() : this.element;
5417		}
5418
5419		startMenu.find( ".ui-menu" )
5420			.hide()
5421			.attr( "aria-hidden", "true" )
5422			.attr( "aria-expanded", "false" );
5423	},
5424
5425	_closeOnDocumentClick: function( event ) {
5426		return !$( event.target ).closest( ".ui-menu" ).length;
5427	},
5428
5429	_isDivider: function( item ) {
5430
5431		// Match hyphen, em dash, en dash
5432		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5433	},
5434
5435	collapse: function( event ) {
5436		var newItem = this.active &&
5437			this.active.parent().closest( ".ui-menu-item", this.element );
5438		if ( newItem && newItem.length ) {
5439			this._close();
5440			this.focus( event, newItem );
5441		}
5442	},
5443
5444	expand: function( event ) {
5445		var newItem = this.active &&
5446			this.active
5447				.children( ".ui-menu " )
5448					.find( this.options.items )
5449						.first();
5450
5451		if ( newItem && newItem.length ) {
5452			this._open( newItem.parent() );
5453
5454			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5455			this._delay( function() {
5456				this.focus( event, newItem );
5457			} );
5458		}
5459	},
5460
5461	next: function( event ) {
5462		this._move( "next", "first", event );
5463	},
5464
5465	previous: function( event ) {
5466		this._move( "prev", "last", event );
5467	},
5468
5469	isFirstItem: function() {
5470		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5471	},
5472
5473	isLastItem: function() {
5474		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5475	},
5476
5477	_move: function( direction, filter, event ) {
5478		var next;
5479		if ( this.active ) {
5480			if ( direction === "first" || direction === "last" ) {
5481				next = this.active
5482					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5483					.eq( -1 );
5484			} else {
5485				next = this.active
5486					[ direction + "All" ]( ".ui-menu-item" )
5487					.eq( 0 );
5488			}
5489		}
5490		if ( !next || !next.length || !this.active ) {
5491			next = this.activeMenu.find( this.options.items )[ filter ]();
5492		}
5493
5494		this.focus( event, next );
5495	},
5496
5497	nextPage: function( event ) {
5498		var item, base, height;
5499
5500		if ( !this.active ) {
5501			this.next( event );
5502			return;
5503		}
5504		if ( this.isLastItem() ) {
5505			return;
5506		}
5507		if ( this._hasScroll() ) {
5508			base = this.active.offset().top;
5509			height = this.element.height();
5510			this.active.nextAll( ".ui-menu-item" ).each( function() {
5511				item = $( this );
5512				return item.offset().top - base - height < 0;
5513			} );
5514
5515			this.focus( event, item );
5516		} else {
5517			this.focus( event, this.activeMenu.find( this.options.items )
5518				[ !this.active ? "first" : "last" ]() );
5519		}
5520	},
5521
5522	previousPage: function( event ) {
5523		var item, base, height;
5524		if ( !this.active ) {
5525			this.next( event );
5526			return;
5527		}
5528		if ( this.isFirstItem() ) {
5529			return;
5530		}
5531		if ( this._hasScroll() ) {
5532			base = this.active.offset().top;
5533			height = this.element.height();
5534			this.active.prevAll( ".ui-menu-item" ).each( function() {
5535				item = $( this );
5536				return item.offset().top - base + height > 0;
5537			} );
5538
5539			this.focus( event, item );
5540		} else {
5541			this.focus( event, this.activeMenu.find( this.options.items ).first() );
5542		}
5543	},
5544
5545	_hasScroll: function() {
5546		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5547	},
5548
5549	select: function( event ) {
5550
5551		// TODO: It should never be possible to not have an active item at this
5552		// point, but the tests don't trigger mouseenter before click.
5553		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5554		var ui = { item: this.active };
5555		if ( !this.active.has( ".ui-menu" ).length ) {
5556			this.collapseAll( event, true );
5557		}
5558		this._trigger( "select", event, ui );
5559	},
5560
5561	_filterMenuItems: function( character ) {
5562		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5563			regex = new RegExp( "^" + escapedCharacter, "i" );
5564
5565		return this.activeMenu
5566			.find( this.options.items )
5567
5568				// Only match on items, not dividers or other content (#10571)
5569				.filter( ".ui-menu-item" )
5570					.filter( function() {
5571						return regex.test(
5572							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5573					} );
5574	}
5575} );
5576
5577
5578/*!
5579 * jQuery UI Autocomplete 1.12.1
5580 * http://jqueryui.com
5581 *
5582 * Copyright jQuery Foundation and other contributors
5583 * Released under the MIT license.
5584 * http://jquery.org/license
5585 */
5586
5587//>>label: Autocomplete
5588//>>group: Widgets
5589//>>description: Lists suggested words as the user is typing.
5590//>>docs: http://api.jqueryui.com/autocomplete/
5591//>>demos: http://jqueryui.com/autocomplete/
5592//>>css.structure: ../../themes/base/core.css
5593//>>css.structure: ../../themes/base/autocomplete.css
5594//>>css.theme: ../../themes/base/theme.css
5595
5596
5597
5598$.widget( "ui.autocomplete", {
5599	version: "1.12.1",
5600	defaultElement: "<input>",
5601	options: {
5602		appendTo: null,
5603		autoFocus: false,
5604		delay: 300,
5605		minLength: 1,
5606		position: {
5607			my: "left top",
5608			at: "left bottom",
5609			collision: "none"
5610		},
5611		source: null,
5612
5613		// Callbacks
5614		change: null,
5615		close: null,
5616		focus: null,
5617		open: null,
5618		response: null,
5619		search: null,
5620		select: null
5621	},
5622
5623	requestIndex: 0,
5624	pending: 0,
5625
5626	_create: function() {
5627
5628		// Some browsers only repeat keydown events, not keypress events,
5629		// so we use the suppressKeyPress flag to determine if we've already
5630		// handled the keydown event. #7269
5631		// Unfortunately the code for & in keypress is the same as the up arrow,
5632		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5633		// events when we know the keydown event was used to modify the
5634		// search term. #7799
5635		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5636			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5637			isTextarea = nodeName === "textarea",
5638			isInput = nodeName === "input";
5639
5640		// Textareas are always multi-line
5641		// Inputs are always single-line, even if inside a contentEditable element
5642		// IE also treats inputs as contentEditable
5643		// All other element types are determined by whether or not they're contentEditable
5644		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5645
5646		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5647		this.isNewMenu = true;
5648
5649		this._addClass( "ui-autocomplete-input" );
5650		this.element.attr( "autocomplete", "off" );
5651
5652		this._on( this.element, {
5653			keydown: function( event ) {
5654				if ( this.element.prop( "readOnly" ) ) {
5655					suppressKeyPress = true;
5656					suppressInput = true;
5657					suppressKeyPressRepeat = true;
5658					return;
5659				}
5660
5661				suppressKeyPress = false;
vendor: 8,598 bytes, lines 5662-5981
5662				suppressInput = false;
5663				suppressKeyPressRepeat = false;
5664				var keyCode = $.ui.keyCode;
5665				switch ( event.keyCode ) {
5666				case keyCode.PAGE_UP:
5667					suppressKeyPress = true;
5668					this._move( "previousPage", event );
5669					break;
5670				case keyCode.PAGE_DOWN:
5671					suppressKeyPress = true;
5672					this._move( "nextPage", event );
5673					break;
5674				case keyCode.UP:
5675					suppressKeyPress = true;
5676					this._keyEvent( "previous", event );
5677					break;
5678				case keyCode.DOWN:
5679					suppressKeyPress = true;
5680					this._keyEvent( "next", event );
5681					break;
5682				case keyCode.ENTER:
5683
5684					// when menu is open and has focus
5685					if ( this.menu.active ) {
5686
5687						// #6055 - Opera still allows the keypress to occur
5688						// which causes forms to submit
5689						suppressKeyPress = true;
5690						event.preventDefault();
5691						this.menu.select( event );
5692					}
5693					break;
5694				case keyCode.TAB:
5695					if ( this.menu.active ) {
5696						this.menu.select( event );
5697					}
5698					break;
5699				case keyCode.ESCAPE:
5700					if ( this.menu.element.is( ":visible" ) ) {
5701						if ( !this.isMultiLine ) {
5702							this._value( this.term );
5703						}
5704						this.close( event );
5705
5706						// Different browsers have different default behavior for escape
5707						// Single press can mean undo or clear
5708						// Double press in IE means clear the whole form
5709						event.preventDefault();
5710					}
5711					break;
5712				default:
5713					suppressKeyPressRepeat = true;
5714
5715					// search timeout should be triggered before the input value is changed
5716					this._searchTimeout( event );
5717					break;
5718				}
5719			},
5720			keypress: function( event ) {
5721				if ( suppressKeyPress ) {
5722					suppressKeyPress = false;
5723					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5724						event.preventDefault();
5725					}
5726					return;
5727				}
5728				if ( suppressKeyPressRepeat ) {
5729					return;
5730				}
5731
5732				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5733				var keyCode = $.ui.keyCode;
5734				switch ( event.keyCode ) {
5735				case keyCode.PAGE_UP:
5736					this._move( "previousPage", event );
5737					break;
5738				case keyCode.PAGE_DOWN:
5739					this._move( "nextPage", event );
5740					break;
5741				case keyCode.UP:
5742					this._keyEvent( "previous", event );
5743					break;
5744				case keyCode.DOWN:
5745					this._keyEvent( "next", event );
5746					break;
5747				}
5748			},
5749			input: function( event ) {
5750				if ( suppressInput ) {
5751					suppressInput = false;
5752					event.preventDefault();
5753					return;
5754				}
5755				this._searchTimeout( event );
5756			},
5757			focus: function() {
5758				this.selectedItem = null;
5759				this.previous = this._value();
5760			},
5761			blur: function( event ) {
5762				if ( this.cancelBlur ) {
5763					delete this.cancelBlur;
5764					return;
5765				}
5766
5767				clearTimeout( this.searching );
5768				this.close( event );
5769				this._change( event );
5770			}
5771		} );
5772
5773		this._initSource();
5774		this.menu = $( "<ul>" )
5775			.appendTo( this._appendTo() )
5776			.menu( {
5777
5778				// disable ARIA support, the live region takes care of that
5779				role: null
5780			} )
5781			.hide()
5782			.menu( "instance" );
5783
5784		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5785		this._on( this.menu.element, {
5786			mousedown: function( event ) {
5787
5788				// prevent moving focus out of the text field
5789				event.preventDefault();
5790
5791				// IE doesn't prevent moving focus even with event.preventDefault()
5792				// so we set a flag to know when we should ignore the blur event
5793				this.cancelBlur = true;
5794				this._delay( function() {
5795					delete this.cancelBlur;
5796
5797					// Support: IE 8 only
5798					// Right clicking a menu item or selecting text from the menu items will
5799					// result in focus moving out of the input. However, we've already received
5800					// and ignored the blur event because of the cancelBlur flag set above. So
5801					// we restore focus to ensure that the menu closes properly based on the user's
5802					// next actions.
5803					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5804						this.element.trigger( "focus" );
5805					}
5806				} );
5807			},
5808			menufocus: function( event, ui ) {
5809				var label, item;
5810
5811				// support: Firefox
5812				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5813				if ( this.isNewMenu ) {
5814					this.isNewMenu = false;
5815					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5816						this.menu.blur();
5817
5818						this.document.one( "mousemove", function() {
5819							$( event.target ).trigger( event.originalEvent );
5820						} );
5821
5822						return;
5823					}
5824				}
5825
5826				item = ui.item.data( "ui-autocomplete-item" );
5827				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5828
5829					// use value to match what will end up in the input, if it was a key event
5830					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5831						this._value( item.value );
5832					}
5833				}
5834
5835				// Announce the value in the liveRegion
5836				label = ui.item.attr( "aria-label" ) || item.value;
5837				if ( label && $.trim( label ).length ) {
5838					this.liveRegion.children().hide();
5839					$( "<div>" ).text( label ).appendTo( this.liveRegion );
5840				}
5841			},
5842			menuselect: function( event, ui ) {
5843				var item = ui.item.data( "ui-autocomplete-item" ),
5844					previous = this.previous;
5845
5846				// Only trigger when focus was lost (click on menu)
5847				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5848					this.element.trigger( "focus" );
5849					this.previous = previous;
5850
5851					// #6109 - IE triggers two focus events and the second
5852					// is asynchronous, so we need to reset the previous
5853					// term synchronously and asynchronously :-(
5854					this._delay( function() {
5855						this.previous = previous;
5856						this.selectedItem = item;
5857					} );
5858				}
5859
5860				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5861					this._value( item.value );
5862				}
5863
5864				// reset the term after the select event
5865				// this allows custom select handling to work properly
5866				this.term = this._value();
5867
5868				this.close( event );
5869				this.selectedItem = item;
5870			}
5871		} );
5872
5873		this.liveRegion = $( "<div>", {
5874			role: "status",
5875			"aria-live": "assertive",
5876			"aria-relevant": "additions"
5877		} )
5878			.appendTo( this.document[ 0 ].body );
5879
5880		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5881
5882		// Turning off autocomplete prevents the browser from remembering the
5883		// value when navigating through history, so we re-enable autocomplete
5884		// if the page is unloaded before the widget is destroyed. #7790
5885		this._on( this.window, {
5886			beforeunload: function() {
5887				this.element.removeAttr( "autocomplete" );
5888			}
5889		} );
5890	},
5891
5892	_destroy: function() {
5893		clearTimeout( this.searching );
5894		this.element.removeAttr( "autocomplete" );
5895		this.menu.element.remove();
5896		this.liveRegion.remove();
5897	},
5898
5899	_setOption: function( key, value ) {
5900		this._super( key, value );
5901		if ( key === "source" ) {
5902			this._initSource();
5903		}
5904		if ( key === "appendTo" ) {
5905			this.menu.element.appendTo( this._appendTo() );
5906		}
5907		if ( key === "disabled" && value && this.xhr ) {
5908			this.xhr.abort();
5909		}
5910	},
5911
5912	_isEventTargetInWidget: function( event ) {
5913		var menuElement = this.menu.element[ 0 ];
5914
5915		return event.target === this.element[ 0 ] ||
5916			event.target === menuElement ||
5917			$.contains( menuElement, event.target );
5918	},
5919
5920	_closeOnClickOutside: function( event ) {
5921		if ( !this._isEventTargetInWidget( event ) ) {
5922			this.close();
5923		}
5924	},
5925
5926	_appendTo: function() {
5927		var element = this.options.appendTo;
5928
5929		if ( element ) {
5930			element = element.jquery || element.nodeType ?
5931				$( element ) :
5932				this.document.find( element ).eq( 0 );
5933		}
5934
5935		if ( !element || !element[ 0 ] ) {
5936			element = this.element.closest( ".ui-front, dialog" );
5937		}
5938
5939		if ( !element.length ) {
5940			element = this.document[ 0 ].body;
5941		}
5942
5943		return element;
5944	},
5945
5946	_initSource: function() {
5947		var array, url,
5948			that = this;
5949		if ( $.isArray( this.options.source ) ) {
5950			array = this.options.source;
5951			this.source = function( request, response ) {
5952				response( $.ui.autocomplete.filter( array, request.term ) );
5953			};
5954		} else if ( typeof this.options.source === "string" ) {
5955			url = this.options.source;
5956			this.source = function( request, response ) {
5957				if ( that.xhr ) {
5958					that.xhr.abort();
5959				}
5960				that.xhr = $.ajax( {
5961					url: url,
5962					data: request,
5963					dataType: "json",
5964					success: function( data ) {
5965						response( data );
5966					},
5967					error: function() {
5968						response( [] );
5969					}
5970				} );
5971			};
5972		} else {
5973			this.source = this.options.source;
5974		}
5975	},
5976
5977	_searchTimeout: function( event ) {
5978		clearTimeout( this.searching );
5979		this.searching = this._delay( function() {
5980
5981			// Search if the value has changed, or if the user retypes the same value (see #7434)
vendor: 4,901 bytes, lines 5982-6184
5982			var equalValues = this.term === this._value(),
5983				menuVisible = this.menu.element.is( ":visible" ),
5984				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5985
5986			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5987				this.selectedItem = null;
5988				this.search( null, event );
5989			}
5990		}, this.options.delay );
5991	},
5992
5993	search: function( value, event ) {
5994		value = value != null ? value : this._value();
5995
5996		// Always save the actual value, not the one passed as an argument
5997		this.term = this._value();
5998
5999		if ( value.length < this.options.minLength ) {
6000			return this.close( event );
6001		}
6002
6003		if ( this._trigger( "search", event ) === false ) {
6004			return;
6005		}
6006
6007		return this._search( value );
6008	},
6009
6010	_search: function( value ) {
6011		this.pending++;
6012		this._addClass( "ui-autocomplete-loading" );
6013		this.cancelSearch = false;
6014
6015		this.source( { term: value }, this._response() );
6016	},
6017
6018	_response: function() {
6019		var index = ++this.requestIndex;
6020
6021		return $.proxy( function( content ) {
6022			if ( index === this.requestIndex ) {
6023				this.__response( content );
6024			}
6025
6026			this.pending--;
6027			if ( !this.pending ) {
6028				this._removeClass( "ui-autocomplete-loading" );
6029			}
6030		}, this );
6031	},
6032
6033	__response: function( content ) {
6034		if ( content ) {
6035			content = this._normalize( content );
6036		}
6037		this._trigger( "response", null, { content: content } );
6038		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6039			this._suggest( content );
6040			this._trigger( "open" );
6041		} else {
6042
6043			// use ._close() instead of .close() so we don't cancel future searches
6044			this._close();
6045		}
6046	},
6047
6048	close: function( event ) {
6049		this.cancelSearch = true;
6050		this._close( event );
6051	},
6052
6053	_close: function( event ) {
6054
6055		// Remove the handler that closes the menu on outside clicks
6056		this._off( this.document, "mousedown" );
6057
6058		if ( this.menu.element.is( ":visible" ) ) {
6059			this.menu.element.hide();
6060			this.menu.blur();
6061			this.isNewMenu = true;
6062			this._trigger( "close", event );
6063		}
6064	},
6065
6066	_change: function( event ) {
6067		if ( this.previous !== this._value() ) {
6068			this._trigger( "change", event, { item: this.selectedItem } );
6069		}
6070	},
6071
6072	_normalize: function( items ) {
6073
6074		// assume all items have the right format when the first item is complete
6075		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6076			return items;
6077		}
6078		return $.map( items, function( item ) {
6079			if ( typeof item === "string" ) {
6080				return {
6081					label: item,
6082					value: item
6083				};
6084			}
6085			return $.extend( {}, item, {
6086				label: item.label || item.value,
6087				value: item.value || item.label
6088			} );
6089		} );
6090	},
6091
6092	_suggest: function( items ) {
6093		var ul = this.menu.element.empty();
6094		this._renderMenu( ul, items );
6095		this.isNewMenu = true;
6096		this.menu.refresh();
6097
6098		// Size and position menu
6099		ul.show();
6100		this._resizeMenu();
6101		ul.position( $.extend( {
6102			of: this.element
6103		}, this.options.position ) );
6104
6105		if ( this.options.autoFocus ) {
6106			this.menu.next();
6107		}
6108
6109		// Listen for interactions outside of the widget (#6642)
6110		this._on( this.document, {
6111			mousedown: "_closeOnClickOutside"
6112		} );
6113	},
6114
6115	_resizeMenu: function() {
6116		var ul = this.menu.element;
6117		ul.outerWidth( Math.max(
6118
6119			// Firefox wraps long text (possibly a rounding bug)
6120			// so we add 1px to avoid the wrapping (#7513)
6121			ul.width( "" ).outerWidth() + 1,
6122			this.element.outerWidth()
6123		) );
6124	},
6125
6126	_renderMenu: function( ul, items ) {
6127		var that = this;
6128		$.each( items, function( index, item ) {
6129			that._renderItemData( ul, item );
6130		} );
6131	},
6132
6133	_renderItemData: function( ul, item ) {
6134		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6135	},
6136
6137	_renderItem: function( ul, item ) {
6138		return $( "<li>" )
6139			.append( $( "<div>" ).text( item.label ) )
6140			.appendTo( ul );
6141	},
6142
6143	_move: function( direction, event ) {
6144		if ( !this.menu.element.is( ":visible" ) ) {
6145			this.search( null, event );
6146			return;
6147		}
6148		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6149				this.menu.isLastItem() && /^next/.test( direction ) ) {
6150
6151			if ( !this.isMultiLine ) {
6152				this._value( this.term );
6153			}
6154
6155			this.menu.blur();
6156			return;
6157		}
6158		this.menu[ direction ]( event );
6159	},
6160
6161	widget: function() {
6162		return this.menu.element;
6163	},
6164
6165	_value: function() {
6166		return this.valueMethod.apply( this.element, arguments );
6167	},
6168
6169	_keyEvent: function( keyEvent, event ) {
6170		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6171			this._move( keyEvent, event );
6172
6173			// Prevents moving cursor to beginning/end of the text field in some browsers
6174			event.preventDefault();
6175		}
6176	},
6177
6178	// Support: Chrome <=50
6179	// We should be able to just use this.element.prop( "isContentEditable" )
6180	// but hidden elements always report false in Chrome.
6181	// https://code.google.com/p/chromium/issues/detail?id=313082
6182	_isContentEditable: function( element ) {
6183		if ( !element.length ) {
6184			return false;
vendor: 14,931 bytes, lines 6185-6710
6185		}
6186
6187		var editable = element.prop( "contentEditable" );
6188
6189		if ( editable === "inherit" ) {
6190		  return this._isContentEditable( element.parent() );
6191		}
6192
6193		return editable === "true";
6194	}
6195} );
6196
6197$.extend( $.ui.autocomplete, {
6198	escapeRegex: function( value ) {
6199		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6200	},
6201	filter: function( array, term ) {
6202		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6203		return $.grep( array, function( value ) {
6204			return matcher.test( value.label || value.value || value );
6205		} );
6206	}
6207} );
6208
6209// Live region extension, adding a `messages` option
6210// NOTE: This is an experimental API. We are still investigating
6211// a full solution for string manipulation and internationalization.
6212$.widget( "ui.autocomplete", $.ui.autocomplete, {
6213	options: {
6214		messages: {
6215			noResults: "No search results.",
6216			results: function( amount ) {
6217				return amount + ( amount > 1 ? " results are" : " result is" ) +
6218					" available, use up and down arrow keys to navigate.";
6219			}
6220		}
6221	},
6222
6223	__response: function( content ) {
6224		var message;
6225		this._superApply( arguments );
6226		if ( this.options.disabled || this.cancelSearch ) {
6227			return;
6228		}
6229		if ( content && content.length ) {
6230			message = this.options.messages.results( content.length );
6231		} else {
6232			message = this.options.messages.noResults;
6233		}
6234		this.liveRegion.children().hide();
6235		$( "<div>" ).text( message ).appendTo( this.liveRegion );
6236	}
6237} );
6238
6239var widgetsAutocomplete = $.ui.autocomplete;
6240
6241
6242/*!
6243 * jQuery UI Controlgroup 1.12.1
6244 * http://jqueryui.com
6245 *
6246 * Copyright jQuery Foundation and other contributors
6247 * Released under the MIT license.
6248 * http://jquery.org/license
6249 */
6250
6251//>>label: Controlgroup
6252//>>group: Widgets
6253//>>description: Visually groups form control widgets
6254//>>docs: http://api.jqueryui.com/controlgroup/
6255//>>demos: http://jqueryui.com/controlgroup/
6256//>>css.structure: ../../themes/base/core.css
6257//>>css.structure: ../../themes/base/controlgroup.css
6258//>>css.theme: ../../themes/base/theme.css
6259
6260
6261var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6262
6263var widgetsControlgroup = $.widget( "ui.controlgroup", {
6264	version: "1.12.1",
6265	defaultElement: "<div>",
6266	options: {
6267		direction: "horizontal",
6268		disabled: null,
6269		onlyVisible: true,
6270		items: {
6271			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6272			"controlgroupLabel": ".ui-controlgroup-label",
6273			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6274			"selectmenu": "select",
6275			"spinner": ".ui-spinner-input"
6276		}
6277	},
6278
6279	_create: function() {
6280		this._enhance();
6281	},
6282
6283	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6284	_enhance: function() {
6285		this.element.attr( "role", "toolbar" );
6286		this.refresh();
6287	},
6288
6289	_destroy: function() {
6290		this._callChildMethod( "destroy" );
6291		this.childWidgets.removeData( "ui-controlgroup-data" );
6292		this.element.removeAttr( "role" );
6293		if ( this.options.items.controlgroupLabel ) {
6294			this.element
6295				.find( this.options.items.controlgroupLabel )
6296				.find( ".ui-controlgroup-label-contents" )
6297				.contents().unwrap();
6298		}
6299	},
6300
6301	_initWidgets: function() {
6302		var that = this,
6303			childWidgets = [];
6304
6305		// First we iterate over each of the items options
6306		$.each( this.options.items, function( widget, selector ) {
6307			var labels;
6308			var options = {};
6309
6310			// Make sure the widget has a selector set
6311			if ( !selector ) {
6312				return;
6313			}
6314
6315			if ( widget === "controlgroupLabel" ) {
6316				labels = that.element.find( selector );
6317				labels.each( function() {
6318					var element = $( this );
6319
6320					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6321						return;
6322					}
6323					element.contents()
6324						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6325				} );
6326				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6327				childWidgets = childWidgets.concat( labels.get() );
6328				return;
6329			}
6330
6331			// Make sure the widget actually exists
6332			if ( !$.fn[ widget ] ) {
6333				return;
6334			}
6335
6336			// We assume everything is in the middle to start because we can't determine
6337			// first / last elements until all enhancments are done.
6338			if ( that[ "_" + widget + "Options" ] ) {
6339				options = that[ "_" + widget + "Options" ]( "middle" );
6340			} else {
6341				options = { classes: {} };
6342			}
6343
6344			// Find instances of this widget inside controlgroup and init them
6345			that.element
6346				.find( selector )
6347				.each( function() {
6348					var element = $( this );
6349					var instance = element[ widget ]( "instance" );
6350
6351					// We need to clone the default options for this type of widget to avoid
6352					// polluting the variable options which has a wider scope than a single widget.
6353					var instanceOptions = $.widget.extend( {}, options );
6354
6355					// If the button is the child of a spinner ignore it
6356					// TODO: Find a more generic solution
6357					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6358						return;
6359					}
6360
6361					// Create the widget if it doesn't exist
6362					if ( !instance ) {
6363						instance = element[ widget ]()[ widget ]( "instance" );
6364					}
6365					if ( instance ) {
6366						instanceOptions.classes =
6367							that._resolveClassesValues( instanceOptions.classes, instance );
6368					}
6369					element[ widget ]( instanceOptions );
6370
6371					// Store an instance of the controlgroup to be able to reference
6372					// from the outermost element for changing options and refresh
6373					var widgetElement = element[ widget ]( "widget" );
6374					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6375						instance ? instance : element[ widget ]( "instance" ) );
6376
6377					childWidgets.push( widgetElement[ 0 ] );
6378				} );
6379		} );
6380
6381		this.childWidgets = $( $.unique( childWidgets ) );
6382		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6383	},
6384
6385	_callChildMethod: function( method ) {
6386		this.childWidgets.each( function() {
6387			var element = $( this ),
6388				data = element.data( "ui-controlgroup-data" );
6389			if ( data && data[ method ] ) {
6390				data[ method ]();
6391			}
6392		} );
6393	},
6394
6395	_updateCornerClass: function( element, position ) {
6396		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6397		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6398
6399		this._removeClass( element, null, remove );
6400		this._addClass( element, null, add );
6401	},
6402
6403	_buildSimpleOptions: function( position, key ) {
6404		var direction = this.options.direction === "vertical";
6405		var result = {
6406			classes: {}
6407		};
6408		result.classes[ key ] = {
6409			"middle": "",
6410			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6411			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6412			"only": "ui-corner-all"
6413		}[ position ];
6414
6415		return result;
6416	},
6417
6418	_spinnerOptions: function( position ) {
6419		var options = this._buildSimpleOptions( position, "ui-spinner" );
6420
6421		options.classes[ "ui-spinner-up" ] = "";
6422		options.classes[ "ui-spinner-down" ] = "";
6423
6424		return options;
6425	},
6426
6427	_buttonOptions: function( position ) {
6428		return this._buildSimpleOptions( position, "ui-button" );
6429	},
6430
6431	_checkboxradioOptions: function( position ) {
6432		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6433	},
6434
6435	_selectmenuOptions: function( position ) {
6436		var direction = this.options.direction === "vertical";
6437		return {
6438			width: direction ? "auto" : false,
6439			classes: {
6440				middle: {
6441					"ui-selectmenu-button-open": "",
6442					"ui-selectmenu-button-closed": ""
6443				},
6444				first: {
6445					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6446					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6447				},
6448				last: {
6449					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6450					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6451				},
6452				only: {
6453					"ui-selectmenu-button-open": "ui-corner-top",
6454					"ui-selectmenu-button-closed": "ui-corner-all"
6455				}
6456
6457			}[ position ]
6458		};
6459	},
6460
6461	_resolveClassesValues: function( classes, instance ) {
6462		var result = {};
6463		$.each( classes, function( key ) {
6464			var current = instance.options.classes[ key ] || "";
6465			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6466			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6467		} );
6468		return result;
6469	},
6470
6471	_setOption: function( key, value ) {
6472		if ( key === "direction" ) {
6473			this._removeClass( "ui-controlgroup-" + this.options.direction );
6474		}
6475
6476		this._super( key, value );
6477		if ( key === "disabled" ) {
6478			this._callChildMethod( value ? "disable" : "enable" );
6479			return;
6480		}
6481
6482		this.refresh();
6483	},
6484
6485	refresh: function() {
6486		var children,
6487			that = this;
6488
6489		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6490
6491		if ( this.options.direction === "horizontal" ) {
6492			this._addClass( null, "ui-helper-clearfix" );
6493		}
6494		this._initWidgets();
6495
6496		children = this.childWidgets;
6497
6498		// We filter here because we need to track all childWidgets not just the visible ones
6499		if ( this.options.onlyVisible ) {
6500			children = children.filter( ":visible" );
6501		}
6502
6503		if ( children.length ) {
6504
6505			// We do this last because we need to make sure all enhancment is done
6506			// before determining first and last
6507			$.each( [ "first", "last" ], function( index, value ) {
6508				var instance = children[ value ]().data( "ui-controlgroup-data" );
6509
6510				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6511					var options = that[ "_" + instance.widgetName + "Options" ](
6512						children.length === 1 ? "only" : value
6513					);
6514					options.classes = that._resolveClassesValues( options.classes, instance );
6515					instance.element[ instance.widgetName ]( options );
6516				} else {
6517					that._updateCornerClass( children[ value ](), value );
6518				}
6519			} );
6520
6521			// Finally call the refresh method on each of the child widgets.
6522			this._callChildMethod( "refresh" );
6523		}
6524	}
6525} );
6526
6527/*!
6528 * jQuery UI Checkboxradio 1.12.1
6529 * http://jqueryui.com
6530 *
6531 * Copyright jQuery Foundation and other contributors
6532 * Released under the MIT license.
6533 * http://jquery.org/license
6534 */
6535
6536//>>label: Checkboxradio
6537//>>group: Widgets
6538//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6539//>>docs: http://api.jqueryui.com/checkboxradio/
6540//>>demos: http://jqueryui.com/checkboxradio/
6541//>>css.structure: ../../themes/base/core.css
6542//>>css.structure: ../../themes/base/button.css
6543//>>css.structure: ../../themes/base/checkboxradio.css
6544//>>css.theme: ../../themes/base/theme.css
6545
6546
6547
6548$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6549	version: "1.12.1",
6550	options: {
6551		disabled: null,
6552		label: null,
6553		icon: true,
6554		classes: {
6555			"ui-checkboxradio-label": "ui-corner-all",
6556			"ui-checkboxradio-icon": "ui-corner-all"
6557		}
6558	},
6559
6560	_getCreateOptions: function() {
6561		var disabled, labels;
6562		var that = this;
6563		var options = this._super() || {};
6564
6565		// We read the type here, because it makes more sense to throw a element type error first,
6566		// rather then the error for lack of a label. Often if its the wrong type, it
6567		// won't have a label (e.g. calling on a div, btn, etc)
6568		this._readType();
6569
6570		labels = this.element.labels();
6571
6572		// If there are multiple labels, use the last one
6573		this.label = $( labels[ labels.length - 1 ] );
6574		if ( !this.label.length ) {
6575			$.error( "No label found for checkboxradio widget" );
6576		}
6577
6578		this.originalLabel = "";
6579
6580		// We need to get the label text but this may also need to make sure it does not contain the
6581		// input itself.
6582		this.label.contents().not( this.element[ 0 ] ).each( function() {
6583
6584			// The label contents could be text, html, or a mix. We concat each element to get a
6585			// string representation of the label, without the input as part of it.
6586			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6587		} );
6588
6589		// Set the label option if we found label text
6590		if ( this.originalLabel ) {
6591			options.label = this.originalLabel;
6592		}
6593
6594		disabled = this.element[ 0 ].disabled;
6595		if ( disabled != null ) {
6596			options.disabled = disabled;
6597		}
6598		return options;
6599	},
6600
6601	_create: function() {
6602		var checked = this.element[ 0 ].checked;
6603
6604		this._bindFormResetHandler();
6605
6606		if ( this.options.disabled == null ) {
6607			this.options.disabled = this.element[ 0 ].disabled;
6608		}
6609
6610		this._setOption( "disabled", this.options.disabled );
6611		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6612		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6613
6614		if ( this.type === "radio" ) {
6615			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6616		}
6617
6618		if ( this.options.label && this.options.label !== this.originalLabel ) {
6619			this._updateLabel();
6620		} else if ( this.originalLabel ) {
6621			this.options.label = this.originalLabel;
6622		}
6623
6624		this._enhance();
6625
6626		if ( checked ) {
6627			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6628			if ( this.icon ) {
6629				this._addClass( this.icon, null, "ui-state-hover" );
6630			}
6631		}
6632
6633		this._on( {
6634			change: "_toggleClasses",
6635			focus: function() {
6636				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6637			},
6638			blur: function() {
6639				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6640			}
6641		} );
6642	},
6643
6644	_readType: function() {
6645		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6646		this.type = this.element[ 0 ].type;
6647		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6648			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6649				" and element.type=" + this.type );
6650		}
6651	},
6652
6653	// Support jQuery Mobile enhanced option
6654	_enhance: function() {
6655		this._updateIcon( this.element[ 0 ].checked );
6656	},
6657
6658	widget: function() {
6659		return this.label;
6660	},
6661
6662	_getRadioGroup: function() {
6663		var group;
6664		var name = this.element[ 0 ].name;
6665		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6666
6667		if ( !name ) {
6668			return $( [] );
6669		}
6670
6671		if ( this.form.length ) {
6672			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6673		} else {
6674
6675			// Not inside a form, check all inputs that also are not inside a form
6676			group = $( nameSelector ).filter( function() {
6677				return $( this ).form().length === 0;
6678			} );
6679		}
6680
6681		return group.not( this.element );
6682	},
6683
6684	_toggleClasses: function() {
6685		var checked = this.element[ 0 ].checked;
6686		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6687
6688		if ( this.options.icon && this.type === "checkbox" ) {
6689			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6690				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6691		}
6692
6693		if ( this.type === "radio" ) {
6694			this._getRadioGroup()
6695				.each( function() {
6696					var instance = $( this ).checkboxradio( "instance" );
6697
6698					if ( instance ) {
6699						instance._removeClass( instance.label,
6700							"ui-checkboxradio-checked", "ui-state-active" );
6701					}
6702				} );
6703		}
6704	},
6705
6706	_destroy: function() {
6707		this._unbindFormResetHandler();
6708
6709		if ( this.icon ) {
6710			this.icon.remove();
vendor: 4,485 bytes, lines 6711-6884
6711			this.iconSpace.remove();
6712		}
6713	},
6714
6715	_setOption: function( key, value ) {
6716
6717		// We don't allow the value to be set to nothing
6718		if ( key === "label" && !value ) {
6719			return;
6720		}
6721
6722		this._super( key, value );
6723
6724		if ( key === "disabled" ) {
6725			this._toggleClass( this.label, null, "ui-state-disabled", value );
6726			this.element[ 0 ].disabled = value;
6727
6728			// Don't refresh when setting disabled
6729			return;
6730		}
6731		this.refresh();
6732	},
6733
6734	_updateIcon: function( checked ) {
6735		var toAdd = "ui-icon ui-icon-background ";
6736
6737		if ( this.options.icon ) {
6738			if ( !this.icon ) {
6739				this.icon = $( "<span>" );
6740				this.iconSpace = $( "<span> </span>" );
6741				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6742			}
6743
6744			if ( this.type === "checkbox" ) {
6745				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6746				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6747			} else {
6748				toAdd += "ui-icon-blank";
6749			}
6750			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6751			if ( !checked ) {
6752				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6753			}
6754			this.icon.prependTo( this.label ).after( this.iconSpace );
6755		} else if ( this.icon !== undefined ) {
6756			this.icon.remove();
6757			this.iconSpace.remove();
6758			delete this.icon;
6759		}
6760	},
6761
6762	_updateLabel: function() {
6763
6764		// Remove the contents of the label ( minus the icon, icon space, and input )
6765		var contents = this.label.contents().not( this.element[ 0 ] );
6766		if ( this.icon ) {
6767			contents = contents.not( this.icon[ 0 ] );
6768		}
6769		if ( this.iconSpace ) {
6770			contents = contents.not( this.iconSpace[ 0 ] );
6771		}
6772		contents.remove();
6773
6774		this.label.append( this.options.label );
6775	},
6776
6777	refresh: function() {
6778		var checked = this.element[ 0 ].checked,
6779			isDisabled = this.element[ 0 ].disabled;
6780
6781		this._updateIcon( checked );
6782		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6783		if ( this.options.label !== null ) {
6784			this._updateLabel();
6785		}
6786
6787		if ( isDisabled !== this.options.disabled ) {
6788			this._setOptions( { "disabled": isDisabled } );
6789		}
6790	}
6791
6792} ] );
6793
6794var widgetsCheckboxradio = $.ui.checkboxradio;
6795
6796
6797/*!
6798 * jQuery UI Button 1.12.1
6799 * http://jqueryui.com
6800 *
6801 * Copyright jQuery Foundation and other contributors
6802 * Released under the MIT license.
6803 * http://jquery.org/license
6804 */
6805
6806//>>label: Button
6807//>>group: Widgets
6808//>>description: Enhances a form with themeable buttons.
6809//>>docs: http://api.jqueryui.com/button/
6810//>>demos: http://jqueryui.com/button/
6811//>>css.structure: ../../themes/base/core.css
6812//>>css.structure: ../../themes/base/button.css
6813//>>css.theme: ../../themes/base/theme.css
6814
6815
6816
6817$.widget( "ui.button", {
6818	version: "1.12.1",
6819	defaultElement: "<button>",
6820	options: {
6821		classes: {
6822			"ui-button": "ui-corner-all"
6823		},
6824		disabled: null,
6825		icon: null,
6826		iconPosition: "beginning",
6827		label: null,
6828		showLabel: true
6829	},
6830
6831	_getCreateOptions: function() {
6832		var disabled,
6833
6834			// This is to support cases like in jQuery Mobile where the base widget does have
6835			// an implementation of _getCreateOptions
6836			options = this._super() || {};
6837
6838		this.isInput = this.element.is( "input" );
6839
6840		disabled = this.element[ 0 ].disabled;
6841		if ( disabled != null ) {
6842			options.disabled = disabled;
6843		}
6844
6845		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6846		if ( this.originalLabel ) {
6847			options.label = this.originalLabel;
6848		}
6849
6850		return options;
6851	},
6852
6853	_create: function() {
6854		if ( !this.option.showLabel & !this.options.icon ) {
6855			this.options.showLabel = true;
6856		}
6857
6858		// We have to check the option again here even though we did in _getCreateOptions,
6859		// because null may have been passed on init which would override what was set in
6860		// _getCreateOptions
6861		if ( this.options.disabled == null ) {
6862			this.options.disabled = this.element[ 0 ].disabled || false;
6863		}
6864
6865		this.hasTitle = !!this.element.attr( "title" );
6866
6867		// Check to see if the label needs to be set or if its already correct
6868		if ( this.options.label && this.options.label !== this.originalLabel ) {
6869			if ( this.isInput ) {
6870				this.element.val( this.options.label );
6871			} else {
6872				this.element.html( this.options.label );
6873			}
6874		}
6875		this._addClass( "ui-button", "ui-widget" );
6876		this._setOption( "disabled", this.options.disabled );
6877		this._enhance();
6878
6879		if ( this.element.is( "a" ) ) {
6880			this._on( {
6881				"keyup": function( event ) {
6882					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6883						event.preventDefault();
6884
vendor: 11,926 bytes, lines 6885-7254
6885						// Support: PhantomJS <= 1.9, IE 8 Only
6886						// If a native click is available use it so we actually cause navigation
6887						// otherwise just trigger a click event
6888						if ( this.element[ 0 ].click ) {
6889							this.element[ 0 ].click();
6890						} else {
6891							this.element.trigger( "click" );
6892						}
6893					}
6894				}
6895			} );
6896		}
6897	},
6898
6899	_enhance: function() {
6900		if ( !this.element.is( "button" ) ) {
6901			this.element.attr( "role", "button" );
6902		}
6903
6904		if ( this.options.icon ) {
6905			this._updateIcon( "icon", this.options.icon );
6906			this._updateTooltip();
6907		}
6908	},
6909
6910	_updateTooltip: function() {
6911		this.title = this.element.attr( "title" );
6912
6913		if ( !this.options.showLabel && !this.title ) {
6914			this.element.attr( "title", this.options.label );
6915		}
6916	},
6917
6918	_updateIcon: function( option, value ) {
6919		var icon = option !== "iconPosition",
6920			position = icon ? this.options.iconPosition : value,
6921			displayBlock = position === "top" || position === "bottom";
6922
6923		// Create icon
6924		if ( !this.icon ) {
6925			this.icon = $( "<span>" );
6926
6927			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6928
6929			if ( !this.options.showLabel ) {
6930				this._addClass( "ui-button-icon-only" );
6931			}
6932		} else if ( icon ) {
6933
6934			// If we are updating the icon remove the old icon class
6935			this._removeClass( this.icon, null, this.options.icon );
6936		}
6937
6938		// If we are updating the icon add the new icon class
6939		if ( icon ) {
6940			this._addClass( this.icon, null, value );
6941		}
6942
6943		this._attachIcon( position );
6944
6945		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6946		// the iconSpace if there is one.
6947		if ( displayBlock ) {
6948			this._addClass( this.icon, null, "ui-widget-icon-block" );
6949			if ( this.iconSpace ) {
6950				this.iconSpace.remove();
6951			}
6952		} else {
6953
6954			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6955			// space if it does not exist
6956			if ( !this.iconSpace ) {
6957				this.iconSpace = $( "<span> </span>" );
6958				this._addClass( this.iconSpace, "ui-button-icon-space" );
6959			}
6960			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6961			this._attachIconSpace( position );
6962		}
6963	},
6964
6965	_destroy: function() {
6966		this.element.removeAttr( "role" );
6967
6968		if ( this.icon ) {
6969			this.icon.remove();
6970		}
6971		if ( this.iconSpace ) {
6972			this.iconSpace.remove();
6973		}
6974		if ( !this.hasTitle ) {
6975			this.element.removeAttr( "title" );
6976		}
6977	},
6978
6979	_attachIconSpace: function( iconPosition ) {
6980		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6981	},
6982
6983	_attachIcon: function( iconPosition ) {
6984		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6985	},
6986
6987	_setOptions: function( options ) {
6988		var newShowLabel = options.showLabel === undefined ?
6989				this.options.showLabel :
6990				options.showLabel,
6991			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6992
6993		if ( !newShowLabel && !newIcon ) {
6994			options.showLabel = true;
6995		}
6996		this._super( options );
6997	},
6998
6999	_setOption: function( key, value ) {
7000		if ( key === "icon" ) {
7001			if ( value ) {
7002				this._updateIcon( key, value );
7003			} else if ( this.icon ) {
7004				this.icon.remove();
7005				if ( this.iconSpace ) {
7006					this.iconSpace.remove();
7007				}
7008			}
7009		}
7010
7011		if ( key === "iconPosition" ) {
7012			this._updateIcon( key, value );
7013		}
7014
7015		// Make sure we can't end up with a button that has neither text nor icon
7016		if ( key === "showLabel" ) {
7017				this._toggleClass( "ui-button-icon-only", null, !value );
7018				this._updateTooltip();
7019		}
7020
7021		if ( key === "label" ) {
7022			if ( this.isInput ) {
7023				this.element.val( value );
7024			} else {
7025
7026				// If there is an icon, append it, else nothing then append the value
7027				// this avoids removal of the icon when setting label text
7028				this.element.html( value );
7029				if ( this.icon ) {
7030					this._attachIcon( this.options.iconPosition );
7031					this._attachIconSpace( this.options.iconPosition );
7032				}
7033			}
7034		}
7035
7036		this._super( key, value );
7037
7038		if ( key === "disabled" ) {
7039			this._toggleClass( null, "ui-state-disabled", value );
7040			this.element[ 0 ].disabled = value;
7041			if ( value ) {
7042				this.element.blur();
7043			}
7044		}
7045	},
7046
7047	refresh: function() {
7048
7049		// Make sure to only check disabled if its an element that supports this otherwise
7050		// check for the disabled class to determine state
7051		var isDisabled = this.element.is( "input, button" ) ?
7052			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7053
7054		if ( isDisabled !== this.options.disabled ) {
7055			this._setOptions( { disabled: isDisabled } );
7056		}
7057
7058		this._updateTooltip();
7059	}
7060} );
7061
7062// DEPRECATED
7063if ( $.uiBackCompat !== false ) {
7064
7065	// Text and Icons options
7066	$.widget( "ui.button", $.ui.button, {
7067		options: {
7068			text: true,
7069			icons: {
7070				primary: null,
7071				secondary: null
7072			}
7073		},
7074
7075		_create: function() {
7076			if ( this.options.showLabel && !this.options.text ) {
7077				this.options.showLabel = this.options.text;
7078			}
7079			if ( !this.options.showLabel && this.options.text ) {
7080				this.options.text = this.options.showLabel;
7081			}
7082			if ( !this.options.icon && ( this.options.icons.primary ||
7083					this.options.icons.secondary ) ) {
7084				if ( this.options.icons.primary ) {
7085					this.options.icon = this.options.icons.primary;
7086				} else {
7087					this.options.icon = this.options.icons.secondary;
7088					this.options.iconPosition = "end";
7089				}
7090			} else if ( this.options.icon ) {
7091				this.options.icons.primary = this.options.icon;
7092			}
7093			this._super();
7094		},
7095
7096		_setOption: function( key, value ) {
7097			if ( key === "text" ) {
7098				this._super( "showLabel", value );
7099				return;
7100			}
7101			if ( key === "showLabel" ) {
7102				this.options.text = value;
7103			}
7104			if ( key === "icon" ) {
7105				this.options.icons.primary = value;
7106			}
7107			if ( key === "icons" ) {
7108				if ( value.primary ) {
7109					this._super( "icon", value.primary );
7110					this._super( "iconPosition", "beginning" );
7111				} else if ( value.secondary ) {
7112					this._super( "icon", value.secondary );
7113					this._super( "iconPosition", "end" );
7114				}
7115			}
7116			this._superApply( arguments );
7117		}
7118	} );
7119
7120	$.fn.button = ( function( orig ) {
7121		return function() {
7122			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7123					( this.length && this[ 0 ].tagName === "INPUT" && (
7124						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7125					) ) ) {
7126				return orig.apply( this, arguments );
7127			}
7128			if ( !$.ui.checkboxradio ) {
7129				$.error( "Checkboxradio widget missing" );
7130			}
7131			if ( arguments.length === 0 ) {
7132				return this.checkboxradio( {
7133					"icon": false
7134				} );
7135			}
7136			return this.checkboxradio.apply( this, arguments );
7137		};
7138	} )( $.fn.button );
7139
7140	$.fn.buttonset = function() {
7141		if ( !$.ui.controlgroup ) {
7142			$.error( "Controlgroup widget missing" );
7143		}
7144		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7145			return this.controlgroup.apply( this,
7146				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7147		}
7148		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7149			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7150		}
7151		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7152			arguments[ 0 ].items = {
7153				button: arguments[ 0 ].items
7154			};
7155		}
7156		return this.controlgroup.apply( this, arguments );
7157	};
7158}
7159
7160var widgetsButton = $.ui.button;
7161
7162
7163// jscs:disable maximumLineLength
7164/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7165/*!
7166 * jQuery UI Datepicker 1.12.1
7167 * http://jqueryui.com
7168 *
7169 * Copyright jQuery Foundation and other contributors
7170 * Released under the MIT license.
7171 * http://jquery.org/license
7172 */
7173
7174//>>label: Datepicker
7175//>>group: Widgets
7176//>>description: Displays a calendar from an input or inline for selecting dates.
7177//>>docs: http://api.jqueryui.com/datepicker/
7178//>>demos: http://jqueryui.com/datepicker/
7179//>>css.structure: ../../themes/base/core.css
7180//>>css.structure: ../../themes/base/datepicker.css
7181//>>css.theme: ../../themes/base/theme.css
7182
7183
7184
7185$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7186
7187var datepicker_instActive;
7188
7189function datepicker_getZindex( elem ) {
7190	var position, value;
7191	while ( elem.length && elem[ 0 ] !== document ) {
7192
7193		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7194		// This makes behavior of this function consistent across browsers
7195		// WebKit always returns auto if the element is positioned
7196		position = elem.css( "position" );
7197		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7198
7199			// IE returns 0 when zIndex is not specified
7200			// other browsers return a string
7201			// we ignore the case of nested elements with an explicit value of 0
7202			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7203			value = parseInt( elem.css( "zIndex" ), 10 );
7204			if ( !isNaN( value ) && value !== 0 ) {
7205				return value;
7206			}
7207		}
7208		elem = elem.parent();
7209	}
7210
7211	return 0;
7212}
7213/* Date picker manager.
7214   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7215   Settings for (groups of) date pickers are maintained in an instance object,
7216   allowing multiple different settings on the same page. */
7217
7218function Datepicker() {
7219	this._curInst = null; // The current instance in use
7220	this._keyEvent = false; // If the last event was a key event
7221	this._disabledInputs = []; // List of date picker inputs that have been disabled
7222	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7223	this._inDialog = false; // True if showing within a "dialog", false if not
7224	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7225	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7226	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7227	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7228	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7229	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7230	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7231	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7232	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7233	this.regional = []; // Available regional settings, indexed by language code
7234	this.regional[ "" ] = { // Default regional settings
7235		closeText: "Done", // Display text for close link
7236		prevText: "Prev", // Display text for previous month link
7237		nextText: "Next", // Display text for next month link
7238		currentText: "Today", // Display text for current month link
7239		monthNames: [ "January","February","March","April","May","June",
7240			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7241		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7242		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7243		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7244		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7245		weekHeader: "Wk", // Column header for week of the year
7246		dateFormat: "mm/dd/yy", // See format options on parseDate
7247		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7248		isRTL: false, // True if right-to-left language, false if left-to-right
7249		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7250		yearSuffix: "" // Additional text to append to the year in the month headers
7251	};
7252	this._defaults = { // Global defaults for all the date picker instances
7253		showOn: "focus", // "focus" for popup on focus,
7254			// "button" for trigger button, or "both" for either
vendor: 6,628 bytes, lines 7255-7387
7255		showAnim: "fadeIn", // Name of jQuery animation for popup
7256		showOptions: {}, // Options for enhanced animations
7257		defaultDate: null, // Used when field is blank: actual date,
7258			// +/-number for offset from today, null for today
7259		appendText: "", // Display text following the input box, e.g. showing the format
7260		buttonText: "...", // Text for trigger button
7261		buttonImage: "", // URL for trigger button image
7262		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7263		hideIfNoPrevNext: false, // True to hide next/previous month links
7264			// if not applicable, false to just disable them
7265		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7266		gotoCurrent: false, // True if today link goes back to current selection instead
7267		changeMonth: false, // True if month can be selected directly, false if only prev/next
7268		changeYear: false, // True if year can be selected directly, false if only prev/next
7269		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7270			// either relative to today's year (-nn:+nn), relative to currently displayed year
7271			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7272		showOtherMonths: false, // True to show dates in other months, false to leave blank
7273		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7274		showWeek: false, // True to show week of the year, false to not show it
7275		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7276			// takes a Date and returns the number of the week for it
7277		shortYearCutoff: "+10", // Short year values < this are in the current century,
7278			// > this are in the previous century,
7279			// string value starting with "+" for current year + value
7280		minDate: null, // The earliest selectable date, or null for no limit
7281		maxDate: null, // The latest selectable date, or null for no limit
7282		duration: "fast", // Duration of display/closure
7283		beforeShowDay: null, // Function that takes a date and returns an array with
7284			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7285			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7286		beforeShow: null, // Function that takes an input field and
7287			// returns a set of custom settings for the date picker
7288		onSelect: null, // Define a callback function when a date is selected
7289		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7290		onClose: null, // Define a callback function when the datepicker is closed
7291		numberOfMonths: 1, // Number of months to show at a time
7292		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7293		stepMonths: 1, // Number of months to step back/forward
7294		stepBigMonths: 12, // Number of months to step back/forward for the big links
7295		altField: "", // Selector for an alternate field to store selected dates into
7296		altFormat: "", // The date format to use for the alternate field
7297		constrainInput: true, // The input is constrained by the current date format
7298		showButtonPanel: false, // True to show button panel, false to not show it
7299		autoSize: false, // True to size the input for the date format, false to leave as is
7300		disabled: false // The initial disabled state
7301	};
7302	$.extend( this._defaults, this.regional[ "" ] );
7303	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7304	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7305	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7306}
7307
7308$.extend( Datepicker.prototype, {
7309	/* Class name added to elements to indicate already configured with a date picker. */
7310	markerClassName: "hasDatepicker",
7311
7312	//Keep track of the maximum number of rows displayed (see #7043)
7313	maxRows: 4,
7314
7315	// TODO rename to "widget" when switching to widget factory
7316	_widgetDatepicker: function() {
7317		return this.dpDiv;
7318	},
7319
7320	/* Override the default settings for all instances of the date picker.
7321	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7322	 * @return the manager object
7323	 */
7324	setDefaults: function( settings ) {
7325		datepicker_extendRemove( this._defaults, settings || {} );
7326		return this;
7327	},
7328
7329	/* Attach the date picker to a jQuery selection.
7330	 * @param  target	element - the target input field or division or span
7331	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7332	 */
7333	_attachDatepicker: function( target, settings ) {
7334		var nodeName, inline, inst;
7335		nodeName = target.nodeName.toLowerCase();
7336		inline = ( nodeName === "div" || nodeName === "span" );
7337		if ( !target.id ) {
7338			this.uuid += 1;
7339			target.id = "dp" + this.uuid;
7340		}
7341		inst = this._newInst( $( target ), inline );
7342		inst.settings = $.extend( {}, settings || {} );
7343		if ( nodeName === "input" ) {
7344			this._connectDatepicker( target, inst );
7345		} else if ( inline ) {
7346			this._inlineDatepicker( target, inst );
7347		}
7348	},
7349
7350	/* Create a new instance object. */
7351	_newInst: function( target, inline ) {
7352		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7353		return { id: id, input: target, // associated target
7354			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7355			drawMonth: 0, drawYear: 0, // month being drawn
7356			inline: inline, // is datepicker inline or not
7357			dpDiv: ( !inline ? this.dpDiv : // presentation div
7358			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7359	},
7360
7361	/* Attach the date picker to an input field. */
7362	_connectDatepicker: function( target, inst ) {
7363		var input = $( target );
7364		inst.append = $( [] );
7365		inst.trigger = $( [] );
7366		if ( input.hasClass( this.markerClassName ) ) {
7367			return;
7368		}
7369		this._attachments( input, inst );
7370		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7371			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7372		this._autoSize( inst );
7373		$.data( target, "datepicker", inst );
7374
7375		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7376		if ( inst.settings.disabled ) {
7377			this._disableDatepicker( target );
7378		}
7379	},
7380
7381	/* Make attachments based on settings. */
7382	_attachments: function( input, inst ) {
7383		var showOn, buttonText, buttonImage,
7384			appendText = this._get( inst, "appendText" ),
7385			isRTL = this._get( inst, "isRTL" );
7386
7387		if ( inst.append ) {
vendor: 13,169 bytes, lines 7388-7758
7388			inst.append.remove();
7389		}
7390		if ( appendText ) {
7391			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7392			input[ isRTL ? "before" : "after" ]( inst.append );
7393		}
7394
7395		input.off( "focus", this._showDatepicker );
7396
7397		if ( inst.trigger ) {
7398			inst.trigger.remove();
7399		}
7400
7401		showOn = this._get( inst, "showOn" );
7402		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7403			input.on( "focus", this._showDatepicker );
7404		}
7405		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7406			buttonText = this._get( inst, "buttonText" );
7407			buttonImage = this._get( inst, "buttonImage" );
7408			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7409				$( "<img/>" ).addClass( this._triggerClass ).
7410					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7411				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7412					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7413					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7414			input[ isRTL ? "before" : "after" ]( inst.trigger );
7415			inst.trigger.on( "click", function() {
7416				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7417					$.datepicker._hideDatepicker();
7418				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7419					$.datepicker._hideDatepicker();
7420					$.datepicker._showDatepicker( input[ 0 ] );
7421				} else {
7422					$.datepicker._showDatepicker( input[ 0 ] );
7423				}
7424				return false;
7425			} );
7426		}
7427	},
7428
7429	/* Apply the maximum length for the date format. */
7430	_autoSize: function( inst ) {
7431		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7432			var findMax, max, maxI, i,
7433				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7434				dateFormat = this._get( inst, "dateFormat" );
7435
7436			if ( dateFormat.match( /[DM]/ ) ) {
7437				findMax = function( names ) {
7438					max = 0;
7439					maxI = 0;
7440					for ( i = 0; i < names.length; i++ ) {
7441						if ( names[ i ].length > max ) {
7442							max = names[ i ].length;
7443							maxI = i;
7444						}
7445					}
7446					return maxI;
7447				};
7448				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7449					"monthNames" : "monthNamesShort" ) ) ) );
7450				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7451					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7452			}
7453			inst.input.attr( "size", this._formatDate( inst, date ).length );
7454		}
7455	},
7456
7457	/* Attach an inline date picker to a div. */
7458	_inlineDatepicker: function( target, inst ) {
7459		var divSpan = $( target );
7460		if ( divSpan.hasClass( this.markerClassName ) ) {
7461			return;
7462		}
7463		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7464		$.data( target, "datepicker", inst );
7465		this._setDate( inst, this._getDefaultDate( inst ), true );
7466		this._updateDatepicker( inst );
7467		this._updateAlternate( inst );
7468
7469		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7470		if ( inst.settings.disabled ) {
7471			this._disableDatepicker( target );
7472		}
7473
7474		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7475		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7476		inst.dpDiv.css( "display", "block" );
7477	},
7478
7479	/* Pop-up the date picker in a "dialog" box.
7480	 * @param  input element - ignored
7481	 * @param  date	string or Date - the initial date to display
7482	 * @param  onSelect  function - the function to call when a date is selected
7483	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7484	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7485	 *					event - with x/y coordinates or
7486	 *					leave empty for default (screen centre)
7487	 * @return the manager object
7488	 */
7489	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7490		var id, browserWidth, browserHeight, scrollX, scrollY,
7491			inst = this._dialogInst; // internal instance
7492
7493		if ( !inst ) {
7494			this.uuid += 1;
7495			id = "dp" + this.uuid;
7496			this._dialogInput = $( "<input type='text' id='" + id +
7497				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7498			this._dialogInput.on( "keydown", this._doKeyDown );
7499			$( "body" ).append( this._dialogInput );
7500			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7501			inst.settings = {};
7502			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7503		}
7504		datepicker_extendRemove( inst.settings, settings || {} );
7505		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7506		this._dialogInput.val( date );
7507
7508		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7509		if ( !this._pos ) {
7510			browserWidth = document.documentElement.clientWidth;
7511			browserHeight = document.documentElement.clientHeight;
7512			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7513			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7514			this._pos = // should use actual width/height below
7515				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7516		}
7517
7518		// Move input on screen for focus, but hidden behind dialog
7519		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7520		inst.settings.onSelect = onSelect;
7521		this._inDialog = true;
7522		this.dpDiv.addClass( this._dialogClass );
7523		this._showDatepicker( this._dialogInput[ 0 ] );
7524		if ( $.blockUI ) {
7525			$.blockUI( this.dpDiv );
7526		}
7527		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7528		return this;
7529	},
7530
7531	/* Detach a datepicker from its control.
7532	 * @param  target	element - the target input field or division or span
7533	 */
7534	_destroyDatepicker: function( target ) {
7535		var nodeName,
7536			$target = $( target ),
7537			inst = $.data( target, "datepicker" );
7538
7539		if ( !$target.hasClass( this.markerClassName ) ) {
7540			return;
7541		}
7542
7543		nodeName = target.nodeName.toLowerCase();
7544		$.removeData( target, "datepicker" );
7545		if ( nodeName === "input" ) {
7546			inst.append.remove();
7547			inst.trigger.remove();
7548			$target.removeClass( this.markerClassName ).
7549				off( "focus", this._showDatepicker ).
7550				off( "keydown", this._doKeyDown ).
7551				off( "keypress", this._doKeyPress ).
7552				off( "keyup", this._doKeyUp );
7553		} else if ( nodeName === "div" || nodeName === "span" ) {
7554			$target.removeClass( this.markerClassName ).empty();
7555		}
7556
7557		if ( datepicker_instActive === inst ) {
7558			datepicker_instActive = null;
7559		}
7560	},
7561
7562	/* Enable the date picker to a jQuery selection.
7563	 * @param  target	element - the target input field or division or span
7564	 */
7565	_enableDatepicker: function( target ) {
7566		var nodeName, inline,
7567			$target = $( target ),
7568			inst = $.data( target, "datepicker" );
7569
7570		if ( !$target.hasClass( this.markerClassName ) ) {
7571			return;
7572		}
7573
7574		nodeName = target.nodeName.toLowerCase();
7575		if ( nodeName === "input" ) {
7576			target.disabled = false;
7577			inst.trigger.filter( "button" ).
7578				each( function() { this.disabled = false; } ).end().
7579				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7580		} else if ( nodeName === "div" || nodeName === "span" ) {
7581			inline = $target.children( "." + this._inlineClass );
7582			inline.children().removeClass( "ui-state-disabled" );
7583			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7584				prop( "disabled", false );
7585		}
7586		this._disabledInputs = $.map( this._disabledInputs,
7587			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7588	},
7589
7590	/* Disable the date picker to a jQuery selection.
7591	 * @param  target	element - the target input field or division or span
7592	 */
7593	_disableDatepicker: function( target ) {
7594		var nodeName, inline,
7595			$target = $( target ),
7596			inst = $.data( target, "datepicker" );
7597
7598		if ( !$target.hasClass( this.markerClassName ) ) {
7599			return;
7600		}
7601
7602		nodeName = target.nodeName.toLowerCase();
7603		if ( nodeName === "input" ) {
7604			target.disabled = true;
7605			inst.trigger.filter( "button" ).
7606				each( function() { this.disabled = true; } ).end().
7607				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7608		} else if ( nodeName === "div" || nodeName === "span" ) {
7609			inline = $target.children( "." + this._inlineClass );
7610			inline.children().addClass( "ui-state-disabled" );
7611			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7612				prop( "disabled", true );
7613		}
7614		this._disabledInputs = $.map( this._disabledInputs,
7615			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7616		this._disabledInputs[ this._disabledInputs.length ] = target;
7617	},
7618
7619	/* Is the first field in a jQuery collection disabled as a datepicker?
7620	 * @param  target	element - the target input field or division or span
7621	 * @return boolean - true if disabled, false if enabled
7622	 */
7623	_isDisabledDatepicker: function( target ) {
7624		if ( !target ) {
7625			return false;
7626		}
7627		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7628			if ( this._disabledInputs[ i ] === target ) {
7629				return true;
7630			}
7631		}
7632		return false;
7633	},
7634
7635	/* Retrieve the instance data for the target control.
7636	 * @param  target  element - the target input field or division or span
7637	 * @return  object - the associated instance data
7638	 * @throws  error if a jQuery problem getting data
7639	 */
7640	_getInst: function( target ) {
7641		try {
7642			return $.data( target, "datepicker" );
7643		}
7644		catch ( err ) {
7645			throw "Missing instance data for this datepicker";
7646		}
7647	},
7648
7649	/* Update or retrieve the settings for a date picker attached to an input field or division.
7650	 * @param  target  element - the target input field or division or span
7651	 * @param  name	object - the new settings to update or
7652	 *				string - the name of the setting to change or retrieve,
7653	 *				when retrieving also "all" for all instance settings or
7654	 *				"defaults" for all global defaults
7655	 * @param  value   any - the new value for the setting
7656	 *				(omit if above is an object or to retrieve a value)
7657	 */
7658	_optionDatepicker: function( target, name, value ) {
7659		var settings, date, minDate, maxDate,
7660			inst = this._getInst( target );
7661
7662		if ( arguments.length === 2 && typeof name === "string" ) {
7663			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7664				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7665				this._get( inst, name ) ) : null ) );
7666		}
7667
7668		settings = name || {};
7669		if ( typeof name === "string" ) {
7670			settings = {};
7671			settings[ name ] = value;
7672		}
7673
7674		if ( inst ) {
7675			if ( this._curInst === inst ) {
7676				this._hideDatepicker();
7677			}
7678
7679			date = this._getDateDatepicker( target, true );
7680			minDate = this._getMinMaxDate( inst, "min" );
7681			maxDate = this._getMinMaxDate( inst, "max" );
7682			datepicker_extendRemove( inst.settings, settings );
7683
7684			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7686				inst.settings.minDate = this._formatDate( inst, minDate );
7687			}
7688			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7689				inst.settings.maxDate = this._formatDate( inst, maxDate );
7690			}
7691			if ( "disabled" in settings ) {
7692				if ( settings.disabled ) {
7693					this._disableDatepicker( target );
7694				} else {
7695					this._enableDatepicker( target );
7696				}
7697			}
7698			this._attachments( $( target ), inst );
7699			this._autoSize( inst );
7700			this._setDate( inst, date );
7701			this._updateAlternate( inst );
7702			this._updateDatepicker( inst );
7703		}
7704	},
7705
7706	// Change method deprecated
7707	_changeDatepicker: function( target, name, value ) {
7708		this._optionDatepicker( target, name, value );
7709	},
7710
7711	/* Redraw the date picker attached to an input field or division.
7712	 * @param  target  element - the target input field or division or span
7713	 */
7714	_refreshDatepicker: function( target ) {
7715		var inst = this._getInst( target );
7716		if ( inst ) {
7717			this._updateDatepicker( inst );
7718		}
7719	},
7720
7721	/* Set the dates for a jQuery selection.
7722	 * @param  target element - the target input field or division or span
7723	 * @param  date	Date - the new date
7724	 */
7725	_setDateDatepicker: function( target, date ) {
7726		var inst = this._getInst( target );
7727		if ( inst ) {
7728			this._setDate( inst, date );
7729			this._updateDatepicker( inst );
7730			this._updateAlternate( inst );
7731		}
7732	},
7733
7734	/* Get the date(s) for the first entry in a jQuery selection.
7735	 * @param  target element - the target input field or division or span
7736	 * @param  noDefault boolean - true if no default date is to be used
7737	 * @return Date - the current date
7738	 */
7739	_getDateDatepicker: function( target, noDefault ) {
7740		var inst = this._getInst( target );
7741		if ( inst && !inst.inline ) {
7742			this._setDateFromField( inst, noDefault );
7743		}
7744		return ( inst ? this._getDate( inst ) : null );
7745	},
7746
7747	/* Handle keystrokes. */
7748	_doKeyDown: function( event ) {
7749		var onSelect, dateStr, sel,
7750			inst = $.datepicker._getInst( event.target ),
7751			handled = true,
7752			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7753
7754		inst._keyEvent = true;
7755		if ( $.datepicker._datepickerShowing ) {
7756			switch ( event.keyCode ) {
7757				case 9: $.datepicker._hideDatepicker();
7758						handled = false;
vendor: 4,635 bytes, lines 7759-7886
7759						break; // hide on tab out
7760				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7761									$.datepicker._currentClass + ")", inst.dpDiv );
7762						if ( sel[ 0 ] ) {
7763							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7764						}
7765
7766						onSelect = $.datepicker._get( inst, "onSelect" );
7767						if ( onSelect ) {
7768							dateStr = $.datepicker._formatDate( inst );
7769
7770							// Trigger custom callback
7771							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7772						} else {
7773							$.datepicker._hideDatepicker();
7774						}
7775
7776						return false; // don't submit the form
7777				case 27: $.datepicker._hideDatepicker();
7778						break; // hide on escape
7779				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7780							-$.datepicker._get( inst, "stepBigMonths" ) :
7781							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7782						break; // previous month/year on page up/+ ctrl
7783				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7784							+$.datepicker._get( inst, "stepBigMonths" ) :
7785							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7786						break; // next month/year on page down/+ ctrl
7787				case 35: if ( event.ctrlKey || event.metaKey ) {
7788							$.datepicker._clearDate( event.target );
7789						}
7790						handled = event.ctrlKey || event.metaKey;
7791						break; // clear on ctrl or command +end
7792				case 36: if ( event.ctrlKey || event.metaKey ) {
7793							$.datepicker._gotoToday( event.target );
7794						}
7795						handled = event.ctrlKey || event.metaKey;
7796						break; // current on ctrl or command +home
7797				case 37: if ( event.ctrlKey || event.metaKey ) {
7798							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7799						}
7800						handled = event.ctrlKey || event.metaKey;
7801
7802						// -1 day on ctrl or command +left
7803						if ( event.originalEvent.altKey ) {
7804							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7805								-$.datepicker._get( inst, "stepBigMonths" ) :
7806								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7807						}
7808
7809						// next month/year on alt +left on Mac
7810						break;
7811				case 38: if ( event.ctrlKey || event.metaKey ) {
7812							$.datepicker._adjustDate( event.target, -7, "D" );
7813						}
7814						handled = event.ctrlKey || event.metaKey;
7815						break; // -1 week on ctrl or command +up
7816				case 39: if ( event.ctrlKey || event.metaKey ) {
7817							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7818						}
7819						handled = event.ctrlKey || event.metaKey;
7820
7821						// +1 day on ctrl or command +right
7822						if ( event.originalEvent.altKey ) {
7823							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7824								+$.datepicker._get( inst, "stepBigMonths" ) :
7825								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7826						}
7827
7828						// next month/year on alt +right
7829						break;
7830				case 40: if ( event.ctrlKey || event.metaKey ) {
7831							$.datepicker._adjustDate( event.target, +7, "D" );
7832						}
7833						handled = event.ctrlKey || event.metaKey;
7834						break; // +1 week on ctrl or command +down
7835				default: handled = false;
7836			}
7837		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7838			$.datepicker._showDatepicker( this );
7839		} else {
7840			handled = false;
7841		}
7842
7843		if ( handled ) {
7844			event.preventDefault();
7845			event.stopPropagation();
7846		}
7847	},
7848
7849	/* Filter entered characters - based on date format. */
7850	_doKeyPress: function( event ) {
7851		var chars, chr,
7852			inst = $.datepicker._getInst( event.target );
7853
7854		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7855			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7856			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7857			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7858		}
7859	},
7860
7861	/* Synchronise manual entry and field/alternate field. */
7862	_doKeyUp: function( event ) {
7863		var date,
7864			inst = $.datepicker._getInst( event.target );
7865
7866		if ( inst.input.val() !== inst.lastVal ) {
7867			try {
7868				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7869					( inst.input ? inst.input.val() : null ),
7870					$.datepicker._getFormatConfig( inst ) );
7871
7872				if ( date ) { // only if valid
7873					$.datepicker._setDateFromField( inst );
7874					$.datepicker._updateAlternate( inst );
7875					$.datepicker._updateDatepicker( inst );
7876				}
7877			}
7878			catch ( err ) {
7879			}
7880		}
7881		return true;
7882	},
7883
7884	/* Pop-up the date picker for a given input field.
7885	 * If false returned from beforeShow event handler do not show.
7886	 * @param  input  element - the input field attached to the date picker or
vendor: 9,739 bytes, lines 7887-8165
7887	 *					event - if triggered by focus
7888	 */
7889	_showDatepicker: function( input ) {
7890		input = input.target || input;
7891		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7892			input = $( "input", input.parentNode )[ 0 ];
7893		}
7894
7895		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7896			return;
7897		}
7898
7899		var inst, beforeShow, beforeShowSettings, isFixed,
7900			offset, showAnim, duration;
7901
7902		inst = $.datepicker._getInst( input );
7903		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7904			$.datepicker._curInst.dpDiv.stop( true, true );
7905			if ( inst && $.datepicker._datepickerShowing ) {
7906				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7907			}
7908		}
7909
7910		beforeShow = $.datepicker._get( inst, "beforeShow" );
7911		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7912		if ( beforeShowSettings === false ) {
7913			return;
7914		}
7915		datepicker_extendRemove( inst.settings, beforeShowSettings );
7916
7917		inst.lastVal = null;
7918		$.datepicker._lastInput = input;
7919		$.datepicker._setDateFromField( inst );
7920
7921		if ( $.datepicker._inDialog ) { // hide cursor
7922			input.value = "";
7923		}
7924		if ( !$.datepicker._pos ) { // position below input
7925			$.datepicker._pos = $.datepicker._findPos( input );
7926			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7927		}
7928
7929		isFixed = false;
7930		$( input ).parents().each( function() {
7931			isFixed |= $( this ).css( "position" ) === "fixed";
7932			return !isFixed;
7933		} );
7934
7935		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7936		$.datepicker._pos = null;
7937
7938		//to avoid flashes on Firefox
7939		inst.dpDiv.empty();
7940
7941		// determine sizing offscreen
7942		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7943		$.datepicker._updateDatepicker( inst );
7944
7945		// fix width for dynamic number of date pickers
7946		// and adjust position before showing
7947		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7948		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7949			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7950			left: offset.left + "px", top: offset.top + "px" } );
7951
7952		if ( !inst.inline ) {
7953			showAnim = $.datepicker._get( inst, "showAnim" );
7954			duration = $.datepicker._get( inst, "duration" );
7955			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7956			$.datepicker._datepickerShowing = true;
7957
7958			if ( $.effects && $.effects.effect[ showAnim ] ) {
7959				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7960			} else {
7961				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7962			}
7963
7964			if ( $.datepicker._shouldFocusInput( inst ) ) {
7965				inst.input.trigger( "focus" );
7966			}
7967
7968			$.datepicker._curInst = inst;
7969		}
7970	},
7971
7972	/* Generate the date picker content. */
7973	_updateDatepicker: function( inst ) {
7974		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7975		datepicker_instActive = inst; // for delegate hover events
7976		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7977		this._attachHandlers( inst );
7978
7979		var origyearshtml,
7980			numMonths = this._getNumberOfMonths( inst ),
7981			cols = numMonths[ 1 ],
7982			width = 17,
7983			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7984
7985		if ( activeCell.length > 0 ) {
7986			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7987		}
7988
7989		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7990		if ( cols > 1 ) {
7991			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7992		}
7993		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7994			"Class" ]( "ui-datepicker-multi" );
7995		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7996			"Class" ]( "ui-datepicker-rtl" );
7997
7998		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7999			inst.input.trigger( "focus" );
8000		}
8001
8002		// Deffered render of the years select (to avoid flashes on Firefox)
8003		if ( inst.yearshtml ) {
8004			origyearshtml = inst.yearshtml;
8005			setTimeout( function() {
8006
8007				//assure that inst.yearshtml didn't change.
8008				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8009					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8010				}
8011				origyearshtml = inst.yearshtml = null;
8012			}, 0 );
8013		}
8014	},
8015
8016	// #6694 - don't focus the input if it's already focused
8017	// this breaks the change event in IE
8018	// Support: IE and jQuery <1.9
8019	_shouldFocusInput: function( inst ) {
8020		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8021	},
8022
8023	/* Check positioning to remain on screen. */
8024	_checkOffset: function( inst, offset, isFixed ) {
8025		var dpWidth = inst.dpDiv.outerWidth(),
8026			dpHeight = inst.dpDiv.outerHeight(),
8027			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8028			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8029			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8030			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8031
8032		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8033		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8034		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8035
8036		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8037		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8038			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8039		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8040			Math.abs( dpHeight + inputHeight ) : 0 );
8041
8042		return offset;
8043	},
8044
8045	/* Find an object's position on the screen. */
8046	_findPos: function( obj ) {
8047		var position,
8048			inst = this._getInst( obj ),
8049			isRTL = this._get( inst, "isRTL" );
8050
8051		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8052			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8053		}
8054
8055		position = $( obj ).offset();
8056		return [ position.left, position.top ];
8057	},
8058
8059	/* Hide the date picker from view.
8060	 * @param  input  element - the input field attached to the date picker
8061	 */
8062	_hideDatepicker: function( input ) {
8063		var showAnim, duration, postProcess, onClose,
8064			inst = this._curInst;
8065
8066		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8067			return;
8068		}
8069
8070		if ( this._datepickerShowing ) {
8071			showAnim = this._get( inst, "showAnim" );
8072			duration = this._get( inst, "duration" );
8073			postProcess = function() {
8074				$.datepicker._tidyDialog( inst );
8075			};
8076
8077			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8078			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8079				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8080			} else {
8081				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8082					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8083			}
8084
8085			if ( !showAnim ) {
8086				postProcess();
8087			}
8088			this._datepickerShowing = false;
8089
8090			onClose = this._get( inst, "onClose" );
8091			if ( onClose ) {
8092				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8093			}
8094
8095			this._lastInput = null;
8096			if ( this._inDialog ) {
8097				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8098				if ( $.blockUI ) {
8099					$.unblockUI();
8100					$( "body" ).append( this.dpDiv );
8101				}
8102			}
8103			this._inDialog = false;
8104		}
8105	},
8106
8107	/* Tidy up after a dialog display. */
8108	_tidyDialog: function( inst ) {
8109		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8110	},
8111
8112	/* Close date picker if clicked elsewhere. */
8113	_checkExternalClick: function( event ) {
8114		if ( !$.datepicker._curInst ) {
8115			return;
8116		}
8117
8118		var $target = $( event.target ),
8119			inst = $.datepicker._getInst( $target[ 0 ] );
8120
8121		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8122				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8123				!$target.hasClass( $.datepicker.markerClassName ) &&
8124				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8125				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8126			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8127				$.datepicker._hideDatepicker();
8128		}
8129	},
8130
8131	/* Adjust one of the date sub-fields. */
8132	_adjustDate: function( id, offset, period ) {
8133		var target = $( id ),
8134			inst = this._getInst( target[ 0 ] );
8135
8136		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8137			return;
8138		}
8139		this._adjustInstDate( inst, offset +
8140			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8141			period );
8142		this._updateDatepicker( inst );
8143	},
8144
8145	/* Action for current link. */
8146	_gotoToday: function( id ) {
8147		var date,
8148			target = $( id ),
8149			inst = this._getInst( target[ 0 ] );
8150
8151		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8152			inst.selectedDay = inst.currentDay;
8153			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154			inst.drawYear = inst.selectedYear = inst.currentYear;
8155		} else {
8156			date = new Date();
8157			inst.selectedDay = date.getDate();
8158			inst.drawMonth = inst.selectedMonth = date.getMonth();
8159			inst.drawYear = inst.selectedYear = date.getFullYear();
8160		}
8161		this._notifyChange( inst );
8162		this._adjustDate( target );
8163	},
8164
8165	/* Action for selecting a new month/year. */
vendor: 2,372 bytes, lines 8166-8241
8166	_selectMonthYear: function( id, select, period ) {
8167		var target = $( id ),
8168			inst = this._getInst( target[ 0 ] );
8169
8170		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8171		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8172			parseInt( select.options[ select.selectedIndex ].value, 10 );
8173
8174		this._notifyChange( inst );
8175		this._adjustDate( target );
8176	},
8177
8178	/* Action for selecting a day. */
8179	_selectDay: function( id, month, year, td ) {
8180		var inst,
8181			target = $( id );
8182
8183		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8184			return;
8185		}
8186
8187		inst = this._getInst( target[ 0 ] );
8188		inst.selectedDay = inst.currentDay = $( "a", td ).html();
8189		inst.selectedMonth = inst.currentMonth = month;
8190		inst.selectedYear = inst.currentYear = year;
8191		this._selectDate( id, this._formatDate( inst,
8192			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8193	},
8194
8195	/* Erase the input field and hide the date picker. */
8196	_clearDate: function( id ) {
8197		var target = $( id );
8198		this._selectDate( target, "" );
8199	},
8200
8201	/* Update the input field with the selected date. */
8202	_selectDate: function( id, dateStr ) {
8203		var onSelect,
8204			target = $( id ),
8205			inst = this._getInst( target[ 0 ] );
8206
8207		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8208		if ( inst.input ) {
8209			inst.input.val( dateStr );
8210		}
8211		this._updateAlternate( inst );
8212
8213		onSelect = this._get( inst, "onSelect" );
8214		if ( onSelect ) {
8215			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8216		} else if ( inst.input ) {
8217			inst.input.trigger( "change" ); // fire the change event
8218		}
8219
8220		if ( inst.inline ) {
8221			this._updateDatepicker( inst );
8222		} else {
8223			this._hideDatepicker();
8224			this._lastInput = inst.input[ 0 ];
8225			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8226				inst.input.trigger( "focus" ); // restore focus
8227			}
8228			this._lastInput = null;
8229		}
8230	},
8231
8232	/* Update any alternate field to synchronise with the main field. */
8233	_updateAlternate: function( inst ) {
8234		var altFormat, date, dateStr,
8235			altField = this._get( inst, "altField" );
8236
8237		if ( altField ) { // update alternate field too
8238			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8239			date = this._getDate( inst );
8240			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8241			$
vendor: 13,647 bytes, lines 8241-8680
8241( altField ).val( dateStr );
8242		}
8243	},
8244
8245	/* Set as beforeShowDay function to prevent selection of weekends.
8246	 * @param  date  Date - the date to customise
8247	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248	 */
8249	noWeekends: function( date ) {
8250		var day = date.getDay();
8251		return [ ( day > 0 && day < 6 ), "" ];
8252	},
8253
8254	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255	 * @param  date  Date - the date to get the week for
8256	 * @return  number - the number of the week within the year that contains this date
8257	 */
8258	iso8601Week: function( date ) {
8259		var time,
8260			checkDate = new Date( date.getTime() );
8261
8262		// Find Thursday of this week starting on Monday
8263		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8264
8265		time = checkDate.getTime();
8266		checkDate.setMonth( 0 ); // Compare with Jan 1
8267		checkDate.setDate( 1 );
8268		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8269	},
8270
8271	/* Parse a string value into a date object.
8272	 * See formatDate below for the possible formats.
8273	 *
8274	 * @param  format string - the expected format of the date
8275	 * @param  value string - the date in the above format
8276	 * @param  settings Object - attributes include:
8277	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8278	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8279	 *					dayNames		string[7] - names of the days from Sunday (optional)
8280	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8281	 *					monthNames		string[12] - names of the months (optional)
8282	 * @return  Date - the extracted date value or null if value is blank
8283	 */
8284	parseDate: function( format, value, settings ) {
8285		if ( format == null || value == null ) {
8286			throw "Invalid arguments";
8287		}
8288
8289		value = ( typeof value === "object" ? value.toString() : value + "" );
8290		if ( value === "" ) {
8291			return null;
8292		}
8293
8294		var iFormat, dim, extra,
8295			iValue = 0,
8296			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8297			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8298				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8299			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8300			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8301			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8302			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8303			year = -1,
8304			month = -1,
8305			day = -1,
8306			doy = -1,
8307			literal = false,
8308			date,
8309
8310			// Check whether a format character is doubled
8311			lookAhead = function( match ) {
8312				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8313				if ( matches ) {
8314					iFormat++;
8315				}
8316				return matches;
8317			},
8318
8319			// Extract a number from the string value
8320			getNumber = function( match ) {
8321				var isDoubled = lookAhead( match ),
8322					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8323					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8324					minSize = ( match === "y" ? size : 1 ),
8325					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8326					num = value.substring( iValue ).match( digits );
8327				if ( !num ) {
8328					throw "Missing number at position " + iValue;
8329				}
8330				iValue += num[ 0 ].length;
8331				return parseInt( num[ 0 ], 10 );
8332			},
8333
8334			// Extract a name from the string value and convert to an index
8335			getName = function( match, shortNames, longNames ) {
8336				var index = -1,
8337					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8338						return [ [ k, v ] ];
8339					} ).sort( function( a, b ) {
8340						return -( a[ 1 ].length - b[ 1 ].length );
8341					} );
8342
8343				$.each( names, function( i, pair ) {
8344					var name = pair[ 1 ];
8345					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8346						index = pair[ 0 ];
8347						iValue += name.length;
8348						return false;
8349					}
8350				} );
8351				if ( index !== -1 ) {
8352					return index + 1;
8353				} else {
8354					throw "Unknown name at position " + iValue;
8355				}
8356			},
8357
8358			// Confirm that a literal character matches the string value
8359			checkLiteral = function() {
8360				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8361					throw "Unexpected literal at position " + iValue;
8362				}
8363				iValue++;
8364			};
8365
8366		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8367			if ( literal ) {
8368				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8369					literal = false;
8370				} else {
8371					checkLiteral();
8372				}
8373			} else {
8374				switch ( format.charAt( iFormat ) ) {
8375					case "d":
8376						day = getNumber( "d" );
8377						break;
8378					case "D":
8379						getName( "D", dayNamesShort, dayNames );
8380						break;
8381					case "o":
8382						doy = getNumber( "o" );
8383						break;
8384					case "m":
8385						month = getNumber( "m" );
8386						break;
8387					case "M":
8388						month = getName( "M", monthNamesShort, monthNames );
8389						break;
8390					case "y":
8391						year = getNumber( "y" );
8392						break;
8393					case "@":
8394						date = new Date( getNumber( "@" ) );
8395						year = date.getFullYear();
8396						month = date.getMonth() + 1;
8397						day = date.getDate();
8398						break;
8399					case "!":
8400						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8401						year = date.getFullYear();
8402						month = date.getMonth() + 1;
8403						day = date.getDate();
8404						break;
8405					case "'":
8406						if ( lookAhead( "'" ) ) {
8407							checkLiteral();
8408						} else {
8409							literal = true;
8410						}
8411						break;
8412					default:
8413						checkLiteral();
8414				}
8415			}
8416		}
8417
8418		if ( iValue < value.length ) {
8419			extra = value.substr( iValue );
8420			if ( !/^\s+/.test( extra ) ) {
8421				throw "Extra/unparsed characters found in date: " + extra;
8422			}
8423		}
8424
8425		if ( year === -1 ) {
8426			year = new Date().getFullYear();
8427		} else if ( year < 100 ) {
8428			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429				( year <= shortYearCutoff ? 0 : -100 );
8430		}
8431
8432		if ( doy > -1 ) {
8433			month = 1;
8434			day = doy;
8435			do {
8436				dim = this._getDaysInMonth( year, month - 1 );
8437				if ( day <= dim ) {
8438					break;
8439				}
8440				month++;
8441				day -= dim;
8442			} while ( true );
8443		}
8444
8445		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8446		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8447			throw "Invalid date"; // E.g. 31/02/00
8448		}
8449		return date;
8450	},
8451
8452	/* Standard date formats. */
8453	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454	COOKIE: "D, dd M yy",
8455	ISO_8601: "yy-mm-dd",
8456	RFC_822: "D, d M y",
8457	RFC_850: "DD, dd-M-y",
8458	RFC_1036: "D, d M y",
8459	RFC_1123: "D, d M yy",
8460	RFC_2822: "D, d M yy",
8461	RSS: "D, d M y", // RFC 822
8462	TICKS: "!",
8463	TIMESTAMP: "@",
8464	W3C: "yy-mm-dd", // ISO 8601
8465
8466	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8467		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8468
8469	/* Format a date object into a string value.
8470	 * The format can be combinations of the following:
8471	 * d  - day of month (no leading zero)
8472	 * dd - day of month (two digit)
8473	 * o  - day of year (no leading zeros)
8474	 * oo - day of year (three digit)
8475	 * D  - day name short
8476	 * DD - day name long
8477	 * m  - month of year (no leading zero)
8478	 * mm - month of year (two digit)
8479	 * M  - month name short
8480	 * MM - month name long
8481	 * y  - year (two digit)
8482	 * yy - year (four digit)
8483	 * @ - Unix timestamp (ms since 01/01/1970)
8484	 * ! - Windows ticks (100ns since 01/01/0001)
8485	 * "..." - literal text
8486	 * '' - single quote
8487	 *
8488	 * @param  format string - the desired format of the date
8489	 * @param  date Date - the date value to format
8490	 * @param  settings Object - attributes include:
8491	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8492	 *					dayNames		string[7] - names of the days from Sunday (optional)
8493	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8494	 *					monthNames		string[12] - names of the months (optional)
8495	 * @return  string - the date in the above format
8496	 */
8497	formatDate: function( format, date, settings ) {
8498		if ( !date ) {
8499			return "";
8500		}
8501
8502		var iFormat,
8503			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8504			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8505			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8506			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8507
8508			// Check whether a format character is doubled
8509			lookAhead = function( match ) {
8510				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8511				if ( matches ) {
8512					iFormat++;
8513				}
8514				return matches;
8515			},
8516
8517			// Format a number, with leading zero if necessary
8518			formatNumber = function( match, value, len ) {
8519				var num = "" + value;
8520				if ( lookAhead( match ) ) {
8521					while ( num.length < len ) {
8522						num = "0" + num;
8523					}
8524				}
8525				return num;
8526			},
8527
8528			// Format a name, short or long as requested
8529			formatName = function( match, value, shortNames, longNames ) {
8530				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8531			},
8532			output = "",
8533			literal = false;
8534
8535		if ( date ) {
8536			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8537				if ( literal ) {
8538					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8539						literal = false;
8540					} else {
8541						output += format.charAt( iFormat );
8542					}
8543				} else {
8544					switch ( format.charAt( iFormat ) ) {
8545						case "d":
8546							output += formatNumber( "d", date.getDate(), 2 );
8547							break;
8548						case "D":
8549							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8550							break;
8551						case "o":
8552							output += formatNumber( "o",
8553								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8554							break;
8555						case "m":
8556							output += formatNumber( "m", date.getMonth() + 1, 2 );
8557							break;
8558						case "M":
8559							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8560							break;
8561						case "y":
8562							output += ( lookAhead( "y" ) ? date.getFullYear() :
8563								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8564							break;
8565						case "@":
8566							output += date.getTime();
8567							break;
8568						case "!":
8569							output += date.getTime() * 10000 + this._ticksTo1970;
8570							break;
8571						case "'":
8572							if ( lookAhead( "'" ) ) {
8573								output += "'";
8574							} else {
8575								literal = true;
8576							}
8577							break;
8578						default:
8579							output += format.charAt( iFormat );
8580					}
8581				}
8582			}
8583		}
8584		return output;
8585	},
8586
8587	/* Extract all possible characters from the date format. */
8588	_possibleChars: function( format ) {
8589		var iFormat,
8590			chars = "",
8591			literal = false,
8592
8593			// Check whether a format character is doubled
8594			lookAhead = function( match ) {
8595				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8596				if ( matches ) {
8597					iFormat++;
8598				}
8599				return matches;
8600			};
8601
8602		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8603			if ( literal ) {
8604				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8605					literal = false;
8606				} else {
8607					chars += format.charAt( iFormat );
8608				}
8609			} else {
8610				switch ( format.charAt( iFormat ) ) {
8611					case "d": case "m": case "y": case "@":
8612						chars += "0123456789";
8613						break;
8614					case "D": case "M":
8615						return null; // Accept anything
8616					case "'":
8617						if ( lookAhead( "'" ) ) {
8618							chars += "'";
8619						} else {
8620							literal = true;
8621						}
8622						break;
8623					default:
8624						chars += format.charAt( iFormat );
8625				}
8626			}
8627		}
8628		return chars;
8629	},
8630
8631	/* Get a setting value, defaulting if necessary. */
8632	_get: function( inst, name ) {
8633		return inst.settings[ name ] !== undefined ?
8634			inst.settings[ name ] : this._defaults[ name ];
8635	},
8636
8637	/* Parse existing date and initialise date picker. */
8638	_setDateFromField: function( inst, noDefault ) {
8639		if ( inst.input.val() === inst.lastVal ) {
8640			return;
8641		}
8642
8643		var dateFormat = this._get( inst, "dateFormat" ),
8644			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645			defaultDate = this._getDefaultDate( inst ),
8646			date = defaultDate,
8647			settings = this._getFormatConfig( inst );
8648
8649		try {
8650			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8651		} catch ( event ) {
8652			dates = ( noDefault ? "" : dates );
8653		}
8654		inst.selectedDay = date.getDate();
8655		inst.drawMonth = inst.selectedMonth = date.getMonth();
8656		inst.drawYear = inst.selectedYear = date.getFullYear();
8657		inst.currentDay = ( dates ? date.getDate() : 0 );
8658		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8659		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8660		this._adjustInstDate( inst );
8661	},
8662
8663	/* Retrieve the default date shown on opening. */
8664	_getDefaultDate: function( inst ) {
8665		return this._restrictMinMax( inst,
8666			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8667	},
8668
8669	/* A date may be specified as an exact value or a relative one. */
8670	_determineDate: function( inst, date, defaultDate ) {
8671		var offsetNumeric = function( offset ) {
8672				var date = new Date();
8673				date.setDate( date.getDate() + offset );
8674				return date;
8675			},
8676			offsetString = function( offset ) {
8677				try {
8678					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8679						offset, $.datepicker._getFormatConfig( inst ) );
8680				}
8680
8681				
vendor: 6,426 bytes, lines 8681-8855
8681catch ( e ) {
8682
8683					// Ignore
8684				}
8685
8686				var date = ( offset.toLowerCase().match( /^c/ ) ?
8687					$.datepicker._getDate( inst ) : null ) || new Date(),
8688					year = date.getFullYear(),
8689					month = date.getMonth(),
8690					day = date.getDate(),
8691					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8692					matches = pattern.exec( offset );
8693
8694				while ( matches ) {
8695					switch ( matches[ 2 ] || "d" ) {
8696						case "d" : case "D" :
8697							day += parseInt( matches[ 1 ], 10 ); break;
8698						case "w" : case "W" :
8699							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8700						case "m" : case "M" :
8701							month += parseInt( matches[ 1 ], 10 );
8702							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8703							break;
8704						case "y": case "Y" :
8705							year += parseInt( matches[ 1 ], 10 );
8706							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8707							break;
8708					}
8709					matches = pattern.exec( offset );
8710				}
8711				return new Date( year, month, day );
8712			},
8713			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8714				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8715
8716		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8717		if ( newDate ) {
8718			newDate.setHours( 0 );
8719			newDate.setMinutes( 0 );
8720			newDate.setSeconds( 0 );
8721			newDate.setMilliseconds( 0 );
8722		}
8723		return this._daylightSavingAdjust( newDate );
8724	},
8725
8726	/* Handle switch to/from daylight saving.
8727	 * Hours may be non-zero on daylight saving cut-over:
8728	 * > 12 when midnight changeover, but then cannot generate
8729	 * midnight datetime, so jump to 1AM, otherwise reset.
8730	 * @param  date  (Date) the date to check
8731	 * @return  (Date) the corrected date
8732	 */
8733	_daylightSavingAdjust: function( date ) {
8734		if ( !date ) {
8735			return null;
8736		}
8737		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8738		return date;
8739	},
8740
8741	/* Set the date(s) directly. */
8742	_setDate: function( inst, date, noChange ) {
8743		var clear = !date,
8744			origMonth = inst.selectedMonth,
8745			origYear = inst.selectedYear,
8746			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8747
8748		inst.selectedDay = inst.currentDay = newDate.getDate();
8749		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8750		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8751		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8752			this._notifyChange( inst );
8753		}
8754		this._adjustInstDate( inst );
8755		if ( inst.input ) {
8756			inst.input.val( clear ? "" : this._formatDate( inst ) );
8757		}
8758	},
8759
8760	/* Retrieve the date(s) directly. */
8761	_getDate: function( inst ) {
8762		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8763			this._daylightSavingAdjust( new Date(
8764			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8765			return startDate;
8766	},
8767
8768	/* Attach the onxxx handlers.  These are declared statically so
8769	 * they work with static code transformers like Caja.
8770	 */
8771	_attachHandlers: function( inst ) {
8772		var stepMonths = this._get( inst, "stepMonths" ),
8773			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8774		inst.dpDiv.find( "[data-handler]" ).map( function() {
8775			var handler = {
8776				prev: function() {
8777					$.datepicker._adjustDate( id, -stepMonths, "M" );
8778				},
8779				next: function() {
8780					$.datepicker._adjustDate( id, +stepMonths, "M" );
8781				},
8782				hide: function() {
8783					$.datepicker._hideDatepicker();
8784				},
8785				today: function() {
8786					$.datepicker._gotoToday( id );
8787				},
8788				selectDay: function() {
8789					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8790					return false;
8791				},
8792				selectMonth: function() {
8793					$.datepicker._selectMonthYear( id, this, "M" );
8794					return false;
8795				},
8796				selectYear: function() {
8797					$.datepicker._selectMonthYear( id, this, "Y" );
8798					return false;
8799				}
8800			};
8801			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8802		} );
8803	},
8804
8805	/* Generate the HTML for the current state of the date picker. */
8806	_generateHTML: function( inst ) {
8807		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8808			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8809			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8810			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8811			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8812			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8813			tempDate = new Date(),
8814			today = this._daylightSavingAdjust(
8815				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8816			isRTL = this._get( inst, "isRTL" ),
8817			showButtonPanel = this._get( inst, "showButtonPanel" ),
8818			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8819			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8820			numMonths = this._getNumberOfMonths( inst ),
8821			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8822			stepMonths = this._get( inst, "stepMonths" ),
8823			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8824			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8825				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8826			minDate = this._getMinMaxDate( inst, "min" ),
8827			maxDate = this._getMinMaxDate( inst, "max" ),
8828			drawMonth = inst.drawMonth - showCurrentAtPos,
8829			drawYear = inst.drawYear;
8830
8831		if ( drawMonth < 0 ) {
8832			drawMonth += 12;
8833			drawYear--;
8834		}
8835		if ( maxDate ) {
8836			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8837				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8838			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8839			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8840				drawMonth--;
8841				if ( drawMonth < 0 ) {
8842					drawMonth = 11;
8843					drawYear--;
8844				}
8845			}
8846		}
8847		inst.drawMonth = drawMonth;
8848		inst.drawYear = drawYear;
8849
8850		prevText = this._get( inst, "prevText" );
8851		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8852			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8853			this._getFormatConfig( inst ) ) );
8854
8855		
vendor: 3,273 bytes, lines 8855-8907
8855prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8856			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8857			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8858			( 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>" ) );
8859
8860		nextText = this._get( inst, "nextText" );
8861		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8862			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8863			this._getFormatConfig( inst ) ) );
8864
8865		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8866			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8867			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8868			( 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>" ) );
8869
8870		currentText = this._get( inst, "currentText" );
8871		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8872		currentText = ( !navigationAsDateFormat ? currentText :
8873			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8874
8875		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'>" +
8876			this._get( inst, "closeText" ) + "</button>" : "" );
8877
8878		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8879			( 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'" +
8880			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8881
8882		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8883		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8884
8885		showWeek = this._get( inst, "showWeek" );
8886		dayNames = this._get( inst, "dayNames" );
8887		dayNamesMin = this._get( inst, "dayNamesMin" );
8888		monthNames = this._get( inst, "monthNames" );
8889		monthNamesShort = this._get( inst, "monthNamesShort" );
8890		beforeShowDay = this._get( inst, "beforeShowDay" );
8891		showOtherMonths = this._get( inst, "showOtherMonths" );
8892		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8893		defaultDate = this._getDefaultDate( inst );
8894		html = "";
8895
8896		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8897			group = "";
8898			this.maxRows = 4;
8899			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8900				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8901				cornerClass = " ui-corner-all";
8902				calender = "";
8903				if ( isMultiMonth ) {
8904					calender += "<div class='ui-datepicker-group";
8905					if ( numMonths[ 1 ] > 1 ) {
8906						switch ( col ) {
8907							case 0: calender += " ui-datepicker-group-first";
vendor: 5,222 bytes, lines 8908-8986
8908								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8909							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8910								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8911							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8912						}
8913					}
8914					calender += "'>";
8915				}
8916				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8917					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8918					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8919					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8920					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8921					"</div><table class='ui-datepicker-calendar'><thead>" +
8922					"<tr>";
8923				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8924				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8925					day = ( dow + firstDay ) % 7;
8926					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8927						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8928				}
8929				calender += thead + "</tr></thead><tbody>";
8930				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8931				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8932					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8933				}
8934				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8935				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8936				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8937				this.maxRows = numRows;
8938				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8939				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8940					calender += "<tr>";
8941					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8942						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8943					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8944						daySettings = ( beforeShowDay ?
8945							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8946						otherMonth = ( printDate.getMonth() !== drawMonth );
8947						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8948							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8949						tbody += "<td class='" +
8950							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8951							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8952							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8953							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8954
8955							// or defaultDate is current printedDate and defaultDate is selectedDate
8956							" " + this._dayOverClass : "" ) + // highlight selected day
8957							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8958							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8959							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8960							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8961							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8962							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8963							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8964							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8965							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8966							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8967							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8968							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8969						printDate.setDate( printDate.getDate() + 1 );
8970						printDate = this._daylightSavingAdjust( printDate );
8971					}
8972					calender += tbody + "</tr>";
8973				}
8974				drawMonth++;
8975				if ( drawMonth > 11 ) {
8976					drawMonth = 0;
8977					drawYear++;
8978				}
8979				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8980							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8981				group += calender;
8982			}
8983			html += group;
8984		}
8985		html += buttonPanel;
8986		inst._keyEvent = false;
vendor: 10,686 bytes, lines 8987-9262
8987		return html;
8988	},
8989
8990	/* Generate the month and year header. */
8991	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8992			secondary, monthNames, monthNamesShort ) {
8993
8994		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8995			changeMonth = this._get( inst, "changeMonth" ),
8996			changeYear = this._get( inst, "changeYear" ),
8997			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
8998			html = "<div class='ui-datepicker-title'>",
8999			monthHtml = "";
9000
9001		// Month selection
9002		if ( secondary || !changeMonth ) {
9003			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9004		} else {
9005			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9006			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9007			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9008			for ( month = 0; month < 12; month++ ) {
9009				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9010					monthHtml += "<option value='" + month + "'" +
9011						( month === drawMonth ? " selected='selected'" : "" ) +
9012						">" + monthNamesShort[ month ] + "</option>";
9013				}
9014			}
9015			monthHtml += "</select>";
9016		}
9017
9018		if ( !showMonthAfterYear ) {
9019			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9020		}
9021
9022		// Year selection
9023		if ( !inst.yearshtml ) {
9024			inst.yearshtml = "";
9025			if ( secondary || !changeYear ) {
9026				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9027			} else {
9028
9029				// determine range of years to display
9030				years = this._get( inst, "yearRange" ).split( ":" );
9031				thisYear = new Date().getFullYear();
9032				determineYear = function( value ) {
9033					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9034						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9035						parseInt( value, 10 ) ) );
9036					return ( isNaN( year ) ? thisYear : year );
9037				};
9038				year = determineYear( years[ 0 ] );
9039				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9040				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9041				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9042				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9043				for ( ; year <= endYear; year++ ) {
9044					inst.yearshtml += "<option value='" + year + "'" +
9045						( year === drawYear ? " selected='selected'" : "" ) +
9046						">" + year + "</option>";
9047				}
9048				inst.yearshtml += "</select>";
9049
9050				html += inst.yearshtml;
9051				inst.yearshtml = null;
9052			}
9053		}
9054
9055		html += this._get( inst, "yearSuffix" );
9056		if ( showMonthAfterYear ) {
9057			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9058		}
9059		html += "</div>"; // Close datepicker_header
9060		return html;
9061	},
9062
9063	/* Adjust one of the date sub-fields. */
9064	_adjustInstDate: function( inst, offset, period ) {
9065		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9066			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9067			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9068			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9069
9070		inst.selectedDay = date.getDate();
9071		inst.drawMonth = inst.selectedMonth = date.getMonth();
9072		inst.drawYear = inst.selectedYear = date.getFullYear();
9073		if ( period === "M" || period === "Y" ) {
9074			this._notifyChange( inst );
9075		}
9076	},
9077
9078	/* Ensure a date is within any min/max bounds. */
9079	_restrictMinMax: function( inst, date ) {
9080		var minDate = this._getMinMaxDate( inst, "min" ),
9081			maxDate = this._getMinMaxDate( inst, "max" ),
9082			newDate = ( minDate && date < minDate ? minDate : date );
9083		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9084	},
9085
9086	/* Notify change of month/year. */
9087	_notifyChange: function( inst ) {
9088		var onChange = this._get( inst, "onChangeMonthYear" );
9089		if ( onChange ) {
9090			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9091				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9092		}
9093	},
9094
9095	/* Determine the number of months to show. */
9096	_getNumberOfMonths: function( inst ) {
9097		var numMonths = this._get( inst, "numberOfMonths" );
9098		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9099	},
9100
9101	/* Determine the current maximum date - ensure no time components are set. */
9102	_getMinMaxDate: function( inst, minMax ) {
9103		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9104	},
9105
9106	/* Find the number of days in a given month. */
9107	_getDaysInMonth: function( year, month ) {
9108		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9109	},
9110
9111	/* Find the day of the week of the first of a month. */
9112	_getFirstDayOfMonth: function( year, month ) {
9113		return new Date( year, month, 1 ).getDay();
9114	},
9115
9116	/* Determines if we should allow a "next/prev" month display change. */
9117	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9118		var numMonths = this._getNumberOfMonths( inst ),
9119			date = this._daylightSavingAdjust( new Date( curYear,
9120			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9121
9122		if ( offset < 0 ) {
9123			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9124		}
9125		return this._isInRange( inst, date );
9126	},
9127
9128	/* Is the given date in the accepted range? */
9129	_isInRange: function( inst, date ) {
9130		var yearSplit, currentYear,
9131			minDate = this._getMinMaxDate( inst, "min" ),
9132			maxDate = this._getMinMaxDate( inst, "max" ),
9133			minYear = null,
9134			maxYear = null,
9135			years = this._get( inst, "yearRange" );
9136			if ( years ) {
9137				yearSplit = years.split( ":" );
9138				currentYear = new Date().getFullYear();
9139				minYear = parseInt( yearSplit[ 0 ], 10 );
9140				maxYear = parseInt( yearSplit[ 1 ], 10 );
9141				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9142					minYear += currentYear;
9143				}
9144				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9145					maxYear += currentYear;
9146				}
9147			}
9148
9149		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9150			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9151			( !minYear || date.getFullYear() >= minYear ) &&
9152			( !maxYear || date.getFullYear() <= maxYear ) );
9153	},
9154
9155	/* Provide the configuration settings for formatting/parsing. */
9156	_getFormatConfig: function( inst ) {
9157		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9158		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9159			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9160		return { shortYearCutoff: shortYearCutoff,
9161			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9162			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9163	},
9164
9165	/* Format the given date for display. */
9166	_formatDate: function( inst, day, month, year ) {
9167		if ( !day ) {
9168			inst.currentDay = inst.selectedDay;
9169			inst.currentMonth = inst.selectedMonth;
9170			inst.currentYear = inst.selectedYear;
9171		}
9172		var date = ( day ? ( typeof day === "object" ? day :
9173			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9174			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9175		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9176	}
9177} );
9178
9179/*
9180 * Bind hover events for datepicker elements.
9181 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9182 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9183 */
9184function datepicker_bindHover( dpDiv ) {
9185	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9186	return dpDiv.on( "mouseout", selector, function() {
9187			$( this ).removeClass( "ui-state-hover" );
9188			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9189				$( this ).removeClass( "ui-datepicker-prev-hover" );
9190			}
9191			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9192				$( this ).removeClass( "ui-datepicker-next-hover" );
9193			}
9194		} )
9195		.on( "mouseover", selector, datepicker_handleMouseover );
9196}
9197
9198function datepicker_handleMouseover() {
9199	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9200		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9201		$( this ).addClass( "ui-state-hover" );
9202		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9203			$( this ).addClass( "ui-datepicker-prev-hover" );
9204		}
9205		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9206			$( this ).addClass( "ui-datepicker-next-hover" );
9207		}
9208	}
9209}
9210
9211/* jQuery extend now ignores nulls! */
9212function datepicker_extendRemove( target, props ) {
9213	$.extend( target, props );
9214	for ( var name in props ) {
9215		if ( props[ name ] == null ) {
9216			target[ name ] = props[ name ];
9217		}
9218	}
9219	return target;
9220}
9221
9222/* Invoke the datepicker functionality.
9223   @param  options  string - a command, optionally followed by additional parameters or
9224					Object - settings for attaching new datepicker functionality
9225   @return  jQuery object */
9226$.fn.datepicker = function( options ) {
9227
9228	/* Verify an empty collection wasn't passed - Fixes #6976 */
9229	if ( !this.length ) {
9230		return this;
9231	}
9232
9233	/* Initialise the date picker. */
9234	if ( !$.datepicker.initialized ) {
9235		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9236		$.datepicker.initialized = true;
9237	}
9238
9239	/* Append datepicker main container to body if not exist. */
9240	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9241		$( "body" ).append( $.datepicker.dpDiv );
9242	}
9243
9244	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9245	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9246		return $.datepicker[ "_" + options + "Datepicker" ].
9247			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9248	}
9249	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9250		return $.datepicker[ "_" + options + "Datepicker" ].
9251			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9252	}
9253	return this.each( function() {
9254		typeof options === "string" ?
9255			$.datepicker[ "_" + options + "Datepicker" ].
9256				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9257			$.datepicker._attachDatepicker( this, options );
9258	} );
9259};
9260
9261$.datepicker = new Datepicker(); // singleton instance
9262$.datepicker.initialized = false;
vendor: 11,796 bytes, lines 9263-9721
9263$.datepicker.uuid = new Date().getTime();
9264$.datepicker.version = "1.12.1";
9265
9266var widgetsDatepicker = $.datepicker;
9267
9268
9269
9270
9271// This file is deprecated
9272var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9273
9274/*!
9275 * jQuery UI Mouse 1.12.1
9276 * http://jqueryui.com
9277 *
9278 * Copyright jQuery Foundation and other contributors
9279 * Released under the MIT license.
9280 * http://jquery.org/license
9281 */
9282
9283//>>label: Mouse
9284//>>group: Widgets
9285//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9286//>>docs: http://api.jqueryui.com/mouse/
9287
9288
9289
9290var mouseHandled = false;
9291$( document ).on( "mouseup", function() {
9292	mouseHandled = false;
9293} );
9294
9295var widgetsMouse = $.widget( "ui.mouse", {
9296	version: "1.12.1",
9297	options: {
9298		cancel: "input, textarea, button, select, option",
9299		distance: 1,
9300		delay: 0
9301	},
9302	_mouseInit: function() {
9303		var that = this;
9304
9305		this.element
9306			.on( "mousedown." + this.widgetName, function( event ) {
9307				return that._mouseDown( event );
9308			} )
9309			.on( "click." + this.widgetName, function( event ) {
9310				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9311					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9312					event.stopImmediatePropagation();
9313					return false;
9314				}
9315			} );
9316
9317		this.started = false;
9318	},
9319
9320	// TODO: make sure destroying one instance of mouse doesn't mess with
9321	// other instances of mouse
9322	_mouseDestroy: function() {
9323		this.element.off( "." + this.widgetName );
9324		if ( this._mouseMoveDelegate ) {
9325			this.document
9326				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9327				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9328		}
9329	},
9330
9331	_mouseDown: function( event ) {
9332
9333		// don't let more than one widget handle mouseStart
9334		if ( mouseHandled ) {
9335			return;
9336		}
9337
9338		this._mouseMoved = false;
9339
9340		// We may have missed mouseup (out of window)
9341		( this._mouseStarted && this._mouseUp( event ) );
9342
9343		this._mouseDownEvent = event;
9344
9345		var that = this,
9346			btnIsLeft = ( event.which === 1 ),
9347
9348			// event.target.nodeName works around a bug in IE 8 with
9349			// disabled inputs (#7620)
9350			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9351				$( event.target ).closest( this.options.cancel ).length : false );
9352		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9353			return true;
9354		}
9355
9356		this.mouseDelayMet = !this.options.delay;
9357		if ( !this.mouseDelayMet ) {
9358			this._mouseDelayTimer = setTimeout( function() {
9359				that.mouseDelayMet = true;
9360			}, this.options.delay );
9361		}
9362
9363		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9364			this._mouseStarted = ( this._mouseStart( event ) !== false );
9365			if ( !this._mouseStarted ) {
9366				event.preventDefault();
9367				return true;
9368			}
9369		}
9370
9371		// Click event may never have fired (Gecko & Opera)
9372		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9373			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9374		}
9375
9376		// These delegates are required to keep context
9377		this._mouseMoveDelegate = function( event ) {
9378			return that._mouseMove( event );
9379		};
9380		this._mouseUpDelegate = function( event ) {
9381			return that._mouseUp( event );
9382		};
9383
9384		this.document
9385			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9386			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9387
9388		event.preventDefault();
9389
9390		mouseHandled = true;
9391		return true;
9392	},
9393
9394	_mouseMove: function( event ) {
9395
9396		// Only check for mouseups outside the document if you've moved inside the document
9397		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9398		// fire a mousemove event if content is placed under the cursor. See #7778
9399		// Support: IE <9
9400		if ( this._mouseMoved ) {
9401
9402			// IE mouseup check - mouseup happened when mouse was out of window
9403			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9404					!event.button ) {
9405				return this._mouseUp( event );
9406
9407			// Iframe mouseup check - mouseup occurred in another document
9408			} else if ( !event.which ) {
9409
9410				// Support: Safari <=8 - 9
9411				// Safari sets which to 0 if you press any of the following keys
9412				// during a drag (#14461)
9413				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9414						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9415					this.ignoreMissingWhich = true;
9416				} else if ( !this.ignoreMissingWhich ) {
9417					return this._mouseUp( event );
9418				}
9419			}
9420		}
9421
9422		if ( event.which || event.button ) {
9423			this._mouseMoved = true;
9424		}
9425
9426		if ( this._mouseStarted ) {
9427			this._mouseDrag( event );
9428			return event.preventDefault();
9429		}
9430
9431		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9432			this._mouseStarted =
9433				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9434			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9435		}
9436
9437		return !this._mouseStarted;
9438	},
9439
9440	_mouseUp: function( event ) {
9441		this.document
9442			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9443			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9444
9445		if ( this._mouseStarted ) {
9446			this._mouseStarted = false;
9447
9448			if ( event.target === this._mouseDownEvent.target ) {
9449				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9450			}
9451
9452			this._mouseStop( event );
9453		}
9454
9455		if ( this._mouseDelayTimer ) {
9456			clearTimeout( this._mouseDelayTimer );
9457			delete this._mouseDelayTimer;
9458		}
9459
9460		this.ignoreMissingWhich = false;
9461		mouseHandled = false;
9462		event.preventDefault();
9463	},
9464
9465	_mouseDistanceMet: function( event ) {
9466		return ( Math.max(
9467				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9468				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9469			) >= this.options.distance
9470		);
9471	},
9472
9473	_mouseDelayMet: function( /* event */ ) {
9474		return this.mouseDelayMet;
9475	},
9476
9477	// These are placeholder methods, to be overriden by extending plugin
9478	_mouseStart: function( /* event */ ) {},
9479	_mouseDrag: function( /* event */ ) {},
9480	_mouseStop: function( /* event */ ) {},
9481	_mouseCapture: function( /* event */ ) { return true; }
9482} );
9483
9484
9485
9486
9487// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9488var plugin = $.ui.plugin = {
9489	add: function( module, option, set ) {
9490		var i,
9491			proto = $.ui[ module ].prototype;
9492		for ( i in set ) {
9493			proto.plugins[ i ] = proto.plugins[ i ] || [];
9494			proto.plugins[ i ].push( [ option, set[ i ] ] );
9495		}
9496	},
9497	call: function( instance, name, args, allowDisconnected ) {
9498		var i,
9499			set = instance.plugins[ name ];
9500
9501		if ( !set ) {
9502			return;
9503		}
9504
9505		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9506				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9507			return;
9508		}
9509
9510		for ( i = 0; i < set.length; i++ ) {
9511			if ( instance.options[ set[ i ][ 0 ] ] ) {
9512				set[ i ][ 1 ].apply( instance.element, args );
9513			}
9514		}
9515	}
9516};
9517
9518
9519
9520var safeBlur = $.ui.safeBlur = function( element ) {
9521
9522	// Support: IE9 - 10 only
9523	// If the <body> is blurred, IE will switch windows, see #9420
9524	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9525		$( element ).trigger( "blur" );
9526	}
9527};
9528
9529
9530/*!
9531 * jQuery UI Draggable 1.12.1
9532 * http://jqueryui.com
9533 *
9534 * Copyright jQuery Foundation and other contributors
9535 * Released under the MIT license.
9536 * http://jquery.org/license
9537 */
9538
9539//>>label: Draggable
9540//>>group: Interactions
9541//>>description: Enables dragging functionality for any element.
9542//>>docs: http://api.jqueryui.com/draggable/
9543//>>demos: http://jqueryui.com/draggable/
9544//>>css.structure: ../../themes/base/draggable.css
9545
9546
9547
9548$.widget( "ui.draggable", $.ui.mouse, {
9549	version: "1.12.1",
9550	widgetEventPrefix: "drag",
9551	options: {
9552		addClasses: true,
9553		appendTo: "parent",
9554		axis: false,
9555		connectToSortable: false,
9556		containment: false,
9557		cursor: "auto",
9558		cursorAt: false,
9559		grid: false,
9560		handle: false,
9561		helper: "original",
9562		iframeFix: false,
9563		opacity: false,
9564		refreshPositions: false,
9565		revert: false,
9566		revertDuration: 500,
9567		scope: "default",
9568		scroll: true,
9569		scrollSensitivity: 20,
9570		scrollSpeed: 20,
9571		snap: false,
9572		snapMode: "both",
9573		snapTolerance: 20,
9574		stack: false,
9575		zIndex: false,
9576
9577		// Callbacks
9578		drag: null,
9579		start: null,
9580		stop: null
9581	},
9582	_create: function() {
9583
9584		if ( this.options.helper === "original" ) {
9585			this._setPositionRelative();
9586		}
9587		if ( this.options.addClasses ) {
9588			this._addClass( "ui-draggable" );
9589		}
9590		this._setHandleClassName();
9591
9592		this._mouseInit();
9593	},
9594
9595	_setOption: function( key, value ) {
9596		this._super( key, value );
9597		if ( key === "handle" ) {
9598			this._removeHandleClassName();
9599			this._setHandleClassName();
9600		}
9601	},
9602
9603	_destroy: function() {
9604		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9605			this.destroyOnClear = true;
9606			return;
9607		}
9608		this._removeHandleClassName();
9609		this._mouseDestroy();
9610	},
9611
9612	_mouseCapture: function( event ) {
9613		var o = this.options;
9614
9615		// Among others, prevent a drag on a resizable-handle
9616		if ( this.helper || o.disabled ||
9617				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9618			return false;
9619		}
9620
9621		//Quit if we're not on a valid handle
9622		this.handle = this._getHandle( event );
9623		if ( !this.handle ) {
9624			return false;
9625		}
9626
9627		this._blurActiveElement( event );
9628
9629		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9630
9631		return true;
9632
9633	},
9634
9635	_blockFrames: function( selector ) {
9636		this.iframeBlocks = this.document.find( selector ).map( function() {
9637			var iframe = $( this );
9638
9639			return $( "<div>" )
9640				.css( "position", "absolute" )
9641				.appendTo( iframe.parent() )
9642				.outerWidth( iframe.outerWidth() )
9643				.outerHeight( iframe.outerHeight() )
9644				.offset( iframe.offset() )[ 0 ];
9645		} );
9646	},
9647
9648	_unblockFrames: function() {
9649		if ( this.iframeBlocks ) {
9650			this.iframeBlocks.remove();
9651			delete this.iframeBlocks;
9652		}
9653	},
9654
9655	_blurActiveElement: function( event ) {
9656		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9657			target = $( event.target );
9658
9659		// Don't blur if the event occurred on an element that is within
9660		// the currently focused element
9661		// See #10527, #12472
9662		if ( target.closest( activeElement ).length ) {
9663			return;
9664		}
9665
9666		// Blur any element that currently has focus, see #4261
9667		$.ui.safeBlur( activeElement );
9668	},
9669
9670	_mouseStart: function( event ) {
9671
9672		var o = this.options;
9673
9674		//Create and append the visible helper
9675		this.helper = this._createHelper( event );
9676
9677		this._addClass( this.helper, "ui-draggable-dragging" );
9678
9679		//Cache the helper size
9680		this._cacheHelperProportions();
9681
9682		//If ddmanager is used for droppables, set the global draggable
9683		if ( $.ui.ddmanager ) {
9684			$.ui.ddmanager.current = this;
9685		}
9686
9687		/*
9688		 * - Position generation -
9689		 * This block generates everything position related - it's the core of draggables.
9690		 */
9691
9692		//Cache the margins of the original element
9693		this._cacheMargins();
9694
9695		//Store the helper's css position
9696		this.cssPosition = this.helper.css( "position" );
9697		this.scrollParent = this.helper.scrollParent( true );
9698		this.offsetParent = this.helper.offsetParent();
9699		this.hasFixedAncestor = this.helper.parents().filter( function() {
9700				return $( this ).css( "position" ) === "fixed";
9701			} ).length > 0;
9702
9703		//The element's absolute position on the page minus margins
9704		this.positionAbs = this.element.offset();
9705		this._refreshOffsets( event );
9706
9707		//Generate the original position
9708		this.originalPosition = this.position = this._generatePosition( event, false );
9709		this.originalPageX = event.pageX;
9710		this.originalPageY = event.pageY;
9711
9712		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9713		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9714
9715		//Set a containment if given in the options
9716		this._setContainment();
9717
9718		//Trigger event + callbacks
9719		if ( this._trigger( "start", event ) === false ) {
9720			this._clear();
9721			return false;
vendor: 5,171 bytes, lines 9722-9919
9722		}
9723
9724		//Recache the helper size
9725		this._cacheHelperProportions();
9726
9727		//Prepare the droppable offsets
9728		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9729			$.ui.ddmanager.prepareOffsets( this, event );
9730		}
9731
9732		// Execute the drag once - this causes the helper not to be visible before getting its
9733		// correct position
9734		this._mouseDrag( event, true );
9735
9736		// If the ddmanager is used for droppables, inform the manager that dragging has started
9737		// (see #5003)
9738		if ( $.ui.ddmanager ) {
9739			$.ui.ddmanager.dragStart( this, event );
9740		}
9741
9742		return true;
9743	},
9744
9745	_refreshOffsets: function( event ) {
9746		this.offset = {
9747			top: this.positionAbs.top - this.margins.top,
9748			left: this.positionAbs.left - this.margins.left,
9749			scroll: false,
9750			parent: this._getParentOffset(),
9751			relative: this._getRelativeOffset()
9752		};
9753
9754		this.offset.click = {
9755			left: event.pageX - this.offset.left,
9756			top: event.pageY - this.offset.top
9757		};
9758	},
9759
9760	_mouseDrag: function( event, noPropagation ) {
9761
9762		// reset any necessary cached properties (see #5009)
9763		if ( this.hasFixedAncestor ) {
9764			this.offset.parent = this._getParentOffset();
9765		}
9766
9767		//Compute the helpers position
9768		this.position = this._generatePosition( event, true );
9769		this.positionAbs = this._convertPositionTo( "absolute" );
9770
9771		//Call plugins and callbacks and use the resulting position if something is returned
9772		if ( !noPropagation ) {
9773			var ui = this._uiHash();
9774			if ( this._trigger( "drag", event, ui ) === false ) {
9775				this._mouseUp( new $.Event( "mouseup", event ) );
9776				return false;
9777			}
9778			this.position = ui.position;
9779		}
9780
9781		this.helper[ 0 ].style.left = this.position.left + "px";
9782		this.helper[ 0 ].style.top = this.position.top + "px";
9783
9784		if ( $.ui.ddmanager ) {
9785			$.ui.ddmanager.drag( this, event );
9786		}
9787
9788		return false;
9789	},
9790
9791	_mouseStop: function( event ) {
9792
9793		//If we are using droppables, inform the manager about the drop
9794		var that = this,
9795			dropped = false;
9796		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9797			dropped = $.ui.ddmanager.drop( this, event );
9798		}
9799
9800		//if a drop comes from outside (a sortable)
9801		if ( this.dropped ) {
9802			dropped = this.dropped;
9803			this.dropped = false;
9804		}
9805
9806		if ( ( this.options.revert === "invalid" && !dropped ) ||
9807				( this.options.revert === "valid" && dropped ) ||
9808				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9809				this.options.revert.call( this.element, dropped ) )
9810		) {
9811			$( this.helper ).animate(
9812				this.originalPosition,
9813				parseInt( this.options.revertDuration, 10 ),
9814				function() {
9815					if ( that._trigger( "stop", event ) !== false ) {
9816						that._clear();
9817					}
9818				}
9819			);
9820		} else {
9821			if ( this._trigger( "stop", event ) !== false ) {
9822				this._clear();
9823			}
9824		}
9825
9826		return false;
9827	},
9828
9829	_mouseUp: function( event ) {
9830		this._unblockFrames();
9831
9832		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9833		// (see #5003)
9834		if ( $.ui.ddmanager ) {
9835			$.ui.ddmanager.dragStop( this, event );
9836		}
9837
9838		// Only need to focus if the event occurred on the draggable itself, see #10527
9839		if ( this.handleElement.is( event.target ) ) {
9840
9841			// The interaction is over; whether or not the click resulted in a drag,
9842			// focus the element
9843			this.element.trigger( "focus" );
9844		}
9845
9846		return $.ui.mouse.prototype._mouseUp.call( this, event );
9847	},
9848
9849	cancel: function() {
9850
9851		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9852			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9853		} else {
9854			this._clear();
9855		}
9856
9857		return this;
9858
9859	},
9860
9861	_getHandle: function( event ) {
9862		return this.options.handle ?
9863			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9864			true;
9865	},
9866
9867	_setHandleClassName: function() {
9868		this.handleElement = this.options.handle ?
9869			this.element.find( this.options.handle ) : this.element;
9870		this._addClass( this.handleElement, "ui-draggable-handle" );
9871	},
9872
9873	_removeHandleClassName: function() {
9874		this._removeClass( this.handleElement, "ui-draggable-handle" );
9875	},
9876
9877	_createHelper: function( event ) {
9878
9879		var o = this.options,
9880			helperIsFunction = $.isFunction( o.helper ),
9881			helper = helperIsFunction ?
9882				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9883				( o.helper === "clone" ?
9884					this.element.clone().removeAttr( "id" ) :
9885					this.element );
9886
9887		if ( !helper.parents( "body" ).length ) {
9888			helper.appendTo( ( o.appendTo === "parent" ?
9889				this.element[ 0 ].parentNode :
9890				o.appendTo ) );
9891		}
9892
9893		// Http://bugs.jqueryui.com/ticket/9446
9894		// a helper function can return the original element
9895		// which wouldn't have been set to relative in _create
9896		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9897			this._setPositionRelative();
9898		}
9899
9900		if ( helper[ 0 ] !== this.element[ 0 ] &&
9901				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9902			helper.css( "position", "absolute" );
9903		}
9904
9905		return helper;
9906
9907	},
9908
9909	_setPositionRelative: function() {
9910		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9911			this.element[ 0 ].style.position = "relative";
9912		}
9913	},
9914
9915	_adjustOffsetFromHelper: function( obj ) {
9916		if ( typeof obj === "string" ) {
9917			obj = obj.split( " " );
9918		}
9919		if ( $
vendor: 22,091 bytes, lines 9919-10628
9919.isArray( obj ) ) {
9920			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9921		}
9922		if ( "left" in obj ) {
9923			this.offset.click.left = obj.left + this.margins.left;
9924		}
9925		if ( "right" in obj ) {
9926			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9927		}
9928		if ( "top" in obj ) {
9929			this.offset.click.top = obj.top + this.margins.top;
9930		}
9931		if ( "bottom" in obj ) {
9932			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9933		}
9934	},
9935
9936	_isRootNode: function( element ) {
9937		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9938	},
9939
9940	_getParentOffset: function() {
9941
9942		//Get the offsetParent and cache its position
9943		var po = this.offsetParent.offset(),
9944			document = this.document[ 0 ];
9945
9946		// This is a special case where we need to modify a offset calculated on start, since the
9947		// following happened:
9948		// 1. The position of the helper is absolute, so it's position is calculated based on the
9949		// next positioned parent
9950		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9951		// the document, which means that the scroll is included in the initial calculation of the
9952		// offset of the parent, and never recalculated upon drag
9953		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9954				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9955			po.left += this.scrollParent.scrollLeft();
9956			po.top += this.scrollParent.scrollTop();
9957		}
9958
9959		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9960			po = { top: 0, left: 0 };
9961		}
9962
9963		return {
9964			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9965			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9966		};
9967
9968	},
9969
9970	_getRelativeOffset: function() {
9971		if ( this.cssPosition !== "relative" ) {
9972			return { top: 0, left: 0 };
9973		}
9974
9975		var p = this.element.position(),
9976			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9977
9978		return {
9979			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9980				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9981			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9982				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9983		};
9984
9985	},
9986
9987	_cacheMargins: function() {
9988		this.margins = {
9989			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9990			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9991			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9992			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9993		};
9994	},
9995
9996	_cacheHelperProportions: function() {
9997		this.helperProportions = {
9998			width: this.helper.outerWidth(),
9999			height: this.helper.outerHeight()
10000		};
10001	},
10002
10003	_setContainment: function() {
10004
10005		var isUserScrollable, c, ce,
10006			o = this.options,
10007			document = this.document[ 0 ];
10008
10009		this.relativeContainer = null;
10010
10011		if ( !o.containment ) {
10012			this.containment = null;
10013			return;
10014		}
10015
10016		if ( o.containment === "window" ) {
10017			this.containment = [
10018				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10019				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10020				$( window ).scrollLeft() + $( window ).width() -
10021					this.helperProportions.width - this.margins.left,
10022				$( window ).scrollTop() +
10023					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10024					this.helperProportions.height - this.margins.top
10025			];
10026			return;
10027		}
10028
10029		if ( o.containment === "document" ) {
10030			this.containment = [
10031				0,
10032				0,
10033				$( document ).width() - this.helperProportions.width - this.margins.left,
10034				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10035					this.helperProportions.height - this.margins.top
10036			];
10037			return;
10038		}
10039
10040		if ( o.containment.constructor === Array ) {
10041			this.containment = o.containment;
10042			return;
10043		}
10044
10045		if ( o.containment === "parent" ) {
10046			o.containment = this.helper[ 0 ].parentNode;
10047		}
10048
10049		c = $( o.containment );
10050		ce = c[ 0 ];
10051
10052		if ( !ce ) {
10053			return;
10054		}
10055
10056		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10057
10058		this.containment = [
10059			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10060				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10061			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10062				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10063			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10064				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10065				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10066				this.helperProportions.width -
10067				this.margins.left -
10068				this.margins.right,
10069			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10070				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10071				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10072				this.helperProportions.height -
10073				this.margins.top -
10074				this.margins.bottom
10075		];
10076		this.relativeContainer = c;
10077	},
10078
10079	_convertPositionTo: function( d, pos ) {
10080
10081		if ( !pos ) {
10082			pos = this.position;
10083		}
10084
10085		var mod = d === "absolute" ? 1 : -1,
10086			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10087
10088		return {
10089			top: (
10090
10091				// The absolute mouse position
10092				pos.top	+
10093
10094				// Only for relative positioned nodes: Relative offset from element to offset parent
10095				this.offset.relative.top * mod +
10096
10097				// The offsetParent's offset without borders (offset + border)
10098				this.offset.parent.top * mod -
10099				( ( this.cssPosition === "fixed" ?
10100					-this.offset.scroll.top :
10101					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10102			),
10103			left: (
10104
10105				// The absolute mouse position
10106				pos.left +
10107
10108				// Only for relative positioned nodes: Relative offset from element to offset parent
10109				this.offset.relative.left * mod +
10110
10111				// The offsetParent's offset without borders (offset + border)
10112				this.offset.parent.left * mod	-
10113				( ( this.cssPosition === "fixed" ?
10114					-this.offset.scroll.left :
10115					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10116			)
10117		};
10118
10119	},
10120
10121	_generatePosition: function( event, constrainPosition ) {
10122
10123		var containment, co, top, left,
10124			o = this.options,
10125			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10126			pageX = event.pageX,
10127			pageY = event.pageY;
10128
10129		// Cache the scroll
10130		if ( !scrollIsRootNode || !this.offset.scroll ) {
10131			this.offset.scroll = {
10132				top: this.scrollParent.scrollTop(),
10133				left: this.scrollParent.scrollLeft()
10134			};
10135		}
10136
10137		/*
10138		 * - Position constraining -
10139		 * Constrain the position to a mix of grid, containment.
10140		 */
10141
10142		// If we are not dragging yet, we won't check for options
10143		if ( constrainPosition ) {
10144			if ( this.containment ) {
10145				if ( this.relativeContainer ) {
10146					co = this.relativeContainer.offset();
10147					containment = [
10148						this.containment[ 0 ] + co.left,
10149						this.containment[ 1 ] + co.top,
10150						this.containment[ 2 ] + co.left,
10151						this.containment[ 3 ] + co.top
10152					];
10153				} else {
10154					containment = this.containment;
10155				}
10156
10157				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10158					pageX = containment[ 0 ] + this.offset.click.left;
10159				}
10160				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10161					pageY = containment[ 1 ] + this.offset.click.top;
10162				}
10163				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10164					pageX = containment[ 2 ] + this.offset.click.left;
10165				}
10166				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10167					pageY = containment[ 3 ] + this.offset.click.top;
10168				}
10169			}
10170
10171			if ( o.grid ) {
10172
10173				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10174				// argument errors in IE (see ticket #6950)
10175				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10176					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10177				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10178					top - this.offset.click.top > containment[ 3 ] ) ?
10179						top :
10180						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10181							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10182
10183				left = o.grid[ 0 ] ? this.originalPageX +
10184					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10185					this.originalPageX;
10186				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10187					left - this.offset.click.left > containment[ 2 ] ) ?
10188						left :
10189						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10190							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10191			}
10192
10193			if ( o.axis === "y" ) {
10194				pageX = this.originalPageX;
10195			}
10196
10197			if ( o.axis === "x" ) {
10198				pageY = this.originalPageY;
10199			}
10200		}
10201
10202		return {
10203			top: (
10204
10205				// The absolute mouse position
10206				pageY -
10207
10208				// Click offset (relative to the element)
10209				this.offset.click.top -
10210
10211				// Only for relative positioned nodes: Relative offset from element to offset parent
10212				this.offset.relative.top -
10213
10214				// The offsetParent's offset without borders (offset + border)
10215				this.offset.parent.top +
10216				( this.cssPosition === "fixed" ?
10217					-this.offset.scroll.top :
10218					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10219			),
10220			left: (
10221
10222				// The absolute mouse position
10223				pageX -
10224
10225				// Click offset (relative to the element)
10226				this.offset.click.left -
10227
10228				// Only for relative positioned nodes: Relative offset from element to offset parent
10229				this.offset.relative.left -
10230
10231				// The offsetParent's offset without borders (offset + border)
10232				this.offset.parent.left +
10233				( this.cssPosition === "fixed" ?
10234					-this.offset.scroll.left :
10235					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10236			)
10237		};
10238
10239	},
10240
10241	_clear: function() {
10242		this._removeClass( this.helper, "ui-draggable-dragging" );
10243		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10244			this.helper.remove();
10245		}
10246		this.helper = null;
10247		this.cancelHelperRemoval = false;
10248		if ( this.destroyOnClear ) {
10249			this.destroy();
10250		}
10251	},
10252
10253	// From now on bulk stuff - mainly helpers
10254
10255	_trigger: function( type, event, ui ) {
10256		ui = ui || this._uiHash();
10257		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10258
10259		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10260		if ( /^(drag|start|stop)/.test( type ) ) {
10261			this.positionAbs = this._convertPositionTo( "absolute" );
10262			ui.offset = this.positionAbs;
10263		}
10264		return $.Widget.prototype._trigger.call( this, type, event, ui );
10265	},
10266
10267	plugins: {},
10268
10269	_uiHash: function() {
10270		return {
10271			helper: this.helper,
10272			position: this.position,
10273			originalPosition: this.originalPosition,
10274			offset: this.positionAbs
10275		};
10276	}
10277
10278} );
10279
10280$.ui.plugin.add( "draggable", "connectToSortable", {
10281	start: function( event, ui, draggable ) {
10282		var uiSortable = $.extend( {}, ui, {
10283			item: draggable.element
10284		} );
10285
10286		draggable.sortables = [];
10287		$( draggable.options.connectToSortable ).each( function() {
10288			var sortable = $( this ).sortable( "instance" );
10289
10290			if ( sortable && !sortable.options.disabled ) {
10291				draggable.sortables.push( sortable );
10292
10293				// RefreshPositions is called at drag start to refresh the containerCache
10294				// which is used in drag. This ensures it's initialized and synchronized
10295				// with any changes that might have happened on the page since initialization.
10296				sortable.refreshPositions();
10297				sortable._trigger( "activate", event, uiSortable );
10298			}
10299		} );
10300	},
10301	stop: function( event, ui, draggable ) {
10302		var uiSortable = $.extend( {}, ui, {
10303			item: draggable.element
10304		} );
10305
10306		draggable.cancelHelperRemoval = false;
10307
10308		$.each( draggable.sortables, function() {
10309			var sortable = this;
10310
10311			if ( sortable.isOver ) {
10312				sortable.isOver = 0;
10313
10314				// Allow this sortable to handle removing the helper
10315				draggable.cancelHelperRemoval = true;
10316				sortable.cancelHelperRemoval = false;
10317
10318				// Use _storedCSS To restore properties in the sortable,
10319				// as this also handles revert (#9675) since the draggable
10320				// may have modified them in unexpected ways (#8809)
10321				sortable._storedCSS = {
10322					position: sortable.placeholder.css( "position" ),
10323					top: sortable.placeholder.css( "top" ),
10324					left: sortable.placeholder.css( "left" )
10325				};
10326
10327				sortable._mouseStop( event );
10328
10329				// Once drag has ended, the sortable should return to using
10330				// its original helper, not the shared helper from draggable
10331				sortable.options.helper = sortable.options._helper;
10332			} else {
10333
10334				// Prevent this Sortable from removing the helper.
10335				// However, don't set the draggable to remove the helper
10336				// either as another connected Sortable may yet handle the removal.
10337				sortable.cancelHelperRemoval = true;
10338
10339				sortable._trigger( "deactivate", event, uiSortable );
10340			}
10341		} );
10342	},
10343	drag: function( event, ui, draggable ) {
10344		$.each( draggable.sortables, function() {
10345			var innermostIntersecting = false,
10346				sortable = this;
10347
10348			// Copy over variables that sortable's _intersectsWith uses
10349			sortable.positionAbs = draggable.positionAbs;
10350			sortable.helperProportions = draggable.helperProportions;
10351			sortable.offset.click = draggable.offset.click;
10352
10353			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10354				innermostIntersecting = true;
10355
10356				$.each( draggable.sortables, function() {
10357
10358					// Copy over variables that sortable's _intersectsWith uses
10359					this.positionAbs = draggable.positionAbs;
10360					this.helperProportions = draggable.helperProportions;
10361					this.offset.click = draggable.offset.click;
10362
10363					if ( this !== sortable &&
10364							this._intersectsWith( this.containerCache ) &&
10365							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10366						innermostIntersecting = false;
10367					}
10368
10369					return innermostIntersecting;
10370				} );
10371			}
10372
10373			if ( innermostIntersecting ) {
10374
10375				// If it intersects, we use a little isOver variable and set it once,
10376				// so that the move-in stuff gets fired only once.
10377				if ( !sortable.isOver ) {
10378					sortable.isOver = 1;
10379
10380					// Store draggable's parent in case we need to reappend to it later.
10381					draggable._parent = ui.helper.parent();
10382
10383					sortable.currentItem = ui.helper
10384						.appendTo( sortable.element )
10385						.data( "ui-sortable-item", true );
10386
10387					// Store helper option to later restore it
10388					sortable.options._helper = sortable.options.helper;
10389
10390					sortable.options.helper = function() {
10391						return ui.helper[ 0 ];
10392					};
10393
10394					// Fire the start events of the sortable with our passed browser event,
10395					// and our own helper (so it doesn't create a new one)
10396					event.target = sortable.currentItem[ 0 ];
10397					sortable._mouseCapture( event, true );
10398					sortable._mouseStart( event, true, true );
10399
10400					// Because the browser event is way off the new appended portlet,
10401					// modify necessary variables to reflect the changes
10402					sortable.offset.click.top = draggable.offset.click.top;
10403					sortable.offset.click.left = draggable.offset.click.left;
10404					sortable.offset.parent.left -= draggable.offset.parent.left -
10405						sortable.offset.parent.left;
10406					sortable.offset.parent.top -= draggable.offset.parent.top -
10407						sortable.offset.parent.top;
10408
10409					draggable._trigger( "toSortable", event );
10410
10411					// Inform draggable that the helper is in a valid drop zone,
10412					// used solely in the revert option to handle "valid/invalid".
10413					draggable.dropped = sortable.element;
10414
10415					// Need to refreshPositions of all sortables in the case that
10416					// adding to one sortable changes the location of the other sortables (#9675)
10417					$.each( draggable.sortables, function() {
10418						this.refreshPositions();
10419					} );
10420
10421					// Hack so receive/update callbacks work (mostly)
10422					draggable.currentItem = draggable.element;
10423					sortable.fromOutside = draggable;
10424				}
10425
10426				if ( sortable.currentItem ) {
10427					sortable._mouseDrag( event );
10428
10429					// Copy the sortable's position because the draggable's can potentially reflect
10430					// a relative position, while sortable is always absolute, which the dragged
10431					// element has now become. (#8809)
10432					ui.position = sortable.position;
10433				}
10434			} else {
10435
10436				// If it doesn't intersect with the sortable, and it intersected before,
10437				// we fake the drag stop of the sortable, but make sure it doesn't remove
10438				// the helper by using cancelHelperRemoval.
10439				if ( sortable.isOver ) {
10440
10441					sortable.isOver = 0;
10442					sortable.cancelHelperRemoval = true;
10443
10444					// Calling sortable's mouseStop would trigger a revert,
10445					// so revert must be temporarily false until after mouseStop is called.
10446					sortable.options._revert = sortable.options.revert;
10447					sortable.options.revert = false;
10448
10449					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10450					sortable._mouseStop( event, true );
10451
10452					// Restore sortable behaviors that were modfied
10453					// when the draggable entered the sortable area (#9481)
10454					sortable.options.revert = sortable.options._revert;
10455					sortable.options.helper = sortable.options._helper;
10456
10457					if ( sortable.placeholder ) {
10458						sortable.placeholder.remove();
10459					}
10460
10461					// Restore and recalculate the draggable's offset considering the sortable
10462					// may have modified them in unexpected ways. (#8809, #10669)
10463					ui.helper.appendTo( draggable._parent );
10464					draggable._refreshOffsets( event );
10465					ui.position = draggable._generatePosition( event, true );
10466
10467					draggable._trigger( "fromSortable", event );
10468
10469					// Inform draggable that the helper is no longer in a valid drop zone
10470					draggable.dropped = false;
10471
10472					// Need to refreshPositions of all sortables just in case removing
10473					// from one sortable changes the location of other sortables (#9675)
10474					$.each( draggable.sortables, function() {
10475						this.refreshPositions();
10476					} );
10477				}
10478			}
10479		} );
10480	}
10481} );
10482
10483$.ui.plugin.add( "draggable", "cursor", {
10484	start: function( event, ui, instance ) {
10485		var t = $( "body" ),
10486			o = instance.options;
10487
10488		if ( t.css( "cursor" ) ) {
10489			o._cursor = t.css( "cursor" );
10490		}
10491		t.css( "cursor", o.cursor );
10492	},
10493	stop: function( event, ui, instance ) {
10494		var o = instance.options;
10495		if ( o._cursor ) {
10496			$( "body" ).css( "cursor", o._cursor );
10497		}
10498	}
10499} );
10500
10501$.ui.plugin.add( "draggable", "opacity", {
10502	start: function( event, ui, instance ) {
10503		var t = $( ui.helper ),
10504			o = instance.options;
10505		if ( t.css( "opacity" ) ) {
10506			o._opacity = t.css( "opacity" );
10507		}
10508		t.css( "opacity", o.opacity );
10509	},
10510	stop: function( event, ui, instance ) {
10511		var o = instance.options;
10512		if ( o._opacity ) {
10513			$( ui.helper ).css( "opacity", o._opacity );
10514		}
10515	}
10516} );
10517
10518$.ui.plugin.add( "draggable", "scroll", {
10519	start: function( event, ui, i ) {
10520		if ( !i.scrollParentNotHidden ) {
10521			i.scrollParentNotHidden = i.helper.scrollParent( false );
10522		}
10523
10524		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10525				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10526			i.overflowOffset = i.scrollParentNotHidden.offset();
10527		}
10528	},
10529	drag: function( event, ui, i  ) {
10530
10531		var o = i.options,
10532			scrolled = false,
10533			scrollParent = i.scrollParentNotHidden[ 0 ],
10534			document = i.document[ 0 ];
10535
10536		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10537			if ( !o.axis || o.axis !== "x" ) {
10538				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10539						o.scrollSensitivity ) {
10540					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10541				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10542					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10543				}
10544			}
10545
10546			if ( !o.axis || o.axis !== "y" ) {
10547				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10548						o.scrollSensitivity ) {
10549					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10550				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10551					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10552				}
10553			}
10554
10555		} else {
10556
10557			if ( !o.axis || o.axis !== "x" ) {
10558				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10559					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10560				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10561						o.scrollSensitivity ) {
10562					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10563				}
10564			}
10565
10566			if ( !o.axis || o.axis !== "y" ) {
10567				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10568					scrolled = $( document ).scrollLeft(
10569						$( document ).scrollLeft() - o.scrollSpeed
10570					);
10571				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10572						o.scrollSensitivity ) {
10573					scrolled = $( document ).scrollLeft(
10574						$( document ).scrollLeft() + o.scrollSpeed
10575					);
10576				}
10577			}
10578
10579		}
10580
10581		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10582			$.ui.ddmanager.prepareOffsets( i, event );
10583		}
10584
10585	}
10586} );
10587
10588$.ui.plugin.add( "draggable", "snap", {
10589	start: function( event, ui, i ) {
10590
10591		var o = i.options;
10592
10593		i.snapElements = [];
10594
10595		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10596			.each( function() {
10597				var $t = $( this ),
10598					$o = $t.offset();
10599				if ( this !== i.element[ 0 ] ) {
10600					i.snapElements.push( {
10601						item: this,
10602						width: $t.outerWidth(), height: $t.outerHeight(),
10603						top: $o.top, left: $o.left
10604					} );
10605				}
10606			} );
10607
10608	},
10609	drag: function( event, ui, inst ) {
10610
10611		var ts, bs, ls, rs, l, r, t, b, i, first,
10612			o = inst.options,
10613			d = o.snapTolerance,
10614			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10615			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10616
10617		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10618
10619			l = inst.snapElements[ i ].left - inst.margins.left;
10620			r = l + inst.snapElements[ i ].width;
10621			t = inst.snapElements[ i ].top - inst.margins.top;
10622			b = t + inst.snapElements[ i ].height;
10623
10624			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10625					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10626					inst.snapElements[ i ].item ) ) {
10627				if ( inst.snapElements[ i ].snapping ) {
10628					
10628( inst.options.snap.release &&
10629						inst.options.snap.release.call(
10630							inst.element,
10631							event,
10632							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10633						) );
10634				}
10635				inst.snapElements[ i ].snapping = false;
vendor: 58,938 bytes, lines 10636-13024
10636				continue;
10637			}
10638
10639			if ( o.snapMode !== "inner" ) {
10640				ts = Math.abs( t - y2 ) <= d;
10641				bs = Math.abs( b - y1 ) <= d;
10642				ls = Math.abs( l - x2 ) <= d;
10643				rs = Math.abs( r - x1 ) <= d;
10644				if ( ts ) {
10645					ui.position.top = inst._convertPositionTo( "relative", {
10646						top: t - inst.helperProportions.height,
10647						left: 0
10648					} ).top;
10649				}
10650				if ( bs ) {
10651					ui.position.top = inst._convertPositionTo( "relative", {
10652						top: b,
10653						left: 0
10654					} ).top;
10655				}
10656				if ( ls ) {
10657					ui.position.left = inst._convertPositionTo( "relative", {
10658						top: 0,
10659						left: l - inst.helperProportions.width
10660					} ).left;
10661				}
10662				if ( rs ) {
10663					ui.position.left = inst._convertPositionTo( "relative", {
10664						top: 0,
10665						left: r
10666					} ).left;
10667				}
10668			}
10669
10670			first = ( ts || bs || ls || rs );
10671
10672			if ( o.snapMode !== "outer" ) {
10673				ts = Math.abs( t - y1 ) <= d;
10674				bs = Math.abs( b - y2 ) <= d;
10675				ls = Math.abs( l - x1 ) <= d;
10676				rs = Math.abs( r - x2 ) <= d;
10677				if ( ts ) {
10678					ui.position.top = inst._convertPositionTo( "relative", {
10679						top: t,
10680						left: 0
10681					} ).top;
10682				}
10683				if ( bs ) {
10684					ui.position.top = inst._convertPositionTo( "relative", {
10685						top: b - inst.helperProportions.height,
10686						left: 0
10687					} ).top;
10688				}
10689				if ( ls ) {
10690					ui.position.left = inst._convertPositionTo( "relative", {
10691						top: 0,
10692						left: l
10693					} ).left;
10694				}
10695				if ( rs ) {
10696					ui.position.left = inst._convertPositionTo( "relative", {
10697						top: 0,
10698						left: r - inst.helperProportions.width
10699					} ).left;
10700				}
10701			}
10702
10703			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10704				( inst.options.snap.snap &&
10705					inst.options.snap.snap.call(
10706						inst.element,
10707						event,
10708						$.extend( inst._uiHash(), {
10709							snapItem: inst.snapElements[ i ].item
10710						} ) ) );
10711			}
10712			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10713
10714		}
10715
10716	}
10717} );
10718
10719$.ui.plugin.add( "draggable", "stack", {
10720	start: function( event, ui, instance ) {
10721		var min,
10722			o = instance.options,
10723			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10724				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10725					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10726			} );
10727
10728		if ( !group.length ) { return; }
10729
10730		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10731		$( group ).each( function( i ) {
10732			$( this ).css( "zIndex", min + i );
10733		} );
10734		this.css( "zIndex", ( min + group.length ) );
10735	}
10736} );
10737
10738$.ui.plugin.add( "draggable", "zIndex", {
10739	start: function( event, ui, instance ) {
10740		var t = $( ui.helper ),
10741			o = instance.options;
10742
10743		if ( t.css( "zIndex" ) ) {
10744			o._zIndex = t.css( "zIndex" );
10745		}
10746		t.css( "zIndex", o.zIndex );
10747	},
10748	stop: function( event, ui, instance ) {
10749		var o = instance.options;
10750
10751		if ( o._zIndex ) {
10752			$( ui.helper ).css( "zIndex", o._zIndex );
10753		}
10754	}
10755} );
10756
10757var widgetsDraggable = $.ui.draggable;
10758
10759
10760/*!
10761 * jQuery UI Resizable 1.12.1
10762 * http://jqueryui.com
10763 *
10764 * Copyright jQuery Foundation and other contributors
10765 * Released under the MIT license.
10766 * http://jquery.org/license
10767 */
10768
10769//>>label: Resizable
10770//>>group: Interactions
10771//>>description: Enables resize functionality for any element.
10772//>>docs: http://api.jqueryui.com/resizable/
10773//>>demos: http://jqueryui.com/resizable/
10774//>>css.structure: ../../themes/base/core.css
10775//>>css.structure: ../../themes/base/resizable.css
10776//>>css.theme: ../../themes/base/theme.css
10777
10778
10779
10780$.widget( "ui.resizable", $.ui.mouse, {
10781	version: "1.12.1",
10782	widgetEventPrefix: "resize",
10783	options: {
10784		alsoResize: false,
10785		animate: false,
10786		animateDuration: "slow",
10787		animateEasing: "swing",
10788		aspectRatio: false,
10789		autoHide: false,
10790		classes: {
10791			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10792		},
10793		containment: false,
10794		ghost: false,
10795		grid: false,
10796		handles: "e,s,se",
10797		helper: false,
10798		maxHeight: null,
10799		maxWidth: null,
10800		minHeight: 10,
10801		minWidth: 10,
10802
10803		// See #7960
10804		zIndex: 90,
10805
10806		// Callbacks
10807		resize: null,
10808		start: null,
10809		stop: null
10810	},
10811
10812	_num: function( value ) {
10813		return parseFloat( value ) || 0;
10814	},
10815
10816	_isNumber: function( value ) {
10817		return !isNaN( parseFloat( value ) );
10818	},
10819
10820	_hasScroll: function( el, a ) {
10821
10822		if ( $( el ).css( "overflow" ) === "hidden" ) {
10823			return false;
10824		}
10825
10826		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10827			has = false;
10828
10829		if ( el[ scroll ] > 0 ) {
10830			return true;
10831		}
10832
10833		// TODO: determine which cases actually cause this to happen
10834		// if the element doesn't have the scroll set, see if it's possible to
10835		// set the scroll
10836		el[ scroll ] = 1;
10837		has = ( el[ scroll ] > 0 );
10838		el[ scroll ] = 0;
10839		return has;
10840	},
10841
10842	_create: function() {
10843
10844		var margins,
10845			o = this.options,
10846			that = this;
10847		this._addClass( "ui-resizable" );
10848
10849		$.extend( this, {
10850			_aspectRatio: !!( o.aspectRatio ),
10851			aspectRatio: o.aspectRatio,
10852			originalElement: this.element,
10853			_proportionallyResizeElements: [],
10854			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10855		} );
10856
10857		// Wrap the element if it cannot hold child nodes
10858		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10859
10860			this.element.wrap(
10861				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10862					position: this.element.css( "position" ),
10863					width: this.element.outerWidth(),
10864					height: this.element.outerHeight(),
10865					top: this.element.css( "top" ),
10866					left: this.element.css( "left" )
10867				} )
10868			);
10869
10870			this.element = this.element.parent().data(
10871				"ui-resizable", this.element.resizable( "instance" )
10872			);
10873
10874			this.elementIsWrapper = true;
10875
10876			margins = {
10877				marginTop: this.originalElement.css( "marginTop" ),
10878				marginRight: this.originalElement.css( "marginRight" ),
10879				marginBottom: this.originalElement.css( "marginBottom" ),
10880				marginLeft: this.originalElement.css( "marginLeft" )
10881			};
10882
10883			this.element.css( margins );
10884			this.originalElement.css( "margin", 0 );
10885
10886			// support: Safari
10887			// Prevent Safari textarea resize
10888			this.originalResizeStyle = this.originalElement.css( "resize" );
10889			this.originalElement.css( "resize", "none" );
10890
10891			this._proportionallyResizeElements.push( this.originalElement.css( {
10892				position: "static",
10893				zoom: 1,
10894				display: "block"
10895			} ) );
10896
10897			// Support: IE9
10898			// avoid IE jump (hard set the margin)
10899			this.originalElement.css( margins );
10900
10901			this._proportionallyResize();
10902		}
10903
10904		this._setupHandles();
10905
10906		if ( o.autoHide ) {
10907			$( this.element )
10908				.on( "mouseenter", function() {
10909					if ( o.disabled ) {
10910						return;
10911					}
10912					that._removeClass( "ui-resizable-autohide" );
10913					that._handles.show();
10914				} )
10915				.on( "mouseleave", function() {
10916					if ( o.disabled ) {
10917						return;
10918					}
10919					if ( !that.resizing ) {
10920						that._addClass( "ui-resizable-autohide" );
10921						that._handles.hide();
10922					}
10923				} );
10924		}
10925
10926		this._mouseInit();
10927	},
10928
10929	_destroy: function() {
10930
10931		this._mouseDestroy();
10932
10933		var wrapper,
10934			_destroy = function( exp ) {
10935				$( exp )
10936					.removeData( "resizable" )
10937					.removeData( "ui-resizable" )
10938					.off( ".resizable" )
10939					.find( ".ui-resizable-handle" )
10940						.remove();
10941			};
10942
10943		// TODO: Unwrap at same DOM position
10944		if ( this.elementIsWrapper ) {
10945			_destroy( this.element );
10946			wrapper = this.element;
10947			this.originalElement.css( {
10948				position: wrapper.css( "position" ),
10949				width: wrapper.outerWidth(),
10950				height: wrapper.outerHeight(),
10951				top: wrapper.css( "top" ),
10952				left: wrapper.css( "left" )
10953			} ).insertAfter( wrapper );
10954			wrapper.remove();
10955		}
10956
10957		this.originalElement.css( "resize", this.originalResizeStyle );
10958		_destroy( this.originalElement );
10959
10960		return this;
10961	},
10962
10963	_setOption: function( key, value ) {
10964		this._super( key, value );
10965
10966		switch ( key ) {
10967		case "handles":
10968			this._removeHandles();
10969			this._setupHandles();
10970			break;
10971		default:
10972			break;
10973		}
10974	},
10975
10976	_setupHandles: function() {
10977		var o = this.options, handle, i, n, hname, axis, that = this;
10978		this.handles = o.handles ||
10979			( !$( ".ui-resizable-handle", this.element ).length ?
10980				"e,s,se" : {
10981					n: ".ui-resizable-n",
10982					e: ".ui-resizable-e",
10983					s: ".ui-resizable-s",
10984					w: ".ui-resizable-w",
10985					se: ".ui-resizable-se",
10986					sw: ".ui-resizable-sw",
10987					ne: ".ui-resizable-ne",
10988					nw: ".ui-resizable-nw"
10989				} );
10990
10991		this._handles = $();
10992		if ( this.handles.constructor === String ) {
10993
10994			if ( this.handles === "all" ) {
10995				this.handles = "n,e,s,w,se,sw,ne,nw";
10996			}
10997
10998			n = this.handles.split( "," );
10999			this.handles = {};
11000
11001			for ( i = 0; i < n.length; i++ ) {
11002
11003				handle = $.trim( n[ i ] );
11004				hname = "ui-resizable-" + handle;
11005				axis = $( "<div>" );
11006				this._addClass( axis, "ui-resizable-handle " + hname );
11007
11008				axis.css( { zIndex: o.zIndex } );
11009
11010				this.handles[ handle ] = ".ui-resizable-" + handle;
11011				this.element.append( axis );
11012			}
11013
11014		}
11015
11016		this._renderAxis = function( target ) {
11017
11018			var i, axis, padPos, padWrapper;
11019
11020			target = target || this.element;
11021
11022			for ( i in this.handles ) {
11023
11024				if ( this.handles[ i ].constructor === String ) {
11025					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11026				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11027					this.handles[ i ] = $( this.handles[ i ] );
11028					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11029				}
11030
11031				if ( this.elementIsWrapper &&
11032						this.originalElement[ 0 ]
11033							.nodeName
11034							.match( /^(textarea|input|select|button)$/i ) ) {
11035					axis = $( this.handles[ i ], this.element );
11036
11037					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11038						axis.outerHeight() :
11039						axis.outerWidth();
11040
11041					padPos = [ "padding",
11042						/ne|nw|n/.test( i ) ? "Top" :
11043						/se|sw|s/.test( i ) ? "Bottom" :
11044						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11045
11046					target.css( padPos, padWrapper );
11047
11048					this._proportionallyResize();
11049				}
11050
11051				this._handles = this._handles.add( this.handles[ i ] );
11052			}
11053		};
11054
11055		// TODO: make renderAxis a prototype function
11056		this._renderAxis( this.element );
11057
11058		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11059		this._handles.disableSelection();
11060
11061		this._handles.on( "mouseover", function() {
11062			if ( !that.resizing ) {
11063				if ( this.className ) {
11064					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11065				}
11066				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11067			}
11068		} );
11069
11070		if ( o.autoHide ) {
11071			this._handles.hide();
11072			this._addClass( "ui-resizable-autohide" );
11073		}
11074	},
11075
11076	_removeHandles: function() {
11077		this._handles.remove();
11078	},
11079
11080	_mouseCapture: function( event ) {
11081		var i, handle,
11082			capture = false;
11083
11084		for ( i in this.handles ) {
11085			handle = $( this.handles[ i ] )[ 0 ];
11086			if ( handle === event.target || $.contains( handle, event.target ) ) {
11087				capture = true;
11088			}
11089		}
11090
11091		return !this.options.disabled && capture;
11092	},
11093
11094	_mouseStart: function( event ) {
11095
11096		var curleft, curtop, cursor,
11097			o = this.options,
11098			el = this.element;
11099
11100		this.resizing = true;
11101
11102		this._renderProxy();
11103
11104		curleft = this._num( this.helper.css( "left" ) );
11105		curtop = this._num( this.helper.css( "top" ) );
11106
11107		if ( o.containment ) {
11108			curleft += $( o.containment ).scrollLeft() || 0;
11109			curtop += $( o.containment ).scrollTop() || 0;
11110		}
11111
11112		this.offset = this.helper.offset();
11113		this.position = { left: curleft, top: curtop };
11114
11115		this.size = this._helper ? {
11116				width: this.helper.width(),
11117				height: this.helper.height()
11118			} : {
11119				width: el.width(),
11120				height: el.height()
11121			};
11122
11123		this.originalSize = this._helper ? {
11124				width: el.outerWidth(),
11125				height: el.outerHeight()
11126			} : {
11127				width: el.width(),
11128				height: el.height()
11129			};
11130
11131		this.sizeDiff = {
11132			width: el.outerWidth() - el.width(),
11133			height: el.outerHeight() - el.height()
11134		};
11135
11136		this.originalPosition = { left: curleft, top: curtop };
11137		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11138
11139		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11140			o.aspectRatio :
11141			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11142
11143		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11144		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11145
11146		this._addClass( "ui-resizable-resizing" );
11147		this._propagate( "start", event );
11148		return true;
11149	},
11150
11151	_mouseDrag: function( event ) {
11152
11153		var data, props,
11154			smp = this.originalMousePosition,
11155			a = this.axis,
11156			dx = ( event.pageX - smp.left ) || 0,
11157			dy = ( event.pageY - smp.top ) || 0,
11158			trigger = this._change[ a ];
11159
11160		this._updatePrevProperties();
11161
11162		if ( !trigger ) {
11163			return false;
11164		}
11165
11166		data = trigger.apply( this, [ event, dx, dy ] );
11167
11168		this._updateVirtualBoundaries( event.shiftKey );
11169		if ( this._aspectRatio || event.shiftKey ) {
11170			data = this._updateRatio( data, event );
11171		}
11172
11173		data = this._respectSize( data, event );
11174
11175		this._updateCache( data );
11176
11177		this._propagate( "resize", event );
11178
11179		props = this._applyChanges();
11180
11181		if ( !this._helper && this._proportionallyResizeElements.length ) {
11182			this._proportionallyResize();
11183		}
11184
11185		if ( !$.isEmptyObject( props ) ) {
11186			this._updatePrevProperties();
11187			this._trigger( "resize", event, this.ui() );
11188			this._applyChanges();
11189		}
11190
11191		return false;
11192	},
11193
11194	_mouseStop: function( event ) {
11195
11196		this.resizing = false;
11197		var pr, ista, soffseth, soffsetw, s, left, top,
11198			o = this.options, that = this;
11199
11200		if ( this._helper ) {
11201
11202			pr = this._proportionallyResizeElements;
11203			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11204			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11205			soffsetw = ista ? 0 : that.sizeDiff.width;
11206
11207			s = {
11208				width: ( that.helper.width()  - soffsetw ),
11209				height: ( that.helper.height() - soffseth )
11210			};
11211			left = ( parseFloat( that.element.css( "left" ) ) +
11212				( that.position.left - that.originalPosition.left ) ) || null;
11213			top = ( parseFloat( that.element.css( "top" ) ) +
11214				( that.position.top - that.originalPosition.top ) ) || null;
11215
11216			if ( !o.animate ) {
11217				this.element.css( $.extend( s, { top: top, left: left } ) );
11218			}
11219
11220			that.helper.height( that.size.height );
11221			that.helper.width( that.size.width );
11222
11223			if ( this._helper && !o.animate ) {
11224				this._proportionallyResize();
11225			}
11226		}
11227
11228		$( "body" ).css( "cursor", "auto" );
11229
11230		this._removeClass( "ui-resizable-resizing" );
11231
11232		this._propagate( "stop", event );
11233
11234		if ( this._helper ) {
11235			this.helper.remove();
11236		}
11237
11238		return false;
11239
11240	},
11241
11242	_updatePrevProperties: function() {
11243		this.prevPosition = {
11244			top: this.position.top,
11245			left: this.position.left
11246		};
11247		this.prevSize = {
11248			width: this.size.width,
11249			height: this.size.height
11250		};
11251	},
11252
11253	_applyChanges: function() {
11254		var props = {};
11255
11256		if ( this.position.top !== this.prevPosition.top ) {
11257			props.top = this.position.top + "px";
11258		}
11259		if ( this.position.left !== this.prevPosition.left ) {
11260			props.left = this.position.left + "px";
11261		}
11262		if ( this.size.width !== this.prevSize.width ) {
11263			props.width = this.size.width + "px";
11264		}
11265		if ( this.size.height !== this.prevSize.height ) {
11266			props.height = this.size.height + "px";
11267		}
11268
11269		this.helper.css( props );
11270
11271		return props;
11272	},
11273
11274	_updateVirtualBoundaries: function( forceAspectRatio ) {
11275		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11276			o = this.options;
11277
11278		b = {
11279			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11280			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11281			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11282			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11283		};
11284
11285		if ( this._aspectRatio || forceAspectRatio ) {
11286			pMinWidth = b.minHeight * this.aspectRatio;
11287			pMinHeight = b.minWidth / this.aspectRatio;
11288			pMaxWidth = b.maxHeight * this.aspectRatio;
11289			pMaxHeight = b.maxWidth / this.aspectRatio;
11290
11291			if ( pMinWidth > b.minWidth ) {
11292				b.minWidth = pMinWidth;
11293			}
11294			if ( pMinHeight > b.minHeight ) {
11295				b.minHeight = pMinHeight;
11296			}
11297			if ( pMaxWidth < b.maxWidth ) {
11298				b.maxWidth = pMaxWidth;
11299			}
11300			if ( pMaxHeight < b.maxHeight ) {
11301				b.maxHeight = pMaxHeight;
11302			}
11303		}
11304		this._vBoundaries = b;
11305	},
11306
11307	_updateCache: function( data ) {
11308		this.offset = this.helper.offset();
11309		if ( this._isNumber( data.left ) ) {
11310			this.position.left = data.left;
11311		}
11312		if ( this._isNumber( data.top ) ) {
11313			this.position.top = data.top;
11314		}
11315		if ( this._isNumber( data.height ) ) {
11316			this.size.height = data.height;
11317		}
11318		if ( this._isNumber( data.width ) ) {
11319			this.size.width = data.width;
11320		}
11321	},
11322
11323	_updateRatio: function( data ) {
11324
11325		var cpos = this.position,
11326			csize = this.size,
11327			a = this.axis;
11328
11329		if ( this._isNumber( data.height ) ) {
11330			data.width = ( data.height * this.aspectRatio );
11331		} else if ( this._isNumber( data.width ) ) {
11332			data.height = ( data.width / this.aspectRatio );
11333		}
11334
11335		if ( a === "sw" ) {
11336			data.left = cpos.left + ( csize.width - data.width );
11337			data.top = null;
11338		}
11339		if ( a === "nw" ) {
11340			data.top = cpos.top + ( csize.height - data.height );
11341			data.left = cpos.left + ( csize.width - data.width );
11342		}
11343
11344		return data;
11345	},
11346
11347	_respectSize: function( data ) {
11348
11349		var o = this._vBoundaries,
11350			a = this.axis,
11351			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11352			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11353			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11354			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11355			dw = this.originalPosition.left + this.originalSize.width,
11356			dh = this.originalPosition.top + this.originalSize.height,
11357			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11358		if ( isminw ) {
11359			data.width = o.minWidth;
11360		}
11361		if ( isminh ) {
11362			data.height = o.minHeight;
11363		}
11364		if ( ismaxw ) {
11365			data.width = o.maxWidth;
11366		}
11367		if ( ismaxh ) {
11368			data.height = o.maxHeight;
11369		}
11370
11371		if ( isminw && cw ) {
11372			data.left = dw - o.minWidth;
11373		}
11374		if ( ismaxw && cw ) {
11375			data.left = dw - o.maxWidth;
11376		}
11377		if ( isminh && ch ) {
11378			data.top = dh - o.minHeight;
11379		}
11380		if ( ismaxh && ch ) {
11381			data.top = dh - o.maxHeight;
11382		}
11383
11384		// Fixing jump error on top/left - bug #2330
11385		if ( !data.width && !data.height && !data.left && data.top ) {
11386			data.top = null;
11387		} else if ( !data.width && !data.height && !data.top && data.left ) {
11388			data.left = null;
11389		}
11390
11391		return data;
11392	},
11393
11394	_getPaddingPlusBorderDimensions: function( element ) {
11395		var i = 0,
11396			widths = [],
11397			borders = [
11398				element.css( "borderTopWidth" ),
11399				element.css( "borderRightWidth" ),
11400				element.css( "borderBottomWidth" ),
11401				element.css( "borderLeftWidth" )
11402			],
11403			paddings = [
11404				element.css( "paddingTop" ),
11405				element.css( "paddingRight" ),
11406				element.css( "paddingBottom" ),
11407				element.css( "paddingLeft" )
11408			];
11409
11410		for ( ; i < 4; i++ ) {
11411			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11412			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11413		}
11414
11415		return {
11416			height: widths[ 0 ] + widths[ 2 ],
11417			width: widths[ 1 ] + widths[ 3 ]
11418		};
11419	},
11420
11421	_proportionallyResize: function() {
11422
11423		if ( !this._proportionallyResizeElements.length ) {
11424			return;
11425		}
11426
11427		var prel,
11428			i = 0,
11429			element = this.helper || this.element;
11430
11431		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11432
11433			prel = this._proportionallyResizeElements[ i ];
11434
11435			// TODO: Seems like a bug to cache this.outerDimensions
11436			// considering that we are in a loop.
11437			if ( !this.outerDimensions ) {
11438				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11439			}
11440
11441			prel.css( {
11442				height: ( element.height() - this.outerDimensions.height ) || 0,
11443				width: ( element.width() - this.outerDimensions.width ) || 0
11444			} );
11445
11446		}
11447
11448	},
11449
11450	_renderProxy: function() {
11451
11452		var el = this.element, o = this.options;
11453		this.elementOffset = el.offset();
11454
11455		if ( this._helper ) {
11456
11457			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11458
11459			this._addClass( this.helper, this._helper );
11460			this.helper.css( {
11461				width: this.element.outerWidth(),
11462				height: this.element.outerHeight(),
11463				position: "absolute",
11464				left: this.elementOffset.left + "px",
11465				top: this.elementOffset.top + "px",
11466				zIndex: ++o.zIndex //TODO: Don't modify option
11467			} );
11468
11469			this.helper
11470				.appendTo( "body" )
11471				.disableSelection();
11472
11473		} else {
11474			this.helper = this.element;
11475		}
11476
11477	},
11478
11479	_change: {
11480		e: function( event, dx ) {
11481			return { width: this.originalSize.width + dx };
11482		},
11483		w: function( event, dx ) {
11484			var cs = this.originalSize, sp = this.originalPosition;
11485			return { left: sp.left + dx, width: cs.width - dx };
11486		},
11487		n: function( event, dx, dy ) {
11488			var cs = this.originalSize, sp = this.originalPosition;
11489			return { top: sp.top + dy, height: cs.height - dy };
11490		},
11491		s: function( event, dx, dy ) {
11492			return { height: this.originalSize.height + dy };
11493		},
11494		se: function( event, dx, dy ) {
11495			return $.extend( this._change.s.apply( this, arguments ),
11496				this._change.e.apply( this, [ event, dx, dy ] ) );
11497		},
11498		sw: function( event, dx, dy ) {
11499			return $.extend( this._change.s.apply( this, arguments ),
11500				this._change.w.apply( this, [ event, dx, dy ] ) );
11501		},
11502		ne: function( event, dx, dy ) {
11503			return $.extend( this._change.n.apply( this, arguments ),
11504				this._change.e.apply( this, [ event, dx, dy ] ) );
11505		},
11506		nw: function( event, dx, dy ) {
11507			return $.extend( this._change.n.apply( this, arguments ),
11508				this._change.w.apply( this, [ event, dx, dy ] ) );
11509		}
11510	},
11511
11512	_propagate: function( n, event ) {
11513		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11514		( n !== "resize" && this._trigger( n, event, this.ui() ) );
11515	},
11516
11517	plugins: {},
11518
11519	ui: function() {
11520		return {
11521			originalElement: this.originalElement,
11522			element: this.element,
11523			helper: this.helper,
11524			position: this.position,
11525			size: this.size,
11526			originalSize: this.originalSize,
11527			originalPosition: this.originalPosition
11528		};
11529	}
11530
11531} );
11532
11533/*
11534 * Resizable Extensions
11535 */
11536
11537$.ui.plugin.add( "resizable", "animate", {
11538
11539	stop: function( event ) {
11540		var that = $( this ).resizable( "instance" ),
11541			o = that.options,
11542			pr = that._proportionallyResizeElements,
11543			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11544			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11545			soffsetw = ista ? 0 : that.sizeDiff.width,
11546			style = {
11547				width: ( that.size.width - soffsetw ),
11548				height: ( that.size.height - soffseth )
11549			},
11550			left = ( parseFloat( that.element.css( "left" ) ) +
11551				( that.position.left - that.originalPosition.left ) ) || null,
11552			top = ( parseFloat( that.element.css( "top" ) ) +
11553				( that.position.top - that.originalPosition.top ) ) || null;
11554
11555		that.element.animate(
11556			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11557				duration: o.animateDuration,
11558				easing: o.animateEasing,
11559				step: function() {
11560
11561					var data = {
11562						width: parseFloat( that.element.css( "width" ) ),
11563						height: parseFloat( that.element.css( "height" ) ),
11564						top: parseFloat( that.element.css( "top" ) ),
11565						left: parseFloat( that.element.css( "left" ) )
11566					};
11567
11568					if ( pr && pr.length ) {
11569						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11570					}
11571
11572					// Propagating resize, and updating values for each animation step
11573					that._updateCache( data );
11574					that._propagate( "resize", event );
11575
11576				}
11577			}
11578		);
11579	}
11580
11581} );
11582
11583$.ui.plugin.add( "resizable", "containment", {
11584
11585	start: function() {
11586		var element, p, co, ch, cw, width, height,
11587			that = $( this ).resizable( "instance" ),
11588			o = that.options,
11589			el = that.element,
11590			oc = o.containment,
11591			ce = ( oc instanceof $ ) ?
11592				oc.get( 0 ) :
11593				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11594
11595		if ( !ce ) {
11596			return;
11597		}
11598
11599		that.containerElement = $( ce );
11600
11601		if ( /document/.test( oc ) || oc === document ) {
11602			that.containerOffset = {
11603				left: 0,
11604				top: 0
11605			};
11606			that.containerPosition = {
11607				left: 0,
11608				top: 0
11609			};
11610
11611			that.parentData = {
11612				element: $( document ),
11613				left: 0,
11614				top: 0,
11615				width: $( document ).width(),
11616				height: $( document ).height() || document.body.parentNode.scrollHeight
11617			};
11618		} else {
11619			element = $( ce );
11620			p = [];
11621			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11622				p[ i ] = that._num( element.css( "padding" + name ) );
11623			} );
11624
11625			that.containerOffset = element.offset();
11626			that.containerPosition = element.position();
11627			that.containerSize = {
11628				height: ( element.innerHeight() - p[ 3 ] ),
11629				width: ( element.innerWidth() - p[ 1 ] )
11630			};
11631
11632			co = that.containerOffset;
11633			ch = that.containerSize.height;
11634			cw = that.containerSize.width;
11635			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11636			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11637
11638			that.parentData = {
11639				element: ce,
11640				left: co.left,
11641				top: co.top,
11642				width: width,
11643				height: height
11644			};
11645		}
11646	},
11647
11648	resize: function( event ) {
11649		var woset, hoset, isParent, isOffsetRelative,
11650			that = $( this ).resizable( "instance" ),
11651			o = that.options,
11652			co = that.containerOffset,
11653			cp = that.position,
11654			pRatio = that._aspectRatio || event.shiftKey,
11655			cop = {
11656				top: 0,
11657				left: 0
11658			},
11659			ce = that.containerElement,
11660			continueResize = true;
11661
11662		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11663			cop = co;
11664		}
11665
11666		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11667			that.size.width = that.size.width +
11668				( that._helper ?
11669					( that.position.left - co.left ) :
11670					( that.position.left - cop.left ) );
11671
11672			if ( pRatio ) {
11673				that.size.height = that.size.width / that.aspectRatio;
11674				continueResize = false;
11675			}
11676			that.position.left = o.helper ? co.left : 0;
11677		}
11678
11679		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11680			that.size.height = that.size.height +
11681				( that._helper ?
11682					( that.position.top - co.top ) :
11683					that.position.top );
11684
11685			if ( pRatio ) {
11686				that.size.width = that.size.height * that.aspectRatio;
11687				continueResize = false;
11688			}
11689			that.position.top = that._helper ? co.top : 0;
11690		}
11691
11692		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11693		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11694
11695		if ( isParent && isOffsetRelative ) {
11696			that.offset.left = that.parentData.left + that.position.left;
11697			that.offset.top = that.parentData.top + that.position.top;
11698		} else {
11699			that.offset.left = that.element.offset().left;
11700			that.offset.top = that.element.offset().top;
11701		}
11702
11703		woset = Math.abs( that.sizeDiff.width +
11704			( that._helper ?
11705				that.offset.left - cop.left :
11706				( that.offset.left - co.left ) ) );
11707
11708		hoset = Math.abs( that.sizeDiff.height +
11709			( that._helper ?
11710				that.offset.top - cop.top :
11711				( that.offset.top - co.top ) ) );
11712
11713		if ( woset + that.size.width >= that.parentData.width ) {
11714			that.size.width = that.parentData.width - woset;
11715			if ( pRatio ) {
11716				that.size.height = that.size.width / that.aspectRatio;
11717				continueResize = false;
11718			}
11719		}
11720
11721		if ( hoset + that.size.height >= that.parentData.height ) {
11722			that.size.height = that.parentData.height - hoset;
11723			if ( pRatio ) {
11724				that.size.width = that.size.height * that.aspectRatio;
11725				continueResize = false;
11726			}
11727		}
11728
11729		if ( !continueResize ) {
11730			that.position.left = that.prevPosition.left;
11731			that.position.top = that.prevPosition.top;
11732			that.size.width = that.prevSize.width;
11733			that.size.height = that.prevSize.height;
11734		}
11735	},
11736
11737	stop: function() {
11738		var that = $( this ).resizable( "instance" ),
11739			o = that.options,
11740			co = that.containerOffset,
11741			cop = that.containerPosition,
11742			ce = that.containerElement,
11743			helper = $( that.helper ),
11744			ho = helper.offset(),
11745			w = helper.outerWidth() - that.sizeDiff.width,
11746			h = helper.outerHeight() - that.sizeDiff.height;
11747
11748		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11749			$( this ).css( {
11750				left: ho.left - cop.left - co.left,
11751				width: w,
11752				height: h
11753			} );
11754		}
11755
11756		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11757			$( this ).css( {
11758				left: ho.left - cop.left - co.left,
11759				width: w,
11760				height: h
11761			} );
11762		}
11763	}
11764} );
11765
11766$.ui.plugin.add( "resizable", "alsoResize", {
11767
11768	start: function() {
11769		var that = $( this ).resizable( "instance" ),
11770			o = that.options;
11771
11772		$( o.alsoResize ).each( function() {
11773			var el = $( this );
11774			el.data( "ui-resizable-alsoresize", {
11775				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11776				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11777			} );
11778		} );
11779	},
11780
11781	resize: function( event, ui ) {
11782		var that = $( this ).resizable( "instance" ),
11783			o = that.options,
11784			os = that.originalSize,
11785			op = that.originalPosition,
11786			delta = {
11787				height: ( that.size.height - os.height ) || 0,
11788				width: ( that.size.width - os.width ) || 0,
11789				top: ( that.position.top - op.top ) || 0,
11790				left: ( that.position.left - op.left ) || 0
11791			};
11792
11793			$( o.alsoResize ).each( function() {
11794				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11795					css = el.parents( ui.originalElement[ 0 ] ).length ?
11796							[ "width", "height" ] :
11797							[ "width", "height", "top", "left" ];
11798
11799				$.each( css, function( i, prop ) {
11800					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11801					if ( sum && sum >= 0 ) {
11802						style[ prop ] = sum || null;
11803					}
11804				} );
11805
11806				el.css( style );
11807			} );
11808	},
11809
11810	stop: function() {
11811		$( this ).removeData( "ui-resizable-alsoresize" );
11812	}
11813} );
11814
11815$.ui.plugin.add( "resizable", "ghost", {
11816
11817	start: function() {
11818
11819		var that = $( this ).resizable( "instance" ), cs = that.size;
11820
11821		that.ghost = that.originalElement.clone();
11822		that.ghost.css( {
11823			opacity: 0.25,
11824			display: "block",
11825			position: "relative",
11826			height: cs.height,
11827			width: cs.width,
11828			margin: 0,
11829			left: 0,
11830			top: 0
11831		} );
11832
11833		that._addClass( that.ghost, "ui-resizable-ghost" );
11834
11835		// DEPRECATED
11836		// TODO: remove after 1.12
11837		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11838
11839			// Ghost option
11840			that.ghost.addClass( this.options.ghost );
11841		}
11842
11843		that.ghost.appendTo( that.helper );
11844
11845	},
11846
11847	resize: function() {
11848		var that = $( this ).resizable( "instance" );
11849		if ( that.ghost ) {
11850			that.ghost.css( {
11851				position: "relative",
11852				height: that.size.height,
11853				width: that.size.width
11854			} );
11855		}
11856	},
11857
11858	stop: function() {
11859		var that = $( this ).resizable( "instance" );
11860		if ( that.ghost && that.helper ) {
11861			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11862		}
11863	}
11864
11865} );
11866
11867$.ui.plugin.add( "resizable", "grid", {
11868
11869	resize: function() {
11870		var outerDimensions,
11871			that = $( this ).resizable( "instance" ),
11872			o = that.options,
11873			cs = that.size,
11874			os = that.originalSize,
11875			op = that.originalPosition,
11876			a = that.axis,
11877			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11878			gridX = ( grid[ 0 ] || 1 ),
11879			gridY = ( grid[ 1 ] || 1 ),
11880			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11881			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11882			newWidth = os.width + ox,
11883			newHeight = os.height + oy,
11884			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11885			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11886			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11887			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11888
11889		o.grid = grid;
11890
11891		if ( isMinWidth ) {
11892			newWidth += gridX;
11893		}
11894		if ( isMinHeight ) {
11895			newHeight += gridY;
11896		}
11897		if ( isMaxWidth ) {
11898			newWidth -= gridX;
11899		}
11900		if ( isMaxHeight ) {
11901			newHeight -= gridY;
11902		}
11903
11904		if ( /^(se|s|e)$/.test( a ) ) {
11905			that.size.width = newWidth;
11906			that.size.height = newHeight;
11907		} else if ( /^(ne)$/.test( a ) ) {
11908			that.size.width = newWidth;
11909			that.size.height = newHeight;
11910			that.position.top = op.top - oy;
11911		} else if ( /^(sw)$/.test( a ) ) {
11912			that.size.width = newWidth;
11913			that.size.height = newHeight;
11914			that.position.left = op.left - ox;
11915		} else {
11916			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11917				outerDimensions = that._getPaddingPlusBorderDimensions( this );
11918			}
11919
11920			if ( newHeight - gridY > 0 ) {
11921				that.size.height = newHeight;
11922				that.position.top = op.top - oy;
11923			} else {
11924				newHeight = gridY - outerDimensions.height;
11925				that.size.height = newHeight;
11926				that.position.top = op.top + os.height - newHeight;
11927			}
11928			if ( newWidth - gridX > 0 ) {
11929				that.size.width = newWidth;
11930				that.position.left = op.left - ox;
11931			} else {
11932				newWidth = gridX - outerDimensions.width;
11933				that.size.width = newWidth;
11934				that.position.left = op.left + os.width - newWidth;
11935			}
11936		}
11937	}
11938
11939} );
11940
11941var widgetsResizable = $.ui.resizable;
11942
11943
11944/*!
11945 * jQuery UI Dialog 1.12.1
11946 * http://jqueryui.com
11947 *
11948 * Copyright jQuery Foundation and other contributors
11949 * Released under the MIT license.
11950 * http://jquery.org/license
11951 */
11952
11953//>>label: Dialog
11954//>>group: Widgets
11955//>>description: Displays customizable dialog windows.
11956//>>docs: http://api.jqueryui.com/dialog/
11957//>>demos: http://jqueryui.com/dialog/
11958//>>css.structure: ../../themes/base/core.css
11959//>>css.structure: ../../themes/base/dialog.css
11960//>>css.theme: ../../themes/base/theme.css
11961
11962
11963
11964$.widget( "ui.dialog", {
11965	version: "1.12.1",
11966	options: {
11967		appendTo: "body",
11968		autoOpen: true,
11969		buttons: [],
11970		classes: {
11971			"ui-dialog": "ui-corner-all",
11972			"ui-dialog-titlebar": "ui-corner-all"
11973		},
11974		closeOnEscape: true,
11975		closeText: "Close",
11976		draggable: true,
11977		hide: null,
11978		height: "auto",
11979		maxHeight: null,
11980		maxWidth: null,
11981		minHeight: 150,
11982		minWidth: 150,
11983		modal: false,
11984		position: {
11985			my: "center",
11986			at: "center",
11987			of: window,
11988			collision: "fit",
11989
11990			// Ensure the titlebar is always visible
11991			using: function( pos ) {
11992				var topOffset = $( this ).css( pos ).offset().top;
11993				if ( topOffset < 0 ) {
11994					$( this ).css( "top", pos.top - topOffset );
11995				}
11996			}
11997		},
11998		resizable: true,
11999		show: null,
12000		title: null,
12001		width: 300,
12002
12003		// Callbacks
12004		beforeClose: null,
12005		close: null,
12006		drag: null,
12007		dragStart: null,
12008		dragStop: null,
12009		focus: null,
12010		open: null,
12011		resize: null,
12012		resizeStart: null,
12013		resizeStop: null
12014	},
12015
12016	sizeRelatedOptions: {
12017		buttons: true,
12018		height: true,
12019		maxHeight: true,
12020		maxWidth: true,
12021		minHeight: true,
12022		minWidth: true,
12023		width: true
12024	},
12025
12026	resizableRelatedOptions: {
12027		maxHeight: true,
12028		maxWidth: true,
12029		minHeight: true,
12030		minWidth: true
12031	},
12032
12033	_create: function() {
12034		this.originalCss = {
12035			display: this.element[ 0 ].style.display,
12036			width: this.element[ 0 ].style.width,
12037			minHeight: this.element[ 0 ].style.minHeight,
12038			maxHeight: this.element[ 0 ].style.maxHeight,
12039			height: this.element[ 0 ].style.height
12040		};
12041		this.originalPosition = {
12042			parent: this.element.parent(),
12043			index: this.element.parent().children().index( this.element )
12044		};
12045		this.originalTitle = this.element.attr( "title" );
12046		if ( this.options.title == null && this.originalTitle != null ) {
12047			this.options.title = this.originalTitle;
12048		}
12049
12050		// Dialogs can't be disabled
12051		if ( this.options.disabled ) {
12052			this.options.disabled = false;
12053		}
12054
12055		this._createWrapper();
12056
12057		this.element
12058			.show()
12059			.removeAttr( "title" )
12060			.appendTo( this.uiDialog );
12061
12062		this._addClass( "ui-dialog-content", "ui-widget-content" );
12063
12064		this._createTitlebar();
12065		this._createButtonPane();
12066
12067		if ( this.options.draggable && $.fn.draggable ) {
12068			this._makeDraggable();
12069		}
12070		if ( this.options.resizable && $.fn.resizable ) {
12071			this._makeResizable();
12072		}
12073
12074		this._isOpen = false;
12075
12076		this._trackFocus();
12077	},
12078
12079	_init: function() {
12080		if ( this.options.autoOpen ) {
12081			this.open();
12082		}
12083	},
12084
12085	_appendTo: function() {
12086		var element = this.options.appendTo;
12087		if ( element && ( element.jquery || element.nodeType ) ) {
12088			return $( element );
12089		}
12090		return this.document.find( element || "body" ).eq( 0 );
12091	},
12092
12093	_destroy: function() {
12094		var next,
12095			originalPosition = this.originalPosition;
12096
12097		this._untrackInstance();
12098		this._destroyOverlay();
12099
12100		this.element
12101			.removeUniqueId()
12102			.css( this.originalCss )
12103
12104			// Without detaching first, the following becomes really slow
12105			.detach();
12106
12107		this.uiDialog.remove();
12108
12109		if ( this.originalTitle ) {
12110			this.element.attr( "title", this.originalTitle );
12111		}
12112
12113		next = originalPosition.parent.children().eq( originalPosition.index );
12114
12115		// Don't try to place the dialog next to itself (#8613)
12116		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12117			next.before( this.element );
12118		} else {
12119			originalPosition.parent.append( this.element );
12120		}
12121	},
12122
12123	widget: function() {
12124		return this.uiDialog;
12125	},
12126
12127	disable: $.noop,
12128	enable: $.noop,
12129
12130	close: function( event ) {
12131		var that = this;
12132
12133		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12134			return;
12135		}
12136
12137		this._isOpen = false;
12138		this._focusedElement = null;
12139		this._destroyOverlay();
12140		this._untrackInstance();
12141
12142		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12143
12144			// Hiding a focused element doesn't trigger blur in WebKit
12145			// so in case we have nothing to focus on, explicitly blur the active element
12146			// https://bugs.webkit.org/show_bug.cgi?id=47182
12147			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12148		}
12149
12150		this._hide( this.uiDialog, this.options.hide, function() {
12151			that._trigger( "close", event );
12152		} );
12153	},
12154
12155	isOpen: function() {
12156		return this._isOpen;
12157	},
12158
12159	moveToTop: function() {
12160		this._moveToTop();
12161	},
12162
12163	_moveToTop: function( event, silent ) {
12164		var moved = false,
12165			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12166				return +$( this ).css( "z-index" );
12167			} ).get(),
12168			zIndexMax = Math.max.apply( null, zIndices );
12169
12170		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12171			this.uiDialog.css( "z-index", zIndexMax + 1 );
12172			moved = true;
12173		}
12174
12175		if ( moved && !silent ) {
12176			this._trigger( "focus", event );
12177		}
12178		return moved;
12179	},
12180
12181	open: function() {
12182		var that = this;
12183		if ( this._isOpen ) {
12184			if ( this._moveToTop() ) {
12185				this._focusTabbable();
12186			}
12187			return;
12188		}
12189
12190		this._isOpen = true;
12191		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12192
12193		this._size();
12194		this._position();
12195		this._createOverlay();
12196		this._moveToTop( null, true );
12197
12198		// Ensure the overlay is moved to the top with the dialog, but only when
12199		// opening. The overlay shouldn't move after the dialog is open so that
12200		// modeless dialogs opened after the modal dialog stack properly.
12201		if ( this.overlay ) {
12202			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12203		}
12204
12205		this._show( this.uiDialog, this.options.show, function() {
12206			that._focusTabbable();
12207			that._trigger( "focus" );
12208		} );
12209
12210		// Track the dialog immediately upon openening in case a focus event
12211		// somehow occurs outside of the dialog before an element inside the
12212		// dialog is focused (#10152)
12213		this._makeFocusTarget();
12214
12215		this._trigger( "open" );
12216	},
12217
12218	_focusTabbable: function() {
12219
12220		// Set focus to the first match:
12221		// 1. An element that was focused previously
12222		// 2. First element inside the dialog matching [autofocus]
12223		// 3. Tabbable element inside the content element
12224		// 4. Tabbable element inside the buttonpane
12225		// 5. The close button
12226		// 6. The dialog itself
12227		var hasFocus = this._focusedElement;
12228		if ( !hasFocus ) {
12229			hasFocus = this.element.find( "[autofocus]" );
12230		}
12231		if ( !hasFocus.length ) {
12232			hasFocus = this.element.find( ":tabbable" );
12233		}
12234		if ( !hasFocus.length ) {
12235			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12236		}
12237		if ( !hasFocus.length ) {
12238			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12239		}
12240		if ( !hasFocus.length ) {
12241			hasFocus = this.uiDialog;
12242		}
12243		hasFocus.eq( 0 ).trigger( "focus" );
12244	},
12245
12246	_keepFocus: function( event ) {
12247		function checkFocus() {
12248			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12249				isActive = this.uiDialog[ 0 ] === activeElement ||
12250					$.contains( this.uiDialog[ 0 ], activeElement );
12251			if ( !isActive ) {
12252				this._focusTabbable();
12253			}
12254		}
12255		event.preventDefault();
12256		checkFocus.call( this );
12257
12258		// support: IE
12259		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12260		// so we check again later
12261		this._delay( checkFocus );
12262	},
12263
12264	_createWrapper: function() {
12265		this.uiDialog = $( "<div>" )
12266			.hide()
12267			.attr( {
12268
12269				// Setting tabIndex makes the div focusable
12270				tabIndex: -1,
12271				role: "dialog"
12272			} )
12273			.appendTo( this._appendTo() );
12274
12275		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12276		this._on( this.uiDialog, {
12277			keydown: function( event ) {
12278				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12279						event.keyCode === $.ui.keyCode.ESCAPE ) {
12280					event.preventDefault();
12281					this.close( event );
12282					return;
12283				}
12284
12285				// Prevent tabbing out of dialogs
12286				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12287					return;
12288				}
12289				var tabbables = this.uiDialog.find( ":tabbable" ),
12290					first = tabbables.filter( ":first" ),
12291					last = tabbables.filter( ":last" );
12292
12293				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12294						!event.shiftKey ) {
12295					this._delay( function() {
12296						first.trigger( "focus" );
12297					} );
12298					event.preventDefault();
12299				} else if ( ( event.target === first[ 0 ] ||
12300						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12301					this._delay( function() {
12302						last.trigger( "focus" );
12303					} );
12304					event.preventDefault();
12305				}
12306			},
12307			mousedown: function( event ) {
12308				if ( this._moveToTop( event ) ) {
12309					this._focusTabbable();
12310				}
12311			}
12312		} );
12313
12314		// We assume that any existing aria-describedby attribute means
12315		// that the dialog content is marked up properly
12316		// otherwise we brute force the content as the description
12317		if ( !this.element.find( "[aria-describedby]" ).length ) {
12318			this.uiDialog.attr( {
12319				"aria-describedby": this.element.uniqueId().attr( "id" )
12320			} );
12321		}
12322	},
12323
12324	_createTitlebar: function() {
12325		var uiDialogTitle;
12326
12327		this.uiDialogTitlebar = $( "<div>" );
12328		this._addClass( this.uiDialogTitlebar,
12329			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12330		this._on( this.uiDialogTitlebar, {
12331			mousedown: function( event ) {
12332
12333				// Don't prevent click on close button (#8838)
12334				// Focusing a dialog that is partially scrolled out of view
12335				// causes the browser to scroll it into view, preventing the click event
12336				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12337
12338					// Dialog isn't getting focus when dragging (#8063)
12339					this.uiDialog.trigger( "focus" );
12340				}
12341			}
12342		} );
12343
12344		// Support: IE
12345		// Use type="button" to prevent enter keypresses in textboxes from closing the
12346		// dialog in IE (#9312)
12347		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12348			.button( {
12349				label: $( "<a>" ).text( this.options.closeText ).html(),
12350				icon: "ui-icon-closethick",
12351				showLabel: false
12352			} )
12353			.appendTo( this.uiDialogTitlebar );
12354
12355		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12356		this._on( this.uiDialogTitlebarClose, {
12357			click: function( event ) {
12358				event.preventDefault();
12359				this.close( event );
12360			}
12361		} );
12362
12363		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12364		this._addClass( uiDialogTitle, "ui-dialog-title" );
12365		this._title( uiDialogTitle );
12366
12367		this.uiDialogTitlebar.prependTo( this.uiDialog );
12368
12369		this.uiDialog.attr( {
12370			"aria-labelledby": uiDialogTitle.attr( "id" )
12371		} );
12372	},
12373
12374	_title: function( title ) {
12375		if ( this.options.title ) {
12376			title.text( this.options.title );
12377		} else {
12378			title.html( "&#160;" );
12379		}
12380	},
12381
12382	_createButtonPane: function() {
12383		this.uiDialogButtonPane = $( "<div>" );
12384		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12385			"ui-widget-content ui-helper-clearfix" );
12386
12387		this.uiButtonSet = $( "<div>" )
12388			.appendTo( this.uiDialogButtonPane );
12389		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12390
12391		this._createButtons();
12392	},
12393
12394	_createButtons: function() {
12395		var that = this,
12396			buttons = this.options.buttons;
12397
12398		// If we already have a button pane, remove it
12399		this.uiDialogButtonPane.remove();
12400		this.uiButtonSet.empty();
12401
12402		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12403			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12404			return;
12405		}
12406
12407		$.each( buttons, function( name, props ) {
12408			var click, buttonOptions;
12409			props = $.isFunction( props ) ?
12410				{ click: props, text: name } :
12411				props;
12412
12413			// Default to a non-submitting button
12414			props = $.extend( { type: "button" }, props );
12415
12416			// Change the context for the click callback to be the main element
12417			click = props.click;
12418			buttonOptions = {
12419				icon: props.icon,
12420				iconPosition: props.iconPosition,
12421				showLabel: props.showLabel,
12422
12423				// Deprecated options
12424				icons: props.icons,
12425				text: props.text
12426			};
12427
12428			delete props.click;
12429			delete props.icon;
12430			delete props.iconPosition;
12431			delete props.showLabel;
12432
12433			// Deprecated options
12434			delete props.icons;
12435			if ( typeof props.text === "boolean" ) {
12436				delete props.text;
12437			}
12438
12439			$( "<button></button>", props )
12440				.button( buttonOptions )
12441				.appendTo( that.uiButtonSet )
12442				.on( "click", function() {
12443					click.apply( that.element[ 0 ], arguments );
12444				} );
12445		} );
12446		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12447		this.uiDialogButtonPane.appendTo( this.uiDialog );
12448	},
12449
12450	_makeDraggable: function() {
12451		var that = this,
12452			options = this.options;
12453
12454		function filteredUi( ui ) {
12455			return {
12456				position: ui.position,
12457				offset: ui.offset
12458			};
12459		}
12460
12461		this.uiDialog.draggable( {
12462			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12463			handle: ".ui-dialog-titlebar",
12464			containment: "document",
12465			start: function( event, ui ) {
12466				that._addClass( $( this ), "ui-dialog-dragging" );
12467				that._blockFrames();
12468				that._trigger( "dragStart", event, filteredUi( ui ) );
12469			},
12470			drag: function( event, ui ) {
12471				that._trigger( "drag", event, filteredUi( ui ) );
12472			},
12473			stop: function( event, ui ) {
12474				var left = ui.offset.left - that.document.scrollLeft(),
12475					top = ui.offset.top - that.document.scrollTop();
12476
12477				options.position = {
12478					my: "left top",
12479					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12480						"top" + ( top >= 0 ? "+" : "" ) + top,
12481					of: that.window
12482				};
12483				that._removeClass( $( this ), "ui-dialog-dragging" );
12484				that._unblockFrames();
12485				that._trigger( "dragStop", event, filteredUi( ui ) );
12486			}
12487		} );
12488	},
12489
12490	_makeResizable: function() {
12491		var that = this,
12492			options = this.options,
12493			handles = options.resizable,
12494
12495			// .ui-resizable has position: relative defined in the stylesheet
12496			// but dialogs have to use absolute or fixed positioning
12497			position = this.uiDialog.css( "position" ),
12498			resizeHandles = typeof handles === "string" ?
12499				handles :
12500				"n,e,s,w,se,sw,ne,nw";
12501
12502		function filteredUi( ui ) {
12503			return {
12504				originalPosition: ui.originalPosition,
12505				originalSize: ui.originalSize,
12506				position: ui.position,
12507				size: ui.size
12508			};
12509		}
12510
12511		this.uiDialog.resizable( {
12512			cancel: ".ui-dialog-content",
12513			containment: "document",
12514			alsoResize: this.element,
12515			maxWidth: options.maxWidth,
12516			maxHeight: options.maxHeight,
12517			minWidth: options.minWidth,
12518			minHeight: this._minHeight(),
12519			handles: resizeHandles,
12520			start: function( event, ui ) {
12521				that._addClass( $( this ), "ui-dialog-resizing" );
12522				that._blockFrames();
12523				that._trigger( "resizeStart", event, filteredUi( ui ) );
12524			},
12525			resize: function( event, ui ) {
12526				that._trigger( "resize", event, filteredUi( ui ) );
12527			},
12528			stop: function( event, ui ) {
12529				var offset = that.uiDialog.offset(),
12530					left = offset.left - that.document.scrollLeft(),
12531					top = offset.top - that.document.scrollTop();
12532
12533				options.height = that.uiDialog.height();
12534				options.width = that.uiDialog.width();
12535				options.position = {
12536					my: "left top",
12537					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12538						"top" + ( top >= 0 ? "+" : "" ) + top,
12539					of: that.window
12540				};
12541				that._removeClass( $( this ), "ui-dialog-resizing" );
12542				that._unblockFrames();
12543				that._trigger( "resizeStop", event, filteredUi( ui ) );
12544			}
12545		} )
12546			.css( "position", position );
12547	},
12548
12549	_trackFocus: function() {
12550		this._on( this.widget(), {
12551			focusin: function( event ) {
12552				this._makeFocusTarget();
12553				this._focusedElement = $( event.target );
12554			}
12555		} );
12556	},
12557
12558	_makeFocusTarget: function() {
12559		this._untrackInstance();
12560		this._trackingInstances().unshift( this );
12561	},
12562
12563	_untrackInstance: function() {
12564		var instances = this._trackingInstances(),
12565			exists = $.inArray( this, instances );
12566		if ( exists !== -1 ) {
12567			instances.splice( exists, 1 );
12568		}
12569	},
12570
12571	_trackingInstances: function() {
12572		var instances = this.document.data( "ui-dialog-instances" );
12573		if ( !instances ) {
12574			instances = [];
12575			this.document.data( "ui-dialog-instances", instances );
12576		}
12577		return instances;
12578	},
12579
12580	_minHeight: function() {
12581		var options = this.options;
12582
12583		return options.height === "auto" ?
12584			options.minHeight :
12585			Math.min( options.minHeight, options.height );
12586	},
12587
12588	_position: function() {
12589
12590		// Need to show the dialog to get the actual offset in the position plugin
12591		var isVisible = this.uiDialog.is( ":visible" );
12592		if ( !isVisible ) {
12593			this.uiDialog.show();
12594		}
12595		this.uiDialog.position( this.options.position );
12596		if ( !isVisible ) {
12597			this.uiDialog.hide();
12598		}
12599	},
12600
12601	_setOptions: function( options ) {
12602		var that = this,
12603			resize = false,
12604			resizableOptions = {};
12605
12606		$.each( options, function( key, value ) {
12607			that._setOption( key, value );
12608
12609			if ( key in that.sizeRelatedOptions ) {
12610				resize = true;
12611			}
12612			if ( key in that.resizableRelatedOptions ) {
12613				resizableOptions[ key ] = value;
12614			}
12615		} );
12616
12617		if ( resize ) {
12618			this._size();
12619			this._position();
12620		}
12621		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12622			this.uiDialog.resizable( "option", resizableOptions );
12623		}
12624	},
12625
12626	_setOption: function( key, value ) {
12627		var isDraggable, isResizable,
12628			uiDialog = this.uiDialog;
12629
12630		if ( key === "disabled" ) {
12631			return;
12632		}
12633
12634		this._super( key, value );
12635
12636		if ( key === "appendTo" ) {
12637			this.uiDialog.appendTo( this._appendTo() );
12638		}
12639
12640		if ( key === "buttons" ) {
12641			this._createButtons();
12642		}
12643
12644		if ( key === "closeText" ) {
12645			this.uiDialogTitlebarClose.button( {
12646
12647				// Ensure that we always pass a string
12648				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12649			} );
12650		}
12651
12652		if ( key === "draggable" ) {
12653			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12654			if ( isDraggable && !value ) {
12655				uiDialog.draggable( "destroy" );
12656			}
12657
12658			if ( !isDraggable && value ) {
12659				this._makeDraggable();
12660			}
12661		}
12662
12663		if ( key === "position" ) {
12664			this._position();
12665		}
12666
12667		if ( key === "resizable" ) {
12668
12669			// currently resizable, becoming non-resizable
12670			isResizable = uiDialog.is( ":data(ui-resizable)" );
12671			if ( isResizable && !value ) {
12672				uiDialog.resizable( "destroy" );
12673			}
12674
12675			// Currently resizable, changing handles
12676			if ( isResizable && typeof value === "string" ) {
12677				uiDialog.resizable( "option", "handles", value );
12678			}
12679
12680			// Currently non-resizable, becoming resizable
12681			if ( !isResizable && value !== false ) {
12682				this._makeResizable();
12683			}
12684		}
12685
12686		if ( key === "title" ) {
12687			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12688		}
12689	},
12690
12691	_size: function() {
12692
12693		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12694		// divs will both have width and height set, so we need to reset them
12695		var nonContentHeight, minContentHeight, maxContentHeight,
12696			options = this.options;
12697
12698		// Reset content sizing
12699		this.element.show().css( {
12700			width: "auto",
12701			minHeight: 0,
12702			maxHeight: "none",
12703			height: 0
12704		} );
12705
12706		if ( options.minWidth > options.width ) {
12707			options.width = options.minWidth;
12708		}
12709
12710		// Reset wrapper sizing
12711		// determine the height of all the non-content elements
12712		nonContentHeight = this.uiDialog.css( {
12713			height: "auto",
12714			width: options.width
12715		} )
12716			.outerHeight();
12717		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12718		maxContentHeight = typeof options.maxHeight === "number" ?
12719			Math.max( 0, options.maxHeight - nonContentHeight ) :
12720			"none";
12721
12722		if ( options.height === "auto" ) {
12723			this.element.css( {
12724				minHeight: minContentHeight,
12725				maxHeight: maxContentHeight,
12726				height: "auto"
12727			} );
12728		} else {
12729			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12730		}
12731
12732		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12733			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12734		}
12735	},
12736
12737	_blockFrames: function() {
12738		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12739			var iframe = $( this );
12740
12741			return $( "<div>" )
12742				.css( {
12743					position: "absolute",
12744					width: iframe.outerWidth(),
12745					height: iframe.outerHeight()
12746				} )
12747				.appendTo( iframe.parent() )
12748				.offset( iframe.offset() )[ 0 ];
12749		} );
12750	},
12751
12752	_unblockFrames: function() {
12753		if ( this.iframeBlocks ) {
12754			this.iframeBlocks.remove();
12755			delete this.iframeBlocks;
12756		}
12757	},
12758
12759	_allowInteraction: function( event ) {
12760		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12761			return true;
12762		}
12763
12764		// TODO: Remove hack when datepicker implements
12765		// the .ui-front logic (#8989)
12766		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12767	},
12768
12769	_createOverlay: function() {
12770		if ( !this.options.modal ) {
12771			return;
12772		}
12773
12774		// We use a delay in case the overlay is created from an
12775		// event that we're going to be cancelling (#2804)
12776		var isOpening = true;
12777		this._delay( function() {
12778			isOpening = false;
12779		} );
12780
12781		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12782
12783			// Prevent use of anchors and inputs
12784			// Using _on() for an event handler shared across many instances is
12785			// safe because the dialogs stack and must be closed in reverse order
12786			this._on( this.document, {
12787				focusin: function( event ) {
12788					if ( isOpening ) {
12789						return;
12790					}
12791
12792					if ( !this._allowInteraction( event ) ) {
12793						event.preventDefault();
12794						this._trackingInstances()[ 0 ]._focusTabbable();
12795					}
12796				}
12797			} );
12798		}
12799
12800		this.overlay = $( "<div>" )
12801			.appendTo( this._appendTo() );
12802
12803		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12804		this._on( this.overlay, {
12805			mousedown: "_keepFocus"
12806		} );
12807		this.document.data( "ui-dialog-overlays",
12808			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12809	},
12810
12811	_destroyOverlay: function() {
12812		if ( !this.options.modal ) {
12813			return;
12814		}
12815
12816		if ( this.overlay ) {
12817			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12818
12819			if ( !overlays ) {
12820				this._off( this.document, "focusin" );
12821				this.document.removeData( "ui-dialog-overlays" );
12822			} else {
12823				this.document.data( "ui-dialog-overlays", overlays );
12824			}
12825
12826			this.overlay.remove();
12827			this.overlay = null;
12828		}
12829	}
12830} );
12831
12832// DEPRECATED
12833// TODO: switch return back to widget declaration at top of file when this is removed
12834if ( $.uiBackCompat !== false ) {
12835
12836	// Backcompat for dialogClass option
12837	$.widget( "ui.dialog", $.ui.dialog, {
12838		options: {
12839			dialogClass: ""
12840		},
12841		_createWrapper: function() {
12842			this._super();
12843			this.uiDialog.addClass( this.options.dialogClass );
12844		},
12845		_setOption: function( key, value ) {
12846			if ( key === "dialogClass" ) {
12847				this.uiDialog
12848					.removeClass( this.options.dialogClass )
12849					.addClass( value );
12850			}
12851			this._superApply( arguments );
12852		}
12853	} );
12854}
12855
12856var widgetsDialog = $.ui.dialog;
12857
12858
12859/*!
12860 * jQuery UI Droppable 1.12.1
12861 * http://jqueryui.com
12862 *
12863 * Copyright jQuery Foundation and other contributors
12864 * Released under the MIT license.
12865 * http://jquery.org/license
12866 */
12867
12868//>>label: Droppable
12869//>>group: Interactions
12870//>>description: Enables drop targets for draggable elements.
12871//>>docs: http://api.jqueryui.com/droppable/
12872//>>demos: http://jqueryui.com/droppable/
12873
12874
12875
12876$.widget( "ui.droppable", {
12877	version: "1.12.1",
12878	widgetEventPrefix: "drop",
12879	options: {
12880		accept: "*",
12881		addClasses: true,
12882		greedy: false,
12883		scope: "default",
12884		tolerance: "intersect",
12885
12886		// Callbacks
12887		activate: null,
12888		deactivate: null,
12889		drop: null,
12890		out: null,
12891		over: null
12892	},
12893	_create: function() {
12894
12895		var proportions,
12896			o = this.options,
12897			accept = o.accept;
12898
12899		this.isover = false;
12900		this.isout = true;
12901
12902		this.accept = $.isFunction( accept ) ? accept : function( d ) {
12903			return d.is( accept );
12904		};
12905
12906		this.proportions = function( /* valueToWrite */ ) {
12907			if ( arguments.length ) {
12908
12909				// Store the droppable's proportions
12910				proportions = arguments[ 0 ];
12911			} else {
12912
12913				// Retrieve or derive the droppable's proportions
12914				return proportions ?
12915					proportions :
12916					proportions = {
12917						width: this.element[ 0 ].offsetWidth,
12918						height: this.element[ 0 ].offsetHeight
12919					};
12920			}
12921		};
12922
12923		this._addToManager( o.scope );
12924
12925		o.addClasses && this._addClass( "ui-droppable" );
12926
12927	},
12928
12929	_addToManager: function( scope ) {
12930
12931		// Add the reference and positions to the manager
12932		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12933		$.ui.ddmanager.droppables[ scope ].push( this );
12934	},
12935
12936	_splice: function( drop ) {
12937		var i = 0;
12938		for ( ; i < drop.length; i++ ) {
12939			if ( drop[ i ] === this ) {
12940				drop.splice( i, 1 );
12941			}
12942		}
12943	},
12944
12945	_destroy: function() {
12946		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12947
12948		this._splice( drop );
12949	},
12950
12951	_setOption: function( key, value ) {
12952
12953		if ( key === "accept" ) {
12954			this.accept = $.isFunction( value ) ? value : function( d ) {
12955				return d.is( value );
12956			};
12957		} else if ( key === "scope" ) {
12958			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12959
12960			this._splice( drop );
12961			this._addToManager( value );
12962		}
12963
12964		this._super( key, value );
12965	},
12966
12967	_activate: function( event ) {
12968		var draggable = $.ui.ddmanager.current;
12969
12970		this._addActiveClass();
12971		if ( draggable ) {
12972			this._trigger( "activate", event, this.ui( draggable ) );
12973		}
12974	},
12975
12976	_deactivate: function( event ) {
12977		var draggable = $.ui.ddmanager.current;
12978
12979		this._removeActiveClass();
12980		if ( draggable ) {
12981			this._trigger( "deactivate", event, this.ui( draggable ) );
12982		}
12983	},
12984
12985	_over: function( event ) {
12986
12987		var draggable = $.ui.ddmanager.current;
12988
12989		// Bail if draggable and droppable are same element
12990		if ( !draggable || ( draggable.currentItem ||
12991				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12992			return;
12993		}
12994
12995		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12996				draggable.element ) ) ) {
12997			this._addHoverClass();
12998			this._trigger( "over", event, this.ui( draggable ) );
12999		}
13000
13001	},
13002
13003	_out: function( event ) {
13004
13005		var draggable = $.ui.ddmanager.current;
13006
13007		// Bail if draggable and droppable are same element
13008		if ( !draggable || ( draggable.currentItem ||
13009				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13010			return;
13011		}
13012
13013		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13014				draggable.element ) ) ) {
13015			this._removeHoverClass();
13016			this._trigger( "out", event, this.ui( draggable ) );
13017		}
13018
13019	},
13020
13021	_drop: function( event, custom ) {
13022
13023		var draggable = custom || $.ui.ddmanager.current,
13024			childrenIntersection = false;
vendor: 4,744 bytes, lines 13025-13197
13025
13026		// Bail if draggable and droppable are same element
13027		if ( !draggable || ( draggable.currentItem ||
13028				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13029			return false;
13030		}
13031
13032		this.element
13033			.find( ":data(ui-droppable)" )
13034			.not( ".ui-draggable-dragging" )
13035			.each( function() {
13036				var inst = $( this ).droppable( "instance" );
13037				if (
13038					inst.options.greedy &&
13039					!inst.options.disabled &&
13040					inst.options.scope === draggable.options.scope &&
13041					inst.accept.call(
13042						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13043					) &&
13044					intersect(
13045						draggable,
13046						$.extend( inst, { offset: inst.element.offset() } ),
13047						inst.options.tolerance, event
13048					)
13049				) {
13050					childrenIntersection = true;
13051					return false; }
13052			} );
13053		if ( childrenIntersection ) {
13054			return false;
13055		}
13056
13057		if ( this.accept.call( this.element[ 0 ],
13058				( draggable.currentItem || draggable.element ) ) ) {
13059			this._removeActiveClass();
13060			this._removeHoverClass();
13061
13062			this._trigger( "drop", event, this.ui( draggable ) );
13063			return this.element;
13064		}
13065
13066		return false;
13067
13068	},
13069
13070	ui: function( c ) {
13071		return {
13072			draggable: ( c.currentItem || c.element ),
13073			helper: c.helper,
13074			position: c.position,
13075			offset: c.positionAbs
13076		};
13077	},
13078
13079	// Extension points just to make backcompat sane and avoid duplicating logic
13080	// TODO: Remove in 1.13 along with call to it below
13081	_addHoverClass: function() {
13082		this._addClass( "ui-droppable-hover" );
13083	},
13084
13085	_removeHoverClass: function() {
13086		this._removeClass( "ui-droppable-hover" );
13087	},
13088
13089	_addActiveClass: function() {
13090		this._addClass( "ui-droppable-active" );
13091	},
13092
13093	_removeActiveClass: function() {
13094		this._removeClass( "ui-droppable-active" );
13095	}
13096} );
13097
13098var intersect = $.ui.intersect = ( function() {
13099	function isOverAxis( x, reference, size ) {
13100		return ( x >= reference ) && ( x < ( reference + size ) );
13101	}
13102
13103	return function( draggable, droppable, toleranceMode, event ) {
13104
13105		if ( !droppable.offset ) {
13106			return false;
13107		}
13108
13109		var x1 = ( draggable.positionAbs ||
13110				draggable.position.absolute ).left + draggable.margins.left,
13111			y1 = ( draggable.positionAbs ||
13112				draggable.position.absolute ).top + draggable.margins.top,
13113			x2 = x1 + draggable.helperProportions.width,
13114			y2 = y1 + draggable.helperProportions.height,
13115			l = droppable.offset.left,
13116			t = droppable.offset.top,
13117			r = l + droppable.proportions().width,
13118			b = t + droppable.proportions().height;
13119
13120		switch ( toleranceMode ) {
13121		case "fit":
13122			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13123		case "intersect":
13124			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13125				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13126				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13127				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13128		case "pointer":
13129			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13130				isOverAxis( event.pageX, l, droppable.proportions().width );
13131		case "touch":
13132			return (
13133				( y1 >= t && y1 <= b ) || // Top edge touching
13134				( y2 >= t && y2 <= b ) || // Bottom edge touching
13135				( y1 < t && y2 > b ) // Surrounded vertically
13136			) && (
13137				( x1 >= l && x1 <= r ) || // Left edge touching
13138				( x2 >= l && x2 <= r ) || // Right edge touching
13139				( x1 < l && x2 > r ) // Surrounded horizontally
13140			);
13141		default:
13142			return false;
13143		}
13144	};
13145} )();
13146
13147/*
13148	This manager tracks offsets of draggables and droppables
13149*/
13150$.ui.ddmanager = {
13151	current: null,
13152	droppables: { "default": [] },
13153	prepareOffsets: function( t, event ) {
13154
13155		var i, j,
13156			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13157			type = event ? event.type : null, // workaround for #2317
13158			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13159
13160		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13161
13162			// No disabled and non-accepted
13163			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13164					( t.currentItem || t.element ) ) ) ) {
13165				continue;
13166			}
13167
13168			// Filter out elements in the current dragged item
13169			for ( j = 0; j < list.length; j++ ) {
13170				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13171					m[ i ].proportions().height = 0;
13172					continue droppablesLoop;
13173				}
13174			}
13175
13176			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13177			if ( !m[ i ].visible ) {
13178				continue;
13179			}
13180
13181			// Activate the droppable if used directly from draggables
13182			if ( type === "mousedown" ) {
13183				m[ i ]._activate.call( m[ i ], event );
13184			}
13185
13186			m[ i ].offset = m[ i ].element.offset();
13187			m[ i ].proportions( {
13188				width: m[ i ].element[ 0 ].offsetWidth,
13189				height: m[ i ].element[ 0 ].offsetHeight
13190			} );
13191
13192		}
13193
13194	},
13195	drop: function( draggable, event ) {
13196
13197		var dropped = false;
vendor: 4,444 bytes, lines 13198-13352
13198
13199		// Create a copy of the droppables in case the list changes during the drop (#9116)
13200		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13201
13202			if ( !this.options ) {
13203				return;
13204			}
13205			if ( !this.options.disabled && this.visible &&
13206					intersect( draggable, this, this.options.tolerance, event ) ) {
13207				dropped = this._drop.call( this, event ) || dropped;
13208			}
13209
13210			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13211					( draggable.currentItem || draggable.element ) ) ) {
13212				this.isout = true;
13213				this.isover = false;
13214				this._deactivate.call( this, event );
13215			}
13216
13217		} );
13218		return dropped;
13219
13220	},
13221	dragStart: function( draggable, event ) {
13222
13223		// Listen for scrolling so that if the dragging causes scrolling the position of the
13224		// droppables can be recalculated (see #5003)
13225		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13226			if ( !draggable.options.refreshPositions ) {
13227				$.ui.ddmanager.prepareOffsets( draggable, event );
13228			}
13229		} );
13230	},
13231	drag: function( draggable, event ) {
13232
13233		// If you have a highly dynamic page, you might try this option. It renders positions
13234		// every time you move the mouse.
13235		if ( draggable.options.refreshPositions ) {
13236			$.ui.ddmanager.prepareOffsets( draggable, event );
13237		}
13238
13239		// Run through all droppables and check their positions based on specific tolerance options
13240		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13241
13242			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13243				return;
13244			}
13245
13246			var parentInstance, scope, parent,
13247				intersects = intersect( draggable, this, this.options.tolerance, event ),
13248				c = !intersects && this.isover ?
13249					"isout" :
13250					( intersects && !this.isover ? "isover" : null );
13251			if ( !c ) {
13252				return;
13253			}
13254
13255			if ( this.options.greedy ) {
13256
13257				// find droppable parents with same scope
13258				scope = this.options.scope;
13259				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13260					return $( this ).droppable( "instance" ).options.scope === scope;
13261				} );
13262
13263				if ( parent.length ) {
13264					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13265					parentInstance.greedyChild = ( c === "isover" );
13266				}
13267			}
13268
13269			// We just moved into a greedy child
13270			if ( parentInstance && c === "isover" ) {
13271				parentInstance.isover = false;
13272				parentInstance.isout = true;
13273				parentInstance._out.call( parentInstance, event );
13274			}
13275
13276			this[ c ] = true;
13277			this[ c === "isout" ? "isover" : "isout" ] = false;
13278			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13279
13280			// We just moved out of a greedy child
13281			if ( parentInstance && c === "isout" ) {
13282				parentInstance.isout = false;
13283				parentInstance.isover = true;
13284				parentInstance._over.call( parentInstance, event );
13285			}
13286		} );
13287
13288	},
13289	dragStop: function( draggable, event ) {
13290		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13291
13292		// Call prepareOffsets one final time since IE does not fire return scroll events when
13293		// overflow was caused by drag (see #5003)
13294		if ( !draggable.options.refreshPositions ) {
13295			$.ui.ddmanager.prepareOffsets( draggable, event );
13296		}
13297	}
13298};
13299
13300// DEPRECATED
13301// TODO: switch return back to widget declaration at top of file when this is removed
13302if ( $.uiBackCompat !== false ) {
13303
13304	// Backcompat for activeClass and hoverClass options
13305	$.widget( "ui.droppable", $.ui.droppable, {
13306		options: {
13307			hoverClass: false,
13308			activeClass: false
13309		},
13310		_addActiveClass: function() {
13311			this._super();
13312			if ( this.options.activeClass ) {
13313				this.element.addClass( this.options.activeClass );
13314			}
13315		},
13316		_removeActiveClass: function() {
13317			this._super();
13318			if ( this.options.activeClass ) {
13319				this.element.removeClass( this.options.activeClass );
13320			}
13321		},
13322		_addHoverClass: function() {
13323			this._super();
13324			if ( this.options.hoverClass ) {
13325				this.element.addClass( this.options.hoverClass );
13326			}
13327		},
13328		_removeHoverClass: function() {
13329			this._super();
13330			if ( this.options.hoverClass ) {
13331				this.element.removeClass( this.options.hoverClass );
13332			}
13333		}
13334	} );
13335}
13336
13337var widgetsDroppable = $.ui.droppable;
13338
13339
13340/*!
13341 * jQuery UI Progressbar 1.12.1
13342 * http://jqueryui.com
13343 *
13344 * Copyright jQuery Foundation and other contributors
13345 * Released under the MIT license.
13346 * http://jquery.org/license
13347 */
13348
13349//>>label: Progressbar
13350//>>group: Widgets
13351// jscs:disable maximumLineLength
13352//>>
vendor: 15,214 bytes, lines 13352-13945
13352description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13353// jscs:enable maximumLineLength
13354//>>docs: http://api.jqueryui.com/progressbar/
13355//>>demos: http://jqueryui.com/progressbar/
13356//>>css.structure: ../../themes/base/core.css
13357//>>css.structure: ../../themes/base/progressbar.css
13358//>>css.theme: ../../themes/base/theme.css
13359
13360
13361
13362var widgetsProgressbar = $.widget( "ui.progressbar", {
13363	version: "1.12.1",
13364	options: {
13365		classes: {
13366			"ui-progressbar": "ui-corner-all",
13367			"ui-progressbar-value": "ui-corner-left",
13368			"ui-progressbar-complete": "ui-corner-right"
13369		},
13370		max: 100,
13371		value: 0,
13372
13373		change: null,
13374		complete: null
13375	},
13376
13377	min: 0,
13378
13379	_create: function() {
13380
13381		// Constrain initial value
13382		this.oldValue = this.options.value = this._constrainedValue();
13383
13384		this.element.attr( {
13385
13386			// Only set static values; aria-valuenow and aria-valuemax are
13387			// set inside _refreshValue()
13388			role: "progressbar",
13389			"aria-valuemin": this.min
13390		} );
13391		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13392
13393		this.valueDiv = $( "<div>" ).appendTo( this.element );
13394		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13395		this._refreshValue();
13396	},
13397
13398	_destroy: function() {
13399		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13400
13401		this.valueDiv.remove();
13402	},
13403
13404	value: function( newValue ) {
13405		if ( newValue === undefined ) {
13406			return this.options.value;
13407		}
13408
13409		this.options.value = this._constrainedValue( newValue );
13410		this._refreshValue();
13411	},
13412
13413	_constrainedValue: function( newValue ) {
13414		if ( newValue === undefined ) {
13415			newValue = this.options.value;
13416		}
13417
13418		this.indeterminate = newValue === false;
13419
13420		// Sanitize value
13421		if ( typeof newValue !== "number" ) {
13422			newValue = 0;
13423		}
13424
13425		return this.indeterminate ? false :
13426			Math.min( this.options.max, Math.max( this.min, newValue ) );
13427	},
13428
13429	_setOptions: function( options ) {
13430
13431		// Ensure "value" option is set after other values (like max)
13432		var value = options.value;
13433		delete options.value;
13434
13435		this._super( options );
13436
13437		this.options.value = this._constrainedValue( value );
13438		this._refreshValue();
13439	},
13440
13441	_setOption: function( key, value ) {
13442		if ( key === "max" ) {
13443
13444			// Don't allow a max less than min
13445			value = Math.max( this.min, value );
13446		}
13447		this._super( key, value );
13448	},
13449
13450	_setOptionDisabled: function( value ) {
13451		this._super( value );
13452
13453		this.element.attr( "aria-disabled", value );
13454		this._toggleClass( null, "ui-state-disabled", !!value );
13455	},
13456
13457	_percentage: function() {
13458		return this.indeterminate ?
13459			100 :
13460			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13461	},
13462
13463	_refreshValue: function() {
13464		var value = this.options.value,
13465			percentage = this._percentage();
13466
13467		this.valueDiv
13468			.toggle( this.indeterminate || value > this.min )
13469			.width( percentage.toFixed( 0 ) + "%" );
13470
13471		this
13472			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13473				value === this.options.max )
13474			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13475
13476		if ( this.indeterminate ) {
13477			this.element.removeAttr( "aria-valuenow" );
13478			if ( !this.overlayDiv ) {
13479				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13480				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13481			}
13482		} else {
13483			this.element.attr( {
13484				"aria-valuemax": this.options.max,
13485				"aria-valuenow": value
13486			} );
13487			if ( this.overlayDiv ) {
13488				this.overlayDiv.remove();
13489				this.overlayDiv = null;
13490			}
13491		}
13492
13493		if ( this.oldValue !== value ) {
13494			this.oldValue = value;
13495			this._trigger( "change" );
13496		}
13497		if ( value === this.options.max ) {
13498			this._trigger( "complete" );
13499		}
13500	}
13501} );
13502
13503
13504/*!
13505 * jQuery UI Selectable 1.12.1
13506 * http://jqueryui.com
13507 *
13508 * Copyright jQuery Foundation and other contributors
13509 * Released under the MIT license.
13510 * http://jquery.org/license
13511 */
13512
13513//>>label: Selectable
13514//>>group: Interactions
13515//>>description: Allows groups of elements to be selected with the mouse.
13516//>>docs: http://api.jqueryui.com/selectable/
13517//>>demos: http://jqueryui.com/selectable/
13518//>>css.structure: ../../themes/base/selectable.css
13519
13520
13521
13522var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13523	version: "1.12.1",
13524	options: {
13525		appendTo: "body",
13526		autoRefresh: true,
13527		distance: 0,
13528		filter: "*",
13529		tolerance: "touch",
13530
13531		// Callbacks
13532		selected: null,
13533		selecting: null,
13534		start: null,
13535		stop: null,
13536		unselected: null,
13537		unselecting: null
13538	},
13539	_create: function() {
13540		var that = this;
13541
13542		this._addClass( "ui-selectable" );
13543
13544		this.dragged = false;
13545
13546		// Cache selectee children based on filter
13547		this.refresh = function() {
13548			that.elementPos = $( that.element[ 0 ] ).offset();
13549			that.selectees = $( that.options.filter, that.element[ 0 ] );
13550			that._addClass( that.selectees, "ui-selectee" );
13551			that.selectees.each( function() {
13552				var $this = $( this ),
13553					selecteeOffset = $this.offset(),
13554					pos = {
13555						left: selecteeOffset.left - that.elementPos.left,
13556						top: selecteeOffset.top - that.elementPos.top
13557					};
13558				$.data( this, "selectable-item", {
13559					element: this,
13560					$element: $this,
13561					left: pos.left,
13562					top: pos.top,
13563					right: pos.left + $this.outerWidth(),
13564					bottom: pos.top + $this.outerHeight(),
13565					startselected: false,
13566					selected: $this.hasClass( "ui-selected" ),
13567					selecting: $this.hasClass( "ui-selecting" ),
13568					unselecting: $this.hasClass( "ui-unselecting" )
13569				} );
13570			} );
13571		};
13572		this.refresh();
13573
13574		this._mouseInit();
13575
13576		this.helper = $( "<div>" );
13577		this._addClass( this.helper, "ui-selectable-helper" );
13578	},
13579
13580	_destroy: function() {
13581		this.selectees.removeData( "selectable-item" );
13582		this._mouseDestroy();
13583	},
13584
13585	_mouseStart: function( event ) {
13586		var that = this,
13587			options = this.options;
13588
13589		this.opos = [ event.pageX, event.pageY ];
13590		this.elementPos = $( this.element[ 0 ] ).offset();
13591
13592		if ( this.options.disabled ) {
13593			return;
13594		}
13595
13596		this.selectees = $( options.filter, this.element[ 0 ] );
13597
13598		this._trigger( "start", event );
13599
13600		$( options.appendTo ).append( this.helper );
13601
13602		// position helper (lasso)
13603		this.helper.css( {
13604			"left": event.pageX,
13605			"top": event.pageY,
13606			"width": 0,
13607			"height": 0
13608		} );
13609
13610		if ( options.autoRefresh ) {
13611			this.refresh();
13612		}
13613
13614		this.selectees.filter( ".ui-selected" ).each( function() {
13615			var selectee = $.data( this, "selectable-item" );
13616			selectee.startselected = true;
13617			if ( !event.metaKey && !event.ctrlKey ) {
13618				that._removeClass( selectee.$element, "ui-selected" );
13619				selectee.selected = false;
13620				that._addClass( selectee.$element, "ui-unselecting" );
13621				selectee.unselecting = true;
13622
13623				// selectable UNSELECTING callback
13624				that._trigger( "unselecting", event, {
13625					unselecting: selectee.element
13626				} );
13627			}
13628		} );
13629
13630		$( event.target ).parents().addBack().each( function() {
13631			var doSelect,
13632				selectee = $.data( this, "selectable-item" );
13633			if ( selectee ) {
13634				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13635					!selectee.$element.hasClass( "ui-selected" );
13636				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13637					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13638				selectee.unselecting = !doSelect;
13639				selectee.selecting = doSelect;
13640				selectee.selected = doSelect;
13641
13642				// selectable (UN)SELECTING callback
13643				if ( doSelect ) {
13644					that._trigger( "selecting", event, {
13645						selecting: selectee.element
13646					} );
13647				} else {
13648					that._trigger( "unselecting", event, {
13649						unselecting: selectee.element
13650					} );
13651				}
13652				return false;
13653			}
13654		} );
13655
13656	},
13657
13658	_mouseDrag: function( event ) {
13659
13660		this.dragged = true;
13661
13662		if ( this.options.disabled ) {
13663			return;
13664		}
13665
13666		var tmp,
13667			that = this,
13668			options = this.options,
13669			x1 = this.opos[ 0 ],
13670			y1 = this.opos[ 1 ],
13671			x2 = event.pageX,
13672			y2 = event.pageY;
13673
13674		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13675		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13676		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13677
13678		this.selectees.each( function() {
13679			var selectee = $.data( this, "selectable-item" ),
13680				hit = false,
13681				offset = {};
13682
13683			//prevent helper from being selected if appendTo: selectable
13684			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13685				return;
13686			}
13687
13688			offset.left   = selectee.left   + that.elementPos.left;
13689			offset.right  = selectee.right  + that.elementPos.left;
13690			offset.top    = selectee.top    + that.elementPos.top;
13691			offset.bottom = selectee.bottom + that.elementPos.top;
13692
13693			if ( options.tolerance === "touch" ) {
13694				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13695                    offset.bottom < y1 ) );
13696			} else if ( options.tolerance === "fit" ) {
13697				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13698                    offset.bottom < y2 );
13699			}
13700
13701			if ( hit ) {
13702
13703				// SELECT
13704				if ( selectee.selected ) {
13705					that._removeClass( selectee.$element, "ui-selected" );
13706					selectee.selected = false;
13707				}
13708				if ( selectee.unselecting ) {
13709					that._removeClass( selectee.$element, "ui-unselecting" );
13710					selectee.unselecting = false;
13711				}
13712				if ( !selectee.selecting ) {
13713					that._addClass( selectee.$element, "ui-selecting" );
13714					selectee.selecting = true;
13715
13716					// selectable SELECTING callback
13717					that._trigger( "selecting", event, {
13718						selecting: selectee.element
13719					} );
13720				}
13721			} else {
13722
13723				// UNSELECT
13724				if ( selectee.selecting ) {
13725					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13726						that._removeClass( selectee.$element, "ui-selecting" );
13727						selectee.selecting = false;
13728						that._addClass( selectee.$element, "ui-selected" );
13729						selectee.selected = true;
13730					} else {
13731						that._removeClass( selectee.$element, "ui-selecting" );
13732						selectee.selecting = false;
13733						if ( selectee.startselected ) {
13734							that._addClass( selectee.$element, "ui-unselecting" );
13735							selectee.unselecting = true;
13736						}
13737
13738						// selectable UNSELECTING callback
13739						that._trigger( "unselecting", event, {
13740							unselecting: selectee.element
13741						} );
13742					}
13743				}
13744				if ( selectee.selected ) {
13745					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13746						that._removeClass( selectee.$element, "ui-selected" );
13747						selectee.selected = false;
13748
13749						that._addClass( selectee.$element, "ui-unselecting" );
13750						selectee.unselecting = true;
13751
13752						// selectable UNSELECTING callback
13753						that._trigger( "unselecting", event, {
13754							unselecting: selectee.element
13755						} );
13756					}
13757				}
13758			}
13759		} );
13760
13761		return false;
13762	},
13763
13764	_mouseStop: function( event ) {
13765		var that = this;
13766
13767		this.dragged = false;
13768
13769		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13770			var selectee = $.data( this, "selectable-item" );
13771			that._removeClass( selectee.$element, "ui-unselecting" );
13772			selectee.unselecting = false;
13773			selectee.startselected = false;
13774			that._trigger( "unselected", event, {
13775				unselected: selectee.element
13776			} );
13777		} );
13778		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13779			var selectee = $.data( this, "selectable-item" );
13780			that._removeClass( selectee.$element, "ui-selecting" )
13781				._addClass( selectee.$element, "ui-selected" );
13782			selectee.selecting = false;
13783			selectee.selected = true;
13784			selectee.startselected = true;
13785			that._trigger( "selected", event, {
13786				selected: selectee.element
13787			} );
13788		} );
13789		this._trigger( "stop", event );
13790
13791		this.helper.remove();
13792
13793		return false;
13794	}
13795
13796} );
13797
13798
13799/*!
13800 * jQuery UI Selectmenu 1.12.1
13801 * http://jqueryui.com
13802 *
13803 * Copyright jQuery Foundation and other contributors
13804 * Released under the MIT license.
13805 * http://jquery.org/license
13806 */
13807
13808//>>label: Selectmenu
13809//>>group: Widgets
13810// jscs:disable maximumLineLength
13811//>>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.
13812// jscs:enable maximumLineLength
13813//>>docs: http://api.jqueryui.com/selectmenu/
13814//>>demos: http://jqueryui.com/selectmenu/
13815//>>css.structure: ../../themes/base/core.css
13816//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13817//>>css.theme: ../../themes/base/theme.css
13818
13819
13820
13821var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13822	version: "1.12.1",
13823	defaultElement: "<select>",
13824	options: {
13825		appendTo: null,
13826		classes: {
13827			"ui-selectmenu-button-open": "ui-corner-top",
13828			"ui-selectmenu-button-closed": "ui-corner-all"
13829		},
13830		disabled: null,
13831		icons: {
13832			button: "ui-icon-triangle-1-s"
13833		},
13834		position: {
13835			my: "left top",
13836			at: "left bottom",
13837			collision: "none"
13838		},
13839		width: false,
13840
13841		// Callbacks
13842		change: null,
13843		close: null,
13844		focus: null,
13845		open: null,
13846		select: null
13847	},
13848
13849	_create: function() {
13850		var selectmenuId = this.element.uniqueId().attr( "id" );
13851		this.ids = {
13852			element: selectmenuId,
13853			button: selectmenuId + "-button",
13854			menu: selectmenuId + "-menu"
13855		};
13856
13857		this._drawButton();
13858		this._drawMenu();
13859		this._bindFormResetHandler();
13860
13861		this._rendered = false;
13862		this.menuItems = $();
13863	},
13864
13865	_drawButton: function() {
13866		var icon,
13867			that = this,
13868			item = this._parseOption(
13869				this.element.find( "option:selected" ),
13870				this.element[ 0 ].selectedIndex
13871			);
13872
13873		// Associate existing label with the new button
13874		this.labels = this.element.labels().attr( "for", this.ids.button );
13875		this._on( this.labels, {
13876			click: function( event ) {
13877				this.button.focus();
13878				event.preventDefault();
13879			}
13880		} );
13881
13882		// Hide original select element
13883		this.element.hide();
13884
13885		// Create button
13886		this.button = $( "<span>", {
13887			tabindex: this.options.disabled ? -1 : 0,
13888			id: this.ids.button,
13889			role: "combobox",
13890			"aria-expanded": "false",
13891			"aria-autocomplete": "list",
13892			"aria-owns": this.ids.menu,
13893			"aria-haspopup": "true",
13894			title: this.element.attr( "title" )
13895		} )
13896			.insertAfter( this.element );
13897
13898		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13899			"ui-button ui-widget" );
13900
13901		icon = $( "<span>" ).appendTo( this.button );
13902		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13903		this.buttonItem = this._renderButtonItem( item )
13904			.appendTo( this.button );
13905
13906		if ( this.options.width !== false ) {
13907			this._resizeButton();
13908		}
13909
13910		this._on( this.button, this._buttonEvents );
13911		this.button.one( "focusin", function() {
13912
13913			// Delay rendering the menu items until the button receives focus.
13914			// The menu may have already been rendered via a programmatic open.
13915			if ( !that._rendered ) {
13916				that._refreshMenu();
13917			}
13918		} );
13919	},
13920
13921	_drawMenu: function() {
13922		var that = this;
13923
13924		// Create menu
13925		this.menu = $( "<ul>", {
13926			"aria-hidden": "true",
13927			"aria-labelledby": this.ids.button,
13928			id: this.ids.menu
13929		} );
13930
13931		// Wrap menu
13932		this.menuWrap = $( "<div>" ).append( this.menu );
13933		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13934		this.menuWrap.appendTo( this._appendTo() );
13935
13936		// Initialize menu widget
13937		this.menuInstance = this.menu
13938			.menu( {
13939				classes: {
13940					"ui-menu": "ui-corner-bottom"
13941				},
13942				role: "listbox",
13943				select: function( event, ui ) {
13944					event.preventDefault();
13945
vendor: 5,595 bytes, lines 13946-14186
13946					// Support: IE8
13947					// If the item was selected via a click, the text selection
13948					// will be destroyed in IE
13949					that._setSelection();
13950
13951					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13952				},
13953				focus: function( event, ui ) {
13954					var item = ui.item.data( "ui-selectmenu-item" );
13955
13956					// Prevent inital focus from firing and check if its a newly focused item
13957					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13958						that._trigger( "focus", event, { item: item } );
13959						if ( !that.isOpen ) {
13960							that._select( item, event );
13961						}
13962					}
13963					that.focusIndex = item.index;
13964
13965					that.button.attr( "aria-activedescendant",
13966						that.menuItems.eq( item.index ).attr( "id" ) );
13967				}
13968			} )
13969			.menu( "instance" );
13970
13971		// Don't close the menu on mouseleave
13972		this.menuInstance._off( this.menu, "mouseleave" );
13973
13974		// Cancel the menu's collapseAll on document click
13975		this.menuInstance._closeOnDocumentClick = function() {
13976			return false;
13977		};
13978
13979		// Selects often contain empty items, but never contain dividers
13980		this.menuInstance._isDivider = function() {
13981			return false;
13982		};
13983	},
13984
13985	refresh: function() {
13986		this._refreshMenu();
13987		this.buttonItem.replaceWith(
13988			this.buttonItem = this._renderButtonItem(
13989
13990				// Fall back to an empty object in case there are no options
13991				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13992			)
13993		);
13994		if ( this.options.width === null ) {
13995			this._resizeButton();
13996		}
13997	},
13998
13999	_refreshMenu: function() {
14000		var item,
14001			options = this.element.find( "option" );
14002
14003		this.menu.empty();
14004
14005		this._parseOptions( options );
14006		this._renderMenu( this.menu, this.items );
14007
14008		this.menuInstance.refresh();
14009		this.menuItems = this.menu.find( "li" )
14010			.not( ".ui-selectmenu-optgroup" )
14011				.find( ".ui-menu-item-wrapper" );
14012
14013		this._rendered = true;
14014
14015		if ( !options.length ) {
14016			return;
14017		}
14018
14019		item = this._getSelectedItem();
14020
14021		// Update the menu to have the correct item focused
14022		this.menuInstance.focus( null, item );
14023		this._setAria( item.data( "ui-selectmenu-item" ) );
14024
14025		// Set disabled state
14026		this._setOption( "disabled", this.element.prop( "disabled" ) );
14027	},
14028
14029	open: function( event ) {
14030		if ( this.options.disabled ) {
14031			return;
14032		}
14033
14034		// If this is the first time the menu is being opened, render the items
14035		if ( !this._rendered ) {
14036			this._refreshMenu();
14037		} else {
14038
14039			// Menu clears focus on close, reset focus to selected item
14040			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14041			this.menuInstance.focus( null, this._getSelectedItem() );
14042		}
14043
14044		// If there are no options, don't open the menu
14045		if ( !this.menuItems.length ) {
14046			return;
14047		}
14048
14049		this.isOpen = true;
14050		this._toggleAttr();
14051		this._resizeMenu();
14052		this._position();
14053
14054		this._on( this.document, this._documentClick );
14055
14056		this._trigger( "open", event );
14057	},
14058
14059	_position: function() {
14060		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14061	},
14062
14063	close: function( event ) {
14064		if ( !this.isOpen ) {
14065			return;
14066		}
14067
14068		this.isOpen = false;
14069		this._toggleAttr();
14070
14071		this.range = null;
14072		this._off( this.document );
14073
14074		this._trigger( "close", event );
14075	},
14076
14077	widget: function() {
14078		return this.button;
14079	},
14080
14081	menuWidget: function() {
14082		return this.menu;
14083	},
14084
14085	_renderButtonItem: function( item ) {
14086		var buttonItem = $( "<span>" );
14087
14088		this._setText( buttonItem, item.label );
14089		this._addClass( buttonItem, "ui-selectmenu-text" );
14090
14091		return buttonItem;
14092	},
14093
14094	_renderMenu: function( ul, items ) {
14095		var that = this,
14096			currentOptgroup = "";
14097
14098		$.each( items, function( index, item ) {
14099			var li;
14100
14101			if ( item.optgroup !== currentOptgroup ) {
14102				li = $( "<li>", {
14103					text: item.optgroup
14104				} );
14105				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14106					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14107						" ui-state-disabled" :
14108						"" ) );
14109
14110				li.appendTo( ul );
14111
14112				currentOptgroup = item.optgroup;
14113			}
14114
14115			that._renderItemData( ul, item );
14116		} );
14117	},
14118
14119	_renderItemData: function( ul, item ) {
14120		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14121	},
14122
14123	_renderItem: function( ul, item ) {
14124		var li = $( "<li>" ),
14125			wrapper = $( "<div>", {
14126				title: item.element.attr( "title" )
14127			} );
14128
14129		if ( item.disabled ) {
14130			this._addClass( li, null, "ui-state-disabled" );
14131		}
14132		this._setText( wrapper, item.label );
14133
14134		return li.append( wrapper ).appendTo( ul );
14135	},
14136
14137	_setText: function( element, value ) {
14138		if ( value ) {
14139			element.text( value );
14140		} else {
14141			element.html( "&#160;" );
14142		}
14143	},
14144
14145	_move: function( direction, event ) {
14146		var item, next,
14147			filter = ".ui-menu-item";
14148
14149		if ( this.isOpen ) {
14150			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14151		} else {
14152			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14153			filter += ":not(.ui-state-disabled)";
14154		}
14155
14156		if ( direction === "first" || direction === "last" ) {
14157			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14158		} else {
14159			next = item[ direction + "All" ]( filter ).eq( 0 );
14160		}
14161
14162		if ( next.length ) {
14163			this.menuInstance.focus( event, next );
14164		}
14165	},
14166
14167	_getSelectedItem: function() {
14168		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14169	},
14170
14171	_toggle: function( event ) {
14172		this[ this.isOpen ? "close" : "open" ]( event );
14173	},
14174
14175	_setSelection: function() {
14176		var selection;
14177
14178		if ( !this.range ) {
14179			return;
14180		}
14181
14182		if ( window.getSelection ) {
14183			selection = window.getSelection();
14184			selection.removeAllRanges();
14185			selection.addRange( this.range );
14186
14187		// Support: IE8
14188		} else {
14189			this.range.select();
14190		}
14191
14192		// Support: IE
14193		// Setting the text selection kills the button focus in IE, but
14194		// restoring the focus doesn't kill the selection.
14195		this.button.focus();
14196	},
14197
14198	_documentClick: {
14199		mousedown: function( event ) {
14200			if ( !this.isOpen ) {
14201				return;
14202			}
14203
14204			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14205					$.ui
vendor: 5,768 bytes, lines 14205-14449
14205.escapeSelector( this.ids.button ) ).length ) {
14206				this.close( event );
14207			}
14208		}
14209	},
14210
14211	_buttonEvents: {
14212
14213		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14214		mousedown: function() {
14215			var selection;
14216
14217			if ( window.getSelection ) {
14218				selection = window.getSelection();
14219				if ( selection.rangeCount ) {
14220					this.range = selection.getRangeAt( 0 );
14221				}
14222
14223			// Support: IE8
14224			} else {
14225				this.range = document.selection.createRange();
14226			}
14227		},
14228
14229		click: function( event ) {
14230			this._setSelection();
14231			this._toggle( event );
14232		},
14233
14234		keydown: function( event ) {
14235			var preventDefault = true;
14236			switch ( event.keyCode ) {
14237			case $.ui.keyCode.TAB:
14238			case $.ui.keyCode.ESCAPE:
14239				this.close( event );
14240				preventDefault = false;
14241				break;
14242			case $.ui.keyCode.ENTER:
14243				if ( this.isOpen ) {
14244					this._selectFocusedItem( event );
14245				}
14246				break;
14247			case $.ui.keyCode.UP:
14248				if ( event.altKey ) {
14249					this._toggle( event );
14250				} else {
14251					this._move( "prev", event );
14252				}
14253				break;
14254			case $.ui.keyCode.DOWN:
14255				if ( event.altKey ) {
14256					this._toggle( event );
14257				} else {
14258					this._move( "next", event );
14259				}
14260				break;
14261			case $.ui.keyCode.SPACE:
14262				if ( this.isOpen ) {
14263					this._selectFocusedItem( event );
14264				} else {
14265					this._toggle( event );
14266				}
14267				break;
14268			case $.ui.keyCode.LEFT:
14269				this._move( "prev", event );
14270				break;
14271			case $.ui.keyCode.RIGHT:
14272				this._move( "next", event );
14273				break;
14274			case $.ui.keyCode.HOME:
14275			case $.ui.keyCode.PAGE_UP:
14276				this._move( "first", event );
14277				break;
14278			case $.ui.keyCode.END:
14279			case $.ui.keyCode.PAGE_DOWN:
14280				this._move( "last", event );
14281				break;
14282			default:
14283				this.menu.trigger( event );
14284				preventDefault = false;
14285			}
14286
14287			if ( preventDefault ) {
14288				event.preventDefault();
14289			}
14290		}
14291	},
14292
14293	_selectFocusedItem: function( event ) {
14294		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14295		if ( !item.hasClass( "ui-state-disabled" ) ) {
14296			this._select( item.data( "ui-selectmenu-item" ), event );
14297		}
14298	},
14299
14300	_select: function( item, event ) {
14301		var oldIndex = this.element[ 0 ].selectedIndex;
14302
14303		// Change native select element
14304		this.element[ 0 ].selectedIndex = item.index;
14305		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14306		this._setAria( item );
14307		this._trigger( "select", event, { item: item } );
14308
14309		if ( item.index !== oldIndex ) {
14310			this._trigger( "change", event, { item: item } );
14311		}
14312
14313		this.close( event );
14314	},
14315
14316	_setAria: function( item ) {
14317		var id = this.menuItems.eq( item.index ).attr( "id" );
14318
14319		this.button.attr( {
14320			"aria-labelledby": id,
14321			"aria-activedescendant": id
14322		} );
14323		this.menu.attr( "aria-activedescendant", id );
14324	},
14325
14326	_setOption: function( key, value ) {
14327		if ( key === "icons" ) {
14328			var icon = this.button.find( "span.ui-icon" );
14329			this._removeClass( icon, null, this.options.icons.button )
14330				._addClass( icon, null, value.button );
14331		}
14332
14333		this._super( key, value );
14334
14335		if ( key === "appendTo" ) {
14336			this.menuWrap.appendTo( this._appendTo() );
14337		}
14338
14339		if ( key === "width" ) {
14340			this._resizeButton();
14341		}
14342	},
14343
14344	_setOptionDisabled: function( value ) {
14345		this._super( value );
14346
14347		this.menuInstance.option( "disabled", value );
14348		this.button.attr( "aria-disabled", value );
14349		this._toggleClass( this.button, null, "ui-state-disabled", value );
14350
14351		this.element.prop( "disabled", value );
14352		if ( value ) {
14353			this.button.attr( "tabindex", -1 );
14354			this.close();
14355		} else {
14356			this.button.attr( "tabindex", 0 );
14357		}
14358	},
14359
14360	_appendTo: function() {
14361		var element = this.options.appendTo;
14362
14363		if ( element ) {
14364			element = element.jquery || element.nodeType ?
14365				$( element ) :
14366				this.document.find( element ).eq( 0 );
14367		}
14368
14369		if ( !element || !element[ 0 ] ) {
14370			element = this.element.closest( ".ui-front, dialog" );
14371		}
14372
14373		if ( !element.length ) {
14374			element = this.document[ 0 ].body;
14375		}
14376
14377		return element;
14378	},
14379
14380	_toggleAttr: function() {
14381		this.button.attr( "aria-expanded", this.isOpen );
14382
14383		// We can't use two _toggleClass() calls here, because we need to make sure
14384		// we always remove classes first and add them second, otherwise if both classes have the
14385		// same theme class, it will be removed after we add it.
14386		this._removeClass( this.button, "ui-selectmenu-button-" +
14387			( this.isOpen ? "closed" : "open" ) )
14388			._addClass( this.button, "ui-selectmenu-button-" +
14389				( this.isOpen ? "open" : "closed" ) )
14390			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14391
14392		this.menu.attr( "aria-hidden", !this.isOpen );
14393	},
14394
14395	_resizeButton: function() {
14396		var width = this.options.width;
14397
14398		// For `width: false`, just remove inline style and stop
14399		if ( width === false ) {
14400			this.button.css( "width", "" );
14401			return;
14402		}
14403
14404		// For `width: null`, match the width of the original element
14405		if ( width === null ) {
14406			width = this.element.show().outerWidth();
14407			this.element.hide();
14408		}
14409
14410		this.button.outerWidth( width );
14411	},
14412
14413	_resizeMenu: function() {
14414		this.menu.outerWidth( Math.max(
14415			this.button.outerWidth(),
14416
14417			// Support: IE10
14418			// IE10 wraps long text (possibly a rounding bug)
14419			// so we add 1px to avoid the wrapping
14420			this.menu.width( "" ).outerWidth() + 1
14421		) );
14422	},
14423
14424	_getCreateOptions: function() {
14425		var options = this._super();
14426
14427		options.disabled = this.element.prop( "disabled" );
14428
14429		return options;
14430	},
14431
14432	_parseOptions: function( options ) {
14433		var that = this,
14434			data = [];
14435		options.each( function( index, item ) {
14436			data.push( that._parseOption( $( item ), index ) );
14437		} );
14438		this.items = data;
14439	},
14440
14441	_parseOption: function( option, index ) {
14442		var optgroup = option.parent( "optgroup" );
14443
14444		return {
14445			element: option,
14446			index: index,
14447			value: option.val(),
14448			label: option.text(),
14449			
14449optgroup: optgroup.attr( "label" ) || "",
14450			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14451		};
14452	},
14453
14454	_destroy: function() {
14455		this._unbindFormResetHandler();
14456		this.menuWrap.remove();
14457		this.button.remove();
14458		this.element.show();
14459		this.element.removeUniqueId();
14460		this.labels.attr( "for", this.ids.element );
14461	}
14462} ]
vendor: 19,267 bytes, lines 14462-15200
14462 );
14463
14464
14465/*!
14466 * jQuery UI Slider 1.12.1
14467 * http://jqueryui.com
14468 *
14469 * Copyright jQuery Foundation and other contributors
14470 * Released under the MIT license.
14471 * http://jquery.org/license
14472 */
14473
14474//>>label: Slider
14475//>>group: Widgets
14476//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14477//>>docs: http://api.jqueryui.com/slider/
14478//>>demos: http://jqueryui.com/slider/
14479//>>css.structure: ../../themes/base/core.css
14480//>>css.structure: ../../themes/base/slider.css
14481//>>css.theme: ../../themes/base/theme.css
14482
14483
14484
14485var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14486	version: "1.12.1",
14487	widgetEventPrefix: "slide",
14488
14489	options: {
14490		animate: false,
14491		classes: {
14492			"ui-slider": "ui-corner-all",
14493			"ui-slider-handle": "ui-corner-all",
14494
14495			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14496			// element, but worked best visually with a variety of themes
14497			"ui-slider-range": "ui-corner-all ui-widget-header"
14498		},
14499		distance: 0,
14500		max: 100,
14501		min: 0,
14502		orientation: "horizontal",
14503		range: false,
14504		step: 1,
14505		value: 0,
14506		values: null,
14507
14508		// Callbacks
14509		change: null,
14510		slide: null,
14511		start: null,
14512		stop: null
14513	},
14514
14515	// Number of pages in a slider
14516	// (how many times can you page up/down to go through the whole range)
14517	numPages: 5,
14518
14519	_create: function() {
14520		this._keySliding = false;
14521		this._mouseSliding = false;
14522		this._animateOff = true;
14523		this._handleIndex = null;
14524		this._detectOrientation();
14525		this._mouseInit();
14526		this._calculateNewMax();
14527
14528		this._addClass( "ui-slider ui-slider-" + this.orientation,
14529			"ui-widget ui-widget-content" );
14530
14531		this._refresh();
14532
14533		this._animateOff = false;
14534	},
14535
14536	_refresh: function() {
14537		this._createRange();
14538		this._createHandles();
14539		this._setupEvents();
14540		this._refreshValue();
14541	},
14542
14543	_createHandles: function() {
14544		var i, handleCount,
14545			options = this.options,
14546			existingHandles = this.element.find( ".ui-slider-handle" ),
14547			handle = "<span tabindex='0'></span>",
14548			handles = [];
14549
14550		handleCount = ( options.values && options.values.length ) || 1;
14551
14552		if ( existingHandles.length > handleCount ) {
14553			existingHandles.slice( handleCount ).remove();
14554			existingHandles = existingHandles.slice( 0, handleCount );
14555		}
14556
14557		for ( i = existingHandles.length; i < handleCount; i++ ) {
14558			handles.push( handle );
14559		}
14560
14561		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14562
14563		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14564
14565		this.handle = this.handles.eq( 0 );
14566
14567		this.handles.each( function( i ) {
14568			$( this )
14569				.data( "ui-slider-handle-index", i )
14570				.attr( "tabIndex", 0 );
14571		} );
14572	},
14573
14574	_createRange: function() {
14575		var options = this.options;
14576
14577		if ( options.range ) {
14578			if ( options.range === true ) {
14579				if ( !options.values ) {
14580					options.values = [ this._valueMin(), this._valueMin() ];
14581				} else if ( options.values.length && options.values.length !== 2 ) {
14582					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14583				} else if ( $.isArray( options.values ) ) {
14584					options.values = options.values.slice( 0 );
14585				}
14586			}
14587
14588			if ( !this.range || !this.range.length ) {
14589				this.range = $( "<div>" )
14590					.appendTo( this.element );
14591
14592				this._addClass( this.range, "ui-slider-range" );
14593			} else {
14594				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14595
14596				// Handle range switching from true to min/max
14597				this.range.css( {
14598					"left": "",
14599					"bottom": ""
14600				} );
14601			}
14602			if ( options.range === "min" || options.range === "max" ) {
14603				this._addClass( this.range, "ui-slider-range-" + options.range );
14604			}
14605		} else {
14606			if ( this.range ) {
14607				this.range.remove();
14608			}
14609			this.range = null;
14610		}
14611	},
14612
14613	_setupEvents: function() {
14614		this._off( this.handles );
14615		this._on( this.handles, this._handleEvents );
14616		this._hoverable( this.handles );
14617		this._focusable( this.handles );
14618	},
14619
14620	_destroy: function() {
14621		this.handles.remove();
14622		if ( this.range ) {
14623			this.range.remove();
14624		}
14625
14626		this._mouseDestroy();
14627	},
14628
14629	_mouseCapture: function( event ) {
14630		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14631			that = this,
14632			o = this.options;
14633
14634		if ( o.disabled ) {
14635			return false;
14636		}
14637
14638		this.elementSize = {
14639			width: this.element.outerWidth(),
14640			height: this.element.outerHeight()
14641		};
14642		this.elementOffset = this.element.offset();
14643
14644		position = { x: event.pageX, y: event.pageY };
14645		normValue = this._normValueFromMouse( position );
14646		distance = this._valueMax() - this._valueMin() + 1;
14647		this.handles.each( function( i ) {
14648			var thisDistance = Math.abs( normValue - that.values( i ) );
14649			if ( ( distance > thisDistance ) ||
14650				( distance === thisDistance &&
14651					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14652				distance = thisDistance;
14653				closestHandle = $( this );
14654				index = i;
14655			}
14656		} );
14657
14658		allowed = this._start( event, index );
14659		if ( allowed === false ) {
14660			return false;
14661		}
14662		this._mouseSliding = true;
14663
14664		this._handleIndex = index;
14665
14666		this._addClass( closestHandle, null, "ui-state-active" );
14667		closestHandle.trigger( "focus" );
14668
14669		offset = closestHandle.offset();
14670		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14671		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14672			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14673			top: event.pageY - offset.top -
14674				( closestHandle.height() / 2 ) -
14675				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14676				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14677				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14678		};
14679
14680		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14681			this._slide( event, index, normValue );
14682		}
14683		this._animateOff = true;
14684		return true;
14685	},
14686
14687	_mouseStart: function() {
14688		return true;
14689	},
14690
14691	_mouseDrag: function( event ) {
14692		var position = { x: event.pageX, y: event.pageY },
14693			normValue = this._normValueFromMouse( position );
14694
14695		this._slide( event, this._handleIndex, normValue );
14696
14697		return false;
14698	},
14699
14700	_mouseStop: function( event ) {
14701		this._removeClass( this.handles, null, "ui-state-active" );
14702		this._mouseSliding = false;
14703
14704		this._stop( event, this._handleIndex );
14705		this._change( event, this._handleIndex );
14706
14707		this._handleIndex = null;
14708		this._clickOffset = null;
14709		this._animateOff = false;
14710
14711		return false;
14712	},
14713
14714	_detectOrientation: function() {
14715		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14716	},
14717
14718	_normValueFromMouse: function( position ) {
14719		var pixelTotal,
14720			pixelMouse,
14721			percentMouse,
14722			valueTotal,
14723			valueMouse;
14724
14725		if ( this.orientation === "horizontal" ) {
14726			pixelTotal = this.elementSize.width;
14727			pixelMouse = position.x - this.elementOffset.left -
14728				( this._clickOffset ? this._clickOffset.left : 0 );
14729		} else {
14730			pixelTotal = this.elementSize.height;
14731			pixelMouse = position.y - this.elementOffset.top -
14732				( this._clickOffset ? this._clickOffset.top : 0 );
14733		}
14734
14735		percentMouse = ( pixelMouse / pixelTotal );
14736		if ( percentMouse > 1 ) {
14737			percentMouse = 1;
14738		}
14739		if ( percentMouse < 0 ) {
14740			percentMouse = 0;
14741		}
14742		if ( this.orientation === "vertical" ) {
14743			percentMouse = 1 - percentMouse;
14744		}
14745
14746		valueTotal = this._valueMax() - this._valueMin();
14747		valueMouse = this._valueMin() + percentMouse * valueTotal;
14748
14749		return this._trimAlignValue( valueMouse );
14750	},
14751
14752	_uiHash: function( index, value, values ) {
14753		var uiHash = {
14754			handle: this.handles[ index ],
14755			handleIndex: index,
14756			value: value !== undefined ? value : this.value()
14757		};
14758
14759		if ( this._hasMultipleValues() ) {
14760			uiHash.value = value !== undefined ? value : this.values( index );
14761			uiHash.values = values || this.values();
14762		}
14763
14764		return uiHash;
14765	},
14766
14767	_hasMultipleValues: function() {
14768		return this.options.values && this.options.values.length;
14769	},
14770
14771	_start: function( event, index ) {
14772		return this._trigger( "start", event, this._uiHash( index ) );
14773	},
14774
14775	_slide: function( event, index, newVal ) {
14776		var allowed, otherVal,
14777			currentValue = this.value(),
14778			newValues = this.values();
14779
14780		if ( this._hasMultipleValues() ) {
14781			otherVal = this.values( index ? 0 : 1 );
14782			currentValue = this.values( index );
14783
14784			if ( this.options.values.length === 2 && this.options.range === true ) {
14785				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14786			}
14787
14788			newValues[ index ] = newVal;
14789		}
14790
14791		if ( newVal === currentValue ) {
14792			return;
14793		}
14794
14795		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14796
14797		// A slide can be canceled by returning false from the slide callback
14798		if ( allowed === false ) {
14799			return;
14800		}
14801
14802		if ( this._hasMultipleValues() ) {
14803			this.values( index, newVal );
14804		} else {
14805			this.value( newVal );
14806		}
14807	},
14808
14809	_stop: function( event, index ) {
14810		this._trigger( "stop", event, this._uiHash( index ) );
14811	},
14812
14813	_change: function( event, index ) {
14814		if ( !this._keySliding && !this._mouseSliding ) {
14815
14816			//store the last changed value index for reference when handles overlap
14817			this._lastChangedValue = index;
14818			this._trigger( "change", event, this._uiHash( index ) );
14819		}
14820	},
14821
14822	value: function( newValue ) {
14823		if ( arguments.length ) {
14824			this.options.value = this._trimAlignValue( newValue );
14825			this._refreshValue();
14826			this._change( null, 0 );
14827			return;
14828		}
14829
14830		return this._value();
14831	},
14832
14833	values: function( index, newValue ) {
14834		var vals,
14835			newValues,
14836			i;
14837
14838		if ( arguments.length > 1 ) {
14839			this.options.values[ index ] = this._trimAlignValue( newValue );
14840			this._refreshValue();
14841			this._change( null, index );
14842			return;
14843		}
14844
14845		if ( arguments.length ) {
14846			if ( $.isArray( arguments[ 0 ] ) ) {
14847				vals = this.options.values;
14848				newValues = arguments[ 0 ];
14849				for ( i = 0; i < vals.length; i += 1 ) {
14850					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14851					this._change( null, i );
14852				}
14853				this._refreshValue();
14854			} else {
14855				if ( this._hasMultipleValues() ) {
14856					return this._values( index );
14857				} else {
14858					return this.value();
14859				}
14860			}
14861		} else {
14862			return this._values();
14863		}
14864	},
14865
14866	_setOption: function( key, value ) {
14867		var i,
14868			valsLength = 0;
14869
14870		if ( key === "range" && this.options.range === true ) {
14871			if ( value === "min" ) {
14872				this.options.value = this._values( 0 );
14873				this.options.values = null;
14874			} else if ( value === "max" ) {
14875				this.options.value = this._values( this.options.values.length - 1 );
14876				this.options.values = null;
14877			}
14878		}
14879
14880		if ( $.isArray( this.options.values ) ) {
14881			valsLength = this.options.values.length;
14882		}
14883
14884		this._super( key, value );
14885
14886		switch ( key ) {
14887			case "orientation":
14888				this._detectOrientation();
14889				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14890					._addClass( "ui-slider-" + this.orientation );
14891				this._refreshValue();
14892				if ( this.options.range ) {
14893					this._refreshRange( value );
14894				}
14895
14896				// Reset positioning from previous orientation
14897				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14898				break;
14899			case "value":
14900				this._animateOff = true;
14901				this._refreshValue();
14902				this._change( null, 0 );
14903				this._animateOff = false;
14904				break;
14905			case "values":
14906				this._animateOff = true;
14907				this._refreshValue();
14908
14909				// Start from the last handle to prevent unreachable handles (#9046)
14910				for ( i = valsLength - 1; i >= 0; i-- ) {
14911					this._change( null, i );
14912				}
14913				this._animateOff = false;
14914				break;
14915			case "step":
14916			case "min":
14917			case "max":
14918				this._animateOff = true;
14919				this._calculateNewMax();
14920				this._refreshValue();
14921				this._animateOff = false;
14922				break;
14923			case "range":
14924				this._animateOff = true;
14925				this._refresh();
14926				this._animateOff = false;
14927				break;
14928		}
14929	},
14930
14931	_setOptionDisabled: function( value ) {
14932		this._super( value );
14933
14934		this._toggleClass( null, "ui-state-disabled", !!value );
14935	},
14936
14937	//internal value getter
14938	// _value() returns value trimmed by min and max, aligned by step
14939	_value: function() {
14940		var val = this.options.value;
14941		val = this._trimAlignValue( val );
14942
14943		return val;
14944	},
14945
14946	//internal values getter
14947	// _values() returns array of values trimmed by min and max, aligned by step
14948	// _values( index ) returns single value trimmed by min and max, aligned by step
14949	_values: function( index ) {
14950		var val,
14951			vals,
14952			i;
14953
14954		if ( arguments.length ) {
14955			val = this.options.values[ index ];
14956			val = this._trimAlignValue( val );
14957
14958			return val;
14959		} else if ( this._hasMultipleValues() ) {
14960
14961			// .slice() creates a copy of the array
14962			// this copy gets trimmed by min and max and then returned
14963			vals = this.options.values.slice();
14964			for ( i = 0; i < vals.length; i += 1 ) {
14965				vals[ i ] = this._trimAlignValue( vals[ i ] );
14966			}
14967
14968			return vals;
14969		} else {
14970			return [];
14971		}
14972	},
14973
14974	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14975	_trimAlignValue: function( val ) {
14976		if ( val <= this._valueMin() ) {
14977			return this._valueMin();
14978		}
14979		if ( val >= this._valueMax() ) {
14980			return this._valueMax();
14981		}
14982		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14983			valModStep = ( val - this._valueMin() ) % step,
14984			alignValue = val - valModStep;
14985
14986		if ( Math.abs( valModStep ) * 2 >= step ) {
14987			alignValue += ( valModStep > 0 ) ? step : ( -step );
14988		}
14989
14990		// Since JavaScript has problems with large floats, round
14991		// the final value to 5 digits after the decimal point (see #4124)
14992		return parseFloat( alignValue.toFixed( 5 ) );
14993	},
14994
14995	_calculateNewMax: function() {
14996		var max = this.options.max,
14997			min = this._valueMin(),
14998			step = this.options.step,
14999			aboveMin = Math.round( ( max - min ) / step ) * step;
15000		max = aboveMin + min;
15001		if ( max > this.options.max ) {
15002
15003			//If max is not divisible by step, rounding off may increase its value
15004			max -= step;
15005		}
15006		this.max = parseFloat( max.toFixed( this._precision() ) );
15007	},
15008
15009	_precision: function() {
15010		var precision = this._precisionOf( this.options.step );
15011		if ( this.options.min !== null ) {
15012			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15013		}
15014		return precision;
15015	},
15016
15017	_precisionOf: function( num ) {
15018		var str = num.toString(),
15019			decimal = str.indexOf( "." );
15020		return decimal === -1 ? 0 : str.length - decimal - 1;
15021	},
15022
15023	_valueMin: function() {
15024		return this.options.min;
15025	},
15026
15027	_valueMax: function() {
15028		return this.max;
15029	},
15030
15031	_refreshRange: function( orientation ) {
15032		if ( orientation === "vertical" ) {
15033			this.range.css( { "width": "", "left": "" } );
15034		}
15035		if ( orientation === "horizontal" ) {
15036			this.range.css( { "height": "", "bottom": "" } );
15037		}
15038	},
15039
15040	_refreshValue: function() {
15041		var lastValPercent, valPercent, value, valueMin, valueMax,
15042			oRange = this.options.range,
15043			o = this.options,
15044			that = this,
15045			animate = ( !this._animateOff ) ? o.animate : false,
15046			_set = {};
15047
15048		if ( this._hasMultipleValues() ) {
15049			this.handles.each( function( i ) {
15050				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15051					that._valueMin() ) * 100;
15052				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15053				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15054				if ( that.options.range === true ) {
15055					if ( that.orientation === "horizontal" ) {
15056						if ( i === 0 ) {
15057							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15058								left: valPercent + "%"
15059							}, o.animate );
15060						}
15061						if ( i === 1 ) {
15062							that.range[ animate ? "animate" : "css" ]( {
15063								width: ( valPercent - lastValPercent ) + "%"
15064							}, {
15065								queue: false,
15066								duration: o.animate
15067							} );
15068						}
15069					} else {
15070						if ( i === 0 ) {
15071							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15072								bottom: ( valPercent ) + "%"
15073							}, o.animate );
15074						}
15075						if ( i === 1 ) {
15076							that.range[ animate ? "animate" : "css" ]( {
15077								height: ( valPercent - lastValPercent ) + "%"
15078							}, {
15079								queue: false,
15080								duration: o.animate
15081							} );
15082						}
15083					}
15084				}
15085				lastValPercent = valPercent;
15086			} );
15087		} else {
15088			value = this.value();
15089			valueMin = this._valueMin();
15090			valueMax = this._valueMax();
15091			valPercent = ( valueMax !== valueMin ) ?
15092					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15093					0;
15094			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15095			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15096
15097			if ( oRange === "min" && this.orientation === "horizontal" ) {
15098				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15099					width: valPercent + "%"
15100				}, o.animate );
15101			}
15102			if ( oRange === "max" && this.orientation === "horizontal" ) {
15103				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15104					width: ( 100 - valPercent ) + "%"
15105				}, o.animate );
15106			}
15107			if ( oRange === "min" && this.orientation === "vertical" ) {
15108				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15109					height: valPercent + "%"
15110				}, o.animate );
15111			}
15112			if ( oRange === "max" && this.orientation === "vertical" ) {
15113				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15114					height: ( 100 - valPercent ) + "%"
15115				}, o.animate );
15116			}
15117		}
15118	},
15119
15120	_handleEvents: {
15121		keydown: function( event ) {
15122			var allowed, curVal, newVal, step,
15123				index = $( event.target ).data( "ui-slider-handle-index" );
15124
15125			switch ( event.keyCode ) {
15126				case $.ui.keyCode.HOME:
15127				case $.ui.keyCode.END:
15128				case $.ui.keyCode.PAGE_UP:
15129				case $.ui.keyCode.PAGE_DOWN:
15130				case $.ui.keyCode.UP:
15131				case $.ui.keyCode.RIGHT:
15132				case $.ui.keyCode.DOWN:
15133				case $.ui.keyCode.LEFT:
15134					event.preventDefault();
15135					if ( !this._keySliding ) {
15136						this._keySliding = true;
15137						this._addClass( $( event.target ), null, "ui-state-active" );
15138						allowed = this._start( event, index );
15139						if ( allowed === false ) {
15140							return;
15141						}
15142					}
15143					break;
15144			}
15145
15146			step = this.options.step;
15147			if ( this._hasMultipleValues() ) {
15148				curVal = newVal = this.values( index );
15149			} else {
15150				curVal = newVal = this.value();
15151			}
15152
15153			switch ( event.keyCode ) {
15154				case $.ui.keyCode.HOME:
15155					newVal = this._valueMin();
15156					break;
15157				case $.ui.keyCode.END:
15158					newVal = this._valueMax();
15159					break;
15160				case $.ui.keyCode.PAGE_UP:
15161					newVal = this._trimAlignValue(
15162						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15163					);
15164					break;
15165				case $.ui.keyCode.PAGE_DOWN:
15166					newVal = this._trimAlignValue(
15167						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15168					break;
15169				case $.ui.keyCode.UP:
15170				case $.ui.keyCode.RIGHT:
15171					if ( curVal === this._valueMax() ) {
15172						return;
15173					}
15174					newVal = this._trimAlignValue( curVal + step );
15175					break;
15176				case $.ui.keyCode.DOWN:
15177				case $.ui.keyCode.LEFT:
15178					if ( curVal === this._valueMin() ) {
15179						return;
15180					}
15181					newVal = this._trimAlignValue( curVal - step );
15182					break;
15183			}
15184
15185			this._slide( event, index, newVal );
15186		},
15187		keyup: function( event ) {
15188			var index = $( event.target ).data( "ui-slider-handle-index" );
15189
15190			if ( this._keySliding ) {
15191				this._keySliding = false;
15192				this._stop( event, index );
15193				this._change( event, index );
15194				this._removeClass( $( event.target ), null, "ui-state-active" );
15195			}
15196		}
15197	}
15198} );
15199
15200
vendor: 3,521 bytes, lines 15201-15359
15201/*!
15202 * jQuery UI Sortable 1.12.1
15203 * http://jqueryui.com
15204 *
15205 * Copyright jQuery Foundation and other contributors
15206 * Released under the MIT license.
15207 * http://jquery.org/license
15208 */
15209
15210//>>label: Sortable
15211//>>group: Interactions
15212//>>description: Enables items in a list to be sorted using the mouse.
15213//>>docs: http://api.jqueryui.com/sortable/
15214//>>demos: http://jqueryui.com/sortable/
15215//>>css.structure: ../../themes/base/sortable.css
15216
15217
15218
15219var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15220	version: "1.12.1",
15221	widgetEventPrefix: "sort",
15222	ready: false,
15223	options: {
15224		appendTo: "parent",
15225		axis: false,
15226		connectWith: false,
15227		containment: false,
15228		cursor: "auto",
15229		cursorAt: false,
15230		dropOnEmpty: true,
15231		forcePlaceholderSize: false,
15232		forceHelperSize: false,
15233		grid: false,
15234		handle: false,
15235		helper: "original",
15236		items: "> *",
15237		opacity: false,
15238		placeholder: false,
15239		revert: false,
15240		scroll: true,
15241		scrollSensitivity: 20,
15242		scrollSpeed: 20,
15243		scope: "default",
15244		tolerance: "intersect",
15245		zIndex: 1000,
15246
15247		// Callbacks
15248		activate: null,
15249		beforeStop: null,
15250		change: null,
15251		deactivate: null,
15252		out: null,
15253		over: null,
15254		receive: null,
15255		remove: null,
15256		sort: null,
15257		start: null,
15258		stop: null,
15259		update: null
15260	},
15261
15262	_isOverAxis: function( x, reference, size ) {
15263		return ( x >= reference ) && ( x < ( reference + size ) );
15264	},
15265
15266	_isFloating: function( item ) {
15267		return ( /left|right/ ).test( item.css( "float" ) ) ||
15268			( /inline|table-cell/ ).test( item.css( "display" ) );
15269	},
15270
15271	_create: function() {
15272		this.containerCache = {};
15273		this._addClass( "ui-sortable" );
15274
15275		//Get the items
15276		this.refresh();
15277
15278		//Let's determine the parent's offset
15279		this.offset = this.element.offset();
15280
15281		//Initialize mouse events for interaction
15282		this._mouseInit();
15283
15284		this._setHandleClassName();
15285
15286		//We're ready to go
15287		this.ready = true;
15288
15289	},
15290
15291	_setOption: function( key, value ) {
15292		this._super( key, value );
15293
15294		if ( key === "handle" ) {
15295			this._setHandleClassName();
15296		}
15297	},
15298
15299	_setHandleClassName: function() {
15300		var that = this;
15301		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15302		$.each( this.items, function() {
15303			that._addClass(
15304				this.instance.options.handle ?
15305					this.item.find( this.instance.options.handle ) :
15306					this.item,
15307				"ui-sortable-handle"
15308			);
15309		} );
15310	},
15311
15312	_destroy: function() {
15313		this._mouseDestroy();
15314
15315		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15316			this.items[ i ].item.removeData( this.widgetName + "-item" );
15317		}
15318
15319		return this;
15320	},
15321
15322	_mouseCapture: function( event, overrideHandle ) {
15323		var currentItem = null,
15324			validHandle = false,
15325			that = this;
15326
15327		if ( this.reverting ) {
15328			return false;
15329		}
15330
15331		if ( this.options.disabled || this.options.type === "static" ) {
15332			return false;
15333		}
15334
15335		//We have to refresh the items data once first
15336		this._refreshItems( event );
15337
15338		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15339		$( event.target ).parents().each( function() {
15340			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15341				currentItem = $( this );
15342				return false;
15343			}
15344		} );
15345		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15346			currentItem = $( event.target );
15347		}
15348
15349		if ( !currentItem ) {
15350			return false;
15351		}
15352		if ( this.options.handle && !overrideHandle ) {
15353			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15354				if ( this === event.target ) {
15355					validHandle = true;
15356				}
15357			} );
15358			if ( !validHandle ) {
15359				return false;
vendor: 8,227 bytes, lines 15360-15625
15360			}
15361		}
15362
15363		this.currentItem = currentItem;
15364		this._removeCurrentsFromItems();
15365		return true;
15366
15367	},
15368
15369	_mouseStart: function( event, overrideHandle, noActivation ) {
15370
15371		var i, body,
15372			o = this.options;
15373
15374		this.currentContainer = this;
15375
15376		//We only need to call refreshPositions, because the refreshItems call has been moved to
15377		// mouseCapture
15378		this.refreshPositions();
15379
15380		//Create and append the visible helper
15381		this.helper = this._createHelper( event );
15382
15383		//Cache the helper size
15384		this._cacheHelperProportions();
15385
15386		/*
15387		 * - Position generation -
15388		 * This block generates everything position related - it's the core of draggables.
15389		 */
15390
15391		//Cache the margins of the original element
15392		this._cacheMargins();
15393
15394		//Get the next scrolling parent
15395		this.scrollParent = this.helper.scrollParent();
15396
15397		//The element's absolute position on the page minus margins
15398		this.offset = this.currentItem.offset();
15399		this.offset = {
15400			top: this.offset.top - this.margins.top,
15401			left: this.offset.left - this.margins.left
15402		};
15403
15404		$.extend( this.offset, {
15405			click: { //Where the click happened, relative to the element
15406				left: event.pageX - this.offset.left,
15407				top: event.pageY - this.offset.top
15408			},
15409			parent: this._getParentOffset(),
15410
15411			// This is a relative to absolute position minus the actual position calculation -
15412			// only used for relative positioned helper
15413			relative: this._getRelativeOffset()
15414		} );
15415
15416		// Only after we got the offset, we can change the helper's position to absolute
15417		// TODO: Still need to figure out a way to make relative sorting possible
15418		this.helper.css( "position", "absolute" );
15419		this.cssPosition = this.helper.css( "position" );
15420
15421		//Generate the original position
15422		this.originalPosition = this._generatePosition( event );
15423		this.originalPageX = event.pageX;
15424		this.originalPageY = event.pageY;
15425
15426		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15427		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15428
15429		//Cache the former DOM position
15430		this.domPosition = {
15431			prev: this.currentItem.prev()[ 0 ],
15432			parent: this.currentItem.parent()[ 0 ]
15433		};
15434
15435		// If the helper is not the original, hide the original so it's not playing any role during
15436		// the drag, won't cause anything bad this way
15437		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15438			this.currentItem.hide();
15439		}
15440
15441		//Create the placeholder
15442		this._createPlaceholder();
15443
15444		//Set a containment if given in the options
15445		if ( o.containment ) {
15446			this._setContainment();
15447		}
15448
15449		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15450			body = this.document.find( "body" );
15451
15452			// Support: IE
15453			this.storedCursor = body.css( "cursor" );
15454			body.css( "cursor", o.cursor );
15455
15456			this.storedStylesheet =
15457				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15458		}
15459
15460		if ( o.opacity ) { // opacity option
15461			if ( this.helper.css( "opacity" ) ) {
15462				this._storedOpacity = this.helper.css( "opacity" );
15463			}
15464			this.helper.css( "opacity", o.opacity );
15465		}
15466
15467		if ( o.zIndex ) { // zIndex option
15468			if ( this.helper.css( "zIndex" ) ) {
15469				this._storedZIndex = this.helper.css( "zIndex" );
15470			}
15471			this.helper.css( "zIndex", o.zIndex );
15472		}
15473
15474		//Prepare scrolling
15475		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15476				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15477			this.overflowOffset = this.scrollParent.offset();
15478		}
15479
15480		//Call callbacks
15481		this._trigger( "start", event, this._uiHash() );
15482
15483		//Recache the helper size
15484		if ( !this._preserveHelperProportions ) {
15485			this._cacheHelperProportions();
15486		}
15487
15488		//Post "activate" events to possible containers
15489		if ( !noActivation ) {
15490			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15491				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15492			}
15493		}
15494
15495		//Prepare possible droppables
15496		if ( $.ui.ddmanager ) {
15497			$.ui.ddmanager.current = this;
15498		}
15499
15500		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15501			$.ui.ddmanager.prepareOffsets( this, event );
15502		}
15503
15504		this.dragging = true;
15505
15506		this._addClass( this.helper, "ui-sortable-helper" );
15507
15508		// Execute the drag once - this causes the helper not to be visiblebefore getting its
15509		// correct position
15510		this._mouseDrag( event );
15511		return true;
15512
15513	},
15514
15515	_mouseDrag: function( event ) {
15516		var i, item, itemElement, intersection,
15517			o = this.options,
15518			scrolled = false;
15519
15520		//Compute the helpers position
15521		this.position = this._generatePosition( event );
15522		this.positionAbs = this._convertPositionTo( "absolute" );
15523
15524		if ( !this.lastPositionAbs ) {
15525			this.lastPositionAbs = this.positionAbs;
15526		}
15527
15528		//Do scrolling
15529		if ( this.options.scroll ) {
15530			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15531					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15532
15533				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15534						event.pageY < o.scrollSensitivity ) {
15535					this.scrollParent[ 0 ].scrollTop =
15536						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15537				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15538					this.scrollParent[ 0 ].scrollTop =
15539						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15540				}
15541
15542				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15543						event.pageX < o.scrollSensitivity ) {
15544					this.scrollParent[ 0 ].scrollLeft = scrolled =
15545						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15546				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15547					this.scrollParent[ 0 ].scrollLeft = scrolled =
15548						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15549				}
15550
15551			} else {
15552
15553				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15554					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15555				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15556						o.scrollSensitivity ) {
15557					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15558				}
15559
15560				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15561					scrolled = this.document.scrollLeft(
15562						this.document.scrollLeft() - o.scrollSpeed
15563					);
15564				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15565						o.scrollSensitivity ) {
15566					scrolled = this.document.scrollLeft(
15567						this.document.scrollLeft() + o.scrollSpeed
15568					);
15569				}
15570
15571			}
15572
15573			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15574				$.ui.ddmanager.prepareOffsets( this, event );
15575			}
15576		}
15577
15578		//Regenerate the absolute position used for position checks
15579		this.positionAbs = this._convertPositionTo( "absolute" );
15580
15581		//Set the helper position
15582		if ( !this.options.axis || this.options.axis !== "y" ) {
15583			this.helper[ 0 ].style.left = this.position.left + "px";
15584		}
15585		if ( !this.options.axis || this.options.axis !== "x" ) {
15586			this.helper[ 0 ].style.top = this.position.top + "px";
15587		}
15588
15589		//Rearrange
15590		for ( i = this.items.length - 1; i >= 0; i-- ) {
15591
15592			//Cache variables and intersection, continue if no intersection
15593			item = this.items[ i ];
15594			itemElement = item.item[ 0 ];
15595			intersection = this._intersectsWithPointer( item );
15596			if ( !intersection ) {
15597				continue;
15598			}
15599
15600			// Only put the placeholder inside the current Container, skip all
15601			// items from other containers. This works because when moving
15602			// an item from one container to another the
15603			// currentContainer is switched before the placeholder is moved.
15604			//
15605			// Without this, moving items in "sub-sortables" can cause
15606			// the placeholder to jitter between the outer and inner container.
15607			if ( item.instance !== this.currentContainer ) {
15608				continue;
15609			}
15610
15611			// Cannot intersect with itself
15612			// no useless actions that have been done before
15613			// no action if the item moved is the parent of the item checked
15614			if ( itemElement !== this.currentItem[ 0 ] &&
15615				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15616				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15617				( this.options.type === "semi-dynamic" ?
15618					!$.contains( this.element[ 0 ], itemElement ) :
15619					true
15620				)
15621			) {
15622
15623				this.direction = intersection === 1 ? "down" : "up";
15624
15625				if ( this.options.tolerance === "pointer" || 
vendor: 5,576 bytes, lines 15625-15841
15625this._intersectsWithSides( item ) ) {
15626					this._rearrange( event, item );
15627				} else {
15628					break;
15629				}
15630
15631				this._trigger( "change", event, this._uiHash() );
15632				break;
15633			}
15634		}
15635
15636		//Post events to containers
15637		this._contactContainers( event );
15638
15639		//Interconnect with droppables
15640		if ( $.ui.ddmanager ) {
15641			$.ui.ddmanager.drag( this, event );
15642		}
15643
15644		//Call callbacks
15645		this._trigger( "sort", event, this._uiHash() );
15646
15647		this.lastPositionAbs = this.positionAbs;
15648		return false;
15649
15650	},
15651
15652	_mouseStop: function( event, noPropagation ) {
15653
15654		if ( !event ) {
15655			return;
15656		}
15657
15658		//If we are using droppables, inform the manager about the drop
15659		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15660			$.ui.ddmanager.drop( this, event );
15661		}
15662
15663		if ( this.options.revert ) {
15664			var that = this,
15665				cur = this.placeholder.offset(),
15666				axis = this.options.axis,
15667				animation = {};
15668
15669			if ( !axis || axis === "x" ) {
15670				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15671					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15672						0 :
15673						this.offsetParent[ 0 ].scrollLeft
15674					);
15675			}
15676			if ( !axis || axis === "y" ) {
15677				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15678					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15679						0 :
15680						this.offsetParent[ 0 ].scrollTop
15681					);
15682			}
15683			this.reverting = true;
15684			$( this.helper ).animate(
15685				animation,
15686				parseInt( this.options.revert, 10 ) || 500,
15687				function() {
15688					that._clear( event );
15689				}
15690			);
15691		} else {
15692			this._clear( event, noPropagation );
15693		}
15694
15695		return false;
15696
15697	},
15698
15699	cancel: function() {
15700
15701		if ( this.dragging ) {
15702
15703			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15704
15705			if ( this.options.helper === "original" ) {
15706				this.currentItem.css( this._storedCSS );
15707				this._removeClass( this.currentItem, "ui-sortable-helper" );
15708			} else {
15709				this.currentItem.show();
15710			}
15711
15712			//Post deactivating events to containers
15713			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15714				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15715				if ( this.containers[ i ].containerCache.over ) {
15716					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15717					this.containers[ i ].containerCache.over = 0;
15718				}
15719			}
15720
15721		}
15722
15723		if ( this.placeholder ) {
15724
15725			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15726			// it unbinds ALL events from the original node!
15727			if ( this.placeholder[ 0 ].parentNode ) {
15728				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15729			}
15730			if ( this.options.helper !== "original" && this.helper &&
15731					this.helper[ 0 ].parentNode ) {
15732				this.helper.remove();
15733			}
15734
15735			$.extend( this, {
15736				helper: null,
15737				dragging: false,
15738				reverting: false,
15739				_noFinalSort: null
15740			} );
15741
15742			if ( this.domPosition.prev ) {
15743				$( this.domPosition.prev ).after( this.currentItem );
15744			} else {
15745				$( this.domPosition.parent ).prepend( this.currentItem );
15746			}
15747		}
15748
15749		return this;
15750
15751	},
15752
15753	serialize: function( o ) {
15754
15755		var items = this._getItemsAsjQuery( o && o.connected ),
15756			str = [];
15757		o = o || {};
15758
15759		$( items ).each( function() {
15760			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15761				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15762			if ( res ) {
15763				str.push(
15764					( o.key || res[ 1 ] + "[]" ) +
15765					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15766			}
15767		} );
15768
15769		if ( !str.length && o.key ) {
15770			str.push( o.key + "=" );
15771		}
15772
15773		return str.join( "&" );
15774
15775	},
15776
15777	toArray: function( o ) {
15778
15779		var items = this._getItemsAsjQuery( o && o.connected ),
15780			ret = [];
15781
15782		o = o || {};
15783
15784		items.each( function() {
15785			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15786		} );
15787		return ret;
15788
15789	},
15790
15791	/* Be careful with the following core functions */
15792	_intersectsWith: function( item ) {
15793
15794		var x1 = this.positionAbs.left,
15795			x2 = x1 + this.helperProportions.width,
15796			y1 = this.positionAbs.top,
15797			y2 = y1 + this.helperProportions.height,
15798			l = item.left,
15799			r = l + item.width,
15800			t = item.top,
15801			b = t + item.height,
15802			dyClick = this.offset.click.top,
15803			dxClick = this.offset.click.left,
15804			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15805				( y1 + dyClick ) < b ),
15806			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15807				( x1 + dxClick ) < r ),
15808			isOverElement = isOverElementHeight && isOverElementWidth;
15809
15810		if ( this.options.tolerance === "pointer" ||
15811			this.options.forcePointerForContainers ||
15812			( this.options.tolerance !== "pointer" &&
15813				this.helperProportions[ this.floating ? "width" : "height" ] >
15814				item[ this.floating ? "width" : "height" ] )
15815		) {
15816			return isOverElement;
15817		} else {
15818
15819			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15820				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15821				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15822				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15823
15824		}
15825	},
15826
15827	_intersectsWithPointer: function( item ) {
15828		var verticalDirection, horizontalDirection,
15829			isOverElementHeight = ( this.options.axis === "x" ) ||
15830				this._isOverAxis(
15831					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15832			isOverElementWidth = ( this.options.axis === "y" ) ||
15833				this._isOverAxis(
15834					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15835			isOverElement = isOverElementHeight && isOverElementWidth;
15836
15837		if ( !isOverElement ) {
15838			return false;
15839		}
15840
15841		verticalDirection = this.
vendor: 13,806 bytes, lines 15841-16288
15841_getDragVerticalDirection();
15842		horizontalDirection = this._getDragHorizontalDirection();
15843
15844		return this.floating ?
15845			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15846			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15847
15848	},
15849
15850	_intersectsWithSides: function( item ) {
15851
15852		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15853				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15854			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15855				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15856			verticalDirection = this._getDragVerticalDirection(),
15857			horizontalDirection = this._getDragHorizontalDirection();
15858
15859		if ( this.floating && horizontalDirection ) {
15860			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15861				( horizontalDirection === "left" && !isOverRightHalf ) );
15862		} else {
15863			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15864				( verticalDirection === "up" && !isOverBottomHalf ) );
15865		}
15866
15867	},
15868
15869	_getDragVerticalDirection: function() {
15870		var delta = this.positionAbs.top - this.lastPositionAbs.top;
15871		return delta !== 0 && ( delta > 0 ? "down" : "up" );
15872	},
15873
15874	_getDragHorizontalDirection: function() {
15875		var delta = this.positionAbs.left - this.lastPositionAbs.left;
15876		return delta !== 0 && ( delta > 0 ? "right" : "left" );
15877	},
15878
15879	refresh: function( event ) {
15880		this._refreshItems( event );
15881		this._setHandleClassName();
15882		this.refreshPositions();
15883		return this;
15884	},
15885
15886	_connectWith: function() {
15887		var options = this.options;
15888		return options.connectWith.constructor === String ?
15889			[ options.connectWith ] :
15890			options.connectWith;
15891	},
15892
15893	_getItemsAsjQuery: function( connected ) {
15894
15895		var i, j, cur, inst,
15896			items = [],
15897			queries = [],
15898			connectWith = this._connectWith();
15899
15900		if ( connectWith && connected ) {
15901			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15902				cur = $( connectWith[ i ], this.document[ 0 ] );
15903				for ( j = cur.length - 1; j >= 0; j-- ) {
15904					inst = $.data( cur[ j ], this.widgetFullName );
15905					if ( inst && inst !== this && !inst.options.disabled ) {
15906						queries.push( [ $.isFunction( inst.options.items ) ?
15907							inst.options.items.call( inst.element ) :
15908							$( inst.options.items, inst.element )
15909								.not( ".ui-sortable-helper" )
15910								.not( ".ui-sortable-placeholder" ), inst ] );
15911					}
15912				}
15913			}
15914		}
15915
15916		queries.push( [ $.isFunction( this.options.items ) ?
15917			this.options.items
15918				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15919			$( this.options.items, this.element )
15920				.not( ".ui-sortable-helper" )
15921				.not( ".ui-sortable-placeholder" ), this ] );
15922
15923		function addItems() {
15924			items.push( this );
15925		}
15926		for ( i = queries.length - 1; i >= 0; i-- ) {
15927			queries[ i ][ 0 ].each( addItems );
15928		}
15929
15930		return $( items );
15931
15932	},
15933
15934	_removeCurrentsFromItems: function() {
15935
15936		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15937
15938		this.items = $.grep( this.items, function( item ) {
15939			for ( var j = 0; j < list.length; j++ ) {
15940				if ( list[ j ] === item.item[ 0 ] ) {
15941					return false;
15942				}
15943			}
15944			return true;
15945		} );
15946
15947	},
15948
15949	_refreshItems: function( event ) {
15950
15951		this.items = [];
15952		this.containers = [ this ];
15953
15954		var i, j, cur, inst, targetData, _queries, item, queriesLength,
15955			items = this.items,
15956			queries = [ [ $.isFunction( this.options.items ) ?
15957				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15958				$( this.options.items, this.element ), this ] ],
15959			connectWith = this._connectWith();
15960
15961		//Shouldn't be run the first time through due to massive slow-down
15962		if ( connectWith && this.ready ) {
15963			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15964				cur = $( connectWith[ i ], this.document[ 0 ] );
15965				for ( j = cur.length - 1; j >= 0; j-- ) {
15966					inst = $.data( cur[ j ], this.widgetFullName );
15967					if ( inst && inst !== this && !inst.options.disabled ) {
15968						queries.push( [ $.isFunction( inst.options.items ) ?
15969							inst.options.items
15970								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15971							$( inst.options.items, inst.element ), inst ] );
15972						this.containers.push( inst );
15973					}
15974				}
15975			}
15976		}
15977
15978		for ( i = queries.length - 1; i >= 0; i-- ) {
15979			targetData = queries[ i ][ 1 ];
15980			_queries = queries[ i ][ 0 ];
15981
15982			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15983				item = $( _queries[ j ] );
15984
15985				// Data for target checking (mouse manager)
15986				item.data( this.widgetName + "-item", targetData );
15987
15988				items.push( {
15989					item: item,
15990					instance: targetData,
15991					width: 0, height: 0,
15992					left: 0, top: 0
15993				} );
15994			}
15995		}
15996
15997	},
15998
15999	refreshPositions: function( fast ) {
16000
16001		// Determine whether items are being displayed horizontally
16002		this.floating = this.items.length ?
16003			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16004			false;
16005
16006		//This has to be redone because due to the item being moved out/into the offsetParent,
16007		// the offsetParent's position will change
16008		if ( this.offsetParent && this.helper ) {
16009			this.offset.parent = this._getParentOffset();
16010		}
16011
16012		var i, item, t, p;
16013
16014		for ( i = this.items.length - 1; i >= 0; i-- ) {
16015			item = this.items[ i ];
16016
16017			//We ignore calculating positions of all connected containers when we're not over them
16018			if ( item.instance !== this.currentContainer && this.currentContainer &&
16019					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16020				continue;
16021			}
16022
16023			t = this.options.toleranceElement ?
16024				$( this.options.toleranceElement, item.item ) :
16025				item.item;
16026
16027			if ( !fast ) {
16028				item.width = t.outerWidth();
16029				item.height = t.outerHeight();
16030			}
16031
16032			p = t.offset();
16033			item.left = p.left;
16034			item.top = p.top;
16035		}
16036
16037		if ( this.options.custom && this.options.custom.refreshContainers ) {
16038			this.options.custom.refreshContainers.call( this );
16039		} else {
16040			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16041				p = this.containers[ i ].element.offset();
16042				this.containers[ i ].containerCache.left = p.left;
16043				this.containers[ i ].containerCache.top = p.top;
16044				this.containers[ i ].containerCache.width =
16045					this.containers[ i ].element.outerWidth();
16046				this.containers[ i ].containerCache.height =
16047					this.containers[ i ].element.outerHeight();
16048			}
16049		}
16050
16051		return this;
16052	},
16053
16054	_createPlaceholder: function( that ) {
16055		that = that || this;
16056		var className,
16057			o = that.options;
16058
16059		if ( !o.placeholder || o.placeholder.constructor === String ) {
16060			className = o.placeholder;
16061			o.placeholder = {
16062				element: function() {
16063
16064					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16065						element = $( "<" + nodeName + ">", that.document[ 0 ] );
16066
16067						that._addClass( element, "ui-sortable-placeholder",
16068								className || that.currentItem[ 0 ].className )
16069							._removeClass( element, "ui-sortable-helper" );
16070
16071					if ( nodeName === "tbody" ) {
16072						that._createTrPlaceholder(
16073							that.currentItem.find( "tr" ).eq( 0 ),
16074							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16075						);
16076					} else if ( nodeName === "tr" ) {
16077						that._createTrPlaceholder( that.currentItem, element );
16078					} else if ( nodeName === "img" ) {
16079						element.attr( "src", that.currentItem.attr( "src" ) );
16080					}
16081
16082					if ( !className ) {
16083						element.css( "visibility", "hidden" );
16084					}
16085
16086					return element;
16087				},
16088				update: function( container, p ) {
16089
16090					// 1. If a className is set as 'placeholder option, we don't force sizes -
16091					// the class is responsible for that
16092					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16093					// class name is specified
16094					if ( className && !o.forcePlaceholderSize ) {
16095						return;
16096					}
16097
16098					//If the element doesn't have a actual height by itself (without styles coming
16099					// from a stylesheet), it receives the inline height from the dragged item
16100					if ( !p.height() ) {
16101						p.height(
16102							that.currentItem.innerHeight() -
16103							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16104							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16105					}
16106					if ( !p.width() ) {
16107						p.width(
16108							that.currentItem.innerWidth() -
16109							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16110							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16111					}
16112				}
16113			};
16114		}
16115
16116		//Create the placeholder
16117		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16118
16119		//Append it after the actual current item
16120		that.currentItem.after( that.placeholder );
16121
16122		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16123		o.placeholder.update( that, that.placeholder );
16124
16125	},
16126
16127	_createTrPlaceholder: function( sourceTr, targetTr ) {
16128		var that = this;
16129
16130		sourceTr.children().each( function() {
16131			$( "<td>&#160;</td>", that.document[ 0 ] )
16132				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16133				.appendTo( targetTr );
16134		} );
16135	},
16136
16137	_contactContainers: function( event ) {
16138		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16139			floating, axis,
16140			innermostContainer = null,
16141			innermostIndex = null;
16142
16143		// Get innermost container that intersects with item
16144		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16145
16146			// Never consider a container that's located within the item itself
16147			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16148				continue;
16149			}
16150
16151			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16152
16153				// If we've already found a container and it's more "inner" than this, then continue
16154				if ( innermostContainer &&
16155						$.contains(
16156							this.containers[ i ].element[ 0 ],
16157							innermostContainer.element[ 0 ] ) ) {
16158					continue;
16159				}
16160
16161				innermostContainer = this.containers[ i ];
16162				innermostIndex = i;
16163
16164			} else {
16165
16166				// container doesn't intersect. trigger "out" event if necessary
16167				if ( this.containers[ i ].containerCache.over ) {
16168					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16169					this.containers[ i ].containerCache.over = 0;
16170				}
16171			}
16172
16173		}
16174
16175		// If no intersecting containers found, return
16176		if ( !innermostContainer ) {
16177			return;
16178		}
16179
16180		// Move the item into the container if it's not there already
16181		if ( this.containers.length === 1 ) {
16182			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16183				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16184				this.containers[ innermostIndex ].containerCache.over = 1;
16185			}
16186		} else {
16187
16188			// When entering a new container, we will find the item with the least distance and
16189			// append our item near it
16190			dist = 10000;
16191			itemWithLeastDistance = null;
16192			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16193			posProperty = floating ? "left" : "top";
16194			sizeProperty = floating ? "width" : "height";
16195			axis = floating ? "pageX" : "pageY";
16196
16197			for ( j = this.items.length - 1; j >= 0; j-- ) {
16198				if ( !$.contains(
16199						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16200				) {
16201					continue;
16202				}
16203				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16204					continue;
16205				}
16206
16207				cur = this.items[ j ].item.offset()[ posProperty ];
16208				nearBottom = false;
16209				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16210					nearBottom = true;
16211				}
16212
16213				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16214					dist = Math.abs( event[ axis ] - cur );
16215					itemWithLeastDistance = this.items[ j ];
16216					this.direction = nearBottom ? "up" : "down";
16217				}
16218			}
16219
16220			//Check if dropOnEmpty is enabled
16221			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16222				return;
16223			}
16224
16225			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16226				if ( !this.currentContainer.containerCache.over ) {
16227					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16228					this.currentContainer.containerCache.over = 1;
16229				}
16230				return;
16231			}
16232
16233			itemWithLeastDistance ?
16234				this._rearrange( event, itemWithLeastDistance, null, true ) :
16235				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16236			this._trigger( "change", event, this._uiHash() );
16237			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16238			this.currentContainer = this.containers[ innermostIndex ];
16239
16240			//Update the placeholder
16241			this.options.placeholder.update( this.currentContainer, this.placeholder );
16242
16243			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16244			this.containers[ innermostIndex ].containerCache.over = 1;
16245		}
16246
16247	},
16248
16249	_createHelper: function( event ) {
16250
16251		var o = this.options,
16252			helper = $.isFunction( o.helper ) ?
16253				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16254				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16255
16256		//Add the helper to the DOM if that didn't happen already
16257		if ( !helper.parents( "body" ).length ) {
16258			$( o.appendTo !== "parent" ?
16259				o.appendTo :
16260				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16261		}
16262
16263		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16264			this._storedCSS = {
16265				width: this.currentItem[ 0 ].style.width,
16266				height: this.currentItem[ 0 ].style.height,
16267				position: this.currentItem.css( "position" ),
16268				top: this.currentItem.css( "top" ),
16269				left: this.currentItem.css( "left" )
16270			};
16271		}
16272
16273		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16274			helper.width( this.currentItem.width() );
16275		}
16276		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16277			helper.height( this.currentItem.height() );
16278		}
16279
16280		return helper;
16281
16282	},
16283
16284	_adjustOffsetFromHelper: function( obj ) {
16285		if ( typeof obj === "string" ) {
16286			obj = obj.split( " " );
16287		}
16288		if ( $
vendor: 9,476 bytes, lines 16288-16568
16288.isArray( obj ) ) {
16289			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16290		}
16291		if ( "left" in obj ) {
16292			this.offset.click.left = obj.left + this.margins.left;
16293		}
16294		if ( "right" in obj ) {
16295			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16296		}
16297		if ( "top" in obj ) {
16298			this.offset.click.top = obj.top + this.margins.top;
16299		}
16300		if ( "bottom" in obj ) {
16301			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16302		}
16303	},
16304
16305	_getParentOffset: function() {
16306
16307		//Get the offsetParent and cache its position
16308		this.offsetParent = this.helper.offsetParent();
16309		var po = this.offsetParent.offset();
16310
16311		// This is a special case where we need to modify a offset calculated on start, since the
16312		// following happened:
16313		// 1. The position of the helper is absolute, so it's position is calculated based on the
16314		// next positioned parent
16315		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16316		// the document, which means that the scroll is included in the initial calculation of the
16317		// offset of the parent, and never recalculated upon drag
16318		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16319				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16320			po.left += this.scrollParent.scrollLeft();
16321			po.top += this.scrollParent.scrollTop();
16322		}
16323
16324		// This needs to be actually done for all browsers, since pageX/pageY includes this
16325		// information with an ugly IE fix
16326		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16327				( this.offsetParent[ 0 ].tagName &&
16328				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16329			po = { top: 0, left: 0 };
16330		}
16331
16332		return {
16333			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16334			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16335		};
16336
16337	},
16338
16339	_getRelativeOffset: function() {
16340
16341		if ( this.cssPosition === "relative" ) {
16342			var p = this.currentItem.position();
16343			return {
16344				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16345					this.scrollParent.scrollTop(),
16346				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16347					this.scrollParent.scrollLeft()
16348			};
16349		} else {
16350			return { top: 0, left: 0 };
16351		}
16352
16353	},
16354
16355	_cacheMargins: function() {
16356		this.margins = {
16357			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16358			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16359		};
16360	},
16361
16362	_cacheHelperProportions: function() {
16363		this.helperProportions = {
16364			width: this.helper.outerWidth(),
16365			height: this.helper.outerHeight()
16366		};
16367	},
16368
16369	_setContainment: function() {
16370
16371		var ce, co, over,
16372			o = this.options;
16373		if ( o.containment === "parent" ) {
16374			o.containment = this.helper[ 0 ].parentNode;
16375		}
16376		if ( o.containment === "document" || o.containment === "window" ) {
16377			this.containment = [
16378				0 - this.offset.relative.left - this.offset.parent.left,
16379				0 - this.offset.relative.top - this.offset.parent.top,
16380				o.containment === "document" ?
16381					this.document.width() :
16382					this.window.width() - this.helperProportions.width - this.margins.left,
16383				( o.containment === "document" ?
16384					( this.document.height() || document.body.parentNode.scrollHeight ) :
16385					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16386				) - this.helperProportions.height - this.margins.top
16387			];
16388		}
16389
16390		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16391			ce = $( o.containment )[ 0 ];
16392			co = $( o.containment ).offset();
16393			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16394
16395			this.containment = [
16396				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16397					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16398				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16399					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16400				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16401					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16402					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16403					this.helperProportions.width - this.margins.left,
16404				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16405					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16406					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16407					this.helperProportions.height - this.margins.top
16408			];
16409		}
16410
16411	},
16412
16413	_convertPositionTo: function( d, pos ) {
16414
16415		if ( !pos ) {
16416			pos = this.position;
16417		}
16418		var mod = d === "absolute" ? 1 : -1,
16419			scroll = this.cssPosition === "absolute" &&
16420				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16421				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16422					this.offsetParent :
16423					this.scrollParent,
16424			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16425
16426		return {
16427			top: (
16428
16429				// The absolute mouse position
16430				pos.top	+
16431
16432				// Only for relative positioned nodes: Relative offset from element to offset parent
16433				this.offset.relative.top * mod +
16434
16435				// The offsetParent's offset without borders (offset + border)
16436				this.offset.parent.top * mod -
16437				( ( this.cssPosition === "fixed" ?
16438					-this.scrollParent.scrollTop() :
16439					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16440			),
16441			left: (
16442
16443				// The absolute mouse position
16444				pos.left +
16445
16446				// Only for relative positioned nodes: Relative offset from element to offset parent
16447				this.offset.relative.left * mod +
16448
16449				// The offsetParent's offset without borders (offset + border)
16450				this.offset.parent.left * mod	-
16451				( ( this.cssPosition === "fixed" ?
16452					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16453					scroll.scrollLeft() ) * mod )
16454			)
16455		};
16456
16457	},
16458
16459	_generatePosition: function( event ) {
16460
16461		var top, left,
16462			o = this.options,
16463			pageX = event.pageX,
16464			pageY = event.pageY,
16465			scroll = this.cssPosition === "absolute" &&
16466				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16467				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16468					this.offsetParent :
16469					this.scrollParent,
16470				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16471
16472		// This is another very weird special case that only happens for relative elements:
16473		// 1. If the css position is relative
16474		// 2. and the scroll parent is the document or similar to the offset parent
16475		// we have to refresh the relative offset during the scroll so there are no jumps
16476		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16477				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16478			this.offset.relative = this._getRelativeOffset();
16479		}
16480
16481		/*
16482		 * - Position constraining -
16483		 * Constrain the position to a mix of grid, containment.
16484		 */
16485
16486		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16487
16488			if ( this.containment ) {
16489				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16490					pageX = this.containment[ 0 ] + this.offset.click.left;
16491				}
16492				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16493					pageY = this.containment[ 1 ] + this.offset.click.top;
16494				}
16495				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16496					pageX = this.containment[ 2 ] + this.offset.click.left;
16497				}
16498				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16499					pageY = this.containment[ 3 ] + this.offset.click.top;
16500				}
16501			}
16502
16503			if ( o.grid ) {
16504				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16505					o.grid[ 1 ] ) * o.grid[ 1 ];
16506				pageY = this.containment ?
16507					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16508						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16509							top :
16510							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16511								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16512								top;
16513
16514				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16515					o.grid[ 0 ] ) * o.grid[ 0 ];
16516				pageX = this.containment ?
16517					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16518						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16519							left :
16520							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16521								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16522								left;
16523			}
16524
16525		}
16526
16527		return {
16528			top: (
16529
16530				// The absolute mouse position
16531				pageY -
16532
16533				// Click offset (relative to the element)
16534				this.offset.click.top -
16535
16536				// Only for relative positioned nodes: Relative offset from element to offset parent
16537				this.offset.relative.top -
16538
16539				// The offsetParent's offset without borders (offset + border)
16540				this.offset.parent.top +
16541				( ( this.cssPosition === "fixed" ?
16542					-this.scrollParent.scrollTop() :
16543					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16544			),
16545			left: (
16546
16547				// The absolute mouse position
16548				pageX -
16549
16550				// Click offset (relative to the element)
16551				this.offset.click.left -
16552
16553				// Only for relative positioned nodes: Relative offset from element to offset parent
16554				this.offset.relative.left -
16555
16556				// The offsetParent's offset without borders (offset + border)
16557				this.offset.parent.left +
16558				( ( this.cssPosition === "fixed" ?
16559					-this.scrollParent.scrollLeft() :
16560					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16561			)
16562		};
16563
16564	},
16565
16566	_rearrange: function( event, i, a, hardRefresh ) {
16567
16568		
16568a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16569			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16570				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
vendor: 5,013 bytes, lines 16570-16738
16570
16571
16572		//Various things done here to improve the performance:
16573		// 1. we create a setTimeout, that calls refreshPositions
16574		// 2. on the instance, we have a counter variable, that get's higher after every append
16575		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16576		// if it's still the same
16577		// 4. this lets only the last addition to the timeout stack through
16578		this.counter = this.counter ? ++this.counter : 1;
16579		var counter = this.counter;
16580
16581		this._delay( function() {
16582			if ( counter === this.counter ) {
16583
16584				//Precompute after each DOM insertion, NOT on mousemove
16585				this.refreshPositions( !hardRefresh );
16586			}
16587		} );
16588
16589	},
16590
16591	_clear: function( event, noPropagation ) {
16592
16593		this.reverting = false;
16594
16595		// We delay all events that have to be triggered to after the point where the placeholder
16596		// has been removed and everything else normalized again
16597		var i,
16598			delayedTriggers = [];
16599
16600		// We first have to update the dom position of the actual currentItem
16601		// Note: don't do it if the current item is already removed (by a user), or it gets
16602		// reappended (see #4088)
16603		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16604			this.placeholder.before( this.currentItem );
16605		}
16606		this._noFinalSort = null;
16607
16608		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16609			for ( i in this._storedCSS ) {
16610				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16611					this._storedCSS[ i ] = "";
16612				}
16613			}
16614			this.currentItem.css( this._storedCSS );
16615			this._removeClass( this.currentItem, "ui-sortable-helper" );
16616		} else {
16617			this.currentItem.show();
16618		}
16619
16620		if ( this.fromOutside && !noPropagation ) {
16621			delayedTriggers.push( function( event ) {
16622				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16623			} );
16624		}
16625		if ( ( this.fromOutside ||
16626				this.domPosition.prev !==
16627				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16628				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16629
16630			// Trigger update callback if the DOM position has changed
16631			delayedTriggers.push( function( event ) {
16632				this._trigger( "update", event, this._uiHash() );
16633			} );
16634		}
16635
16636		// Check if the items Container has Changed and trigger appropriate
16637		// events.
16638		if ( this !== this.currentContainer ) {
16639			if ( !noPropagation ) {
16640				delayedTriggers.push( function( event ) {
16641					this._trigger( "remove", event, this._uiHash() );
16642				} );
16643				delayedTriggers.push( ( function( c ) {
16644					return function( event ) {
16645						c._trigger( "receive", event, this._uiHash( this ) );
16646					};
16647				} ).call( this, this.currentContainer ) );
16648				delayedTriggers.push( ( function( c ) {
16649					return function( event ) {
16650						c._trigger( "update", event, this._uiHash( this ) );
16651					};
16652				} ).call( this, this.currentContainer ) );
16653			}
16654		}
16655
16656		//Post events to containers
16657		function delayEvent( type, instance, container ) {
16658			return function( event ) {
16659				container._trigger( type, event, instance._uiHash( instance ) );
16660			};
16661		}
16662		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16663			if ( !noPropagation ) {
16664				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16665			}
16666			if ( this.containers[ i ].containerCache.over ) {
16667				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16668				this.containers[ i ].containerCache.over = 0;
16669			}
16670		}
16671
16672		//Do what was originally in plugins
16673		if ( this.storedCursor ) {
16674			this.document.find( "body" ).css( "cursor", this.storedCursor );
16675			this.storedStylesheet.remove();
16676		}
16677		if ( this._storedOpacity ) {
16678			this.helper.css( "opacity", this._storedOpacity );
16679		}
16680		if ( this._storedZIndex ) {
16681			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16682		}
16683
16684		this.dragging = false;
16685
16686		if ( !noPropagation ) {
16687			this._trigger( "beforeStop", event, this._uiHash() );
16688		}
16689
16690		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16691		// it unbinds ALL events from the original node!
16692		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16693
16694		if ( !this.cancelHelperRemoval ) {
16695			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16696				this.helper.remove();
16697			}
16698			this.helper = null;
16699		}
16700
16701		if ( !noPropagation ) {
16702			for ( i = 0; i < delayedTriggers.length; i++ ) {
16703
16704				// Trigger all delayed events
16705				delayedTriggers[ i ].call( this, event );
16706			}
16707			this._trigger( "stop", event, this._uiHash() );
16708		}
16709
16710		this.fromOutside = false;
16711		return !this.cancelHelperRemoval;
16712
16713	},
16714
16715	_trigger: function() {
16716		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16717			this.cancel();
16718		}
16719	},
16720
16721	_uiHash: function( _inst ) {
16722		var inst = _inst || this;
16723		return {
16724			helper: inst.helper,
16725			placeholder: inst.placeholder || $( [] ),
16726			position: inst.position,
16727			originalPosition: inst.originalPosition,
16728			offset: inst.positionAbs,
16729			item: inst.currentItem,
16730			sender: _inst ? _inst.element : null
16731		};
16732	}
16733
16734} );
16735
16736
16737/*!
16738 * jQuery UI Spinner 1.1
vendor: 26,644 bytes, lines 16738-17782
167382.1
16739 * http://jqueryui.com
16740 *
16741 * Copyright jQuery Foundation and other contributors
16742 * Released under the MIT license.
16743 * http://jquery.org/license
16744 */
16745
16746//>>label: Spinner
16747//>>group: Widgets
16748//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16749//>>docs: http://api.jqueryui.com/spinner/
16750//>>demos: http://jqueryui.com/spinner/
16751//>>css.structure: ../../themes/base/core.css
16752//>>css.structure: ../../themes/base/spinner.css
16753//>>css.theme: ../../themes/base/theme.css
16754
16755
16756
16757function spinnerModifer( fn ) {
16758	return function() {
16759		var previous = this.element.val();
16760		fn.apply( this, arguments );
16761		this._refresh();
16762		if ( previous !== this.element.val() ) {
16763			this._trigger( "change" );
16764		}
16765	};
16766}
16767
16768$.widget( "ui.spinner", {
16769	version: "1.12.1",
16770	defaultElement: "<input>",
16771	widgetEventPrefix: "spin",
16772	options: {
16773		classes: {
16774			"ui-spinner": "ui-corner-all",
16775			"ui-spinner-down": "ui-corner-br",
16776			"ui-spinner-up": "ui-corner-tr"
16777		},
16778		culture: null,
16779		icons: {
16780			down: "ui-icon-triangle-1-s",
16781			up: "ui-icon-triangle-1-n"
16782		},
16783		incremental: true,
16784		max: null,
16785		min: null,
16786		numberFormat: null,
16787		page: 10,
16788		step: 1,
16789
16790		change: null,
16791		spin: null,
16792		start: null,
16793		stop: null
16794	},
16795
16796	_create: function() {
16797
16798		// handle string values that need to be parsed
16799		this._setOption( "max", this.options.max );
16800		this._setOption( "min", this.options.min );
16801		this._setOption( "step", this.options.step );
16802
16803		// Only format if there is a value, prevents the field from being marked
16804		// as invalid in Firefox, see #9573.
16805		if ( this.value() !== "" ) {
16806
16807			// Format the value, but don't constrain.
16808			this._value( this.element.val(), true );
16809		}
16810
16811		this._draw();
16812		this._on( this._events );
16813		this._refresh();
16814
16815		// Turning off autocomplete prevents the browser from remembering the
16816		// value when navigating through history, so we re-enable autocomplete
16817		// if the page is unloaded before the widget is destroyed. #7790
16818		this._on( this.window, {
16819			beforeunload: function() {
16820				this.element.removeAttr( "autocomplete" );
16821			}
16822		} );
16823	},
16824
16825	_getCreateOptions: function() {
16826		var options = this._super();
16827		var element = this.element;
16828
16829		$.each( [ "min", "max", "step" ], function( i, option ) {
16830			var value = element.attr( option );
16831			if ( value != null && value.length ) {
16832				options[ option ] = value;
16833			}
16834		} );
16835
16836		return options;
16837	},
16838
16839	_events: {
16840		keydown: function( event ) {
16841			if ( this._start( event ) && this._keydown( event ) ) {
16842				event.preventDefault();
16843			}
16844		},
16845		keyup: "_stop",
16846		focus: function() {
16847			this.previous = this.element.val();
16848		},
16849		blur: function( event ) {
16850			if ( this.cancelBlur ) {
16851				delete this.cancelBlur;
16852				return;
16853			}
16854
16855			this._stop();
16856			this._refresh();
16857			if ( this.previous !== this.element.val() ) {
16858				this._trigger( "change", event );
16859			}
16860		},
16861		mousewheel: function( event, delta ) {
16862			if ( !delta ) {
16863				return;
16864			}
16865			if ( !this.spinning && !this._start( event ) ) {
16866				return false;
16867			}
16868
16869			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16870			clearTimeout( this.mousewheelTimer );
16871			this.mousewheelTimer = this._delay( function() {
16872				if ( this.spinning ) {
16873					this._stop( event );
16874				}
16875			}, 100 );
16876			event.preventDefault();
16877		},
16878		"mousedown .ui-spinner-button": function( event ) {
16879			var previous;
16880
16881			// We never want the buttons to have focus; whenever the user is
16882			// interacting with the spinner, the focus should be on the input.
16883			// If the input is focused then this.previous is properly set from
16884			// when the input first received focus. If the input is not focused
16885			// then we need to set this.previous based on the value before spinning.
16886			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16887				this.previous : this.element.val();
16888			function checkFocus() {
16889				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16890				if ( !isActive ) {
16891					this.element.trigger( "focus" );
16892					this.previous = previous;
16893
16894					// support: IE
16895					// IE sets focus asynchronously, so we need to check if focus
16896					// moved off of the input because the user clicked on the button.
16897					this._delay( function() {
16898						this.previous = previous;
16899					} );
16900				}
16901			}
16902
16903			// Ensure focus is on (or stays on) the text field
16904			event.preventDefault();
16905			checkFocus.call( this );
16906
16907			// Support: IE
16908			// IE doesn't prevent moving focus even with event.preventDefault()
16909			// so we set a flag to know when we should ignore the blur event
16910			// and check (again) if focus moved off of the input.
16911			this.cancelBlur = true;
16912			this._delay( function() {
16913				delete this.cancelBlur;
16914				checkFocus.call( this );
16915			} );
16916
16917			if ( this._start( event ) === false ) {
16918				return;
16919			}
16920
16921			this._repeat( null, $( event.currentTarget )
16922				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16923		},
16924		"mouseup .ui-spinner-button": "_stop",
16925		"mouseenter .ui-spinner-button": function( event ) {
16926
16927			// button will add ui-state-active if mouse was down while mouseleave and kept down
16928			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16929				return;
16930			}
16931
16932			if ( this._start( event ) === false ) {
16933				return false;
16934			}
16935			this._repeat( null, $( event.currentTarget )
16936				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16937		},
16938
16939		// TODO: do we really want to consider this a stop?
16940		// shouldn't we just stop the repeater and wait until mouseup before
16941		// we trigger the stop event?
16942		"mouseleave .ui-spinner-button": "_stop"
16943	},
16944
16945	// Support mobile enhanced option and make backcompat more sane
16946	_enhance: function() {
16947		this.uiSpinner = this.element
16948			.attr( "autocomplete", "off" )
16949			.wrap( "<span>" )
16950			.parent()
16951
16952				// Add buttons
16953				.append(
16954					"<a></a><a></a>"
16955				);
16956	},
16957
16958	_draw: function() {
16959		this._enhance();
16960
16961		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16962		this._addClass( "ui-spinner-input" );
16963
16964		this.element.attr( "role", "spinbutton" );
16965
16966		// Button bindings
16967		this.buttons = this.uiSpinner.children( "a" )
16968			.attr( "tabIndex", -1 )
16969			.attr( "aria-hidden", true )
16970			.button( {
16971				classes: {
16972					"ui-button": ""
16973				}
16974			} );
16975
16976		// TODO: Right now button does not support classes this is already updated in button PR
16977		this._removeClass( this.buttons, "ui-corner-all" );
16978
16979		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16980		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16981		this.buttons.first().button( {
16982			"icon": this.options.icons.up,
16983			"showLabel": false
16984		} );
16985		this.buttons.last().button( {
16986			"icon": this.options.icons.down,
16987			"showLabel": false
16988		} );
16989
16990		// IE 6 doesn't understand height: 50% for the buttons
16991		// unless the wrapper has an explicit height
16992		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16993				this.uiSpinner.height() > 0 ) {
16994			this.uiSpinner.height( this.uiSpinner.height() );
16995		}
16996	},
16997
16998	_keydown: function( event ) {
16999		var options = this.options,
17000			keyCode = $.ui.keyCode;
17001
17002		switch ( event.keyCode ) {
17003		case keyCode.UP:
17004			this._repeat( null, 1, event );
17005			return true;
17006		case keyCode.DOWN:
17007			this._repeat( null, -1, event );
17008			return true;
17009		case keyCode.PAGE_UP:
17010			this._repeat( null, options.page, event );
17011			return true;
17012		case keyCode.PAGE_DOWN:
17013			this._repeat( null, -options.page, event );
17014			return true;
17015		}
17016
17017		return false;
17018	},
17019
17020	_start: function( event ) {
17021		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17022			return false;
17023		}
17024
17025		if ( !this.counter ) {
17026			this.counter = 1;
17027		}
17028		this.spinning = true;
17029		return true;
17030	},
17031
17032	_repeat: function( i, steps, event ) {
17033		i = i || 500;
17034
17035		clearTimeout( this.timer );
17036		this.timer = this._delay( function() {
17037			this._repeat( 40, steps, event );
17038		}, i );
17039
17040		this._spin( steps * this.options.step, event );
17041	},
17042
17043	_spin: function( step, event ) {
17044		var value = this.value() || 0;
17045
17046		if ( !this.counter ) {
17047			this.counter = 1;
17048		}
17049
17050		value = this._adjustValue( value + step * this._increment( this.counter ) );
17051
17052		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17053			this._value( value );
17054			this.counter++;
17055		}
17056	},
17057
17058	_increment: function( i ) {
17059		var incremental = this.options.incremental;
17060
17061		if ( incremental ) {
17062			return $.isFunction( incremental ) ?
17063				incremental( i ) :
17064				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17065		}
17066
17067		return 1;
17068	},
17069
17070	_precision: function() {
17071		var precision = this._precisionOf( this.options.step );
17072		if ( this.options.min !== null ) {
17073			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17074		}
17075		return precision;
17076	},
17077
17078	_precisionOf: function( num ) {
17079		var str = num.toString(),
17080			decimal = str.indexOf( "." );
17081		return decimal === -1 ? 0 : str.length - decimal - 1;
17082	},
17083
17084	_adjustValue: function( value ) {
17085		var base, aboveMin,
17086			options = this.options;
17087
17088		// Make sure we're at a valid step
17089		// - find out where we are relative to the base (min or 0)
17090		base = options.min !== null ? options.min : 0;
17091		aboveMin = value - base;
17092
17093		// - round to the nearest step
17094		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17095
17096		// - rounding is based on 0, so adjust back to our base
17097		value = base + aboveMin;
17098
17099		// Fix precision from bad JS floating point math
17100		value = parseFloat( value.toFixed( this._precision() ) );
17101
17102		// Clamp the value
17103		if ( options.max !== null && value > options.max ) {
17104			return options.max;
17105		}
17106		if ( options.min !== null && value < options.min ) {
17107			return options.min;
17108		}
17109
17110		return value;
17111	},
17112
17113	_stop: function( event ) {
17114		if ( !this.spinning ) {
17115			return;
17116		}
17117
17118		clearTimeout( this.timer );
17119		clearTimeout( this.mousewheelTimer );
17120		this.counter = 0;
17121		this.spinning = false;
17122		this._trigger( "stop", event );
17123	},
17124
17125	_setOption: function( key, value ) {
17126		var prevValue, first, last;
17127
17128		if ( key === "culture" || key === "numberFormat" ) {
17129			prevValue = this._parse( this.element.val() );
17130			this.options[ key ] = value;
17131			this.element.val( this._format( prevValue ) );
17132			return;
17133		}
17134
17135		if ( key === "max" || key === "min" || key === "step" ) {
17136			if ( typeof value === "string" ) {
17137				value = this._parse( value );
17138			}
17139		}
17140		if ( key === "icons" ) {
17141			first = this.buttons.first().find( ".ui-icon" );
17142			this._removeClass( first, null, this.options.icons.up );
17143			this._addClass( first, null, value.up );
17144			last = this.buttons.last().find( ".ui-icon" );
17145			this._removeClass( last, null, this.options.icons.down );
17146			this._addClass( last, null, value.down );
17147		}
17148
17149		this._super( key, value );
17150	},
17151
17152	_setOptionDisabled: function( value ) {
17153		this._super( value );
17154
17155		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17156		this.element.prop( "disabled", !!value );
17157		this.buttons.button( value ? "disable" : "enable" );
17158	},
17159
17160	_setOptions: spinnerModifer( function( options ) {
17161		this._super( options );
17162	} ),
17163
17164	_parse: function( val ) {
17165		if ( typeof val === "string" && val !== "" ) {
17166			val = window.Globalize && this.options.numberFormat ?
17167				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17168		}
17169		return val === "" || isNaN( val ) ? null : val;
17170	},
17171
17172	_format: function( value ) {
17173		if ( value === "" ) {
17174			return "";
17175		}
17176		return window.Globalize && this.options.numberFormat ?
17177			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17178			value;
17179	},
17180
17181	_refresh: function() {
17182		this.element.attr( {
17183			"aria-valuemin": this.options.min,
17184			"aria-valuemax": this.options.max,
17185
17186			// TODO: what should we do with values that can't be parsed?
17187			"aria-valuenow": this._parse( this.element.val() )
17188		} );
17189	},
17190
17191	isValid: function() {
17192		var value = this.value();
17193
17194		// Null is invalid
17195		if ( value === null ) {
17196			return false;
17197		}
17198
17199		// If value gets adjusted, it's invalid
17200		return value === this._adjustValue( value );
17201	},
17202
17203	// Update the value without triggering change
17204	_value: function( value, allowAny ) {
17205		var parsed;
17206		if ( value !== "" ) {
17207			parsed = this._parse( value );
17208			if ( parsed !== null ) {
17209				if ( !allowAny ) {
17210					parsed = this._adjustValue( parsed );
17211				}
17212				value = this._format( parsed );
17213			}
17214		}
17215		this.element.val( value );
17216		this._refresh();
17217	},
17218
17219	_destroy: function() {
17220		this.element
17221			.prop( "disabled", false )
17222			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17223
17224		this.uiSpinner.replaceWith( this.element );
17225	},
17226
17227	stepUp: spinnerModifer( function( steps ) {
17228		this._stepUp( steps );
17229	} ),
17230	_stepUp: function( steps ) {
17231		if ( this._start() ) {
17232			this._spin( ( steps || 1 ) * this.options.step );
17233			this._stop();
17234		}
17235	},
17236
17237	stepDown: spinnerModifer( function( steps ) {
17238		this._stepDown( steps );
17239	} ),
17240	_stepDown: function( steps ) {
17241		if ( this._start() ) {
17242			this._spin( ( steps || 1 ) * -this.options.step );
17243			this._stop();
17244		}
17245	},
17246
17247	pageUp: spinnerModifer( function( pages ) {
17248		this._stepUp( ( pages || 1 ) * this.options.page );
17249	} ),
17250
17251	pageDown: spinnerModifer( function( pages ) {
17252		this._stepDown( ( pages || 1 ) * this.options.page );
17253	} ),
17254
17255	value: function( newVal ) {
17256		if ( !arguments.length ) {
17257			return this._parse( this.element.val() );
17258		}
17259		spinnerModifer( this._value ).call( this, newVal );
17260	},
17261
17262	widget: function() {
17263		return this.uiSpinner;
17264	}
17265} );
17266
17267// DEPRECATED
17268// TODO: switch return back to widget declaration at top of file when this is removed
17269if ( $.uiBackCompat !== false ) {
17270
17271	// Backcompat for spinner html extension points
17272	$.widget( "ui.spinner", $.ui.spinner, {
17273		_enhance: function() {
17274			this.uiSpinner = this.element
17275				.attr( "autocomplete", "off" )
17276				.wrap( this._uiSpinnerHtml() )
17277				.parent()
17278
17279					// Add buttons
17280					.append( this._buttonHtml() );
17281		},
17282		_uiSpinnerHtml: function() {
17283			return "<span>";
17284		},
17285
17286		_buttonHtml: function() {
17287			return "<a></a><a></a>";
17288		}
17289	} );
17290}
17291
17292var widgetsSpinner = $.ui.spinner;
17293
17294
17295/*!
17296 * jQuery UI Tabs 1.12.1
17297 * http://jqueryui.com
17298 *
17299 * Copyright jQuery Foundation and other contributors
17300 * Released under the MIT license.
17301 * http://jquery.org/license
17302 */
17303
17304//>>label: Tabs
17305//>>group: Widgets
17306//>>description: Transforms a set of container elements into a tab structure.
17307//>>docs: http://api.jqueryui.com/tabs/
17308//>>demos: http://jqueryui.com/tabs/
17309//>>css.structure: ../../themes/base/core.css
17310//>>css.structure: ../../themes/base/tabs.css
17311//>>css.theme: ../../themes/base/theme.css
17312
17313
17314
17315$.widget( "ui.tabs", {
17316	version: "1.12.1",
17317	delay: 300,
17318	options: {
17319		active: null,
17320		classes: {
17321			"ui-tabs": "ui-corner-all",
17322			"ui-tabs-nav": "ui-corner-all",
17323			"ui-tabs-panel": "ui-corner-bottom",
17324			"ui-tabs-tab": "ui-corner-top"
17325		},
17326		collapsible: false,
17327		event: "click",
17328		heightStyle: "content",
17329		hide: null,
17330		show: null,
17331
17332		// Callbacks
17333		activate: null,
17334		beforeActivate: null,
17335		beforeLoad: null,
17336		load: null
17337	},
17338
17339	_isLocal: ( function() {
17340		var rhash = /#.*$/;
17341
17342		return function( anchor ) {
17343			var anchorUrl, locationUrl;
17344
17345			anchorUrl = anchor.href.replace( rhash, "" );
17346			locationUrl = location.href.replace( rhash, "" );
17347
17348			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17349			try {
17350				anchorUrl = decodeURIComponent( anchorUrl );
17351			} catch ( error ) {}
17352			try {
17353				locationUrl = decodeURIComponent( locationUrl );
17354			} catch ( error ) {}
17355
17356			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17357		};
17358	} )(),
17359
17360	_create: function() {
17361		var that = this,
17362			options = this.options;
17363
17364		this.running = false;
17365
17366		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17367		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17368
17369		this._processTabs();
17370		options.active = this._initialActive();
17371
17372		// Take disabling tabs via class attribute from HTML
17373		// into account and update option properly.
17374		if ( $.isArray( options.disabled ) ) {
17375			options.disabled = $.unique( options.disabled.concat(
17376				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17377					return that.tabs.index( li );
17378				} )
17379			) ).sort();
17380		}
17381
17382		// Check for length avoids error when initializing empty list
17383		if ( this.options.active !== false && this.anchors.length ) {
17384			this.active = this._findActive( options.active );
17385		} else {
17386			this.active = $();
17387		}
17388
17389		this._refresh();
17390
17391		if ( this.active.length ) {
17392			this.load( options.active );
17393		}
17394	},
17395
17396	_initialActive: function() {
17397		var active = this.options.active,
17398			collapsible = this.options.collapsible,
17399			locationHash = location.hash.substring( 1 );
17400
17401		if ( active === null ) {
17402
17403			// check the fragment identifier in the URL
17404			if ( locationHash ) {
17405				this.tabs.each( function( i, tab ) {
17406					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17407						active = i;
17408						return false;
17409					}
17410				} );
17411			}
17412
17413			// Check for a tab marked active via a class
17414			if ( active === null ) {
17415				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17416			}
17417
17418			// No active tab, set to false
17419			if ( active === null || active === -1 ) {
17420				active = this.tabs.length ? 0 : false;
17421			}
17422		}
17423
17424		// Handle numbers: negative, out of range
17425		if ( active !== false ) {
17426			active = this.tabs.index( this.tabs.eq( active ) );
17427			if ( active === -1 ) {
17428				active = collapsible ? false : 0;
17429			}
17430		}
17431
17432		// Don't allow collapsible: false and active: false
17433		if ( !collapsible && active === false && this.anchors.length ) {
17434			active = 0;
17435		}
17436
17437		return active;
17438	},
17439
17440	_getCreateEventData: function() {
17441		return {
17442			tab: this.active,
17443			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17444		};
17445	},
17446
17447	_tabKeydown: function( event ) {
17448		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17449			selectedIndex = this.tabs.index( focusedTab ),
17450			goingForward = true;
17451
17452		if ( this._handlePageNav( event ) ) {
17453			return;
17454		}
17455
17456		switch ( event.keyCode ) {
17457		case $.ui.keyCode.RIGHT:
17458		case $.ui.keyCode.DOWN:
17459			selectedIndex++;
17460			break;
17461		case $.ui.keyCode.UP:
17462		case $.ui.keyCode.LEFT:
17463			goingForward = false;
17464			selectedIndex--;
17465			break;
17466		case $.ui.keyCode.END:
17467			selectedIndex = this.anchors.length - 1;
17468			break;
17469		case $.ui.keyCode.HOME:
17470			selectedIndex = 0;
17471			break;
17472		case $.ui.keyCode.SPACE:
17473
17474			// Activate only, no collapsing
17475			event.preventDefault();
17476			clearTimeout( this.activating );
17477			this._activate( selectedIndex );
17478			return;
17479		case $.ui.keyCode.ENTER:
17480
17481			// Toggle (cancel delayed activation, allow collapsing)
17482			event.preventDefault();
17483			clearTimeout( this.activating );
17484
17485			// Determine if we should collapse or activate
17486			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17487			return;
17488		default:
17489			return;
17490		}
17491
17492		// Focus the appropriate tab, based on which key was pressed
17493		event.preventDefault();
17494		clearTimeout( this.activating );
17495		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17496
17497		// Navigating with control/command key will prevent automatic activation
17498		if ( !event.ctrlKey && !event.metaKey ) {
17499
17500			// Update aria-selected immediately so that AT think the tab is already selected.
17501			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17502			// but the tab will already be activated by the time the announcement finishes.
17503			focusedTab.attr( "aria-selected", "false" );
17504			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17505
17506			this.activating = this._delay( function() {
17507				this.option( "active", selectedIndex );
17508			}, this.delay );
17509		}
17510	},
17511
17512	_panelKeydown: function( event ) {
17513		if ( this._handlePageNav( event ) ) {
17514			return;
17515		}
17516
17517		// Ctrl+up moves focus to the current tab
17518		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17519			event.preventDefault();
17520			this.active.trigger( "focus" );
17521		}
17522	},
17523
17524	// Alt+page up/down moves focus to the previous/next tab (and activates)
17525	_handlePageNav: function( event ) {
17526		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17527			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17528			return true;
17529		}
17530		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17531			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17532			return true;
17533		}
17534	},
17535
17536	_findNextTab: function( index, goingForward ) {
17537		var lastTabIndex = this.tabs.length - 1;
17538
17539		function constrain() {
17540			if ( index > lastTabIndex ) {
17541				index = 0;
17542			}
17543			if ( index < 0 ) {
17544				index = lastTabIndex;
17545			}
17546			return index;
17547		}
17548
17549		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17550			index = goingForward ? index + 1 : index - 1;
17551		}
17552
17553		return index;
17554	},
17555
17556	_focusNextTab: function( index, goingForward ) {
17557		index = this._findNextTab( index, goingForward );
17558		this.tabs.eq( index ).trigger( "focus" );
17559		return index;
17560	},
17561
17562	_setOption: function( key, value ) {
17563		if ( key === "active" ) {
17564
17565			// _activate() will handle invalid values and update this.options
17566			this._activate( value );
17567			return;
17568		}
17569
17570		this._super( key, value );
17571
17572		if ( key === "collapsible" ) {
17573			this._toggleClass( "ui-tabs-collapsible", null, value );
17574
17575			// Setting collapsible: false while collapsed; open first panel
17576			if ( !value && this.options.active === false ) {
17577				this._activate( 0 );
17578			}
17579		}
17580
17581		if ( key === "event" ) {
17582			this._setupEvents( value );
17583		}
17584
17585		if ( key === "heightStyle" ) {
17586			this._setupHeightStyle( value );
17587		}
17588	},
17589
17590	_sanitizeSelector: function( hash ) {
17591		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17592	},
17593
17594	refresh: function() {
17595		var options = this.options,
17596			lis = this.tablist.children( ":has(a[href])" );
17597
17598		// Get disabled tabs from class attribute from HTML
17599		// this will get converted to a boolean if needed in _refresh()
17600		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17601			return lis.index( tab );
17602		} );
17603
17604		this._processTabs();
17605
17606		// Was collapsed or no tabs
17607		if ( options.active === false || !this.anchors.length ) {
17608			options.active = false;
17609			this.active = $();
17610
17611		// was active, but active tab is gone
17612		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17613
17614			// all remaining tabs are disabled
17615			if ( this.tabs.length === options.disabled.length ) {
17616				options.active = false;
17617				this.active = $();
17618
17619			// activate previous tab
17620			} else {
17621				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17622			}
17623
17624		// was active, active tab still exists
17625		} else {
17626
17627			// make sure active index is correct
17628			options.active = this.tabs.index( this.active );
17629		}
17630
17631		this._refresh();
17632	},
17633
17634	_refresh: function() {
17635		this._setOptionDisabled( this.options.disabled );
17636		this._setupEvents( this.options.event );
17637		this._setupHeightStyle( this.options.heightStyle );
17638
17639		this.tabs.not( this.active ).attr( {
17640			"aria-selected": "false",
17641			"aria-expanded": "false",
17642			tabIndex: -1
17643		} );
17644		this.panels.not( this._getPanelForTab( this.active ) )
17645			.hide()
17646			.attr( {
17647				"aria-hidden": "true"
17648			} );
17649
17650		// Make sure one tab is in the tab order
17651		if ( !this.active.length ) {
17652			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17653		} else {
17654			this.active
17655				.attr( {
17656					"aria-selected": "true",
17657					"aria-expanded": "true",
17658					tabIndex: 0
17659				} );
17660			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17661			this._getPanelForTab( this.active )
17662				.show()
17663				.attr( {
17664					"aria-hidden": "false"
17665				} );
17666		}
17667	},
17668
17669	_processTabs: function() {
17670		var that = this,
17671			prevTabs = this.tabs,
17672			prevAnchors = this.anchors,
17673			prevPanels = this.panels;
17674
17675		this.tablist = this._getList().attr( "role", "tablist" );
17676		this._addClass( this.tablist, "ui-tabs-nav",
17677			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17678
17679		// Prevent users from focusing disabled tabs via click
17680		this.tablist
17681			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17682				if ( $( this ).is( ".ui-state-disabled" ) ) {
17683					event.preventDefault();
17684				}
17685			} )
17686
17687			// Support: IE <9
17688			// Preventing the default action in mousedown doesn't prevent IE
17689			// from focusing the element, so if the anchor gets focused, blur.
17690			// We don't have to worry about focusing the previously focused
17691			// element since clicking on a non-focusable element should focus
17692			// the body anyway.
17693			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17694				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17695					this.blur();
17696				}
17697			} );
17698
17699		this.tabs = this.tablist.find( "> li:has(a[href])" )
17700			.attr( {
17701				role: "tab",
17702				tabIndex: -1
17703			} );
17704		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17705
17706		this.anchors = this.tabs.map( function() {
17707			return $( "a", this )[ 0 ];
17708		} )
17709			.attr( {
17710				role: "presentation",
17711				tabIndex: -1
17712			} );
17713		this._addClass( this.anchors, "ui-tabs-anchor" );
17714
17715		this.panels = $();
17716
17717		this.anchors.each( function( i, anchor ) {
17718			var selector, panel, panelId,
17719				anchorId = $( anchor ).uniqueId().attr( "id" ),
17720				tab = $( anchor ).closest( "li" ),
17721				originalAriaControls = tab.attr( "aria-controls" );
17722
17723			// Inline tab
17724			if ( that._isLocal( anchor ) ) {
17725				selector = anchor.hash;
17726				panelId = selector.substring( 1 );
17727				panel = that.element.find( that._sanitizeSelector( selector ) );
17728
17729			// remote tab
17730			} else {
17731
17732				// If the tab doesn't already have aria-controls,
17733				// generate an id by using a throw-away element
17734				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17735				selector = "#" + panelId;
17736				panel = that.element.find( selector );
17737				if ( !panel.length ) {
17738					panel = that._createPanel( panelId );
17739					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17740				}
17741				panel.attr( "aria-live", "polite" );
17742			}
17743
17744			if ( panel.length ) {
17745				that.panels = that.panels.add( panel );
17746			}
17747			if ( originalAriaControls ) {
17748				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17749			}
17750			tab.attr( {
17751				"aria-controls": panelId,
17752				"aria-labelledby": anchorId
17753			} );
17754			panel.attr( "aria-labelledby", anchorId );
17755		} );
17756
17757		this.panels.attr( "role", "tabpanel" );
17758		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17759
17760		// Avoid memory leaks (#10056)
17761		if ( prevTabs ) {
17762			this._off( prevTabs.not( this.tabs ) );
17763			this._off( prevAnchors.not( this.anchors ) );
17764			this._off( prevPanels.not( this.panels ) );
17765		}
17766	},
17767
17768	// Allow overriding how to find the list for rare usage scenarios (#7715)
17769	_getList: function() {
17770		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17771	},
17772
17773	_createPanel: function( id ) {
17774		return $( "<div>" )
17775			.attr( "id", id )
17776			.data( "ui-tabs-destroy", true );
17777	},
17778
17779	_setOptionDisabled: function( disabled ) {
17780		var currentItem, li, i;
17781
17782		if ( $
vendor: 6,224 bytes, lines 17782-18013
17782.isArray( disabled ) ) {
17783			if ( !disabled.length ) {
17784				disabled = false;
17785			} else if ( disabled.length === this.anchors.length ) {
17786				disabled = true;
17787			}
17788		}
17789
17790		// Disable tabs
17791		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17792			currentItem = $( li );
17793			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17794				currentItem.attr( "aria-disabled", "true" );
17795				this._addClass( currentItem, null, "ui-state-disabled" );
17796			} else {
17797				currentItem.removeAttr( "aria-disabled" );
17798				this._removeClass( currentItem, null, "ui-state-disabled" );
17799			}
17800		}
17801
17802		this.options.disabled = disabled;
17803
17804		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17805			disabled === true );
17806	},
17807
17808	_setupEvents: function( event ) {
17809		var events = {};
17810		if ( event ) {
17811			$.each( event.split( " " ), function( index, eventName ) {
17812				events[ eventName ] = "_eventHandler";
17813			} );
17814		}
17815
17816		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17817
17818		// Always prevent the default action, even when disabled
17819		this._on( true, this.anchors, {
17820			click: function( event ) {
17821				event.preventDefault();
17822			}
17823		} );
17824		this._on( this.anchors, events );
17825		this._on( this.tabs, { keydown: "_tabKeydown" } );
17826		this._on( this.panels, { keydown: "_panelKeydown" } );
17827
17828		this._focusable( this.tabs );
17829		this._hoverable( this.tabs );
17830	},
17831
17832	_setupHeightStyle: function( heightStyle ) {
17833		var maxHeight,
17834			parent = this.element.parent();
17835
17836		if ( heightStyle === "fill" ) {
17837			maxHeight = parent.height();
17838			maxHeight -= this.element.outerHeight() - this.element.height();
17839
17840			this.element.siblings( ":visible" ).each( function() {
17841				var elem = $( this ),
17842					position = elem.css( "position" );
17843
17844				if ( position === "absolute" || position === "fixed" ) {
17845					return;
17846				}
17847				maxHeight -= elem.outerHeight( true );
17848			} );
17849
17850			this.element.children().not( this.panels ).each( function() {
17851				maxHeight -= $( this ).outerHeight( true );
17852			} );
17853
17854			this.panels.each( function() {
17855				$( this ).height( Math.max( 0, maxHeight -
17856					$( this ).innerHeight() + $( this ).height() ) );
17857			} )
17858				.css( "overflow", "auto" );
17859		} else if ( heightStyle === "auto" ) {
17860			maxHeight = 0;
17861			this.panels.each( function() {
17862				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17863			} ).height( maxHeight );
17864		}
17865	},
17866
17867	_eventHandler: function( event ) {
17868		var options = this.options,
17869			active = this.active,
17870			anchor = $( event.currentTarget ),
17871			tab = anchor.closest( "li" ),
17872			clickedIsActive = tab[ 0 ] === active[ 0 ],
17873			collapsing = clickedIsActive && options.collapsible,
17874			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17875			toHide = !active.length ? $() : this._getPanelForTab( active ),
17876			eventData = {
17877				oldTab: active,
17878				oldPanel: toHide,
17879				newTab: collapsing ? $() : tab,
17880				newPanel: toShow
17881			};
17882
17883		event.preventDefault();
17884
17885		if ( tab.hasClass( "ui-state-disabled" ) ||
17886
17887				// tab is already loading
17888				tab.hasClass( "ui-tabs-loading" ) ||
17889
17890				// can't switch durning an animation
17891				this.running ||
17892
17893				// click on active header, but not collapsible
17894				( clickedIsActive && !options.collapsible ) ||
17895
17896				// allow canceling activation
17897				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17898			return;
17899		}
17900
17901		options.active = collapsing ? false : this.tabs.index( tab );
17902
17903		this.active = clickedIsActive ? $() : tab;
17904		if ( this.xhr ) {
17905			this.xhr.abort();
17906		}
17907
17908		if ( !toHide.length && !toShow.length ) {
17909			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17910		}
17911
17912		if ( toShow.length ) {
17913			this.load( this.tabs.index( tab ), event );
17914		}
17915		this._toggle( event, eventData );
17916	},
17917
17918	// Handles show/hide for selecting tabs
17919	_toggle: function( event, eventData ) {
17920		var that = this,
17921			toShow = eventData.newPanel,
17922			toHide = eventData.oldPanel;
17923
17924		this.running = true;
17925
17926		function complete() {
17927			that.running = false;
17928			that._trigger( "activate", event, eventData );
17929		}
17930
17931		function show() {
17932			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17933
17934			if ( toShow.length && that.options.show ) {
17935				that._show( toShow, that.options.show, complete );
17936			} else {
17937				toShow.show();
17938				complete();
17939			}
17940		}
17941
17942		// Start out by hiding, then showing, then completing
17943		if ( toHide.length && this.options.hide ) {
17944			this._hide( toHide, this.options.hide, function() {
17945				that._removeClass( eventData.oldTab.closest( "li" ),
17946					"ui-tabs-active", "ui-state-active" );
17947				show();
17948			} );
17949		} else {
17950			this._removeClass( eventData.oldTab.closest( "li" ),
17951				"ui-tabs-active", "ui-state-active" );
17952			toHide.hide();
17953			show();
17954		}
17955
17956		toHide.attr( "aria-hidden", "true" );
17957		eventData.oldTab.attr( {
17958			"aria-selected": "false",
17959			"aria-expanded": "false"
17960		} );
17961
17962		// If we're switching tabs, remove the old tab from the tab order.
17963		// If we're opening from collapsed state, remove the previous tab from the tab order.
17964		// If we're collapsing, then keep the collapsing tab in the tab order.
17965		if ( toShow.length && toHide.length ) {
17966			eventData.oldTab.attr( "tabIndex", -1 );
17967		} else if ( toShow.length ) {
17968			this.tabs.filter( function() {
17969				return $( this ).attr( "tabIndex" ) === 0;
17970			} )
17971				.attr( "tabIndex", -1 );
17972		}
17973
17974		toShow.attr( "aria-hidden", "false" );
17975		eventData.newTab.attr( {
17976			"aria-selected": "true",
17977			"aria-expanded": "true",
17978			tabIndex: 0
17979		} );
17980	},
17981
17982	_activate: function( index ) {
17983		var anchor,
17984			active = this._findActive( index );
17985
17986		// Trying to activate the already active panel
17987		if ( active[ 0 ] === this.active[ 0 ] ) {
17988			return;
17989		}
17990
17991		// Trying to collapse, simulate a click on the current active header
17992		if ( !active.length ) {
17993			active = this.active;
17994		}
17995
17996		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
17997		this._eventHandler( {
17998			target: anchor,
17999			currentTarget: anchor,
18000			preventDefault: $.noop
18001		} );
18002	},
18003
18004	_findActive: function( index ) {
18005		return index === false ? $() : this.tabs.eq( index );
18006	},
18007
18008	_getIndex: function( index ) {
18009
18010		// meta-function to give users option to provide a href string instead of a numerical index.
18011		if ( typeof index === "string" ) {
18012			index = this.anchors.index( this.anchors.filter( "[href$='" +
18013				$.
vendor: 18,388 bytes, lines 18013-18706
18013ui.escapeSelector( index ) + "']" ) );
18014		}
18015
18016		return index;
18017	},
18018
18019	_destroy: function() {
18020		if ( this.xhr ) {
18021			this.xhr.abort();
18022		}
18023
18024		this.tablist
18025			.removeAttr( "role" )
18026			.off( this.eventNamespace );
18027
18028		this.anchors
18029			.removeAttr( "role tabIndex" )
18030			.removeUniqueId();
18031
18032		this.tabs.add( this.panels ).each( function() {
18033			if ( $.data( this, "ui-tabs-destroy" ) ) {
18034				$( this ).remove();
18035			} else {
18036				$( this ).removeAttr( "role tabIndex " +
18037					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18038			}
18039		} );
18040
18041		this.tabs.each( function() {
18042			var li = $( this ),
18043				prev = li.data( "ui-tabs-aria-controls" );
18044			if ( prev ) {
18045				li
18046					.attr( "aria-controls", prev )
18047					.removeData( "ui-tabs-aria-controls" );
18048			} else {
18049				li.removeAttr( "aria-controls" );
18050			}
18051		} );
18052
18053		this.panels.show();
18054
18055		if ( this.options.heightStyle !== "content" ) {
18056			this.panels.css( "height", "" );
18057		}
18058	},
18059
18060	enable: function( index ) {
18061		var disabled = this.options.disabled;
18062		if ( disabled === false ) {
18063			return;
18064		}
18065
18066		if ( index === undefined ) {
18067			disabled = false;
18068		} else {
18069			index = this._getIndex( index );
18070			if ( $.isArray( disabled ) ) {
18071				disabled = $.map( disabled, function( num ) {
18072					return num !== index ? num : null;
18073				} );
18074			} else {
18075				disabled = $.map( this.tabs, function( li, num ) {
18076					return num !== index ? num : null;
18077				} );
18078			}
18079		}
18080		this._setOptionDisabled( disabled );
18081	},
18082
18083	disable: function( index ) {
18084		var disabled = this.options.disabled;
18085		if ( disabled === true ) {
18086			return;
18087		}
18088
18089		if ( index === undefined ) {
18090			disabled = true;
18091		} else {
18092			index = this._getIndex( index );
18093			if ( $.inArray( index, disabled ) !== -1 ) {
18094				return;
18095			}
18096			if ( $.isArray( disabled ) ) {
18097				disabled = $.merge( [ index ], disabled ).sort();
18098			} else {
18099				disabled = [ index ];
18100			}
18101		}
18102		this._setOptionDisabled( disabled );
18103	},
18104
18105	load: function( index, event ) {
18106		index = this._getIndex( index );
18107		var that = this,
18108			tab = this.tabs.eq( index ),
18109			anchor = tab.find( ".ui-tabs-anchor" ),
18110			panel = this._getPanelForTab( tab ),
18111			eventData = {
18112				tab: tab,
18113				panel: panel
18114			},
18115			complete = function( jqXHR, status ) {
18116				if ( status === "abort" ) {
18117					that.panels.stop( false, true );
18118				}
18119
18120				that._removeClass( tab, "ui-tabs-loading" );
18121				panel.removeAttr( "aria-busy" );
18122
18123				if ( jqXHR === that.xhr ) {
18124					delete that.xhr;
18125				}
18126			};
18127
18128		// Not remote
18129		if ( this._isLocal( anchor[ 0 ] ) ) {
18130			return;
18131		}
18132
18133		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18134
18135		// Support: jQuery <1.8
18136		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18137		// but as of 1.8, $.ajax() always returns a jqXHR object.
18138		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18139			this._addClass( tab, "ui-tabs-loading" );
18140			panel.attr( "aria-busy", "true" );
18141
18142			this.xhr
18143				.done( function( response, status, jqXHR ) {
18144
18145					// support: jQuery <1.8
18146					// http://bugs.jquery.com/ticket/11778
18147					setTimeout( function() {
18148						panel.html( response );
18149						that._trigger( "load", event, eventData );
18150
18151						complete( jqXHR, status );
18152					}, 1 );
18153				} )
18154				.fail( function( jqXHR, status ) {
18155
18156					// support: jQuery <1.8
18157					// http://bugs.jquery.com/ticket/11778
18158					setTimeout( function() {
18159						complete( jqXHR, status );
18160					}, 1 );
18161				} );
18162		}
18163	},
18164
18165	_ajaxSettings: function( anchor, event, eventData ) {
18166		var that = this;
18167		return {
18168
18169			// Support: IE <11 only
18170			// Strip any hash that exists to prevent errors with the Ajax request
18171			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18172			beforeSend: function( jqXHR, settings ) {
18173				return that._trigger( "beforeLoad", event,
18174					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18175			}
18176		};
18177	},
18178
18179	_getPanelForTab: function( tab ) {
18180		var id = $( tab ).attr( "aria-controls" );
18181		return this.element.find( this._sanitizeSelector( "#" + id ) );
18182	}
18183} );
18184
18185// DEPRECATED
18186// TODO: Switch return back to widget declaration at top of file when this is removed
18187if ( $.uiBackCompat !== false ) {
18188
18189	// Backcompat for ui-tab class (now ui-tabs-tab)
18190	$.widget( "ui.tabs", $.ui.tabs, {
18191		_processTabs: function() {
18192			this._superApply( arguments );
18193			this._addClass( this.tabs, "ui-tab" );
18194		}
18195	} );
18196}
18197
18198var widgetsTabs = $.ui.tabs;
18199
18200
18201/*!
18202 * jQuery UI Tooltip 1.12.1
18203 * http://jqueryui.com
18204 *
18205 * Copyright jQuery Foundation and other contributors
18206 * Released under the MIT license.
18207 * http://jquery.org/license
18208 */
18209
18210//>>label: Tooltip
18211//>>group: Widgets
18212//>>description: Shows additional information for any element on hover or focus.
18213//>>docs: http://api.jqueryui.com/tooltip/
18214//>>demos: http://jqueryui.com/tooltip/
18215//>>css.structure: ../../themes/base/core.css
18216//>>css.structure: ../../themes/base/tooltip.css
18217//>>css.theme: ../../themes/base/theme.css
18218
18219
18220
18221$.widget( "ui.tooltip", {
18222	version: "1.12.1",
18223	options: {
18224		classes: {
18225			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18226		},
18227		content: function() {
18228
18229			// support: IE<9, Opera in jQuery <1.7
18230			// .text() can't accept undefined, so coerce to a string
18231			var title = $( this ).attr( "title" ) || "";
18232
18233			// Escape title, since we're going from an attribute to raw HTML
18234			return $( "<a>" ).text( title ).html();
18235		},
18236		hide: true,
18237
18238		// Disabled elements have inconsistent behavior across browsers (#8661)
18239		items: "[title]:not([disabled])",
18240		position: {
18241			my: "left top+15",
18242			at: "left bottom",
18243			collision: "flipfit flip"
18244		},
18245		show: true,
18246		track: false,
18247
18248		// Callbacks
18249		close: null,
18250		open: null
18251	},
18252
18253	_addDescribedBy: function( elem, id ) {
18254		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18255		describedby.push( id );
18256		elem
18257			.data( "ui-tooltip-id", id )
18258			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18259	},
18260
18261	_removeDescribedBy: function( elem ) {
18262		var id = elem.data( "ui-tooltip-id" ),
18263			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18264			index = $.inArray( id, describedby );
18265
18266		if ( index !== -1 ) {
18267			describedby.splice( index, 1 );
18268		}
18269
18270		elem.removeData( "ui-tooltip-id" );
18271		describedby = $.trim( describedby.join( " " ) );
18272		if ( describedby ) {
18273			elem.attr( "aria-describedby", describedby );
18274		} else {
18275			elem.removeAttr( "aria-describedby" );
18276		}
18277	},
18278
18279	_create: function() {
18280		this._on( {
18281			mouseover: "open",
18282			focusin: "open"
18283		} );
18284
18285		// IDs of generated tooltips, needed for destroy
18286		this.tooltips = {};
18287
18288		// IDs of parent tooltips where we removed the title attribute
18289		this.parents = {};
18290
18291		// Append the aria-live region so tooltips announce correctly
18292		this.liveRegion = $( "<div>" )
18293			.attr( {
18294				role: "log",
18295				"aria-live": "assertive",
18296				"aria-relevant": "additions"
18297			} )
18298			.appendTo( this.document[ 0 ].body );
18299		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18300
18301		this.disabledTitles = $( [] );
18302	},
18303
18304	_setOption: function( key, value ) {
18305		var that = this;
18306
18307		this._super( key, value );
18308
18309		if ( key === "content" ) {
18310			$.each( this.tooltips, function( id, tooltipData ) {
18311				that._updateContent( tooltipData.element );
18312			} );
18313		}
18314	},
18315
18316	_setOptionDisabled: function( value ) {
18317		this[ value ? "_disable" : "_enable" ]();
18318	},
18319
18320	_disable: function() {
18321		var that = this;
18322
18323		// Close open tooltips
18324		$.each( this.tooltips, function( id, tooltipData ) {
18325			var event = $.Event( "blur" );
18326			event.target = event.currentTarget = tooltipData.element[ 0 ];
18327			that.close( event, true );
18328		} );
18329
18330		// Remove title attributes to prevent native tooltips
18331		this.disabledTitles = this.disabledTitles.add(
18332			this.element.find( this.options.items ).addBack()
18333				.filter( function() {
18334					var element = $( this );
18335					if ( element.is( "[title]" ) ) {
18336						return element
18337							.data( "ui-tooltip-title", element.attr( "title" ) )
18338							.removeAttr( "title" );
18339					}
18340				} )
18341		);
18342	},
18343
18344	_enable: function() {
18345
18346		// restore title attributes
18347		this.disabledTitles.each( function() {
18348			var element = $( this );
18349			if ( element.data( "ui-tooltip-title" ) ) {
18350				element.attr( "title", element.data( "ui-tooltip-title" ) );
18351			}
18352		} );
18353		this.disabledTitles = $( [] );
18354	},
18355
18356	open: function( event ) {
18357		var that = this,
18358			target = $( event ? event.target : this.element )
18359
18360				// we need closest here due to mouseover bubbling,
18361				// but always pointing at the same event target
18362				.closest( this.options.items );
18363
18364		// No element to show a tooltip for or the tooltip is already open
18365		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18366			return;
18367		}
18368
18369		if ( target.attr( "title" ) ) {
18370			target.data( "ui-tooltip-title", target.attr( "title" ) );
18371		}
18372
18373		target.data( "ui-tooltip-open", true );
18374
18375		// Kill parent tooltips, custom or native, for hover
18376		if ( event && event.type === "mouseover" ) {
18377			target.parents().each( function() {
18378				var parent = $( this ),
18379					blurEvent;
18380				if ( parent.data( "ui-tooltip-open" ) ) {
18381					blurEvent = $.Event( "blur" );
18382					blurEvent.target = blurEvent.currentTarget = this;
18383					that.close( blurEvent, true );
18384				}
18385				if ( parent.attr( "title" ) ) {
18386					parent.uniqueId();
18387					that.parents[ this.id ] = {
18388						element: this,
18389						title: parent.attr( "title" )
18390					};
18391					parent.attr( "title", "" );
18392				}
18393			} );
18394		}
18395
18396		this._registerCloseHandlers( event, target );
18397		this._updateContent( target, event );
18398	},
18399
18400	_updateContent: function( target, event ) {
18401		var content,
18402			contentOption = this.options.content,
18403			that = this,
18404			eventType = event ? event.type : null;
18405
18406		if ( typeof contentOption === "string" || contentOption.nodeType ||
18407				contentOption.jquery ) {
18408			return this._open( event, target, contentOption );
18409		}
18410
18411		content = contentOption.call( target[ 0 ], function( response ) {
18412
18413			// IE may instantly serve a cached response for ajax requests
18414			// delay this call to _open so the other call to _open runs first
18415			that._delay( function() {
18416
18417				// Ignore async response if tooltip was closed already
18418				if ( !target.data( "ui-tooltip-open" ) ) {
18419					return;
18420				}
18421
18422				// JQuery creates a special event for focusin when it doesn't
18423				// exist natively. To improve performance, the native event
18424				// object is reused and the type is changed. Therefore, we can't
18425				// rely on the type being correct after the event finished
18426				// bubbling, so we set it back to the previous value. (#8740)
18427				if ( event ) {
18428					event.type = eventType;
18429				}
18430				this._open( event, target, response );
18431			} );
18432		} );
18433		if ( content ) {
18434			this._open( event, target, content );
18435		}
18436	},
18437
18438	_open: function( event, target, content ) {
18439		var tooltipData, tooltip, delayedShow, a11yContent,
18440			positionOption = $.extend( {}, this.options.position );
18441
18442		if ( !content ) {
18443			return;
18444		}
18445
18446		// Content can be updated multiple times. If the tooltip already
18447		// exists, then just update the content and bail.
18448		tooltipData = this._find( target );
18449		if ( tooltipData ) {
18450			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18451			return;
18452		}
18453
18454		// If we have a title, clear it to prevent the native tooltip
18455		// we have to check first to avoid defining a title if none exists
18456		// (we don't want to cause an element to start matching [title])
18457		//
18458		// We use removeAttr only for key events, to allow IE to export the correct
18459		// accessible attributes. For mouse events, set to empty string to avoid
18460		// native tooltip showing up (happens only when removing inside mouseover).
18461		if ( target.is( "[title]" ) ) {
18462			if ( event && event.type === "mouseover" ) {
18463				target.attr( "title", "" );
18464			} else {
18465				target.removeAttr( "title" );
18466			}
18467		}
18468
18469		tooltipData = this._tooltip( target );
18470		tooltip = tooltipData.tooltip;
18471		this._addDescribedBy( target, tooltip.attr( "id" ) );
18472		tooltip.find( ".ui-tooltip-content" ).html( content );
18473
18474		// Support: Voiceover on OS X, JAWS on IE <= 9
18475		// JAWS announces deletions even when aria-relevant="additions"
18476		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18477		this.liveRegion.children().hide();
18478		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18479		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18480		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18481		a11yContent.appendTo( this.liveRegion );
18482
18483		function position( event ) {
18484			positionOption.of = event;
18485			if ( tooltip.is( ":hidden" ) ) {
18486				return;
18487			}
18488			tooltip.position( positionOption );
18489		}
18490		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18491			this._on( this.document, {
18492				mousemove: position
18493			} );
18494
18495			// trigger once to override element-relative positioning
18496			position( event );
18497		} else {
18498			tooltip.position( $.extend( {
18499				of: target
18500			}, this.options.position ) );
18501		}
18502
18503		tooltip.hide();
18504
18505		this._show( tooltip, this.options.show );
18506
18507		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18508		// as the tooltip is visible, position the tooltip using the most recent
18509		// event.
18510		// Adds the check to add the timers only when both delay and track options are set (#14682)
18511		if ( this.options.track && this.options.show && this.options.show.delay ) {
18512			delayedShow = this.delayedShow = setInterval( function() {
18513				if ( tooltip.is( ":visible" ) ) {
18514					position( positionOption.of );
18515					clearInterval( delayedShow );
18516				}
18517			}, $.fx.interval );
18518		}
18519
18520		this._trigger( "open", event, { tooltip: tooltip } );
18521	},
18522
18523	_registerCloseHandlers: function( event, target ) {
18524		var events = {
18525			keyup: function( event ) {
18526				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18527					var fakeEvent = $.Event( event );
18528					fakeEvent.currentTarget = target[ 0 ];
18529					this.close( fakeEvent, true );
18530				}
18531			}
18532		};
18533
18534		// Only bind remove handler for delegated targets. Non-delegated
18535		// tooltips will handle this in destroy.
18536		if ( target[ 0 ] !== this.element[ 0 ] ) {
18537			events.remove = function() {
18538				this._removeTooltip( this._find( target ).tooltip );
18539			};
18540		}
18541
18542		if ( !event || event.type === "mouseover" ) {
18543			events.mouseleave = "close";
18544		}
18545		if ( !event || event.type === "focusin" ) {
18546			events.focusout = "close";
18547		}
18548		this._on( true, target, events );
18549	},
18550
18551	close: function( event ) {
18552		var tooltip,
18553			that = this,
18554			target = $( event ? event.currentTarget : this.element ),
18555			tooltipData = this._find( target );
18556
18557		// The tooltip may already be closed
18558		if ( !tooltipData ) {
18559
18560			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18561			// additional data once there's actually content to show (in _open()). So even if the
18562			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18563			// the period between open() and _open().
18564			target.removeData( "ui-tooltip-open" );
18565			return;
18566		}
18567
18568		tooltip = tooltipData.tooltip;
18569
18570		// Disabling closes the tooltip, so we need to track when we're closing
18571		// to avoid an infinite loop in case the tooltip becomes disabled on close
18572		if ( tooltipData.closing ) {
18573			return;
18574		}
18575
18576		// Clear the interval for delayed tracking tooltips
18577		clearInterval( this.delayedShow );
18578
18579		// Only set title if we had one before (see comment in _open())
18580		// If the title attribute has changed since open(), don't restore
18581		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18582			target.attr( "title", target.data( "ui-tooltip-title" ) );
18583		}
18584
18585		this._removeDescribedBy( target );
18586
18587		tooltipData.hiding = true;
18588		tooltip.stop( true );
18589		this._hide( tooltip, this.options.hide, function() {
18590			that._removeTooltip( $( this ) );
18591		} );
18592
18593		target.removeData( "ui-tooltip-open" );
18594		this._off( target, "mouseleave focusout keyup" );
18595
18596		// Remove 'remove' binding only on delegated targets
18597		if ( target[ 0 ] !== this.element[ 0 ] ) {
18598			this._off( target, "remove" );
18599		}
18600		this._off( this.document, "mousemove" );
18601
18602		if ( event && event.type === "mouseleave" ) {
18603			$.each( this.parents, function( id, parent ) {
18604				$( parent.element ).attr( "title", parent.title );
18605				delete that.parents[ id ];
18606			} );
18607		}
18608
18609		tooltipData.closing = true;
18610		this._trigger( "close", event, { tooltip: tooltip } );
18611		if ( !tooltipData.hiding ) {
18612			tooltipData.closing = false;
18613		}
18614	},
18615
18616	_tooltip: function( element ) {
18617		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18618			content = $( "<div>" ).appendTo( tooltip ),
18619			id = tooltip.uniqueId().attr( "id" );
18620
18621		this._addClass( content, "ui-tooltip-content" );
18622		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18623
18624		tooltip.appendTo( this._appendTo( element ) );
18625
18626		return this.tooltips[ id ] = {
18627			element: element,
18628			tooltip: tooltip
18629		};
18630	},
18631
18632	_find: function( target ) {
18633		var id = target.data( "ui-tooltip-id" );
18634		return id ? this.tooltips[ id ] : null;
18635	},
18636
18637	_removeTooltip: function( tooltip ) {
18638		tooltip.remove();
18639		delete this.tooltips[ tooltip.attr( "id" ) ];
18640	},
18641
18642	_appendTo: function( target ) {
18643		var element = target.closest( ".ui-front, dialog" );
18644
18645		if ( !element.length ) {
18646			element = this.document[ 0 ].body;
18647		}
18648
18649		return element;
18650	},
18651
18652	_destroy: function() {
18653		var that = this;
18654
18655		// Close open tooltips
18656		$.each( this.tooltips, function( id, tooltipData ) {
18657
18658			// Delegate to close method to handle common cleanup
18659			var event = $.Event( "blur" ),
18660				element = tooltipData.element;
18661			event.target = event.currentTarget = element[ 0 ];
18662			that.close( event, true );
18663
18664			// Remove immediately; destroying an open tooltip doesn't use the
18665			// hide animation
18666			$( "#" + id ).remove();
18667
18668			// Restore the title
18669			if ( element.data( "ui-tooltip-title" ) ) {
18670
18671				// If the title attribute has changed since open(), don't restore
18672				if ( !element.attr( "title" ) ) {
18673					element.attr( "title", element.data( "ui-tooltip-title" ) );
18674				}
18675				element.removeData( "ui-tooltip-title" );
18676			}
18677		} );
18678		this.liveRegion.remove();
18679	}
18680} );
18681
18682// DEPRECATED
18683// TODO: Switch return back to widget declaration at top of file when this is removed
18684if ( $.uiBackCompat !== false ) {
18685
18686	// Backcompat for tooltipClass option
18687	$.widget( "ui.tooltip", $.ui.tooltip, {
18688		options: {
18689			tooltipClass: null
18690		},
18691		_tooltip: function() {
18692			var tooltipData = this._superApply( arguments );
18693			if ( this.options.tooltipClass ) {
18694				tooltipData.tooltip.addClass( this.options.tooltipClass );
18695			}
18696			return tooltipData;
18697		}
18698	} );
18699}
18700
18701var widgetsTooltip = $.ui.tooltip;
18702
18703
18704
18705
18706}));

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.