PageSourceSearch

https://www.dei.gov.ba/fe/js/jquery-ui.js

js dei.gov.ba collected 2026-09-24 09:29:29 UTC 520,717 bytes, 18,709 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,021 bytes, lines 2812-3842
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} );
2835
2836function parseClip( str, element ) {
2837		var outerWidth = element.outerWidth(),
2838			outerHeight = element.outerHeight(),
2839			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)\)$/,
2840			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2841
2842		return {
2843			top: parseFloat( values[ 1 ] ) || 0,
2844			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2845			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2846			left: parseFloat( values[ 4 ] ) || 0
2847		};
2848}
2849
2850$.fx.step.clip = function( fx ) {
2851	if ( !fx.clipInit ) {
2852		fx.start = $( fx.elem ).cssClip();
2853		if ( typeof fx.end === "string" ) {
2854			fx.end = parseClip( fx.end, fx.elem );
2855		}
2856		fx.clipInit = true;
2857	}
2858
2859	$( fx.elem ).cssClip( {
2860		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2861		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2862		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2863		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2864	} );
2865};
2866
2867} )();
2868
2869/******************************************************************************/
2870/*********************************** EASING ***********************************/
2871/******************************************************************************/
2872
2873( function() {
2874
2875// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
2876
2877var baseEasings = {};
2878
2879$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2880	baseEasings[ name ] = function( p ) {
2881		return Math.pow( p, i + 2 );
2882	};
2883} );
2884
2885$.extend( baseEasings, {
2886	Sine: function( p ) {
2887		return 1 - Math.cos( p * Math.PI / 2 );
2888	},
2889	Circ: function( p ) {
2890		return 1 - Math.sqrt( 1 - p * p );
2891	},
2892	Elastic: function( p ) {
2893		return p === 0 || p === 1 ? p :
2894			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2895	},
2896	Back: function( p ) {
2897		return p * p * ( 3 * p - 2 );
2898	},
2899	Bounce: function( p ) {
2900		var pow2,
2901			bounce = 4;
2902
2903		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2904		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2905	}
2906} );
2907
2908$.each( baseEasings, function( name, easeIn ) {
2909	$.easing[ "easeIn" + name ] = easeIn;
2910	$.easing[ "easeOut" + name ] = function( p ) {
2911		return 1 - easeIn( 1 - p );
2912	};
2913	$.easing[ "easeInOut" + name ] = function( p ) {
2914		return p < 0.5 ?
2915			easeIn( p * 2 ) / 2 :
2916			1 - easeIn( p * -2 + 2 ) / 2;
2917	};
2918} );
2919
2920} )();
2921
2922var effect = $.effects;
2923
2924
2925/*!
2926 * jQuery UI Effects Blind 1.12.1
2927 * http://jqueryui.com
2928 *
2929 * Copyright jQuery Foundation and other contributors
2930 * Released under the MIT license.
2931 * http://jquery.org/license
2932 */
2933
2934//>>label: Blind Effect
2935//>>group: Effects
2936//>>description: Blinds the element.
2937//>>docs: http://api.jqueryui.com/blind-effect/
2938//>>demos: http://jqueryui.com/effect/
2939
2940
2941
2942var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2943	var map = {
2944			up: [ "bottom", "top" ],
2945			vertical: [ "bottom", "top" ],
2946			down: [ "top", "bottom" ],
2947			left: [ "right", "left" ],
2948			horizontal: [ "right", "left" ],
2949			right: [ "left", "right" ]
2950		},
2951		element = $( this ),
2952		direction = options.direction || "up",
2953		start = element.cssClip(),
2954		animate = { clip: $.extend( {}, start ) },
2955		placeholder = $.effects.createPlaceholder( element );
2956
2957	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2958
2959	if ( options.mode === "show" ) {
2960		element.cssClip( animate.clip );
2961		if ( placeholder ) {
2962			placeholder.css( $.effects.clipToBox( animate ) );
2963		}
2964
2965		animate.clip = start;
2966	}
2967
2968	if ( placeholder ) {
2969		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2970	}
2971
2972	element.animate( animate, {
2973		queue: false,
2974		duration: options.duration,
2975		easing: options.easing,
2976		complete: done
2977	} );
2978} );
2979
2980
2981/*!
2982 * jQuery UI Effects Bounce 1.12.1
2983 * http://jqueryui.com
2984 *
2985 * Copyright jQuery Foundation and other contributors
2986 * Released under the MIT license.
2987 * http://jquery.org/license
2988 */
2989
2990//>>label: Bounce Effect
2991//>>group: Effects
2992//>>description: Bounces an element horizontally or vertically n times.
2993//>>docs: http://api.jqueryui.com/bounce-effect/
2994//>>demos: http://jqueryui.com/effect/
2995
2996
2997
2998var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
2999	var upAnim, downAnim, refValue,
3000		element = $( this ),
3001
3002		// Defaults:
3003		mode = options.mode,
3004		hide = mode === "hide",
3005		show = mode === "show",
3006		direction = options.direction || "up",
3007		distance = options.distance,
3008		times = options.times || 5,
3009
3010		// Number of internal animations
3011		anims = times * 2 + ( show || hide ? 1 : 0 ),
3012		speed = options.duration / anims,
3013		easing = options.easing,
3014
3015		// Utility:
3016		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3017		motion = ( direction === "up" || direction === "left" ),
3018		i = 0,
3019
3020		queuelen = element.queue().length;
3021
3022	$.effects.createPlaceholder( element );
3023
3024	refValue = element.css( ref );
3025
3026	// Default distance for the BIGGEST bounce is the outer Distance / 3
3027	if ( !distance ) {
3028		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3029	}
3030
3031	if ( show ) {
3032		downAnim = { opacity: 1 };
3033		downAnim[ ref ] = refValue;
3034
3035		// If we are showing, force opacity 0 and set the initial position
3036		// then do the "first" animation
3037		element
3038			.css( "opacity", 0 )
3039			.css( ref, motion ? -distance * 2 : distance * 2 )
3040			.animate( downAnim, speed, easing );
3041	}
3042
3043	// Start at the smallest distance if we are hiding
3044	if ( hide ) {
3045		distance = distance / Math.pow( 2, times - 1 );
3046	}
3047
3048	downAnim = {};
3049	downAnim[ ref ] = refValue;
3050
3051	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3052	for ( ; i < times; i++ ) {
3053		upAnim = {};
3054		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3055
3056		element
3057			.animate( upAnim, speed, easing )
3058			.animate( downAnim, speed, easing );
3059
3060		distance = hide ? distance * 2 : distance / 2;
3061	}
3062
3063	// Last Bounce when Hiding
3064	if ( hide ) {
3065		upAnim = { opacity: 0 };
3066		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3067
3068		element.animate( upAnim, speed, easing );
3069	}
3070
3071	element.queue( done );
3072
3073	$.effects.unshift( element, queuelen, anims + 1 );
3074} );
3075
3076
3077/*!
3078 * jQuery UI Effects Clip 1.12.1
3079 * http://jqueryui.com
3080 *
3081 * Copyright jQuery Foundation and other contributors
3082 * Released under the MIT license.
3083 * http://jquery.org/license
3084 */
3085
3086//>>label: Clip Effect
3087//>>group: Effects
3088//>>description: Clips the element on and off like an old TV.
3089//>>docs: http://api.jqueryui.com/clip-effect/
3090//>>demos: http://jqueryui.com/effect/
3091
3092
3093
3094var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3095	var start,
3096		animate = {},
3097		element = $( this ),
3098		direction = options.direction || "vertical",
3099		both = direction === "both",
3100		horizontal = both || direction === "horizontal",
3101		vertical = both || direction === "vertical";
3102
3103	start = element.cssClip();
3104	animate.clip = {
3105		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3106		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3107		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3108		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3109	};
3110
3111	$.effects.createPlaceholder( element );
3112
3113	if ( options.mode === "show" ) {
3114		element.cssClip( animate.clip );
3115		animate.clip = start;
3116	}
3117
3118	element.animate( animate, {
3119		queue: false,
3120		duration: options.duration,
3121		easing: options.easing,
3122		complete: done
3123	} );
3124
3125} );
3126
3127
3128/*!
3129 * jQuery UI Effects Drop 1.12.1
3130 * http://jqueryui.com
3131 *
3132 * Copyright jQuery Foundation and other contributors
3133 * Released under the MIT license.
3134 * http://jquery.org/license
3135 */
3136
3137//>>label: Drop Effect
3138//>>group: Effects
3139//>>description: Moves an element in one direction and hides it at the same time.
3140//>>docs: http://api.jqueryui.com/drop-effect/
3141//>>demos: http://jqueryui.com/effect/
3142
3143
3144
3145var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3146
3147	var distance,
3148		element = $( this ),
3149		mode = options.mode,
3150		show = mode === "show",
3151		direction = options.direction || "left",
3152		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3153		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3154		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3155		animation = {
3156			opacity: 0
3157		};
3158
3159	$.effects.createPlaceholder( element );
3160
3161	distance = options.distance ||
3162		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3163
3164	animation[ ref ] = motion + distance;
3165
3166	if ( show ) {
3167		element.css( animation );
3168
3169		animation[ ref ] = oppositeMotion + distance;
3170		animation.opacity = 1;
3171	}
3172
3173	// Animate
3174	element.animate( animation, {
3175		queue: false,
3176		duration: options.duration,
3177		easing: options.easing,
3178		complete: done
3179	} );
3180} );
3181
3182
3183/*!
3184 * jQuery UI Effects Explode 1.12.1
3185 * http://jqueryui.com
3186 *
3187 * Copyright jQuery Foundation and other contributors
3188 * Released under the MIT license.
3189 * http://jquery.org/license
3190 */
3191
3192//>>label: Explode Effect
3193//>>group: Effects
3194// jscs:disable maximumLineLength
3195//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3196// jscs:enable maximumLineLength
3197//>>docs: http://api.jqueryui.com/explode-effect/
3198//>>demos: http://jqueryui.com/effect/
3199
3200
3201
3202var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3203
3204	var i, j, left, top, mx, my,
3205		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3206		cells = rows,
3207		element = $( this ),
3208		mode = options.mode,
3209		show = mode === "show",
3210
3211		// Show and then visibility:hidden the element before calculating offset
3212		offset = element.show().css( "visibility", "hidden" ).offset(),
3213
3214		// Width and height of a piece
3215		width = Math.ceil( element.outerWidth() / cells ),
3216		height = Math.ceil( element.outerHeight() / rows ),
3217		pieces = [];
3218
3219	// Children animate complete:
3220	function childComplete() {
3221		pieces.push( this );
3222		if ( pieces.length === rows * cells ) {
3223			animComplete();
3224		}
3225	}
3226
3227	// Clone the element for each row and cell.
3228	for ( i = 0; i < rows; i++ ) { // ===>
3229		top = offset.top + i * height;
3230		my = i - ( rows - 1 ) / 2;
3231
3232		for ( j = 0; j < cells; j++ ) { // |||
3233			left = offset.left + j * width;
3234			mx = j - ( cells - 1 ) / 2;
3235
3236			// Create a clone of the now hidden main element that will be absolute positioned
3237			// within a wrapper div off the -left and -top equal to size of our pieces
3238			element
3239				.clone()
3240				.appendTo( "body" )
3241				.wrap( "<div></div>" )
3242				.css( {
3243					position: "absolute",
3244					visibility: "visible",
3245					left: -j * width,
3246					top: -i * height
3247				} )
3248
3249				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3250				// where the original was located +left and +top equal to the size of pieces
3251				.parent()
3252					.addClass( "ui-effects-explode" )
3253					.css( {
3254						position: "absolute",
3255						overflow: "hidden",
3256						width: width,
3257						height: height,
3258						left: left + ( show ? mx * width : 0 ),
3259						top: top + ( show ? my * height : 0 ),
3260						opacity: show ? 0 : 1
3261					} )
3262					.animate( {
3263						left: left + ( show ? 0 : mx * width ),
3264						top: top + ( show ? 0 : my * height ),
3265						opacity: show ? 1 : 0
3266					}, options.duration || 500, options.easing, childComplete );
3267		}
3268	}
3269
3270	function animComplete() {
3271		element.css( {
3272			visibility: "visible"
3273		} );
3274		$( pieces ).remove();
3275		done();
3276	}
3277} );
3278
3279
3280/*!
3281 * jQuery UI Effects Fade 1.12.1
3282 * http://jqueryui.com
3283 *
3284 * Copyright jQuery Foundation and other contributors
3285 * Released under the MIT license.
3286 * http://jquery.org/license
3287 */
3288
3289//>>label: Fade Effect
3290//>>group: Effects
3291//>>description: Fades the element.
3292//>>docs: http://api.jqueryui.com/fade-effect/
3293//>>demos: http://jqueryui.com/effect/
3294
3295
3296
3297var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3298	var show = options.mode === "show";
3299
3300	$( this )
3301		.css( "opacity", show ? 0 : 1 )
3302		.animate( {
3303			opacity: show ? 1 : 0
3304		}, {
3305			queue: false,
3306			duration: options.duration,
3307			easing: options.easing,
3308			complete: done
3309		} );
3310} );
3311
3312
3313/*!
3314 * jQuery UI Effects Fold 1.12.1
3315 * http://jqueryui.com
3316 *
3317 * Copyright jQuery Foundation and other contributors
3318 * Released under the MIT license.
3319 * http://jquery.org/license
3320 */
3321
3322//>>label: Fold Effect
3323//>>group: Effects
3324//>>description: Folds an element first horizontally and then vertically.
3325//>>docs: http://api.jqueryui.com/fold-effect/
3326//>>demos: http://jqueryui.com/effect/
3327
3328
3329
3330var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3331
3332	// Create element
3333	var element = $( this ),
3334		mode = options.mode,
3335		show = mode === "show",
3336		hide = mode === "hide",
3337		size = options.size || 15,
3338		percent = /([0-9]+)%/.exec( size ),
3339		horizFirst = !!options.horizFirst,
3340		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3341		duration = options.duration / 2,
3342
3343		placeholder = $.effects.createPlaceholder( element ),
3344
3345		start = element.cssClip(),
3346		animation1 = { clip: $.extend( {}, start ) },
3347		animation2 = { clip: $.extend( {}, start ) },
3348
3349		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3350
3351		queuelen = element.queue().length;
3352
3353	if ( percent ) {
3354		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3355	}
3356	animation1.clip[ ref[ 0 ] ] = size;
3357	animation2.clip[ ref[ 0 ] ] = size;
3358	animation2.clip[ ref[ 1 ] ] = 0;
3359
3360	if ( show ) {
3361		element.cssClip( animation2.clip );
3362		if ( placeholder ) {
3363			placeholder.css( $.effects.clipToBox( animation2 ) );
3364		}
3365
3366		animation2.clip = start;
3367	}
3368
3369	// Animate
3370	element
3371		.queue( function( next ) {
3372			if ( placeholder ) {
3373				placeholder
3374					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3375					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3376			}
3377
3378			next();
3379		} )
3380		.animate( animation1, duration, options.easing )
3381		.animate( animation2, duration, options.easing )
3382		.queue( done );
3383
3384	$.effects.unshift( element, queuelen, 4 );
3385} );
3386
3387
3388/*!
3389 * jQuery UI Effects Highlight 1.12.1
3390 * http://jqueryui.com
3391 *
3392 * Copyright jQuery Foundation and other contributors
3393 * Released under the MIT license.
3394 * http://jquery.org/license
3395 */
3396
3397//>>label: Highlight Effect
3398//>>group: Effects
3399//>>description: Highlights the background of an element in a defined color for a custom duration.
3400//>>docs: http://api.jqueryui.com/highlight-effect/
3401//>>demos: http://jqueryui.com/effect/
3402
3403
3404
3405var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3406	var element = $( this ),
3407		animation = {
3408			backgroundColor: element.css( "backgroundColor" )
3409		};
3410
3411	if ( options.mode === "hide" ) {
3412		animation.opacity = 0;
3413	}
3414
3415	$.effects.saveStyle( element );
3416
3417	element
3418		.css( {
3419			backgroundImage: "none",
3420			backgroundColor: options.color || "#ffff99"
3421		} )
3422		.animate( animation, {
3423			queue: false,
3424			duration: options.duration,
3425			easing: options.easing,
3426			complete: done
3427		} );
3428} );
3429
3430
3431/*!
3432 * jQuery UI Effects Size 1.12.1
3433 * http://jqueryui.com
3434 *
3435 * Copyright jQuery Foundation and other contributors
3436 * Released under the MIT license.
3437 * http://jquery.org/license
3438 */
3439
3440//>>label: Size Effect
3441//>>group: Effects
3442//>>description: Resize an element to a specified width and height.
3443//>>docs: http://api.jqueryui.com/size-effect/
3444//>>demos: http://jqueryui.com/effect/
3445
3446
3447
3448var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3449
3450	// Create element
3451	var baseline, factor, temp,
3452		element = $( this ),
3453
3454		// Copy for children
3455		cProps = [ "fontSize" ],
3456		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3457		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3458
3459		// Set options
3460		mode = options.mode,
3461		restore = mode !== "effect",
3462		scale = options.scale || "both",
3463		origin = options.origin || [ "middle", "center" ],
3464		position = element.css( "position" ),
3465		pos = element.position(),
3466		original = $.effects.scaledDimensions( element ),
3467		from = options.from || original,
3468		to = options.to || $.effects.scaledDimensions( element, 0 );
3469
3470	$.effects.createPlaceholder( element );
3471
3472	if ( mode === "show" ) {
3473		temp = from;
3474		from = to;
3475		to = temp;
3476	}
3477
3478	// Set scaling factor
3479	factor = {
3480		from: {
3481			y: from.height / original.height,
3482			x: from.width / original.width
3483		},
3484		to: {
3485			y: to.height / original.height,
3486			x: to.width / original.width
3487		}
3488	};
3489
3490	// Scale the css box
3491	if ( scale === "box" || scale === "both" ) {
3492
3493		// Vertical props scaling
3494		if ( factor.from.y !== factor.to.y ) {
3495			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3496			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3497		}
3498
3499		// Horizontal props scaling
3500		if ( factor.from.x !== factor.to.x ) {
3501			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3502			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3503		}
3504	}
3505
3506	// Scale the content
3507	if ( scale === "content" || scale === "both" ) {
3508
3509		// Vertical props scaling
3510		if ( factor.from.y !== factor.to.y ) {
3511			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3512			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3513		}
3514	}
3515
3516	// Adjust the position properties based on the provided origin points
3517	if ( origin ) {
3518		baseline = $.effects.getBaseline( origin, original );
3519		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3520		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3521		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3522		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3523	}
3524	element.css( from );
3525
3526	// Animate the children if desired
3527	if ( scale === "content" || scale === "both" ) {
3528
3529		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3530		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3531
3532		// Only animate children with width attributes specified
3533		// TODO: is this right? should we include anything with css width specified as well
3534		element.find( "*[width]" ).each( function() {
3535			var child = $( this ),
3536				childOriginal = $.effects.scaledDimensions( child ),
3537				childFrom = {
3538					height: childOriginal.height * factor.from.y,
3539					width: childOriginal.width * factor.from.x,
3540					outerHeight: childOriginal.outerHeight * factor.from.y,
3541					outerWidth: childOriginal.outerWidth * factor.from.x
3542				},
3543				childTo = {
3544					height: childOriginal.height * factor.to.y,
3545					width: childOriginal.width * factor.to.x,
3546					outerHeight: childOriginal.height * factor.to.y,
3547					outerWidth: childOriginal.width * factor.to.x
3548				};
3549
3550			// Vertical props scaling
3551			if ( factor.from.y !== factor.to.y ) {
3552				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3553				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3554			}
3555
3556			// Horizontal props scaling
3557			if ( factor.from.x !== factor.to.x ) {
3558				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3559				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3560			}
3561
3562			if ( restore ) {
3563				$.effects.saveStyle( child );
3564			}
3565
3566			// Animate children
3567			child.css( childFrom );
3568			child.animate( childTo, options.duration, options.easing, function() {
3569
3570				// Restore children
3571				if ( restore ) {
3572					$.effects.restoreStyle( child );
3573				}
3574			} );
3575		} );
3576	}
3577
3578	// Animate
3579	element.animate( to, {
3580		queue: false,
3581		duration: options.duration,
3582		easing: options.easing,
3583		complete: function() {
3584
3585			var offset = element.offset();
3586
3587			if ( to.opacity === 0 ) {
3588				element.css( "opacity", from.opacity );
3589			}
3590
3591			if ( !restore ) {
3592				element
3593					.css( "position", position === "static" ? "relative" : position )
3594					.offset( offset );
3595
3596				// Need to save style here so that automatic style restoration
3597				// doesn't restore to the original styles from before the animation.
3598				$.effects.saveStyle( element );
3599			}
3600
3601			done();
3602		}
3603	} );
3604
3605} );
3606
3607
3608/*!
3609 * jQuery UI Effects Scale 1.12.1
3610 * http://jqueryui.com
3611 *
3612 * Copyright jQuery Foundation and other contributors
3613 * Released under the MIT license.
3614 * http://jquery.org/license
3615 */
3616
3617//>>label: Scale Effect
3618//>>group: Effects
3619//>>description: Grows or shrinks an element and its content.
3620//>>docs: http://api.jqueryui.com/scale-effect/
3621//>>demos: http://jqueryui.com/effect/
3622
3623
3624
3625var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3626
3627	// Create element
3628	var el = $( this ),
3629		mode = options.mode,
3630		percent = parseInt( options.percent, 10 ) ||
3631			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3632
3633		newOptions = $.extend( true, {
3634			from: $.effects.scaledDimensions( el ),
3635			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3636			origin: options.origin || [ "middle", "center" ]
3637		}, options );
3638
3639	// Fade option to support puff
3640	if ( options.fade ) {
3641		newOptions.from.opacity = 1;
3642		newOptions.to.opacity = 0;
3643	}
3644
3645	$.effects.effect.size.call( this, newOptions, done );
3646} );
3647
3648
3649/*!
3650 * jQuery UI Effects Puff 1.12.1
3651 * http://jqueryui.com
3652 *
3653 * Copyright jQuery Foundation and other contributors
3654 * Released under the MIT license.
3655 * http://jquery.org/license
3656 */
3657
3658//>>label: Puff Effect
3659//>>group: Effects
3660//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3661//>>docs: http://api.jqueryui.com/puff-effect/
3662//>>demos: http://jqueryui.com/effect/
3663
3664
3665
3666var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3667	var newOptions = $.extend( true, {}, options, {
3668		fade: true,
3669		percent: parseInt( options.percent, 10 ) || 150
3670	} );
3671
3672	$.effects.effect.scale.call( this, newOptions, done );
3673} );
3674
3675
3676/*!
3677 * jQuery UI Effects Pulsate 1.12.1
3678 * http://jqueryui.com
3679 *
3680 * Copyright jQuery Foundation and other contributors
3681 * Released under the MIT license.
3682 * http://jquery.org/license
3683 */
3684
3685//>>label: Pulsate Effect
3686//>>group: Effects
3687//>>description: Pulsates an element n times by changing the opacity to zero and back.
3688//>>docs: http://api.jqueryui.com/pulsate-effect/
3689//>>demos: http://jqueryui.com/effect/
3690
3691
3692
3693var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3694	var element = $( this ),
3695		mode = options.mode,
3696		show = mode === "show",
3697		hide = mode === "hide",
3698		showhide = show || hide,
3699
3700		// Showing or hiding leaves off the "last" animation
3701		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3702		duration = options.duration / anims,
3703		animateTo = 0,
3704		i = 1,
3705		queuelen = element.queue().length;
3706
3707	if ( show || !element.is( ":visible" ) ) {
3708		element.css( "opacity", 0 ).show();
3709		animateTo = 1;
3710	}
3711
3712	// Anims - 1 opacity "toggles"
3713	for ( ; i < anims; i++ ) {
3714		element.animate( { opacity: animateTo }, duration, options.easing );
3715		animateTo = 1 - animateTo;
3716	}
3717
3718	element.animate( { opacity: animateTo }, duration, options.easing );
3719
3720	element.queue( done );
3721
3722	$.effects.unshift( element, queuelen, anims + 1 );
3723} );
3724
3725
3726/*!
3727 * jQuery UI Effects Shake 1.12.1
3728 * http://jqueryui.com
3729 *
3730 * Copyright jQuery Foundation and other contributors
3731 * Released under the MIT license.
3732 * http://jquery.org/license
3733 */
3734
3735//>>label: Shake Effect
3736//>>group: Effects
3737//>>description: Shakes an element horizontally or vertically n times.
3738//>>docs: http://api.jqueryui.com/shake-effect/
3739//>>demos: http://jqueryui.com/effect/
3740
3741
3742
3743var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3744
3745	var i = 1,
3746		element = $( this ),
3747		direction = options.direction || "left",
3748		distance = options.distance || 20,
3749		times = options.times || 3,
3750		anims = times * 2 + 1,
3751		speed = Math.round( options.duration / anims ),
3752		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3753		positiveMotion = ( direction === "up" || direction === "left" ),
3754		animation = {},
3755		animation1 = {},
3756		animation2 = {},
3757
3758		queuelen = element.queue().length;
3759
3760	$.effects.createPlaceholder( element );
3761
3762	// Animation
3763	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3764	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3765	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3766
3767	// Animate
3768	element.animate( animation, speed, options.easing );
3769
3770	// Shakes
3771	for ( ; i < times; i++ ) {
3772		element
3773			.animate( animation1, speed, options.easing )
3774			.animate( animation2, speed, options.easing );
3775	}
3776
3777	element
3778		.animate( animation1, speed, options.easing )
3779		.animate( animation, speed / 2, options.easing )
3780		.queue( done );
3781
3782	$.effects.unshift( element, queuelen, anims + 1 );
3783} );
3784
3785
3786/*!
3787 * jQuery UI Effects Slide 1.12.1
3788 * http://jqueryui.com
3789 *
3790 * Copyright jQuery Foundation and other contributors
3791 * Released under the MIT license.
3792 * http://jquery.org/license
3793 */
3794
3795//>>label: Slide Effect
3796//>>group: Effects
3797//>>description: Slides an element in and out of the viewport.
3798//>>docs: http://api.jqueryui.com/slide-effect/
3799//>>demos: http://jqueryui.com/effect/
3800
3801
3802
3803var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3804	var startClip, startRef,
3805		element = $( this ),
3806		map = {
3807			up: [ "bottom", "top" ],
3808			down: [ "top", "bottom" ],
3809			left: [ "right", "left" ],
3810			right: [ "left", "right" ]
3811		},
3812		mode = options.mode,
3813		direction = options.direction || "left",
3814		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3815		positiveMotion = ( direction === "up" || direction === "left" ),
3816		distance = options.distance ||
3817			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3818		animation = {};
3819
3820	$.effects.createPlaceholder( element );
3821
3822	startClip = element.cssClip();
3823	startRef = element.position()[ ref ];
3824
3825	// Define hide animation
3826	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3827	animation.clip = element.cssClip();
3828	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3829
3830	// Reverse the animation if we're showing
3831	if ( mode === "show" ) {
3832		element.cssClip( animation.clip );
3833		element.css( ref, animation[ ref ] );
3834		animation.clip = startClip;
3835		animation[ ref ] = startRef;
3836	}
3837
3838	// Actually animate
3839	element.animate( animation, {
3840		queue: false,
3841		duration: options.duration,
3842		easing: options.easing,
vendor: 4,900 bytes, lines 3843-4038
3843		complete: done
3844	} );
3845} );
3846
3847
3848/*!
3849 * jQuery UI Effects Transfer 1.12.1
3850 * http://jqueryui.com
3851 *
3852 * Copyright jQuery Foundation and other contributors
3853 * Released under the MIT license.
3854 * http://jquery.org/license
3855 */
3856
3857//>>label: Transfer Effect
3858//>>group: Effects
3859//>>description: Displays a transfer effect from one element to another.
3860//>>docs: http://api.jqueryui.com/transfer-effect/
3861//>>demos: http://jqueryui.com/effect/
3862
3863
3864
3865var effect;
3866if ( $.uiBackCompat !== false ) {
3867	effect = $.effects.define( "transfer", function( options, done ) {
3868		$( this ).transfer( options, done );
3869	} );
3870}
3871var effectsEffectTransfer = effect;
3872
3873
3874/*!
3875 * jQuery UI Focusable 1.12.1
3876 * http://jqueryui.com
3877 *
3878 * Copyright jQuery Foundation and other contributors
3879 * Released under the MIT license.
3880 * http://jquery.org/license
3881 */
3882
3883//>>label: :focusable Selector
3884//>>group: Core
3885//>>description: Selects elements which can be focused.
3886//>>docs: http://api.jqueryui.com/focusable-selector/
3887
3888
3889
3890// Selectors
3891$.ui.focusable = function( element, hasTabindex ) {
3892	var map, mapName, img, focusableIfVisible, fieldset,
3893		nodeName = element.nodeName.toLowerCase();
3894
3895	if ( "area" === nodeName ) {
3896		map = element.parentNode;
3897		mapName = map.name;
3898		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3899			return false;
3900		}
3901		img = $( "img[usemap='#" + mapName + "']" );
3902		return img.length > 0 && img.is( ":visible" );
3903	}
3904
3905	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3906		focusableIfVisible = !element.disabled;
3907
3908		if ( focusableIfVisible ) {
3909
3910			// Form controls within a disabled fieldset are disabled.
3911			// However, controls within the fieldset's legend do not get disabled.
3912			// Since controls generally aren't placed inside legends, we skip
3913			// this portion of the check.
3914			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3915			if ( fieldset ) {
3916				focusableIfVisible = !fieldset.disabled;
3917			}
3918		}
3919	} else if ( "a" === nodeName ) {
3920		focusableIfVisible = element.href || hasTabindex;
3921	} else {
3922		focusableIfVisible = hasTabindex;
3923	}
3924
3925	return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) );
3926};
3927
3928// Support: IE 8 only
3929// IE 8 doesn't resolve inherit to visible/hidden for computed values
3930function visible( element ) {
3931	var visibility = element.css( "visibility" );
3932	while ( visibility === "inherit" ) {
3933		element = element.parent();
3934		visibility = element.css( "visibility" );
3935	}
3936	return visibility !== "hidden";
3937}
3938
3939$.extend( $.expr[ ":" ], {
3940	focusable: function( element ) {
3941		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3942	}
3943} );
3944
3945var focusable = $.ui.focusable;
3946
3947
3948
3949
3950// Support: IE8 Only
3951// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop
3952// with a string, so we need to find the proper form.
3953var form = $.fn.form = function() {
3954	return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form );
3955};
3956
3957
3958/*!
3959 * jQuery UI Form Reset Mixin 1.12.1
3960 * http://jqueryui.com
3961 *
3962 * Copyright jQuery Foundation and other contributors
3963 * Released under the MIT license.
3964 * http://jquery.org/license
3965 */
3966
3967//>>label: Form Reset Mixin
3968//>>group: Core
3969//>>description: Refresh input widgets when their form is reset
3970//>>docs: http://api.jqueryui.com/form-reset-mixin/
3971
3972
3973
3974var formResetMixin = $.ui.formResetMixin = {
3975	_formResetHandler: function() {
3976		var form = $( this );
3977
3978		// Wait for the form reset to actually happen before refreshing
3979		setTimeout( function() {
3980			var instances = form.data( "ui-form-reset-instances" );
3981			$.each( instances, function() {
3982				this.refresh();
3983			} );
3984		} );
3985	},
3986
3987	_bindFormResetHandler: function() {
3988		this.form = this.element.form();
3989		if ( !this.form.length ) {
3990			return;
3991		}
3992
3993		var instances = this.form.data( "ui-form-reset-instances" ) || [];
3994		if ( !instances.length ) {
3995
3996			// We don't use _on() here because we use a single event handler per form
3997			this.form.on( "reset.ui-form-reset", this._formResetHandler );
3998		}
3999		instances.push( this );
4000		this.form.data( "ui-form-reset-instances", instances );
4001	},
4002
4003	_unbindFormResetHandler: function() {
4004		if ( !this.form.length ) {
4005			return;
4006		}
4007
4008		var instances = this.form.data( "ui-form-reset-instances" );
4009		instances.splice( $.inArray( this, instances ), 1 );
4010		if ( instances.length ) {
4011			this.form.data( "ui-form-reset-instances", instances );
4012		} else {
4013			this.form
4014				.removeData( "ui-form-reset-instances" )
4015				.off( "reset.ui-form-reset" );
4016		}
4017	}
4018};
4019
4020
4021/*!
4022 * jQuery UI Support for jQuery core 1.7.x 1.12.1
4023 * http://jqueryui.com
4024 *
4025 * Copyright jQuery Foundation and other contributors
4026 * Released under the MIT license.
4027 * http://jquery.org/license
4028 *
4029 */
4030
4031//>>label: jQuery 1.7 Support
4032//>>group: Core
4033//>>description: Support version 1.7.x of jQuery core
4034
4035
4036
4037// Support: jQuery 1.7 only
4038// Not a great way to check versions, but since we only support 
40381.7+ and only
4039// need to detect <1.8, this is a simple check that should suffice. Checking
4040// for "1.7." would be a bit safer, but the version string is 1.7, not 1.7.0
4041// and we'll never reach 1.70.0 (if we do, we certainly won't be supporting
4042// 1.7 anymore). See #11197 for why we're not using feature detection.
4043if ( $.fn.jquery.substring( 0, 3 ) === "1.7" ) {
4044
4045	// Setters for .innerWidth(), .innerHeight(), .outerWidth(), .outerHeight()
4046	// Unlike jQuery Core 1.8+, these only support numeric values to set the
4047	// dimensions in pixels
4048	$.each( [ "Width", "Height" ], function( i, name ) {
4049		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
4050			type = name.toLowerCase(),
4051			orig = {
4052				innerWidth: $.fn.innerWidth,
4053				innerHeight: $.fn.innerHeight,
4054				outerWidth: $.fn.outerWidth,
4055				outerHeight: $.fn.outerHeight
4056			};
4057
4058		function reduce( elem, size, border, margin ) {
4059			$.each( side, function() {
4060				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
4061				if ( border ) {
4062					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
4063				}
4064				if ( margin ) {
4065					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
4066				}
4067			} );
4068			return size;
4069		}
4070
4071		$.fn[ "inner" + name ] = function( size ) {
4072			if ( size === undefined ) {
4073				return orig[ "inner" + name ].call( this );
4074			}
4075
4076			return this.each( function() {
4077				$( this ).css( type, reduce( this, size ) + "px" );
4078			} );
4079		};
4080
4081		$.fn[ "outer" + name ] = function( size, margin ) {
4082			if ( typeof size !== "number" ) {
4083				return orig[ "outer" + name ].call( this, size );
4084			}
4085
4086			return this.each( function() {
4087				$( this ).css( type, reduce( this, size, true, margin ) + "px" );
4088			} );
4089		};
4090	} );
4091
4092	$.fn.addBack = function( selector ) {
4093		return this.add( selector == null ?
4094			this.prevObject : this.prevObject.filter( selector )
4095		);
4096	};
4097}
4098
4099;
4100/*!
4101 * jQuery UI Keycode 1.12.1
4102 * http://jqueryui.com
4103 *
4104 * Copyright jQuery Foundation and other contributors
4105 * Released under the MIT license.
4106 * http://jquery.org/license
4107 */
4108
4109//>>label: Keycode
4110//>>group: Core
4111//>>description: Provide keycodes as keynames
4112//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/
4113
4114
4115var keycode = $.ui.keyCode = {
4116	BACKSPACE: 8,
4117	COMMA: 188,
4118	DELETE: 46,
4119	DOWN: 40,
4120	END: 35,
4121	ENTER: 13,
4122	ESCAPE: 27,
4123	HOME: 36,
4124	LEFT: 37,
4125	PAGE_DOWN: 34,
4126	PAGE_UP: 33,
4127	PERIOD: 190,
4128	RIGHT: 39,
4129	SPACE: 32,
4130	TAB: 9,
4131	UP: 38
4132};
4133
4134
4135
4136
4137// Internal use only
4138var escapeSelector = $.ui.escapeSelector = ( function() {
4139	var selectorEscape = /([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;
4140	return function( selector ) {
4141		return selector.replace( selectorEscape, "\\$1" );
4142	};
4143} )();
4144
4145
4146/*!
4147 * jQuery UI Labels 1.12.1
4148 * http://jqueryui.com
4149 *
4150 * Copyright jQuery Foundation and other contributors
4151 * Released under the MIT license.
4152 * http://jquery.org/license
4153 */
4154
4155//>>label: labels
4156//>>group: Core
4157//>>description: Find all the labels associated with a given input
4158//>>docs: http://api.jqueryui.com/labels/
4159
4160
4161
4162var labels = $.fn.labels = function() {
4163	var ancestor, selector, id, labels, ancestors;
4164
4165	// Check control.labels first
4166	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4167		return this.pushStack( this[ 0 ].labels );
4168	}
4169
4170	// Support: IE <= 11, FF <= 37, Android <= 2.3 only
4171	// Above browsers do not support control.labels. Everything below is to support them
4172	// as well as document fragments. control.labels does not work on document fragments
4173	labels = this.eq( 0 ).parents( "label" );
4174
4175	// Look for the label based on the id
4176	id = this.attr( "id" );
4177	if ( id ) {
4178
4179		// We don't search against the document in case the element
4180		// is disconnected from the DOM
4181		ancestor = this.eq( 0 ).parents().last();
4182
4183		// Get a full set of top level ancestors
4184		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4185
4186		// Create a selector for the label based on the id
4187		selector = "label[for='" + $.ui.escapeSelector( id ) + "']";
4188
4189		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4190
4191	}
4192
4193	// Return whatever we have found for labels
4194	return this.pushStack( labels );
4195};
4196
4197
4198/*!
4199 * jQuery UI Scroll Parent 1.12.1
4200 * http://jqueryui.com
4201 *
4202 * Copyright jQuery Foundation and other contributors
4203 * Released under the MIT license.
4204 * http://jquery.org/license
4205 */
4206
4207//>>label: scrollParent
4208//>>group: Core
4209//>>description: Get the closest ancestor element that is scrollable.
4210//>>docs: http://api.jqueryui.com/scrollParent/
4211
4212
4213
4214var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4215	var position = this.css( "position" ),
4216		excludeStaticParent = position === "absolute",
4217		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4218		scrollParent = this.parents().filter( function() {
4219			var parent = $( this );
4220			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4221				return false;
vendor: 5,582 bytes, lines 4222-4465
4222			}
4223			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4224				parent.css( "overflow-x" ) );
4225		} ).eq( 0 );
4226
4227	return position === "fixed" || !scrollParent.length ?
4228		$( this[ 0 ].ownerDocument || document ) :
4229		scrollParent;
4230};
4231
4232
4233/*!
4234 * jQuery UI Tabbable 1.12.1
4235 * http://jqueryui.com
4236 *
4237 * Copyright jQuery Foundation and other contributors
4238 * Released under the MIT license.
4239 * http://jquery.org/license
4240 */
4241
4242//>>label: :tabbable Selector
4243//>>group: Core
4244//>>description: Selects elements which can be tabbed to.
4245//>>docs: http://api.jqueryui.com/tabbable-selector/
4246
4247
4248
4249var tabbable = $.extend( $.expr[ ":" ], {
4250	tabbable: function( element ) {
4251		var tabIndex = $.attr( element, "tabindex" ),
4252			hasTabindex = tabIndex != null;
4253		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4254	}
4255} );
4256
4257
4258/*!
4259 * jQuery UI Unique ID 1.12.1
4260 * http://jqueryui.com
4261 *
4262 * Copyright jQuery Foundation and other contributors
4263 * Released under the MIT license.
4264 * http://jquery.org/license
4265 */
4266
4267//>>label: uniqueId
4268//>>group: Core
4269//>>description: Functions to generate and remove uniqueId's
4270//>>docs: http://api.jqueryui.com/uniqueId/
4271
4272
4273
4274var uniqueId = $.fn.extend( {
4275	uniqueId: ( function() {
4276		var uuid = 0;
4277
4278		return function() {
4279			return this.each( function() {
4280				if ( !this.id ) {
4281					this.id = "ui-id-" + ( ++uuid );
4282				}
4283			} );
4284		};
4285	} )(),
4286
4287	removeUniqueId: function() {
4288		return this.each( function() {
4289			if ( /^ui-id-\d+$/.test( this.id ) ) {
4290				$( this ).removeAttr( "id" );
4291			}
4292		} );
4293	}
4294} );
4295
4296
4297/*!
4298 * jQuery UI Accordion 1.12.1
4299 * http://jqueryui.com
4300 *
4301 * Copyright jQuery Foundation and other contributors
4302 * Released under the MIT license.
4303 * http://jquery.org/license
4304 */
4305
4306//>>label: Accordion
4307//>>group: Widgets
4308// jscs:disable maximumLineLength
4309//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4310// jscs:enable maximumLineLength
4311//>>docs: http://api.jqueryui.com/accordion/
4312//>>demos: http://jqueryui.com/accordion/
4313//>>css.structure: ../../themes/base/core.css
4314//>>css.structure: ../../themes/base/accordion.css
4315//>>css.theme: ../../themes/base/theme.css
4316
4317
4318
4319var widgetsAccordion = $.widget( "ui.accordion", {
4320	version: "1.12.1",
4321	options: {
4322		active: 0,
4323		animate: {},
4324		classes: {
4325			"ui-accordion-header": "ui-corner-top",
4326			"ui-accordion-header-collapsed": "ui-corner-all",
4327			"ui-accordion-content": "ui-corner-bottom"
4328		},
4329		collapsible: false,
4330		event: "click",
4331		header: "> li > :first-child, > :not(li):even",
4332		heightStyle: "auto",
4333		icons: {
4334			activeHeader: "ui-icon-triangle-1-s",
4335			header: "ui-icon-triangle-1-e"
4336		},
4337
4338		// Callbacks
4339		activate: null,
4340		beforeActivate: null
4341	},
4342
4343	hideProps: {
4344		borderTopWidth: "hide",
4345		borderBottomWidth: "hide",
4346		paddingTop: "hide",
4347		paddingBottom: "hide",
4348		height: "hide"
4349	},
4350
4351	showProps: {
4352		borderTopWidth: "show",
4353		borderBottomWidth: "show",
4354		paddingTop: "show",
4355		paddingBottom: "show",
4356		height: "show"
4357	},
4358
4359	_create: function() {
4360		var options = this.options;
4361
4362		this.prevShow = this.prevHide = $();
4363		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4364		this.element.attr( "role", "tablist" );
4365
4366		// Don't allow collapsible: false and active: false / null
4367		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4368			options.active = 0;
4369		}
4370
4371		this._processPanels();
4372
4373		// handle negative values
4374		if ( options.active < 0 ) {
4375			options.active += this.headers.length;
4376		}
4377		this._refresh();
4378	},
4379
4380	_getCreateEventData: function() {
4381		return {
4382			header: this.active,
4383			panel: !this.active.length ? $() : this.active.next()
4384		};
4385	},
4386
4387	_createIcons: function() {
4388		var icon, children,
4389			icons = this.options.icons;
4390
4391		if ( icons ) {
4392			icon = $( "<span>" );
4393			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4394			icon.prependTo( this.headers );
4395			children = this.active.children( ".ui-accordion-header-icon" );
4396			this._removeClass( children, icons.header )
4397				._addClass( children, null, icons.activeHeader )
4398				._addClass( this.headers, "ui-accordion-icons" );
4399		}
4400	},
4401
4402	_destroyIcons: function() {
4403		this._removeClass( this.headers, "ui-accordion-icons" );
4404		this.headers.children( ".ui-accordion-header-icon" ).remove();
4405	},
4406
4407	_destroy: function() {
4408		var contents;
4409
4410		// Clean up main element
4411		this.element.removeAttr( "role" );
4412
4413		// Clean up headers
4414		this.headers
4415			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4416			.removeUniqueId();
4417
4418		this._destroyIcons();
4419
4420		// Clean up content panels
4421		contents = this.headers.next()
4422			.css( "display", "" )
4423			.removeAttr( "role aria-hidden aria-labelledby" )
4424			.removeUniqueId();
4425
4426		if ( this.options.heightStyle !== "content" ) {
4427			contents.css( "height", "" );
4428		}
4429	},
4430
4431	_setOption: function( key, value ) {
4432		if ( key === "active" ) {
4433
4434			// _activate() will handle invalid values and update this.options
4435			this._activate( value );
4436			return;
4437		}
4438
4439		if ( key === "event" ) {
4440			if ( this.options.event ) {
4441				this._off( this.headers, this.options.event );
4442			}
4443			this._setupEvents( value );
4444		}
4445
4446		this._super( key, value );
4447
4448		// Setting collapsible: false while collapsed; open first panel
4449		if ( key === "collapsible" && !value && this.options.active === false ) {
4450			this._activate( 0 );
4451		}
4452
4453		if ( key === "icons" ) {
4454			this._destroyIcons();
4455			if ( value ) {
4456				this._createIcons();
4457			}
4458		}
4459	},
4460
4461	_setOptionDisabled: function( value ) {
4462		this._super( value );
4463
4464		this.element.attr( "aria-disabled", value );
4465
vendor: 16,234 bytes, lines 4466-5065
4466		// Support: IE8 Only
4467		// #5332 / #6059 - opacity doesn't cascade to positioned elements in IE
4468		// so we need to add the disabled class to the headers and panels
4469		this._toggleClass( null, "ui-state-disabled", !!value );
4470		this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled",
4471			!!value );
4472	},
4473
4474	_keydown: function( event ) {
4475		if ( event.altKey || event.ctrlKey ) {
4476			return;
4477		}
4478
4479		var keyCode = $.ui.keyCode,
4480			length = this.headers.length,
4481			currentIndex = this.headers.index( event.target ),
4482			toFocus = false;
4483
4484		switch ( event.keyCode ) {
4485		case keyCode.RIGHT:
4486		case keyCode.DOWN:
4487			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4488			break;
4489		case keyCode.LEFT:
4490		case keyCode.UP:
4491			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4492			break;
4493		case keyCode.SPACE:
4494		case keyCode.ENTER:
4495			this._eventHandler( event );
4496			break;
4497		case keyCode.HOME:
4498			toFocus = this.headers[ 0 ];
4499			break;
4500		case keyCode.END:
4501			toFocus = this.headers[ length - 1 ];
4502			break;
4503		}
4504
4505		if ( toFocus ) {
4506			$( event.target ).attr( "tabIndex", -1 );
4507			$( toFocus ).attr( "tabIndex", 0 );
4508			$( toFocus ).trigger( "focus" );
4509			event.preventDefault();
4510		}
4511	},
4512
4513	_panelKeyDown: function( event ) {
4514		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4515			$( event.currentTarget ).prev().trigger( "focus" );
4516		}
4517	},
4518
4519	refresh: function() {
4520		var options = this.options;
4521		this._processPanels();
4522
4523		// Was collapsed or no panel
4524		if ( ( options.active === false && options.collapsible === true ) ||
4525				!this.headers.length ) {
4526			options.active = false;
4527			this.active = $();
4528
4529		// active false only when collapsible is true
4530		} else if ( options.active === false ) {
4531			this._activate( 0 );
4532
4533		// was active, but active panel is gone
4534		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4535
4536			// all remaining panel are disabled
4537			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4538				options.active = false;
4539				this.active = $();
4540
4541			// activate previous panel
4542			} else {
4543				this._activate( Math.max( 0, options.active - 1 ) );
4544			}
4545
4546		// was active, active panel still exists
4547		} else {
4548
4549			// make sure active index is correct
4550			options.active = this.headers.index( this.active );
4551		}
4552
4553		this._destroyIcons();
4554
4555		this._refresh();
4556	},
4557
4558	_processPanels: function() {
4559		var prevHeaders = this.headers,
4560			prevPanels = this.panels;
4561
4562		this.headers = this.element.find( this.options.header );
4563		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4564			"ui-state-default" );
4565
4566		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4567		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4568
4569		// Avoid memory leaks (#10056)
4570		if ( prevPanels ) {
4571			this._off( prevHeaders.not( this.headers ) );
4572			this._off( prevPanels.not( this.panels ) );
4573		}
4574	},
4575
4576	_refresh: function() {
4577		var maxHeight,
4578			options = this.options,
4579			heightStyle = options.heightStyle,
4580			parent = this.element.parent();
4581
4582		this.active = this._findActive( options.active );
4583		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4584			._removeClass( this.active, "ui-accordion-header-collapsed" );
4585		this._addClass( this.active.next(), "ui-accordion-content-active" );
4586		this.active.next().show();
4587
4588		this.headers
4589			.attr( "role", "tab" )
4590			.each( function() {
4591				var header = $( this ),
4592					headerId = header.uniqueId().attr( "id" ),
4593					panel = header.next(),
4594					panelId = panel.uniqueId().attr( "id" );
4595				header.attr( "aria-controls", panelId );
4596				panel.attr( "aria-labelledby", headerId );
4597			} )
4598			.next()
4599				.attr( "role", "tabpanel" );
4600
4601		this.headers
4602			.not( this.active )
4603				.attr( {
4604					"aria-selected": "false",
4605					"aria-expanded": "false",
4606					tabIndex: -1
4607				} )
4608				.next()
4609					.attr( {
4610						"aria-hidden": "true"
4611					} )
4612					.hide();
4613
4614		// Make sure at least one header is in the tab order
4615		if ( !this.active.length ) {
4616			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4617		} else {
4618			this.active.attr( {
4619				"aria-selected": "true",
4620				"aria-expanded": "true",
4621				tabIndex: 0
4622			} )
4623				.next()
4624					.attr( {
4625						"aria-hidden": "false"
4626					} );
4627		}
4628
4629		this._createIcons();
4630
4631		this._setupEvents( options.event );
4632
4633		if ( heightStyle === "fill" ) {
4634			maxHeight = parent.height();
4635			this.element.siblings( ":visible" ).each( function() {
4636				var elem = $( this ),
4637					position = elem.css( "position" );
4638
4639				if ( position === "absolute" || position === "fixed" ) {
4640					return;
4641				}
4642				maxHeight -= elem.outerHeight( true );
4643			} );
4644
4645			this.headers.each( function() {
4646				maxHeight -= $( this ).outerHeight( true );
4647			} );
4648
4649			this.headers.next()
4650				.each( function() {
4651					$( this ).height( Math.max( 0, maxHeight -
4652						$( this ).innerHeight() + $( this ).height() ) );
4653				} )
4654				.css( "overflow", "auto" );
4655		} else if ( heightStyle === "auto" ) {
4656			maxHeight = 0;
4657			this.headers.next()
4658				.each( function() {
4659					var isVisible = $( this ).is( ":visible" );
4660					if ( !isVisible ) {
4661						$( this ).show();
4662					}
4663					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4664					if ( !isVisible ) {
4665						$( this ).hide();
4666					}
4667				} )
4668				.height( maxHeight );
4669		}
4670	},
4671
4672	_activate: function( index ) {
4673		var active = this._findActive( index )[ 0 ];
4674
4675		// Trying to activate the already active panel
4676		if ( active === this.active[ 0 ] ) {
4677			return;
4678		}
4679
4680		// Trying to collapse, simulate a click on the currently active header
4681		active = active || this.active[ 0 ];
4682
4683		this._eventHandler( {
4684			target: active,
4685			currentTarget: active,
4686			preventDefault: $.noop
4687		} );
4688	},
4689
4690	_findActive: function( selector ) {
4691		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4692	},
4693
4694	_setupEvents: function( event ) {
4695		var events = {
4696			keydown: "_keydown"
4697		};
4698		if ( event ) {
4699			$.each( event.split( " " ), function( index, eventName ) {
4700				events[ eventName ] = "_eventHandler";
4701			} );
4702		}
4703
4704		this._off( this.headers.add( this.headers.next() ) );
4705		this._on( this.headers, events );
4706		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4707		this._hoverable( this.headers );
4708		this._focusable( this.headers );
4709	},
4710
4711	_eventHandler: function( event ) {
4712		var activeChildren, clickedChildren,
4713			options = this.options,
4714			active = this.active,
4715			clicked = $( event.currentTarget ),
4716			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4717			collapsing = clickedIsActive && options.collapsible,
4718			toShow = collapsing ? $() : clicked.next(),
4719			toHide = active.next(),
4720			eventData = {
4721				oldHeader: active,
4722				oldPanel: toHide,
4723				newHeader: collapsing ? $() : clicked,
4724				newPanel: toShow
4725			};
4726
4727		event.preventDefault();
4728
4729		if (
4730
4731				// click on active header, but not collapsible
4732				( clickedIsActive && !options.collapsible ) ||
4733
4734				// allow canceling activation
4735				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4736			return;
4737		}
4738
4739		options.active = collapsing ? false : this.headers.index( clicked );
4740
4741		// When the call to ._toggle() comes after the class changes
4742		// it causes a very odd bug in IE 8 (see #6720)
4743		this.active = clickedIsActive ? $() : clicked;
4744		this._toggle( eventData );
4745
4746		// Switch classes
4747		// corner classes on the previously active header stay after the animation
4748		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4749		if ( options.icons ) {
4750			activeChildren = active.children( ".ui-accordion-header-icon" );
4751			this._removeClass( activeChildren, null, options.icons.activeHeader )
4752				._addClass( activeChildren, null, options.icons.header );
4753		}
4754
4755		if ( !clickedIsActive ) {
4756			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4757				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4758			if ( options.icons ) {
4759				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4760				this._removeClass( clickedChildren, null, options.icons.header )
4761					._addClass( clickedChildren, null, options.icons.activeHeader );
4762			}
4763
4764			this._addClass( clicked.next(), "ui-accordion-content-active" );
4765		}
4766	},
4767
4768	_toggle: function( data ) {
4769		var toShow = data.newPanel,
4770			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4771
4772		// Handle activating a panel during the animation for another activation
4773		this.prevShow.add( this.prevHide ).stop( true, true );
4774		this.prevShow = toShow;
4775		this.prevHide = toHide;
4776
4777		if ( this.options.animate ) {
4778			this._animate( toShow, toHide, data );
4779		} else {
4780			toHide.hide();
4781			toShow.show();
4782			this._toggleComplete( data );
4783		}
4784
4785		toHide.attr( {
4786			"aria-hidden": "true"
4787		} );
4788		toHide.prev().attr( {
4789			"aria-selected": "false",
4790			"aria-expanded": "false"
4791		} );
4792
4793		// if we're switching panels, remove the old header from the tab order
4794		// if we're opening from collapsed state, remove the previous header from the tab order
4795		// if we're collapsing, then keep the collapsing header in the tab order
4796		if ( toShow.length && toHide.length ) {
4797			toHide.prev().attr( {
4798				"tabIndex": -1,
4799				"aria-expanded": "false"
4800			} );
4801		} else if ( toShow.length ) {
4802			this.headers.filter( function() {
4803				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4804			} )
4805				.attr( "tabIndex", -1 );
4806		}
4807
4808		toShow
4809			.attr( "aria-hidden", "false" )
4810			.prev()
4811				.attr( {
4812					"aria-selected": "true",
4813					"aria-expanded": "true",
4814					tabIndex: 0
4815				} );
4816	},
4817
4818	_animate: function( toShow, toHide, data ) {
4819		var total, easing, duration,
4820			that = this,
4821			adjust = 0,
4822			boxSizing = toShow.css( "box-sizing" ),
4823			down = toShow.length &&
4824				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4825			animate = this.options.animate || {},
4826			options = down && animate.down || animate,
4827			complete = function() {
4828				that._toggleComplete( data );
4829			};
4830
4831		if ( typeof options === "number" ) {
4832			duration = options;
4833		}
4834		if ( typeof options === "string" ) {
4835			easing = options;
4836		}
4837
4838		// fall back from options to animation in case of partial down settings
4839		easing = easing || options.easing || animate.easing;
4840		duration = duration || options.duration || animate.duration;
4841
4842		if ( !toHide.length ) {
4843			return toShow.animate( this.showProps, duration, easing, complete );
4844		}
4845		if ( !toShow.length ) {
4846			return toHide.animate( this.hideProps, duration, easing, complete );
4847		}
4848
4849		total = toShow.show().outerHeight();
4850		toHide.animate( this.hideProps, {
4851			duration: duration,
4852			easing: easing,
4853			step: function( now, fx ) {
4854				fx.now = Math.round( now );
4855			}
4856		} );
4857		toShow
4858			.hide()
4859			.animate( this.showProps, {
4860				duration: duration,
4861				easing: easing,
4862				complete: complete,
4863				step: function( now, fx ) {
4864					fx.now = Math.round( now );
4865					if ( fx.prop !== "height" ) {
4866						if ( boxSizing === "content-box" ) {
4867							adjust += fx.now;
4868						}
4869					} else if ( that.options.heightStyle !== "content" ) {
4870						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4871						adjust = 0;
4872					}
4873				}
4874			} );
4875	},
4876
4877	_toggleComplete: function( data ) {
4878		var toHide = data.oldPanel,
4879			prev = toHide.prev();
4880
4881		this._removeClass( toHide, "ui-accordion-content-active" );
4882		this._removeClass( prev, "ui-accordion-header-active" )
4883			._addClass( prev, "ui-accordion-header-collapsed" );
4884
4885		// Work around for rendering bug in IE (#5421)
4886		if ( toHide.length ) {
4887			toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;
4888		}
4889		this._trigger( "activate", null, data );
4890	}
4891} );
4892
4893
4894
4895var safeActiveElement = $.ui.safeActiveElement = function( document ) {
4896	var activeElement;
4897
4898	// Support: IE 9 only
4899	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
4900	try {
4901		activeElement = document.activeElement;
4902	} catch ( error ) {
4903		activeElement = document.body;
4904	}
4905
4906	// Support: IE 9 - 11 only
4907	// IE may return null instead of an element
4908	// Interestingly, this only seems to occur when NOT in an iframe
4909	if ( !activeElement ) {
4910		activeElement = document.body;
4911	}
4912
4913	// Support: IE 11 only
4914	// IE11 returns a seemingly empty object in some cases when accessing
4915	// document.activeElement from an <iframe>
4916	if ( !activeElement.nodeName ) {
4917		activeElement = document.body;
4918	}
4919
4920	return activeElement;
4921};
4922
4923
4924/*!
4925 * jQuery UI Menu 1.12.1
4926 * http://jqueryui.com
4927 *
4928 * Copyright jQuery Foundation and other contributors
4929 * Released under the MIT license.
4930 * http://jquery.org/license
4931 */
4932
4933//>>label: Menu
4934//>>group: Widgets
4935//>>description: Creates nestable menus.
4936//>>docs: http://api.jqueryui.com/menu/
4937//>>demos: http://jqueryui.com/menu/
4938//>>css.structure: ../../themes/base/core.css
4939//>>css.structure: ../../themes/base/menu.css
4940//>>css.theme: ../../themes/base/theme.css
4941
4942
4943
4944var widgetsMenu = $.widget( "ui.menu", {
4945	version: "1.12.1",
4946	defaultElement: "<ul>",
4947	delay: 300,
4948	options: {
4949		icons: {
4950			submenu: "ui-icon-caret-1-e"
4951		},
4952		items: "> *",
4953		menus: "ul",
4954		position: {
4955			my: "left top",
4956			at: "right top"
4957		},
4958		role: "menu",
4959
4960		// Callbacks
4961		blur: null,
4962		focus: null,
4963		select: null
4964	},
4965
4966	_create: function() {
4967		this.activeMenu = this.element;
4968
4969		// Flag used to prevent firing of the click handler
4970		// as the event bubbles up through nested menus
4971		this.mouseHandled = false;
4972		this.element
4973			.uniqueId()
4974			.attr( {
4975				role: this.options.role,
4976				tabIndex: 0
4977			} );
4978
4979		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4980		this._on( {
4981
4982			// Prevent focus from sticking to links inside menu after clicking
4983			// them (focus should always stay on UL during navigation).
4984			"mousedown .ui-menu-item": function( event ) {
4985				event.preventDefault();
4986			},
4987			"click .ui-menu-item": function( event ) {
4988				var target = $( event.target );
4989				var active = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
4990				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4991					this.select( event );
4992
4993					// Only set the mouseHandled flag if the event will bubble, see #9469.
4994					if ( !event.isPropagationStopped() ) {
4995						this.mouseHandled = true;
4996					}
4997
4998					// Open submenu on click
4999					if ( target.has( ".ui-menu" ).length ) {
5000						this.expand( event );
5001					} else if ( !this.element.is( ":focus" ) &&
5002							active.closest( ".ui-menu" ).length ) {
5003
5004						// Redirect focus to the menu
5005						this.element.trigger( "focus", [ true ] );
5006
5007						// If the active item is on the top level, let it stay active.
5008						// Otherwise, blur the active item since it is no longer visible.
5009						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
5010							clearTimeout( this.timer );
5011						}
5012					}
5013				}
5014			},
5015			"mouseenter .ui-menu-item": function( event ) {
5016
5017				// Ignore mouse events while typeahead is active, see #10458.
5018				// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
5019				// is over an item in the menu
5020				if ( this.previousFilter ) {
5021					return;
5022				}
5023
5024				var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
5025					target = $( event.currentTarget );
5026
5027				// Ignore bubbled events on parent items, see #11641
5028				if ( actualTarget[ 0 ] !== target[ 0 ] ) {
5029					return;
5030				}
5031
5032				// Remove ui-state-active class from siblings of the newly focused menu item
5033				// to avoid a jump caused by adjacent elements both having a class with a border
5034				this._removeClass( target.siblings().children( ".ui-state-active" ),
5035					null, "ui-state-active" );
5036				this.focus( event, target );
5037			},
5038			mouseleave: "collapseAll",
5039			"mouseleave .ui-menu": "collapseAll",
5040			focus: function( event, keepActiveItem ) {
5041
5042				// If there's already an active item, keep it active
5043				// If not, activate the first item
5044				var item = this.active || this.element.find( this.options.items ).eq( 0 );
5045
5046				if ( !keepActiveItem ) {
5047					this.focus( event, item );
5048				}
5049			},
5050			blur: function( event ) {
5051				this._delay( function() {
5052					var notContained = !$.contains(
5053						this.element[ 0 ],
5054						$.ui.safeActiveElement( this.document[ 0 ] )
5055					);
5056					if ( notContained ) {
5057						this.collapseAll( event );
5058					}
5059				} );
5060			},
5061			keydown: "_keydown"
5062		} );
5063
5064		this.refresh();
5065
5066		// Clicks outside of a menu collapse any open menus
5067		this._on( this.document, {
5068			click: function( event ) {
5069				if ( this._closeOnDocumentClick( event ) ) {
5070					this.collapseAll( event );
5071				}
5072
5073				// Reset the mouseHandled flag
5074				this.mouseHandled = false;
5075			}
5076		}
vendor: 9,131 bytes, lines 5076-5410
5076 );
5077	},
5078
5079	_destroy: function() {
5080		var items = this.element.find( ".ui-menu-item" )
5081				.removeAttr( "role aria-disabled" ),
5082			submenus = items.children( ".ui-menu-item-wrapper" )
5083				.removeUniqueId()
5084				.removeAttr( "tabIndex role aria-haspopup" );
5085
5086		// Destroy (sub)menus
5087		this.element
5088			.removeAttr( "aria-activedescendant" )
5089			.find( ".ui-menu" ).addBack()
5090				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5091					"tabIndex" )
5092				.removeUniqueId()
5093				.show();
5094
5095		submenus.children().each( function() {
5096			var elem = $( this );
5097			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5098				elem.remove();
5099			}
5100		} );
5101	},
5102
5103	_keydown: function( event ) {
5104		var match, prev, character, skip,
5105			preventDefault = true;
5106
5107		switch ( event.keyCode ) {
5108		case $.ui.keyCode.PAGE_UP:
5109			this.previousPage( event );
5110			break;
5111		case $.ui.keyCode.PAGE_DOWN:
5112			this.nextPage( event );
5113			break;
5114		case $.ui.keyCode.HOME:
5115			this._move( "first", "first", event );
5116			break;
5117		case $.ui.keyCode.END:
5118			this._move( "last", "last", event );
5119			break;
5120		case $.ui.keyCode.UP:
5121			this.previous( event );
5122			break;
5123		case $.ui.keyCode.DOWN:
5124			this.next( event );
5125			break;
5126		case $.ui.keyCode.LEFT:
5127			this.collapse( event );
5128			break;
5129		case $.ui.keyCode.RIGHT:
5130			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5131				this.expand( event );
5132			}
5133			break;
5134		case $.ui.keyCode.ENTER:
5135		case $.ui.keyCode.SPACE:
5136			this._activate( event );
5137			break;
5138		case $.ui.keyCode.ESCAPE:
5139			this.collapse( event );
5140			break;
5141		default:
5142			preventDefault = false;
5143			prev = this.previousFilter || "";
5144			skip = false;
5145
5146			// Support number pad values
5147			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5148				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5149
5150			clearTimeout( this.filterTimer );
5151
5152			if ( character === prev ) {
5153				skip = true;
5154			} else {
5155				character = prev + character;
5156			}
5157
5158			match = this._filterMenuItems( character );
5159			match = skip && match.index( this.active.next() ) !== -1 ?
5160				this.active.nextAll( ".ui-menu-item" ) :
5161				match;
5162
5163			// If no matches on the current filter, reset to the last character pressed
5164			// to move down the menu to the first item that starts with that character
5165			if ( !match.length ) {
5166				character = String.fromCharCode( event.keyCode );
5167				match = this._filterMenuItems( character );
5168			}
5169
5170			if ( match.length ) {
5171				this.focus( event, match );
5172				this.previousFilter = character;
5173				this.filterTimer = this._delay( function() {
5174					delete this.previousFilter;
5175				}, 1000 );
5176			} else {
5177				delete this.previousFilter;
5178			}
5179		}
5180
5181		if ( preventDefault ) {
5182			event.preventDefault();
5183		}
5184	},
5185
5186	_activate: function( event ) {
5187		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5188			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5189				this.expand( event );
5190			} else {
5191				this.select( event );
5192			}
5193		}
5194	},
5195
5196	refresh: function() {
5197		var menus, items, newSubmenus, newItems, newWrappers,
5198			that = this,
5199			icon = this.options.icons.submenu,
5200			submenus = this.element.find( this.options.menus );
5201
5202		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5203
5204		// Initialize nested menus
5205		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5206			.hide()
5207			.attr( {
5208				role: this.options.role,
5209				"aria-hidden": "true",
5210				"aria-expanded": "false"
5211			} )
5212			.each( function() {
5213				var menu = $( this ),
5214					item = menu.prev(),
5215					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5216
5217				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5218				item
5219					.attr( "aria-haspopup", "true" )
5220					.prepend( submenuCaret );
5221				menu.attr( "aria-labelledby", item.attr( "id" ) );
5222			} );
5223
5224		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5225
5226		menus = submenus.add( this.element );
5227		items = menus.find( this.options.items );
5228
5229		// Initialize menu-items containing spaces and/or dashes only as dividers
5230		items.not( ".ui-menu-item" ).each( function() {
5231			var item = $( this );
5232			if ( that._isDivider( item ) ) {
5233				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5234			}
5235		} );
5236
5237		// Don't refresh list items that are already adapted
5238		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5239		newWrappers = newItems.children()
5240			.not( ".ui-menu" )
5241				.uniqueId()
5242				.attr( {
5243					tabIndex: -1,
5244					role: this._itemRole()
5245				} );
5246		this._addClass( newItems, "ui-menu-item" )
5247			._addClass( newWrappers, "ui-menu-item-wrapper" );
5248
5249		// Add aria-disabled attribute to any disabled menu item
5250		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5251
5252		// If the active item has been removed, blur the menu
5253		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5254			this.blur();
5255		}
5256	},
5257
5258	_itemRole: function() {
5259		return {
5260			menu: "menuitem",
5261			listbox: "option"
5262		}[ this.options.role ];
5263	},
5264
5265	_setOption: function( key, value ) {
5266		if ( key === "icons" ) {
5267			var icons = this.element.find( ".ui-menu-icon" );
5268			this._removeClass( icons, null, this.options.icons.submenu )
5269				._addClass( icons, null, value.submenu );
5270		}
5271		this._super( key, value );
5272	},
5273
5274	_setOptionDisabled: function( value ) {
5275		this._super( value );
5276
5277		this.element.attr( "aria-disabled", String( value ) );
5278		this._toggleClass( null, "ui-state-disabled", !!value );
5279	},
5280
5281	focus: function( event, item ) {
5282		var nested, focused, activeParent;
5283		this.blur( event, event && event.type === "focus" );
5284
5285		this._scrollIntoView( item );
5286
5287		this.active = item.first();
5288
5289		focused = this.active.children( ".ui-menu-item-wrapper" );
5290		this._addClass( focused, null, "ui-state-active" );
5291
5292		// Only update aria-activedescendant if there's a role
5293		// otherwise we assume focus is managed elsewhere
5294		if ( this.options.role ) {
5295			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5296		}
5297
5298		// Highlight active parent menu item, if any
5299		activeParent = this.active
5300			.parent()
5301				.closest( ".ui-menu-item" )
5302					.children( ".ui-menu-item-wrapper" );
5303		this._addClass( activeParent, null, "ui-state-active" );
5304
5305		if ( event && event.type === "keydown" ) {
5306			this._close();
5307		} else {
5308			this.timer = this._delay( function() {
5309				this._close();
5310			}, this.delay );
5311		}
5312
5313		nested = item.children( ".ui-menu" );
5314		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5315			this._startOpening( nested );
5316		}
5317		this.activeMenu = item.parent();
5318
5319		this._trigger( "focus", event, { item: item } );
5320	},
5321
5322	_scrollIntoView: function( item ) {
5323		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5324		if ( this._hasScroll() ) {
5325			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5326			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5327			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5328			scroll = this.activeMenu.scrollTop();
5329			elementHeight = this.activeMenu.height();
5330			itemHeight = item.outerHeight();
5331
5332			if ( offset < 0 ) {
5333				this.activeMenu.scrollTop( scroll + offset );
5334			} else if ( offset + itemHeight > elementHeight ) {
5335				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5336			}
5337		}
5338	},
5339
5340	blur: function( event, fromFocus ) {
5341		if ( !fromFocus ) {
5342			clearTimeout( this.timer );
5343		}
5344
5345		if ( !this.active ) {
5346			return;
5347		}
5348
5349		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5350			null, "ui-state-active" );
5351
5352		this._trigger( "blur", event, { item: this.active } );
5353		this.active = null;
5354	},
5355
5356	_startOpening: function( submenu ) {
5357		clearTimeout( this.timer );
5358
5359		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5360		// shift in the submenu position when mousing over the caret icon
5361		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5362			return;
5363		}
5364
5365		this.timer = this._delay( function() {
5366			this._close();
5367			this._open( submenu );
5368		}, this.delay );
5369	},
5370
5371	_open: function( submenu ) {
5372		var position = $.extend( {
5373			of: this.active
5374		}, this.options.position );
5375
5376		clearTimeout( this.timer );
5377		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5378			.hide()
5379			.attr( "aria-hidden", "true" );
5380
5381		submenu
5382			.show()
5383			.removeAttr( "aria-hidden" )
5384			.attr( "aria-expanded", "true" )
5385			.position( position );
5386	},
5387
5388	collapseAll: function( event, all ) {
5389		clearTimeout( this.timer );
5390		this.timer = this._delay( function() {
5391
5392			// If we were passed an event, look for the submenu that contains the event
5393			var currentMenu = all ? this.element :
5394				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5395
5396			// If we found no valid submenu ancestor, use the main menu to close all
5397			// sub menus anyway
5398			if ( !currentMenu.length ) {
5399				currentMenu = this.element;
5400			}
5401
5402			this._close( currentMenu );
5403
5404			this.blur( event );
5405
5406			// Work around active item staying active after menu is blurred
5407			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5408
5409			this.activeMenu = currentMenu;
5410		}, 
vendor: 6,612 bytes, lines 5410-5662
5410this.delay );
5411	},
5412
5413	// With no arguments, closes the currently active menu - if nothing is active
5414	// it closes all menus.  If passed an argument, it will search for menus BELOW
5415	_close: function( startMenu ) {
5416		if ( !startMenu ) {
5417			startMenu = this.active ? this.active.parent() : this.element;
5418		}
5419
5420		startMenu.find( ".ui-menu" )
5421			.hide()
5422			.attr( "aria-hidden", "true" )
5423			.attr( "aria-expanded", "false" );
5424	},
5425
5426	_closeOnDocumentClick: function( event ) {
5427		return !$( event.target ).closest( ".ui-menu" ).length;
5428	},
5429
5430	_isDivider: function( item ) {
5431
5432		// Match hyphen, em dash, en dash
5433		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5434	},
5435
5436	collapse: function( event ) {
5437		var newItem = this.active &&
5438			this.active.parent().closest( ".ui-menu-item", this.element );
5439		if ( newItem && newItem.length ) {
5440			this._close();
5441			this.focus( event, newItem );
5442		}
5443	},
5444
5445	expand: function( event ) {
5446		var newItem = this.active &&
5447			this.active
5448				.children( ".ui-menu " )
5449					.find( this.options.items )
5450						.first();
5451
5452		if ( newItem && newItem.length ) {
5453			this._open( newItem.parent() );
5454
5455			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5456			this._delay( function() {
5457				this.focus( event, newItem );
5458			} );
5459		}
5460	},
5461
5462	next: function( event ) {
5463		this._move( "next", "first", event );
5464	},
5465
5466	previous: function( event ) {
5467		this._move( "prev", "last", event );
5468	},
5469
5470	isFirstItem: function() {
5471		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5472	},
5473
5474	isLastItem: function() {
5475		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5476	},
5477
5478	_move: function( direction, filter, event ) {
5479		var next;
5480		if ( this.active ) {
5481			if ( direction === "first" || direction === "last" ) {
5482				next = this.active
5483					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5484					.eq( -1 );
5485			} else {
5486				next = this.active
5487					[ direction + "All" ]( ".ui-menu-item" )
5488					.eq( 0 );
5489			}
5490		}
5491		if ( !next || !next.length || !this.active ) {
5492			next = this.activeMenu.find( this.options.items )[ filter ]();
5493		}
5494
5495		this.focus( event, next );
5496	},
5497
5498	nextPage: function( event ) {
5499		var item, base, height;
5500
5501		if ( !this.active ) {
5502			this.next( event );
5503			return;
5504		}
5505		if ( this.isLastItem() ) {
5506			return;
5507		}
5508		if ( this._hasScroll() ) {
5509			base = this.active.offset().top;
5510			height = this.element.height();
5511			this.active.nextAll( ".ui-menu-item" ).each( function() {
5512				item = $( this );
5513				return item.offset().top - base - height < 0;
5514			} );
5515
5516			this.focus( event, item );
5517		} else {
5518			this.focus( event, this.activeMenu.find( this.options.items )
5519				[ !this.active ? "first" : "last" ]() );
5520		}
5521	},
5522
5523	previousPage: function( event ) {
5524		var item, base, height;
5525		if ( !this.active ) {
5526			this.next( event );
5527			return;
5528		}
5529		if ( this.isFirstItem() ) {
5530			return;
5531		}
5532		if ( this._hasScroll() ) {
5533			base = this.active.offset().top;
5534			height = this.element.height();
5535			this.active.prevAll( ".ui-menu-item" ).each( function() {
5536				item = $( this );
5537				return item.offset().top - base + height > 0;
5538			} );
5539
5540			this.focus( event, item );
5541		} else {
5542			this.focus( event, this.activeMenu.find( this.options.items ).first() );
5543		}
5544	},
5545
5546	_hasScroll: function() {
5547		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5548	},
5549
5550	select: function( event ) {
5551
5552		// TODO: It should never be possible to not have an active item at this
5553		// point, but the tests don't trigger mouseenter before click.
5554		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5555		var ui = { item: this.active };
5556		if ( !this.active.has( ".ui-menu" ).length ) {
5557			this.collapseAll( event, true );
5558		}
5559		this._trigger( "select", event, ui );
5560	},
5561
5562	_filterMenuItems: function( character ) {
5563		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5564			regex = new RegExp( "^" + escapedCharacter, "i" );
5565
5566		return this.activeMenu
5567			.find( this.options.items )
5568
5569				// Only match on items, not dividers or other content (#10571)
5570				.filter( ".ui-menu-item" )
5571					.filter( function() {
5572						return regex.test(
5573							$.trim( $( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5574					} );
5575	}
5576} );
5577
5578
5579/*!
5580 * jQuery UI Autocomplete 1.12.1
5581 * http://jqueryui.com
5582 *
5583 * Copyright jQuery Foundation and other contributors
5584 * Released under the MIT license.
5585 * http://jquery.org/license
5586 */
5587
5588//>>label: Autocomplete
5589//>>group: Widgets
5590//>>description: Lists suggested words as the user is typing.
5591//>>docs: http://api.jqueryui.com/autocomplete/
5592//>>demos: http://jqueryui.com/autocomplete/
5593//>>css.structure: ../../themes/base/core.css
5594//>>css.structure: ../../themes/base/autocomplete.css
5595//>>css.theme: ../../themes/base/theme.css
5596
5597
5598
5599$.widget( "ui.autocomplete", {
5600	version: "1.12.1",
5601	defaultElement: "<input>",
5602	options: {
5603		appendTo: null,
5604		autoFocus: false,
5605		delay: 300,
5606		minLength: 1,
5607		position: {
5608			my: "left top",
5609			at: "left bottom",
5610			collision: "none"
5611		},
5612		source: null,
5613
5614		// Callbacks
5615		change: null,
5616		close: null,
5617		focus: null,
5618		open: null,
5619		response: null,
5620		search: null,
5621		select: null
5622	},
5623
5624	requestIndex: 0,
5625	pending: 0,
5626
5627	_create: function() {
5628
5629		// Some browsers only repeat keydown events, not keypress events,
5630		// so we use the suppressKeyPress flag to determine if we've already
5631		// handled the keydown event. #7269
5632		// Unfortunately the code for & in keypress is the same as the up arrow,
5633		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5634		// events when we know the keydown event was used to modify the
5635		// search term. #7799
5636		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5637			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5638			isTextarea = nodeName === "textarea",
5639			isInput = nodeName === "input";
5640
5641		// Textareas are always multi-line
5642		// Inputs are always single-line, even if inside a contentEditable element
5643		// IE also treats inputs as contentEditable
5644		// All other element types are determined by whether or not they're contentEditable
5645		this.isMultiLine = isTextarea || !isInput && this._isContentEditable( this.element );
5646
5647		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5648		this.isNewMenu = true;
5649
5650		this._addClass( "ui-autocomplete-input" );
5651		this.element.attr( "autocomplete", "off" );
5652
5653		this._on( this.element, {
5654			keydown: function( event ) {
5655				if ( this.element.prop( "readOnly" ) ) {
5656					suppressKeyPress = true;
5657					suppressInput = true;
5658					suppressKeyPressRepeat = true;
5659					return;
5660				}
5661
5662				suppressKeyPress = false;
vendor: 8,598 bytes, lines 5663-5982
5663				suppressInput = false;
5664				suppressKeyPressRepeat = false;
5665				var keyCode = $.ui.keyCode;
5666				switch ( event.keyCode ) {
5667				case keyCode.PAGE_UP:
5668					suppressKeyPress = true;
5669					this._move( "previousPage", event );
5670					break;
5671				case keyCode.PAGE_DOWN:
5672					suppressKeyPress = true;
5673					this._move( "nextPage", event );
5674					break;
5675				case keyCode.UP:
5676					suppressKeyPress = true;
5677					this._keyEvent( "previous", event );
5678					break;
5679				case keyCode.DOWN:
5680					suppressKeyPress = true;
5681					this._keyEvent( "next", event );
5682					break;
5683				case keyCode.ENTER:
5684
5685					// when menu is open and has focus
5686					if ( this.menu.active ) {
5687
5688						// #6055 - Opera still allows the keypress to occur
5689						// which causes forms to submit
5690						suppressKeyPress = true;
5691						event.preventDefault();
5692						this.menu.select( event );
5693					}
5694					break;
5695				case keyCode.TAB:
5696					if ( this.menu.active ) {
5697						this.menu.select( event );
5698					}
5699					break;
5700				case keyCode.ESCAPE:
5701					if ( this.menu.element.is( ":visible" ) ) {
5702						if ( !this.isMultiLine ) {
5703							this._value( this.term );
5704						}
5705						this.close( event );
5706
5707						// Different browsers have different default behavior for escape
5708						// Single press can mean undo or clear
5709						// Double press in IE means clear the whole form
5710						event.preventDefault();
5711					}
5712					break;
5713				default:
5714					suppressKeyPressRepeat = true;
5715
5716					// search timeout should be triggered before the input value is changed
5717					this._searchTimeout( event );
5718					break;
5719				}
5720			},
5721			keypress: function( event ) {
5722				if ( suppressKeyPress ) {
5723					suppressKeyPress = false;
5724					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5725						event.preventDefault();
5726					}
5727					return;
5728				}
5729				if ( suppressKeyPressRepeat ) {
5730					return;
5731				}
5732
5733				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5734				var keyCode = $.ui.keyCode;
5735				switch ( event.keyCode ) {
5736				case keyCode.PAGE_UP:
5737					this._move( "previousPage", event );
5738					break;
5739				case keyCode.PAGE_DOWN:
5740					this._move( "nextPage", event );
5741					break;
5742				case keyCode.UP:
5743					this._keyEvent( "previous", event );
5744					break;
5745				case keyCode.DOWN:
5746					this._keyEvent( "next", event );
5747					break;
5748				}
5749			},
5750			input: function( event ) {
5751				if ( suppressInput ) {
5752					suppressInput = false;
5753					event.preventDefault();
5754					return;
5755				}
5756				this._searchTimeout( event );
5757			},
5758			focus: function() {
5759				this.selectedItem = null;
5760				this.previous = this._value();
5761			},
5762			blur: function( event ) {
5763				if ( this.cancelBlur ) {
5764					delete this.cancelBlur;
5765					return;
5766				}
5767
5768				clearTimeout( this.searching );
5769				this.close( event );
5770				this._change( event );
5771			}
5772		} );
5773
5774		this._initSource();
5775		this.menu = $( "<ul>" )
5776			.appendTo( this._appendTo() )
5777			.menu( {
5778
5779				// disable ARIA support, the live region takes care of that
5780				role: null
5781			} )
5782			.hide()
5783			.menu( "instance" );
5784
5785		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5786		this._on( this.menu.element, {
5787			mousedown: function( event ) {
5788
5789				// prevent moving focus out of the text field
5790				event.preventDefault();
5791
5792				// IE doesn't prevent moving focus even with event.preventDefault()
5793				// so we set a flag to know when we should ignore the blur event
5794				this.cancelBlur = true;
5795				this._delay( function() {
5796					delete this.cancelBlur;
5797
5798					// Support: IE 8 only
5799					// Right clicking a menu item or selecting text from the menu items will
5800					// result in focus moving out of the input. However, we've already received
5801					// and ignored the blur event because of the cancelBlur flag set above. So
5802					// we restore focus to ensure that the menu closes properly based on the user's
5803					// next actions.
5804					if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5805						this.element.trigger( "focus" );
5806					}
5807				} );
5808			},
5809			menufocus: function( event, ui ) {
5810				var label, item;
5811
5812				// support: Firefox
5813				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5814				if ( this.isNewMenu ) {
5815					this.isNewMenu = false;
5816					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5817						this.menu.blur();
5818
5819						this.document.one( "mousemove", function() {
5820							$( event.target ).trigger( event.originalEvent );
5821						} );
5822
5823						return;
5824					}
5825				}
5826
5827				item = ui.item.data( "ui-autocomplete-item" );
5828				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5829
5830					// use value to match what will end up in the input, if it was a key event
5831					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5832						this._value( item.value );
5833					}
5834				}
5835
5836				// Announce the value in the liveRegion
5837				label = ui.item.attr( "aria-label" ) || item.value;
5838				if ( label && $.trim( label ).length ) {
5839					this.liveRegion.children().hide();
5840					$( "<div>" ).text( label ).appendTo( this.liveRegion );
5841				}
5842			},
5843			menuselect: function( event, ui ) {
5844				var item = ui.item.data( "ui-autocomplete-item" ),
5845					previous = this.previous;
5846
5847				// Only trigger when focus was lost (click on menu)
5848				if ( this.element[ 0 ] !== $.ui.safeActiveElement( this.document[ 0 ] ) ) {
5849					this.element.trigger( "focus" );
5850					this.previous = previous;
5851
5852					// #6109 - IE triggers two focus events and the second
5853					// is asynchronous, so we need to reset the previous
5854					// term synchronously and asynchronously :-(
5855					this._delay( function() {
5856						this.previous = previous;
5857						this.selectedItem = item;
5858					} );
5859				}
5860
5861				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5862					this._value( item.value );
5863				}
5864
5865				// reset the term after the select event
5866				// this allows custom select handling to work properly
5867				this.term = this._value();
5868
5869				this.close( event );
5870				this.selectedItem = item;
5871			}
5872		} );
5873
5874		this.liveRegion = $( "<div>", {
5875			role: "status",
5876			"aria-live": "assertive",
5877			"aria-relevant": "additions"
5878		} )
5879			.appendTo( this.document[ 0 ].body );
5880
5881		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5882
5883		// Turning off autocomplete prevents the browser from remembering the
5884		// value when navigating through history, so we re-enable autocomplete
5885		// if the page is unloaded before the widget is destroyed. #7790
5886		this._on( this.window, {
5887			beforeunload: function() {
5888				this.element.removeAttr( "autocomplete" );
5889			}
5890		} );
5891	},
5892
5893	_destroy: function() {
5894		clearTimeout( this.searching );
5895		this.element.removeAttr( "autocomplete" );
5896		this.menu.element.remove();
5897		this.liveRegion.remove();
5898	},
5899
5900	_setOption: function( key, value ) {
5901		this._super( key, value );
5902		if ( key === "source" ) {
5903			this._initSource();
5904		}
5905		if ( key === "appendTo" ) {
5906			this.menu.element.appendTo( this._appendTo() );
5907		}
5908		if ( key === "disabled" && value && this.xhr ) {
5909			this.xhr.abort();
5910		}
5911	},
5912
5913	_isEventTargetInWidget: function( event ) {
5914		var menuElement = this.menu.element[ 0 ];
5915
5916		return event.target === this.element[ 0 ] ||
5917			event.target === menuElement ||
5918			$.contains( menuElement, event.target );
5919	},
5920
5921	_closeOnClickOutside: function( event ) {
5922		if ( !this._isEventTargetInWidget( event ) ) {
5923			this.close();
5924		}
5925	},
5926
5927	_appendTo: function() {
5928		var element = this.options.appendTo;
5929
5930		if ( element ) {
5931			element = element.jquery || element.nodeType ?
5932				$( element ) :
5933				this.document.find( element ).eq( 0 );
5934		}
5935
5936		if ( !element || !element[ 0 ] ) {
5937			element = this.element.closest( ".ui-front, dialog" );
5938		}
5939
5940		if ( !element.length ) {
5941			element = this.document[ 0 ].body;
5942		}
5943
5944		return element;
5945	},
5946
5947	_initSource: function() {
5948		var array, url,
5949			that = this;
5950		if ( $.isArray( this.options.source ) ) {
5951			array = this.options.source;
5952			this.source = function( request, response ) {
5953				response( $.ui.autocomplete.filter( array, request.term ) );
5954			};
5955		} else if ( typeof this.options.source === "string" ) {
5956			url = this.options.source;
5957			this.source = function( request, response ) {
5958				if ( that.xhr ) {
5959					that.xhr.abort();
5960				}
5961				that.xhr = $.ajax( {
5962					url: url,
5963					data: request,
5964					dataType: "json",
5965					success: function( data ) {
5966						response( data );
5967					},
5968					error: function() {
5969						response( [] );
5970					}
5971				} );
5972			};
5973		} else {
5974			this.source = this.options.source;
5975		}
5976	},
5977
5978	_searchTimeout: function( event ) {
5979		clearTimeout( this.searching );
5980		this.searching = this._delay( function() {
5981
5982			// Search if the value has changed, or if the user retypes the same value (see #7434)
vendor: 4,901 bytes, lines 5983-6185
5983			var equalValues = this.term === this._value(),
5984				menuVisible = this.menu.element.is( ":visible" ),
5985				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5986
5987			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5988				this.selectedItem = null;
5989				this.search( null, event );
5990			}
5991		}, this.options.delay );
5992	},
5993
5994	search: function( value, event ) {
5995		value = value != null ? value : this._value();
5996
5997		// Always save the actual value, not the one passed as an argument
5998		this.term = this._value();
5999
6000		if ( value.length < this.options.minLength ) {
6001			return this.close( event );
6002		}
6003
6004		if ( this._trigger( "search", event ) === false ) {
6005			return;
6006		}
6007
6008		return this._search( value );
6009	},
6010
6011	_search: function( value ) {
6012		this.pending++;
6013		this._addClass( "ui-autocomplete-loading" );
6014		this.cancelSearch = false;
6015
6016		this.source( { term: value }, this._response() );
6017	},
6018
6019	_response: function() {
6020		var index = ++this.requestIndex;
6021
6022		return $.proxy( function( content ) {
6023			if ( index === this.requestIndex ) {
6024				this.__response( content );
6025			}
6026
6027			this.pending--;
6028			if ( !this.pending ) {
6029				this._removeClass( "ui-autocomplete-loading" );
6030			}
6031		}, this );
6032	},
6033
6034	__response: function( content ) {
6035		if ( content ) {
6036			content = this._normalize( content );
6037		}
6038		this._trigger( "response", null, { content: content } );
6039		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
6040			this._suggest( content );
6041			this._trigger( "open" );
6042		} else {
6043
6044			// use ._close() instead of .close() so we don't cancel future searches
6045			this._close();
6046		}
6047	},
6048
6049	close: function( event ) {
6050		this.cancelSearch = true;
6051		this._close( event );
6052	},
6053
6054	_close: function( event ) {
6055
6056		// Remove the handler that closes the menu on outside clicks
6057		this._off( this.document, "mousedown" );
6058
6059		if ( this.menu.element.is( ":visible" ) ) {
6060			this.menu.element.hide();
6061			this.menu.blur();
6062			this.isNewMenu = true;
6063			this._trigger( "close", event );
6064		}
6065	},
6066
6067	_change: function( event ) {
6068		if ( this.previous !== this._value() ) {
6069			this._trigger( "change", event, { item: this.selectedItem } );
6070		}
6071	},
6072
6073	_normalize: function( items ) {
6074
6075		// assume all items have the right format when the first item is complete
6076		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
6077			return items;
6078		}
6079		return $.map( items, function( item ) {
6080			if ( typeof item === "string" ) {
6081				return {
6082					label: item,
6083					value: item
6084				};
6085			}
6086			return $.extend( {}, item, {
6087				label: item.label || item.value,
6088				value: item.value || item.label
6089			} );
6090		} );
6091	},
6092
6093	_suggest: function( items ) {
6094		var ul = this.menu.element.empty();
6095		this._renderMenu( ul, items );
6096		this.isNewMenu = true;
6097		this.menu.refresh();
6098
6099		// Size and position menu
6100		ul.show();
6101		this._resizeMenu();
6102		ul.position( $.extend( {
6103			of: this.element
6104		}, this.options.position ) );
6105
6106		if ( this.options.autoFocus ) {
6107			this.menu.next();
6108		}
6109
6110		// Listen for interactions outside of the widget (#6642)
6111		this._on( this.document, {
6112			mousedown: "_closeOnClickOutside"
6113		} );
6114	},
6115
6116	_resizeMenu: function() {
6117		var ul = this.menu.element;
6118		ul.outerWidth( Math.max(
6119
6120			// Firefox wraps long text (possibly a rounding bug)
6121			// so we add 1px to avoid the wrapping (#7513)
6122			ul.width( "" ).outerWidth() + 1,
6123			this.element.outerWidth()
6124		) );
6125	},
6126
6127	_renderMenu: function( ul, items ) {
6128		var that = this;
6129		$.each( items, function( index, item ) {
6130			that._renderItemData( ul, item );
6131		} );
6132	},
6133
6134	_renderItemData: function( ul, item ) {
6135		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6136	},
6137
6138	_renderItem: function( ul, item ) {
6139		return $( "<li>" )
6140			.append( $( "<div>" ).text( item.label ) )
6141			.appendTo( ul );
6142	},
6143
6144	_move: function( direction, event ) {
6145		if ( !this.menu.element.is( ":visible" ) ) {
6146			this.search( null, event );
6147			return;
6148		}
6149		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6150				this.menu.isLastItem() && /^next/.test( direction ) ) {
6151
6152			if ( !this.isMultiLine ) {
6153				this._value( this.term );
6154			}
6155
6156			this.menu.blur();
6157			return;
6158		}
6159		this.menu[ direction ]( event );
6160	},
6161
6162	widget: function() {
6163		return this.menu.element;
6164	},
6165
6166	_value: function() {
6167		return this.valueMethod.apply( this.element, arguments );
6168	},
6169
6170	_keyEvent: function( keyEvent, event ) {
6171		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6172			this._move( keyEvent, event );
6173
6174			// Prevents moving cursor to beginning/end of the text field in some browsers
6175			event.preventDefault();
6176		}
6177	},
6178
6179	// Support: Chrome <=50
6180	// We should be able to just use this.element.prop( "isContentEditable" )
6181	// but hidden elements always report false in Chrome.
6182	// https://code.google.com/p/chromium/issues/detail?id=313082
6183	_isContentEditable: function( element ) {
6184		if ( !element.length ) {
6185			return false;
vendor: 14,931 bytes, lines 6186-6711
6186		}
6187
6188		var editable = element.prop( "contentEditable" );
6189
6190		if ( editable === "inherit" ) {
6191		  return this._isContentEditable( element.parent() );
6192		}
6193
6194		return editable === "true";
6195	}
6196} );
6197
6198$.extend( $.ui.autocomplete, {
6199	escapeRegex: function( value ) {
6200		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6201	},
6202	filter: function( array, term ) {
6203		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6204		return $.grep( array, function( value ) {
6205			return matcher.test( value.label || value.value || value );
6206		} );
6207	}
6208} );
6209
6210// Live region extension, adding a `messages` option
6211// NOTE: This is an experimental API. We are still investigating
6212// a full solution for string manipulation and internationalization.
6213$.widget( "ui.autocomplete", $.ui.autocomplete, {
6214	options: {
6215		messages: {
6216			noResults: "No search results.",
6217			results: function( amount ) {
6218				return amount + ( amount > 1 ? " results are" : " result is" ) +
6219					" available, use up and down arrow keys to navigate.";
6220			}
6221		}
6222	},
6223
6224	__response: function( content ) {
6225		var message;
6226		this._superApply( arguments );
6227		if ( this.options.disabled || this.cancelSearch ) {
6228			return;
6229		}
6230		if ( content && content.length ) {
6231			message = this.options.messages.results( content.length );
6232		} else {
6233			message = this.options.messages.noResults;
6234		}
6235		this.liveRegion.children().hide();
6236		$( "<div>" ).text( message ).appendTo( this.liveRegion );
6237	}
6238} );
6239
6240var widgetsAutocomplete = $.ui.autocomplete;
6241
6242
6243/*!
6244 * jQuery UI Controlgroup 1.12.1
6245 * http://jqueryui.com
6246 *
6247 * Copyright jQuery Foundation and other contributors
6248 * Released under the MIT license.
6249 * http://jquery.org/license
6250 */
6251
6252//>>label: Controlgroup
6253//>>group: Widgets
6254//>>description: Visually groups form control widgets
6255//>>docs: http://api.jqueryui.com/controlgroup/
6256//>>demos: http://jqueryui.com/controlgroup/
6257//>>css.structure: ../../themes/base/core.css
6258//>>css.structure: ../../themes/base/controlgroup.css
6259//>>css.theme: ../../themes/base/theme.css
6260
6261
6262var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6263
6264var widgetsControlgroup = $.widget( "ui.controlgroup", {
6265	version: "1.12.1",
6266	defaultElement: "<div>",
6267	options: {
6268		direction: "horizontal",
6269		disabled: null,
6270		onlyVisible: true,
6271		items: {
6272			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6273			"controlgroupLabel": ".ui-controlgroup-label",
6274			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6275			"selectmenu": "select",
6276			"spinner": ".ui-spinner-input"
6277		}
6278	},
6279
6280	_create: function() {
6281		this._enhance();
6282	},
6283
6284	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6285	_enhance: function() {
6286		this.element.attr( "role", "toolbar" );
6287		this.refresh();
6288	},
6289
6290	_destroy: function() {
6291		this._callChildMethod( "destroy" );
6292		this.childWidgets.removeData( "ui-controlgroup-data" );
6293		this.element.removeAttr( "role" );
6294		if ( this.options.items.controlgroupLabel ) {
6295			this.element
6296				.find( this.options.items.controlgroupLabel )
6297				.find( ".ui-controlgroup-label-contents" )
6298				.contents().unwrap();
6299		}
6300	},
6301
6302	_initWidgets: function() {
6303		var that = this,
6304			childWidgets = [];
6305
6306		// First we iterate over each of the items options
6307		$.each( this.options.items, function( widget, selector ) {
6308			var labels;
6309			var options = {};
6310
6311			// Make sure the widget has a selector set
6312			if ( !selector ) {
6313				return;
6314			}
6315
6316			if ( widget === "controlgroupLabel" ) {
6317				labels = that.element.find( selector );
6318				labels.each( function() {
6319					var element = $( this );
6320
6321					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6322						return;
6323					}
6324					element.contents()
6325						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6326				} );
6327				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6328				childWidgets = childWidgets.concat( labels.get() );
6329				return;
6330			}
6331
6332			// Make sure the widget actually exists
6333			if ( !$.fn[ widget ] ) {
6334				return;
6335			}
6336
6337			// We assume everything is in the middle to start because we can't determine
6338			// first / last elements until all enhancments are done.
6339			if ( that[ "_" + widget + "Options" ] ) {
6340				options = that[ "_" + widget + "Options" ]( "middle" );
6341			} else {
6342				options = { classes: {} };
6343			}
6344
6345			// Find instances of this widget inside controlgroup and init them
6346			that.element
6347				.find( selector )
6348				.each( function() {
6349					var element = $( this );
6350					var instance = element[ widget ]( "instance" );
6351
6352					// We need to clone the default options for this type of widget to avoid
6353					// polluting the variable options which has a wider scope than a single widget.
6354					var instanceOptions = $.widget.extend( {}, options );
6355
6356					// If the button is the child of a spinner ignore it
6357					// TODO: Find a more generic solution
6358					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6359						return;
6360					}
6361
6362					// Create the widget if it doesn't exist
6363					if ( !instance ) {
6364						instance = element[ widget ]()[ widget ]( "instance" );
6365					}
6366					if ( instance ) {
6367						instanceOptions.classes =
6368							that._resolveClassesValues( instanceOptions.classes, instance );
6369					}
6370					element[ widget ]( instanceOptions );
6371
6372					// Store an instance of the controlgroup to be able to reference
6373					// from the outermost element for changing options and refresh
6374					var widgetElement = element[ widget ]( "widget" );
6375					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6376						instance ? instance : element[ widget ]( "instance" ) );
6377
6378					childWidgets.push( widgetElement[ 0 ] );
6379				} );
6380		} );
6381
6382		this.childWidgets = $( $.unique( childWidgets ) );
6383		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6384	},
6385
6386	_callChildMethod: function( method ) {
6387		this.childWidgets.each( function() {
6388			var element = $( this ),
6389				data = element.data( "ui-controlgroup-data" );
6390			if ( data && data[ method ] ) {
6391				data[ method ]();
6392			}
6393		} );
6394	},
6395
6396	_updateCornerClass: function( element, position ) {
6397		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6398		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6399
6400		this._removeClass( element, null, remove );
6401		this._addClass( element, null, add );
6402	},
6403
6404	_buildSimpleOptions: function( position, key ) {
6405		var direction = this.options.direction === "vertical";
6406		var result = {
6407			classes: {}
6408		};
6409		result.classes[ key ] = {
6410			"middle": "",
6411			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6412			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6413			"only": "ui-corner-all"
6414		}[ position ];
6415
6416		return result;
6417	},
6418
6419	_spinnerOptions: function( position ) {
6420		var options = this._buildSimpleOptions( position, "ui-spinner" );
6421
6422		options.classes[ "ui-spinner-up" ] = "";
6423		options.classes[ "ui-spinner-down" ] = "";
6424
6425		return options;
6426	},
6427
6428	_buttonOptions: function( position ) {
6429		return this._buildSimpleOptions( position, "ui-button" );
6430	},
6431
6432	_checkboxradioOptions: function( position ) {
6433		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6434	},
6435
6436	_selectmenuOptions: function( position ) {
6437		var direction = this.options.direction === "vertical";
6438		return {
6439			width: direction ? "auto" : false,
6440			classes: {
6441				middle: {
6442					"ui-selectmenu-button-open": "",
6443					"ui-selectmenu-button-closed": ""
6444				},
6445				first: {
6446					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6447					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6448				},
6449				last: {
6450					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6451					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6452				},
6453				only: {
6454					"ui-selectmenu-button-open": "ui-corner-top",
6455					"ui-selectmenu-button-closed": "ui-corner-all"
6456				}
6457
6458			}[ position ]
6459		};
6460	},
6461
6462	_resolveClassesValues: function( classes, instance ) {
6463		var result = {};
6464		$.each( classes, function( key ) {
6465			var current = instance.options.classes[ key ] || "";
6466			current = $.trim( current.replace( controlgroupCornerRegex, "" ) );
6467			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6468		} );
6469		return result;
6470	},
6471
6472	_setOption: function( key, value ) {
6473		if ( key === "direction" ) {
6474			this._removeClass( "ui-controlgroup-" + this.options.direction );
6475		}
6476
6477		this._super( key, value );
6478		if ( key === "disabled" ) {
6479			this._callChildMethod( value ? "disable" : "enable" );
6480			return;
6481		}
6482
6483		this.refresh();
6484	},
6485
6486	refresh: function() {
6487		var children,
6488			that = this;
6489
6490		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6491
6492		if ( this.options.direction === "horizontal" ) {
6493			this._addClass( null, "ui-helper-clearfix" );
6494		}
6495		this._initWidgets();
6496
6497		children = this.childWidgets;
6498
6499		// We filter here because we need to track all childWidgets not just the visible ones
6500		if ( this.options.onlyVisible ) {
6501			children = children.filter( ":visible" );
6502		}
6503
6504		if ( children.length ) {
6505
6506			// We do this last because we need to make sure all enhancment is done
6507			// before determining first and last
6508			$.each( [ "first", "last" ], function( index, value ) {
6509				var instance = children[ value ]().data( "ui-controlgroup-data" );
6510
6511				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6512					var options = that[ "_" + instance.widgetName + "Options" ](
6513						children.length === 1 ? "only" : value
6514					);
6515					options.classes = that._resolveClassesValues( options.classes, instance );
6516					instance.element[ instance.widgetName ]( options );
6517				} else {
6518					that._updateCornerClass( children[ value ](), value );
6519				}
6520			} );
6521
6522			// Finally call the refresh method on each of the child widgets.
6523			this._callChildMethod( "refresh" );
6524		}
6525	}
6526} );
6527
6528/*!
6529 * jQuery UI Checkboxradio 1.12.1
6530 * http://jqueryui.com
6531 *
6532 * Copyright jQuery Foundation and other contributors
6533 * Released under the MIT license.
6534 * http://jquery.org/license
6535 */
6536
6537//>>label: Checkboxradio
6538//>>group: Widgets
6539//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6540//>>docs: http://api.jqueryui.com/checkboxradio/
6541//>>demos: http://jqueryui.com/checkboxradio/
6542//>>css.structure: ../../themes/base/core.css
6543//>>css.structure: ../../themes/base/button.css
6544//>>css.structure: ../../themes/base/checkboxradio.css
6545//>>css.theme: ../../themes/base/theme.css
6546
6547
6548
6549$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6550	version: "1.12.1",
6551	options: {
6552		disabled: null,
6553		label: null,
6554		icon: true,
6555		classes: {
6556			"ui-checkboxradio-label": "ui-corner-all",
6557			"ui-checkboxradio-icon": "ui-corner-all"
6558		}
6559	},
6560
6561	_getCreateOptions: function() {
6562		var disabled, labels;
6563		var that = this;
6564		var options = this._super() || {};
6565
6566		// We read the type here, because it makes more sense to throw a element type error first,
6567		// rather then the error for lack of a label. Often if its the wrong type, it
6568		// won't have a label (e.g. calling on a div, btn, etc)
6569		this._readType();
6570
6571		labels = this.element.labels();
6572
6573		// If there are multiple labels, use the last one
6574		this.label = $( labels[ labels.length - 1 ] );
6575		if ( !this.label.length ) {
6576			$.error( "No label found for checkboxradio widget" );
6577		}
6578
6579		this.originalLabel = "";
6580
6581		// We need to get the label text but this may also need to make sure it does not contain the
6582		// input itself.
6583		this.label.contents().not( this.element[ 0 ] ).each( function() {
6584
6585			// The label contents could be text, html, or a mix. We concat each element to get a
6586			// string representation of the label, without the input as part of it.
6587			that.originalLabel += this.nodeType === 3 ? $( this ).text() : this.outerHTML;
6588		} );
6589
6590		// Set the label option if we found label text
6591		if ( this.originalLabel ) {
6592			options.label = this.originalLabel;
6593		}
6594
6595		disabled = this.element[ 0 ].disabled;
6596		if ( disabled != null ) {
6597			options.disabled = disabled;
6598		}
6599		return options;
6600	},
6601
6602	_create: function() {
6603		var checked = this.element[ 0 ].checked;
6604
6605		this._bindFormResetHandler();
6606
6607		if ( this.options.disabled == null ) {
6608			this.options.disabled = this.element[ 0 ].disabled;
6609		}
6610
6611		this._setOption( "disabled", this.options.disabled );
6612		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6613		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6614
6615		if ( this.type === "radio" ) {
6616			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6617		}
6618
6619		if ( this.options.label && this.options.label !== this.originalLabel ) {
6620			this._updateLabel();
6621		} else if ( this.originalLabel ) {
6622			this.options.label = this.originalLabel;
6623		}
6624
6625		this._enhance();
6626
6627		if ( checked ) {
6628			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6629			if ( this.icon ) {
6630				this._addClass( this.icon, null, "ui-state-hover" );
6631			}
6632		}
6633
6634		this._on( {
6635			change: "_toggleClasses",
6636			focus: function() {
6637				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6638			},
6639			blur: function() {
6640				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6641			}
6642		} );
6643	},
6644
6645	_readType: function() {
6646		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6647		this.type = this.element[ 0 ].type;
6648		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6649			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6650				" and element.type=" + this.type );
6651		}
6652	},
6653
6654	// Support jQuery Mobile enhanced option
6655	_enhance: function() {
6656		this._updateIcon( this.element[ 0 ].checked );
6657	},
6658
6659	widget: function() {
6660		return this.label;
6661	},
6662
6663	_getRadioGroup: function() {
6664		var group;
6665		var name = this.element[ 0 ].name;
6666		var nameSelector = "input[name='" + $.ui.escapeSelector( name ) + "']";
6667
6668		if ( !name ) {
6669			return $( [] );
6670		}
6671
6672		if ( this.form.length ) {
6673			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6674		} else {
6675
6676			// Not inside a form, check all inputs that also are not inside a form
6677			group = $( nameSelector ).filter( function() {
6678				return $( this ).form().length === 0;
6679			} );
6680		}
6681
6682		return group.not( this.element );
6683	},
6684
6685	_toggleClasses: function() {
6686		var checked = this.element[ 0 ].checked;
6687		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6688
6689		if ( this.options.icon && this.type === "checkbox" ) {
6690			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6691				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6692		}
6693
6694		if ( this.type === "radio" ) {
6695			this._getRadioGroup()
6696				.each( function() {
6697					var instance = $( this ).checkboxradio( "instance" );
6698
6699					if ( instance ) {
6700						instance._removeClass( instance.label,
6701							"ui-checkboxradio-checked", "ui-state-active" );
6702					}
6703				} );
6704		}
6705	},
6706
6707	_destroy: function() {
6708		this._unbindFormResetHandler();
6709
6710		if ( this.icon ) {
6711			this.icon.remove();
vendor: 4,485 bytes, lines 6712-6885
6712			this.iconSpace.remove();
6713		}
6714	},
6715
6716	_setOption: function( key, value ) {
6717
6718		// We don't allow the value to be set to nothing
6719		if ( key === "label" && !value ) {
6720			return;
6721		}
6722
6723		this._super( key, value );
6724
6725		if ( key === "disabled" ) {
6726			this._toggleClass( this.label, null, "ui-state-disabled", value );
6727			this.element[ 0 ].disabled = value;
6728
6729			// Don't refresh when setting disabled
6730			return;
6731		}
6732		this.refresh();
6733	},
6734
6735	_updateIcon: function( checked ) {
6736		var toAdd = "ui-icon ui-icon-background ";
6737
6738		if ( this.options.icon ) {
6739			if ( !this.icon ) {
6740				this.icon = $( "<span>" );
6741				this.iconSpace = $( "<span> </span>" );
6742				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6743			}
6744
6745			if ( this.type === "checkbox" ) {
6746				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6747				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6748			} else {
6749				toAdd += "ui-icon-blank";
6750			}
6751			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6752			if ( !checked ) {
6753				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6754			}
6755			this.icon.prependTo( this.label ).after( this.iconSpace );
6756		} else if ( this.icon !== undefined ) {
6757			this.icon.remove();
6758			this.iconSpace.remove();
6759			delete this.icon;
6760		}
6761	},
6762
6763	_updateLabel: function() {
6764
6765		// Remove the contents of the label ( minus the icon, icon space, and input )
6766		var contents = this.label.contents().not( this.element[ 0 ] );
6767		if ( this.icon ) {
6768			contents = contents.not( this.icon[ 0 ] );
6769		}
6770		if ( this.iconSpace ) {
6771			contents = contents.not( this.iconSpace[ 0 ] );
6772		}
6773		contents.remove();
6774
6775		this.label.append( this.options.label );
6776	},
6777
6778	refresh: function() {
6779		var checked = this.element[ 0 ].checked,
6780			isDisabled = this.element[ 0 ].disabled;
6781
6782		this._updateIcon( checked );
6783		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6784		if ( this.options.label !== null ) {
6785			this._updateLabel();
6786		}
6787
6788		if ( isDisabled !== this.options.disabled ) {
6789			this._setOptions( { "disabled": isDisabled } );
6790		}
6791	}
6792
6793} ] );
6794
6795var widgetsCheckboxradio = $.ui.checkboxradio;
6796
6797
6798/*!
6799 * jQuery UI Button 1.12.1
6800 * http://jqueryui.com
6801 *
6802 * Copyright jQuery Foundation and other contributors
6803 * Released under the MIT license.
6804 * http://jquery.org/license
6805 */
6806
6807//>>label: Button
6808//>>group: Widgets
6809//>>description: Enhances a form with themeable buttons.
6810//>>docs: http://api.jqueryui.com/button/
6811//>>demos: http://jqueryui.com/button/
6812//>>css.structure: ../../themes/base/core.css
6813//>>css.structure: ../../themes/base/button.css
6814//>>css.theme: ../../themes/base/theme.css
6815
6816
6817
6818$.widget( "ui.button", {
6819	version: "1.12.1",
6820	defaultElement: "<button>",
6821	options: {
6822		classes: {
6823			"ui-button": "ui-corner-all"
6824		},
6825		disabled: null,
6826		icon: null,
6827		iconPosition: "beginning",
6828		label: null,
6829		showLabel: true
6830	},
6831
6832	_getCreateOptions: function() {
6833		var disabled,
6834
6835			// This is to support cases like in jQuery Mobile where the base widget does have
6836			// an implementation of _getCreateOptions
6837			options = this._super() || {};
6838
6839		this.isInput = this.element.is( "input" );
6840
6841		disabled = this.element[ 0 ].disabled;
6842		if ( disabled != null ) {
6843			options.disabled = disabled;
6844		}
6845
6846		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6847		if ( this.originalLabel ) {
6848			options.label = this.originalLabel;
6849		}
6850
6851		return options;
6852	},
6853
6854	_create: function() {
6855		if ( !this.option.showLabel & !this.options.icon ) {
6856			this.options.showLabel = true;
6857		}
6858
6859		// We have to check the option again here even though we did in _getCreateOptions,
6860		// because null may have been passed on init which would override what was set in
6861		// _getCreateOptions
6862		if ( this.options.disabled == null ) {
6863			this.options.disabled = this.element[ 0 ].disabled || false;
6864		}
6865
6866		this.hasTitle = !!this.element.attr( "title" );
6867
6868		// Check to see if the label needs to be set or if its already correct
6869		if ( this.options.label && this.options.label !== this.originalLabel ) {
6870			if ( this.isInput ) {
6871				this.element.val( this.options.label );
6872			} else {
6873				this.element.html( this.options.label );
6874			}
6875		}
6876		this._addClass( "ui-button", "ui-widget" );
6877		this._setOption( "disabled", this.options.disabled );
6878		this._enhance();
6879
6880		if ( this.element.is( "a" ) ) {
6881			this._on( {
6882				"keyup": function( event ) {
6883					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6884						event.preventDefault();
6885
vendor: 11,927 bytes, lines 6886-7256
6886						// Support: PhantomJS <= 1.9, IE 8 Only
6887						// If a native click is available use it so we actually cause navigation
6888						// otherwise just trigger a click event
6889						if ( this.element[ 0 ].click ) {
6890							this.element[ 0 ].click();
6891						} else {
6892							this.element.trigger( "click" );
6893						}
6894					}
6895				}
6896			} );
6897		}
6898	},
6899
6900	_enhance: function() {
6901		if ( !this.element.is( "button" ) ) {
6902			this.element.attr( "role", "button" );
6903		}
6904
6905		if ( this.options.icon ) {
6906			this._updateIcon( "icon", this.options.icon );
6907			this._updateTooltip();
6908		}
6909	},
6910
6911	_updateTooltip: function() {
6912		this.title = this.element.attr( "title" );
6913
6914		if ( !this.options.showLabel && !this.title ) {
6915			this.element.attr( "title", this.options.label );
6916		}
6917	},
6918
6919	_updateIcon: function( option, value ) {
6920		var icon = option !== "iconPosition",
6921			position = icon ? this.options.iconPosition : value,
6922			displayBlock = position === "top" || position === "bottom";
6923
6924		// Create icon
6925		if ( !this.icon ) {
6926			this.icon = $( "<span>" );
6927
6928			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6929
6930			if ( !this.options.showLabel ) {
6931				this._addClass( "ui-button-icon-only" );
6932			}
6933		} else if ( icon ) {
6934
6935			// If we are updating the icon remove the old icon class
6936			this._removeClass( this.icon, null, this.options.icon );
6937		}
6938
6939		// If we are updating the icon add the new icon class
6940		if ( icon ) {
6941			this._addClass( this.icon, null, value );
6942		}
6943
6944		this._attachIcon( position );
6945
6946		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6947		// the iconSpace if there is one.
6948		if ( displayBlock ) {
6949			this._addClass( this.icon, null, "ui-widget-icon-block" );
6950			if ( this.iconSpace ) {
6951				this.iconSpace.remove();
6952			}
6953		} else {
6954
6955			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6956			// space if it does not exist
6957			if ( !this.iconSpace ) {
6958				this.iconSpace = $( "<span> </span>" );
6959				this._addClass( this.iconSpace, "ui-button-icon-space" );
6960			}
6961			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6962			this._attachIconSpace( position );
6963		}
6964	},
6965
6966	_destroy: function() {
6967		this.element.removeAttr( "role" );
6968
6969		if ( this.icon ) {
6970			this.icon.remove();
6971		}
6972		if ( this.iconSpace ) {
6973			this.iconSpace.remove();
6974		}
6975		if ( !this.hasTitle ) {
6976			this.element.removeAttr( "title" );
6977		}
6978	},
6979
6980	_attachIconSpace: function( iconPosition ) {
6981		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6982	},
6983
6984	_attachIcon: function( iconPosition ) {
6985		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6986	},
6987
6988	_setOptions: function( options ) {
6989		var newShowLabel = options.showLabel === undefined ?
6990				this.options.showLabel :
6991				options.showLabel,
6992			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6993
6994		if ( !newShowLabel && !newIcon ) {
6995			options.showLabel = true;
6996		}
6997		this._super( options );
6998	},
6999
7000	_setOption: function( key, value ) {
7001		if ( key === "icon" ) {
7002			if ( value ) {
7003				this._updateIcon( key, value );
7004			} else if ( this.icon ) {
7005				this.icon.remove();
7006				if ( this.iconSpace ) {
7007					this.iconSpace.remove();
7008				}
7009			}
7010		}
7011
7012		if ( key === "iconPosition" ) {
7013			this._updateIcon( key, value );
7014		}
7015
7016		// Make sure we can't end up with a button that has neither text nor icon
7017		if ( key === "showLabel" ) {
7018				this._toggleClass( "ui-button-icon-only", null, !value );
7019				this._updateTooltip();
7020		}
7021
7022		if ( key === "label" ) {
7023			if ( this.isInput ) {
7024				this.element.val( value );
7025			} else {
7026
7027				// If there is an icon, append it, else nothing then append the value
7028				// this avoids removal of the icon when setting label text
7029				this.element.html( value );
7030				if ( this.icon ) {
7031					this._attachIcon( this.options.iconPosition );
7032					this._attachIconSpace( this.options.iconPosition );
7033				}
7034			}
7035		}
7036
7037		this._super( key, value );
7038
7039		if ( key === "disabled" ) {
7040			this._toggleClass( null, "ui-state-disabled", value );
7041			this.element[ 0 ].disabled = value;
7042			if ( value ) {
7043				this.element.blur();
7044			}
7045		}
7046	},
7047
7048	refresh: function() {
7049
7050		// Make sure to only check disabled if its an element that supports this otherwise
7051		// check for the disabled class to determine state
7052		var isDisabled = this.element.is( "input, button" ) ?
7053			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
7054
7055		if ( isDisabled !== this.options.disabled ) {
7056			this._setOptions( { disabled: isDisabled } );
7057		}
7058
7059		this._updateTooltip();
7060	}
7061} );
7062
7063// DEPRECATED
7064if ( $.uiBackCompat !== false ) {
7065
7066	// Text and Icons options
7067	$.widget( "ui.button", $.ui.button, {
7068		options: {
7069			text: true,
7070			icons: {
7071				primary: null,
7072				secondary: null
7073			}
7074		},
7075
7076		_create: function() {
7077			if ( this.options.showLabel && !this.options.text ) {
7078				this.options.showLabel = this.options.text;
7079			}
7080			if ( !this.options.showLabel && this.options.text ) {
7081				this.options.text = this.options.showLabel;
7082			}
7083			if ( !this.options.icon && ( this.options.icons.primary ||
7084					this.options.icons.secondary ) ) {
7085				if ( this.options.icons.primary ) {
7086					this.options.icon = this.options.icons.primary;
7087				} else {
7088					this.options.icon = this.options.icons.secondary;
7089					this.options.iconPosition = "end";
7090				}
7091			} else if ( this.options.icon ) {
7092				this.options.icons.primary = this.options.icon;
7093			}
7094			this._super();
7095		},
7096
7097		_setOption: function( key, value ) {
7098			if ( key === "text" ) {
7099				this._super( "showLabel", value );
7100				return;
7101			}
7102			if ( key === "showLabel" ) {
7103				this.options.text = value;
7104			}
7105			if ( key === "icon" ) {
7106				this.options.icons.primary = value;
7107			}
7108			if ( key === "icons" ) {
7109				if ( value.primary ) {
7110					this._super( "icon", value.primary );
7111					this._super( "iconPosition", "beginning" );
7112				} else if ( value.secondary ) {
7113					this._super( "icon", value.secondary );
7114					this._super( "iconPosition", "end" );
7115				}
7116			}
7117			this._superApply( arguments );
7118		}
7119	} );
7120
7121	$.fn.button = ( function( orig ) {
7122		return function() {
7123			if ( !this.length || ( this.length && this[ 0 ].tagName !== "INPUT" ) ||
7124					( this.length && this[ 0 ].tagName === "INPUT" && (
7125						this.attr( "type" ) !== "checkbox" && this.attr( "type" ) !== "radio"
7126					) ) ) {
7127				return orig.apply( this, arguments );
7128			}
7129			if ( !$.ui.checkboxradio ) {
7130				$.error( "Checkboxradio widget missing" );
7131			}
7132			if ( arguments.length === 0 ) {
7133				return this.checkboxradio( {
7134					"icon": false
7135				} );
7136			}
7137			return this.checkboxradio.apply( this, arguments );
7138		};
7139	} )( $.fn.button );
7140
7141	$.fn.buttonset = function() {
7142		if ( !$.ui.controlgroup ) {
7143			$.error( "Controlgroup widget missing" );
7144		}
7145		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7146			return this.controlgroup.apply( this,
7147				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7148		}
7149		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7150			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7151		}
7152		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7153			arguments[ 0 ].items = {
7154				button: arguments[ 0 ].items
7155			};
7156		}
7157		return this.controlgroup.apply( this, arguments );
7158	};
7159}
7160
7161var widgetsButton = $.ui.button;
7162
7163
7164// jscs:disable maximumLineLength
7165/* jscs:disable requireCamelCaseOrUpperCaseIdentifiers */
7166/*!
7167 * jQuery UI Datepicker 1.12.1
7168 * http://jqueryui.com
7169 *
7170 * Copyright jQuery Foundation and other contributors
7171
7172 * Released under the MIT license.
7173 * http://jquery.org/license
7174 */
7175
7176//>>label: Datepicker
7177//>>group: Widgets
7178//>>description: Displays a calendar from an input or inline for selecting dates.
7179//>>docs: http://api.jqueryui.com/datepicker/
7180//>>demos: http://jqueryui.com/datepicker/
7181//>>css.structure: ../../themes/base/core.css
7182//>>css.structure: ../../themes/base/datepicker.css
7183//>>css.theme: ../../themes/base/theme.css
7184
7185
7186
7187$.extend( $.ui, { datepicker: { version: "1.12.1" } } );
7188
7189var datepicker_instActive;
7190
7191function datepicker_getZindex( elem ) {
7192	var position, value;
7193	while ( elem.length && elem[ 0 ] !== document ) {
7194
7195		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7196		// This makes behavior of this function consistent across browsers
7197		// WebKit always returns auto if the element is positioned
7198		position = elem.css( "position" );
7199		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7200
7201			// IE returns 0 when zIndex is not specified
7202			// other browsers return a string
7203			// we ignore the case of nested elements with an explicit value of 0
7204			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7205			value = parseInt( elem.css( "zIndex" ), 10 );
7206			if ( !isNaN( value ) && value !== 0 ) {
7207				return value;
7208			}
7209		}
7210		elem = elem.parent();
7211	}
7212
7213	return 0;
7214}
7215/* Date picker manager.
7216   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7217   Settings for (groups of) date pickers are maintained in an instance object,
7218   allowing multiple different settings on the same page. */
7219
7220function Datepicker() {
7221	this._curInst = null; // The current instance in use
7222	this._keyEvent = false; // If the last event was a key event
7223	this._disabledInputs = []; // List of date picker inputs that have been disabled
7224	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7225	this._inDialog = false; // True if showing within a "dialog", false if not
7226	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7227	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7228	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7229	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7230	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7231	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7232	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7233	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7234	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7235	this.regional = []; // Available regional settings, indexed by language code
7236	this.regional[ "" ] = { // Default regional settings
7237		closeText: "Done", // Display text for close link
7238		prevText: "Prev", // Display text for previous month link
7239		nextText: "Next", // Display text for next month link
7240		currentText: "Today", // Display text for current month link
7241		monthNames: [ "January","February","March","April","May","June",
7242			"July","August","September","October","November","December" ], // Names of months for drop-down and formatting
7243		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7244		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7245		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7246		dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], // Column headings for days starting at Sunday
7247		weekHeader: "Wk", // Column header for week of the year
7248		dateFormat: "mm/dd/yy", // See format options on parseDate
7249		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7250		isRTL: false, // True if right-to-left language, false if left-to-right
7251		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7252		yearSuffix: "" // Additional text to append to the year in the month headers
7253	};
7254	this._defaults = { // Global defaults for all the date picker instances
7255		showOn: "focus", // "focus" for popup on focus,
7256			// "button" for trigger button, or "both" for either
vendor: 6,628 bytes, lines 7257-7389
7257		showAnim: "fadeIn", // Name of jQuery animation for popup
7258		showOptions: {}, // Options for enhanced animations
7259		defaultDate: null, // Used when field is blank: actual date,
7260			// +/-number for offset from today, null for today
7261		appendText: "", // Display text following the input box, e.g. showing the format
7262		buttonText: "...", // Text for trigger button
7263		buttonImage: "", // URL for trigger button image
7264		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7265		hideIfNoPrevNext: false, // True to hide next/previous month links
7266			// if not applicable, false to just disable them
7267		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7268		gotoCurrent: false, // True if today link goes back to current selection instead
7269		changeMonth: false, // True if month can be selected directly, false if only prev/next
7270		changeYear: false, // True if year can be selected directly, false if only prev/next
7271		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7272			// either relative to today's year (-nn:+nn), relative to currently displayed year
7273			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7274		showOtherMonths: false, // True to show dates in other months, false to leave blank
7275		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7276		showWeek: false, // True to show week of the year, false to not show it
7277		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7278			// takes a Date and returns the number of the week for it
7279		shortYearCutoff: "+10", // Short year values < this are in the current century,
7280			// > this are in the previous century,
7281			// string value starting with "+" for current year + value
7282		minDate: null, // The earliest selectable date, or null for no limit
7283		maxDate: null, // The latest selectable date, or null for no limit
7284		duration: "fast", // Duration of display/closure
7285		beforeShowDay: null, // Function that takes a date and returns an array with
7286			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7287			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7288		beforeShow: null, // Function that takes an input field and
7289			// returns a set of custom settings for the date picker
7290		onSelect: null, // Define a callback function when a date is selected
7291		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7292		onClose: null, // Define a callback function when the datepicker is closed
7293		numberOfMonths: 1, // Number of months to show at a time
7294		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7295		stepMonths: 1, // Number of months to step back/forward
7296		stepBigMonths: 12, // Number of months to step back/forward for the big links
7297		altField: "", // Selector for an alternate field to store selected dates into
7298		altFormat: "", // The date format to use for the alternate field
7299		constrainInput: true, // The input is constrained by the current date format
7300		showButtonPanel: false, // True to show button panel, false to not show it
7301		autoSize: false, // True to size the input for the date format, false to leave as is
7302		disabled: false // The initial disabled state
7303	};
7304	$.extend( this._defaults, this.regional[ "" ] );
7305	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7306	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7307	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7308}
7309
7310$.extend( Datepicker.prototype, {
7311	/* Class name added to elements to indicate already configured with a date picker. */
7312	markerClassName: "hasDatepicker",
7313
7314	//Keep track of the maximum number of rows displayed (see #7043)
7315	maxRows: 4,
7316
7317	// TODO rename to "widget" when switching to widget factory
7318	_widgetDatepicker: function() {
7319		return this.dpDiv;
7320	},
7321
7322	/* Override the default settings for all instances of the date picker.
7323	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7324	 * @return the manager object
7325	 */
7326	setDefaults: function( settings ) {
7327		datepicker_extendRemove( this._defaults, settings || {} );
7328		return this;
7329	},
7330
7331	/* Attach the date picker to a jQuery selection.
7332	 * @param  target	element - the target input field or division or span
7333	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7334	 */
7335	_attachDatepicker: function( target, settings ) {
7336		var nodeName, inline, inst;
7337		nodeName = target.nodeName.toLowerCase();
7338		inline = ( nodeName === "div" || nodeName === "span" );
7339		if ( !target.id ) {
7340			this.uuid += 1;
7341			target.id = "dp" + this.uuid;
7342		}
7343		inst = this._newInst( $( target ), inline );
7344		inst.settings = $.extend( {}, settings || {} );
7345		if ( nodeName === "input" ) {
7346			this._connectDatepicker( target, inst );
7347		} else if ( inline ) {
7348			this._inlineDatepicker( target, inst );
7349		}
7350	},
7351
7352	/* Create a new instance object. */
7353	_newInst: function( target, inline ) {
7354		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7355		return { id: id, input: target, // associated target
7356			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7357			drawMonth: 0, drawYear: 0, // month being drawn
7358			inline: inline, // is datepicker inline or not
7359			dpDiv: ( !inline ? this.dpDiv : // presentation div
7360			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7361	},
7362
7363	/* Attach the date picker to an input field. */
7364	_connectDatepicker: function( target, inst ) {
7365		var input = $( target );
7366		inst.append = $( [] );
7367		inst.trigger = $( [] );
7368		if ( input.hasClass( this.markerClassName ) ) {
7369			return;
7370		}
7371		this._attachments( input, inst );
7372		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7373			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7374		this._autoSize( inst );
7375		$.data( target, "datepicker", inst );
7376
7377		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7378		if ( inst.settings.disabled ) {
7379			this._disableDatepicker( target );
7380		}
7381	},
7382
7383	/* Make attachments based on settings. */
7384	_attachments: function( input, inst ) {
7385		var showOn, buttonText, buttonImage,
7386			appendText = this._get( inst, "appendText" ),
7387			isRTL = this._get( inst, "isRTL" );
7388
7389		if ( inst.append ) {
vendor: 13,169 bytes, lines 7390-7760
7390			inst.append.remove();
7391		}
7392		if ( appendText ) {
7393			inst.append = $( "<span class='" + this._appendClass + "'>" + appendText + "</span>" );
7394			input[ isRTL ? "before" : "after" ]( inst.append );
7395		}
7396
7397		input.off( "focus", this._showDatepicker );
7398
7399		if ( inst.trigger ) {
7400			inst.trigger.remove();
7401		}
7402
7403		showOn = this._get( inst, "showOn" );
7404		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7405			input.on( "focus", this._showDatepicker );
7406		}
7407		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7408			buttonText = this._get( inst, "buttonText" );
7409			buttonImage = this._get( inst, "buttonImage" );
7410			inst.trigger = $( this._get( inst, "buttonImageOnly" ) ?
7411				$( "<img/>" ).addClass( this._triggerClass ).
7412					attr( { src: buttonImage, alt: buttonText, title: buttonText } ) :
7413				$( "<button type='button'></button>" ).addClass( this._triggerClass ).
7414					html( !buttonImage ? buttonText : $( "<img/>" ).attr(
7415					{ src:buttonImage, alt:buttonText, title:buttonText } ) ) );
7416			input[ isRTL ? "before" : "after" ]( inst.trigger );
7417			inst.trigger.on( "click", function() {
7418				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7419					$.datepicker._hideDatepicker();
7420				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7421					$.datepicker._hideDatepicker();
7422					$.datepicker._showDatepicker( input[ 0 ] );
7423				} else {
7424					$.datepicker._showDatepicker( input[ 0 ] );
7425				}
7426				return false;
7427			} );
7428		}
7429	},
7430
7431	/* Apply the maximum length for the date format. */
7432	_autoSize: function( inst ) {
7433		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7434			var findMax, max, maxI, i,
7435				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7436				dateFormat = this._get( inst, "dateFormat" );
7437
7438			if ( dateFormat.match( /[DM]/ ) ) {
7439				findMax = function( names ) {
7440					max = 0;
7441					maxI = 0;
7442					for ( i = 0; i < names.length; i++ ) {
7443						if ( names[ i ].length > max ) {
7444							max = names[ i ].length;
7445							maxI = i;
7446						}
7447					}
7448					return maxI;
7449				};
7450				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7451					"monthNames" : "monthNamesShort" ) ) ) );
7452				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7453					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7454			}
7455			inst.input.attr( "size", this._formatDate( inst, date ).length );
7456		}
7457	},
7458
7459	/* Attach an inline date picker to a div. */
7460	_inlineDatepicker: function( target, inst ) {
7461		var divSpan = $( target );
7462		if ( divSpan.hasClass( this.markerClassName ) ) {
7463			return;
7464		}
7465		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7466		$.data( target, "datepicker", inst );
7467		this._setDate( inst, this._getDefaultDate( inst ), true );
7468		this._updateDatepicker( inst );
7469		this._updateAlternate( inst );
7470
7471		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7472		if ( inst.settings.disabled ) {
7473			this._disableDatepicker( target );
7474		}
7475
7476		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7477		// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7478		inst.dpDiv.css( "display", "block" );
7479	},
7480
7481	/* Pop-up the date picker in a "dialog" box.
7482	 * @param  input element - ignored
7483	 * @param  date	string or Date - the initial date to display
7484	 * @param  onSelect  function - the function to call when a date is selected
7485	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7486	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7487	 *					event - with x/y coordinates or
7488	 *					leave empty for default (screen centre)
7489	 * @return the manager object
7490	 */
7491	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7492		var id, browserWidth, browserHeight, scrollX, scrollY,
7493			inst = this._dialogInst; // internal instance
7494
7495		if ( !inst ) {
7496			this.uuid += 1;
7497			id = "dp" + this.uuid;
7498			this._dialogInput = $( "<input type='text' id='" + id +
7499				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7500			this._dialogInput.on( "keydown", this._doKeyDown );
7501			$( "body" ).append( this._dialogInput );
7502			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7503			inst.settings = {};
7504			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7505		}
7506		datepicker_extendRemove( inst.settings, settings || {} );
7507		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7508		this._dialogInput.val( date );
7509
7510		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7511		if ( !this._pos ) {
7512			browserWidth = document.documentElement.clientWidth;
7513			browserHeight = document.documentElement.clientHeight;
7514			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7515			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7516			this._pos = // should use actual width/height below
7517				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7518		}
7519
7520		// Move input on screen for focus, but hidden behind dialog
7521		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7522		inst.settings.onSelect = onSelect;
7523		this._inDialog = true;
7524		this.dpDiv.addClass( this._dialogClass );
7525		this._showDatepicker( this._dialogInput[ 0 ] );
7526		if ( $.blockUI ) {
7527			$.blockUI( this.dpDiv );
7528		}
7529		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7530		return this;
7531	},
7532
7533	/* Detach a datepicker from its control.
7534	 * @param  target	element - the target input field or division or span
7535	 */
7536	_destroyDatepicker: function( target ) {
7537		var nodeName,
7538			$target = $( target ),
7539			inst = $.data( target, "datepicker" );
7540
7541		if ( !$target.hasClass( this.markerClassName ) ) {
7542			return;
7543		}
7544
7545		nodeName = target.nodeName.toLowerCase();
7546		$.removeData( target, "datepicker" );
7547		if ( nodeName === "input" ) {
7548			inst.append.remove();
7549			inst.trigger.remove();
7550			$target.removeClass( this.markerClassName ).
7551				off( "focus", this._showDatepicker ).
7552				off( "keydown", this._doKeyDown ).
7553				off( "keypress", this._doKeyPress ).
7554				off( "keyup", this._doKeyUp );
7555		} else if ( nodeName === "div" || nodeName === "span" ) {
7556			$target.removeClass( this.markerClassName ).empty();
7557		}
7558
7559		if ( datepicker_instActive === inst ) {
7560			datepicker_instActive = null;
7561		}
7562	},
7563
7564	/* Enable the date picker to a jQuery selection.
7565	 * @param  target	element - the target input field or division or span
7566	 */
7567	_enableDatepicker: function( target ) {
7568		var nodeName, inline,
7569			$target = $( target ),
7570			inst = $.data( target, "datepicker" );
7571
7572		if ( !$target.hasClass( this.markerClassName ) ) {
7573			return;
7574		}
7575
7576		nodeName = target.nodeName.toLowerCase();
7577		if ( nodeName === "input" ) {
7578			target.disabled = false;
7579			inst.trigger.filter( "button" ).
7580				each( function() { this.disabled = false; } ).end().
7581				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7582		} else if ( nodeName === "div" || nodeName === "span" ) {
7583			inline = $target.children( "." + this._inlineClass );
7584			inline.children().removeClass( "ui-state-disabled" );
7585			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7586				prop( "disabled", false );
7587		}
7588		this._disabledInputs = $.map( this._disabledInputs,
7589			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7590	},
7591
7592	/* Disable the date picker to a jQuery selection.
7593	 * @param  target	element - the target input field or division or span
7594	 */
7595	_disableDatepicker: function( target ) {
7596		var nodeName, inline,
7597			$target = $( target ),
7598			inst = $.data( target, "datepicker" );
7599
7600		if ( !$target.hasClass( this.markerClassName ) ) {
7601			return;
7602		}
7603
7604		nodeName = target.nodeName.toLowerCase();
7605		if ( nodeName === "input" ) {
7606			target.disabled = true;
7607			inst.trigger.filter( "button" ).
7608				each( function() { this.disabled = true; } ).end().
7609				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7610		} else if ( nodeName === "div" || nodeName === "span" ) {
7611			inline = $target.children( "." + this._inlineClass );
7612			inline.children().addClass( "ui-state-disabled" );
7613			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7614				prop( "disabled", true );
7615		}
7616		this._disabledInputs = $.map( this._disabledInputs,
7617			function( value ) { return ( value === target ? null : value ); } ); // delete entry
7618		this._disabledInputs[ this._disabledInputs.length ] = target;
7619	},
7620
7621	/* Is the first field in a jQuery collection disabled as a datepicker?
7622	 * @param  target	element - the target input field or division or span
7623	 * @return boolean - true if disabled, false if enabled
7624	 */
7625	_isDisabledDatepicker: function( target ) {
7626		if ( !target ) {
7627			return false;
7628		}
7629		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7630			if ( this._disabledInputs[ i ] === target ) {
7631				return true;
7632			}
7633		}
7634		return false;
7635	},
7636
7637	/* Retrieve the instance data for the target control.
7638	 * @param  target  element - the target input field or division or span
7639	 * @return  object - the associated instance data
7640	 * @throws  error if a jQuery problem getting data
7641	 */
7642	_getInst: function( target ) {
7643		try {
7644			return $.data( target, "datepicker" );
7645		}
7646		catch ( err ) {
7647			throw "Missing instance data for this datepicker";
7648		}
7649	},
7650
7651	/* Update or retrieve the settings for a date picker attached to an input field or division.
7652	 * @param  target  element - the target input field or division or span
7653	 * @param  name	object - the new settings to update or
7654	 *				string - the name of the setting to change or retrieve,
7655	 *				when retrieving also "all" for all instance settings or
7656	 *				"defaults" for all global defaults
7657	 * @param  value   any - the new value for the setting
7658	 *				(omit if above is an object or to retrieve a value)
7659	 */
7660	_optionDatepicker: function( target, name, value ) {
7661		var settings, date, minDate, maxDate,
7662			inst = this._getInst( target );
7663
7664		if ( arguments.length === 2 && typeof name === "string" ) {
7665			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7666				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7667				this._get( inst, name ) ) : null ) );
7668		}
7669
7670		settings = name || {};
7671		if ( typeof name === "string" ) {
7672			settings = {};
7673			settings[ name ] = value;
7674		}
7675
7676		if ( inst ) {
7677			if ( this._curInst === inst ) {
7678				this._hideDatepicker();
7679			}
7680
7681			date = this._getDateDatepicker( target, true );
7682			minDate = this._getMinMaxDate( inst, "min" );
7683			maxDate = this._getMinMaxDate( inst, "max" );
7684			datepicker_extendRemove( inst.settings, settings );
7685
7686			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7687			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7688				inst.settings.minDate = this._formatDate( inst, minDate );
7689			}
7690			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7691				inst.settings.maxDate = this._formatDate( inst, maxDate );
7692			}
7693			if ( "disabled" in settings ) {
7694				if ( settings.disabled ) {
7695					this._disableDatepicker( target );
7696				} else {
7697					this._enableDatepicker( target );
7698				}
7699			}
7700			this._attachments( $( target ), inst );
7701			this._autoSize( inst );
7702			this._setDate( inst, date );
7703			this._updateAlternate( inst );
7704			this._updateDatepicker( inst );
7705		}
7706	},
7707
7708	// Change method deprecated
7709	_changeDatepicker: function( target, name, value ) {
7710		this._optionDatepicker( target, name, value );
7711	},
7712
7713	/* Redraw the date picker attached to an input field or division.
7714	 * @param  target  element - the target input field or division or span
7715	 */
7716	_refreshDatepicker: function( target ) {
7717		var inst = this._getInst( target );
7718		if ( inst ) {
7719			this._updateDatepicker( inst );
7720		}
7721	},
7722
7723	/* Set the dates for a jQuery selection.
7724	 * @param  target element - the target input field or division or span
7725	 * @param  date	Date - the new date
7726	 */
7727	_setDateDatepicker: function( target, date ) {
7728		var inst = this._getInst( target );
7729		if ( inst ) {
7730			this._setDate( inst, date );
7731			this._updateDatepicker( inst );
7732			this._updateAlternate( inst );
7733		}
7734	},
7735
7736	/* Get the date(s) for the first entry in a jQuery selection.
7737	 * @param  target element - the target input field or division or span
7738	 * @param  noDefault boolean - true if no default date is to be used
7739	 * @return Date - the current date
7740	 */
7741	_getDateDatepicker: function( target, noDefault ) {
7742		var inst = this._getInst( target );
7743		if ( inst && !inst.inline ) {
7744			this._setDateFromField( inst, noDefault );
7745		}
7746		return ( inst ? this._getDate( inst ) : null );
7747	},
7748
7749	/* Handle keystrokes. */
7750	_doKeyDown: function( event ) {
7751		var onSelect, dateStr, sel,
7752			inst = $.datepicker._getInst( event.target ),
7753			handled = true,
7754			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7755
7756		inst._keyEvent = true;
7757		if ( $.datepicker._datepickerShowing ) {
7758			switch ( event.keyCode ) {
7759				case 9: $.datepicker._hideDatepicker();
7760						handled = false;
vendor: 4,635 bytes, lines 7761-7888
7761						break; // hide on tab out
7762				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7763									$.datepicker._currentClass + ")", inst.dpDiv );
7764						if ( sel[ 0 ] ) {
7765							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7766						}
7767
7768						onSelect = $.datepicker._get( inst, "onSelect" );
7769						if ( onSelect ) {
7770							dateStr = $.datepicker._formatDate( inst );
7771
7772							// Trigger custom callback
7773							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7774						} else {
7775							$.datepicker._hideDatepicker();
7776						}
7777
7778						return false; // don't submit the form
7779				case 27: $.datepicker._hideDatepicker();
7780						break; // hide on escape
7781				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7782							-$.datepicker._get( inst, "stepBigMonths" ) :
7783							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7784						break; // previous month/year on page up/+ ctrl
7785				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7786							+$.datepicker._get( inst, "stepBigMonths" ) :
7787							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7788						break; // next month/year on page down/+ ctrl
7789				case 35: if ( event.ctrlKey || event.metaKey ) {
7790							$.datepicker._clearDate( event.target );
7791						}
7792						handled = event.ctrlKey || event.metaKey;
7793						break; // clear on ctrl or command +end
7794				case 36: if ( event.ctrlKey || event.metaKey ) {
7795							$.datepicker._gotoToday( event.target );
7796						}
7797						handled = event.ctrlKey || event.metaKey;
7798						break; // current on ctrl or command +home
7799				case 37: if ( event.ctrlKey || event.metaKey ) {
7800							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7801						}
7802						handled = event.ctrlKey || event.metaKey;
7803
7804						// -1 day on ctrl or command +left
7805						if ( event.originalEvent.altKey ) {
7806							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7807								-$.datepicker._get( inst, "stepBigMonths" ) :
7808								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7809						}
7810
7811						// next month/year on alt +left on Mac
7812						break;
7813				case 38: if ( event.ctrlKey || event.metaKey ) {
7814							$.datepicker._adjustDate( event.target, -7, "D" );
7815						}
7816						handled = event.ctrlKey || event.metaKey;
7817						break; // -1 week on ctrl or command +up
7818				case 39: if ( event.ctrlKey || event.metaKey ) {
7819							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7820						}
7821						handled = event.ctrlKey || event.metaKey;
7822
7823						// +1 day on ctrl or command +right
7824						if ( event.originalEvent.altKey ) {
7825							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7826								+$.datepicker._get( inst, "stepBigMonths" ) :
7827								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7828						}
7829
7830						// next month/year on alt +right
7831						break;
7832				case 40: if ( event.ctrlKey || event.metaKey ) {
7833							$.datepicker._adjustDate( event.target, +7, "D" );
7834						}
7835						handled = event.ctrlKey || event.metaKey;
7836						break; // +1 week on ctrl or command +down
7837				default: handled = false;
7838			}
7839		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7840			$.datepicker._showDatepicker( this );
7841		} else {
7842			handled = false;
7843		}
7844
7845		if ( handled ) {
7846			event.preventDefault();
7847			event.stopPropagation();
7848		}
7849	},
7850
7851	/* Filter entered characters - based on date format. */
7852	_doKeyPress: function( event ) {
7853		var chars, chr,
7854			inst = $.datepicker._getInst( event.target );
7855
7856		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7857			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7858			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7859			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7860		}
7861	},
7862
7863	/* Synchronise manual entry and field/alternate field. */
7864	_doKeyUp: function( event ) {
7865		var date,
7866			inst = $.datepicker._getInst( event.target );
7867
7868		if ( inst.input.val() !== inst.lastVal ) {
7869			try {
7870				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7871					( inst.input ? inst.input.val() : null ),
7872					$.datepicker._getFormatConfig( inst ) );
7873
7874				if ( date ) { // only if valid
7875					$.datepicker._setDateFromField( inst );
7876					$.datepicker._updateAlternate( inst );
7877					$.datepicker._updateDatepicker( inst );
7878				}
7879			}
7880			catch ( err ) {
7881			}
7882		}
7883		return true;
7884	},
7885
7886	/* Pop-up the date picker for a given input field.
7887	 * If false returned from beforeShow event handler do not show.
7888	 * @param  input  element - the input field attached to the date picker or
vendor: 9,739 bytes, lines 7889-8167
7889	 *					event - if triggered by focus
7890	 */
7891	_showDatepicker: function( input ) {
7892		input = input.target || input;
7893		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7894			input = $( "input", input.parentNode )[ 0 ];
7895		}
7896
7897		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7898			return;
7899		}
7900
7901		var inst, beforeShow, beforeShowSettings, isFixed,
7902			offset, showAnim, duration;
7903
7904		inst = $.datepicker._getInst( input );
7905		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7906			$.datepicker._curInst.dpDiv.stop( true, true );
7907			if ( inst && $.datepicker._datepickerShowing ) {
7908				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7909			}
7910		}
7911
7912		beforeShow = $.datepicker._get( inst, "beforeShow" );
7913		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7914		if ( beforeShowSettings === false ) {
7915			return;
7916		}
7917		datepicker_extendRemove( inst.settings, beforeShowSettings );
7918
7919		inst.lastVal = null;
7920		$.datepicker._lastInput = input;
7921		$.datepicker._setDateFromField( inst );
7922
7923		if ( $.datepicker._inDialog ) { // hide cursor
7924			input.value = "";
7925		}
7926		if ( !$.datepicker._pos ) { // position below input
7927			$.datepicker._pos = $.datepicker._findPos( input );
7928			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7929		}
7930
7931		isFixed = false;
7932		$( input ).parents().each( function() {
7933			isFixed |= $( this ).css( "position" ) === "fixed";
7934			return !isFixed;
7935		} );
7936
7937		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7938		$.datepicker._pos = null;
7939
7940		//to avoid flashes on Firefox
7941		inst.dpDiv.empty();
7942
7943		// determine sizing offscreen
7944		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7945		$.datepicker._updateDatepicker( inst );
7946
7947		// fix width for dynamic number of date pickers
7948		// and adjust position before showing
7949		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7950		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7951			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7952			left: offset.left + "px", top: offset.top + "px" } );
7953
7954		if ( !inst.inline ) {
7955			showAnim = $.datepicker._get( inst, "showAnim" );
7956			duration = $.datepicker._get( inst, "duration" );
7957			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7958			$.datepicker._datepickerShowing = true;
7959
7960			if ( $.effects && $.effects.effect[ showAnim ] ) {
7961				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7962			} else {
7963				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7964			}
7965
7966			if ( $.datepicker._shouldFocusInput( inst ) ) {
7967				inst.input.trigger( "focus" );
7968			}
7969
7970			$.datepicker._curInst = inst;
7971		}
7972	},
7973
7974	/* Generate the date picker content. */
7975	_updateDatepicker: function( inst ) {
7976		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7977		datepicker_instActive = inst; // for delegate hover events
7978		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7979		this._attachHandlers( inst );
7980
7981		var origyearshtml,
7982			numMonths = this._getNumberOfMonths( inst ),
7983			cols = numMonths[ 1 ],
7984			width = 17,
7985			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
7986
7987		if ( activeCell.length > 0 ) {
7988			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7989		}
7990
7991		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7992		if ( cols > 1 ) {
7993			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7994		}
7995		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7996			"Class" ]( "ui-datepicker-multi" );
7997		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7998			"Class" ]( "ui-datepicker-rtl" );
7999
8000		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8001			inst.input.trigger( "focus" );
8002		}
8003
8004		// Deffered render of the years select (to avoid flashes on Firefox)
8005		if ( inst.yearshtml ) {
8006			origyearshtml = inst.yearshtml;
8007			setTimeout( function() {
8008
8009				//assure that inst.yearshtml didn't change.
8010				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8011					inst.dpDiv.find( "select.ui-datepicker-year:first" ).replaceWith( inst.yearshtml );
8012				}
8013				origyearshtml = inst.yearshtml = null;
8014			}, 0 );
8015		}
8016	},
8017
8018	// #6694 - don't focus the input if it's already focused
8019	// this breaks the change event in IE
8020	// Support: IE and jQuery <1.9
8021	_shouldFocusInput: function( inst ) {
8022		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8023	},
8024
8025	/* Check positioning to remain on screen. */
8026	_checkOffset: function( inst, offset, isFixed ) {
8027		var dpWidth = inst.dpDiv.outerWidth(),
8028			dpHeight = inst.dpDiv.outerHeight(),
8029			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8030			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8031			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8032			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8033
8034		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8035		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8036		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8037
8038		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8039		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8040			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8041		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8042			Math.abs( dpHeight + inputHeight ) : 0 );
8043
8044		return offset;
8045	},
8046
8047	/* Find an object's position on the screen. */
8048	_findPos: function( obj ) {
8049		var position,
8050			inst = this._getInst( obj ),
8051			isRTL = this._get( inst, "isRTL" );
8052
8053		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden( obj ) ) ) {
8054			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8055		}
8056
8057		position = $( obj ).offset();
8058		return [ position.left, position.top ];
8059	},
8060
8061	/* Hide the date picker from view.
8062	 * @param  input  element - the input field attached to the date picker
8063	 */
8064	_hideDatepicker: function( input ) {
8065		var showAnim, duration, postProcess, onClose,
8066			inst = this._curInst;
8067
8068		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8069			return;
8070		}
8071
8072		if ( this._datepickerShowing ) {
8073			showAnim = this._get( inst, "showAnim" );
8074			duration = this._get( inst, "duration" );
8075			postProcess = function() {
8076				$.datepicker._tidyDialog( inst );
8077			};
8078
8079			// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8080			if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8081				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8082			} else {
8083				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8084					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8085			}
8086
8087			if ( !showAnim ) {
8088				postProcess();
8089			}
8090			this._datepickerShowing = false;
8091
8092			onClose = this._get( inst, "onClose" );
8093			if ( onClose ) {
8094				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8095			}
8096
8097			this._lastInput = null;
8098			if ( this._inDialog ) {
8099				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8100				if ( $.blockUI ) {
8101					$.unblockUI();
8102					$( "body" ).append( this.dpDiv );
8103				}
8104			}
8105			this._inDialog = false;
8106		}
8107	},
8108
8109	/* Tidy up after a dialog display. */
8110	_tidyDialog: function( inst ) {
8111		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8112	},
8113
8114	/* Close date picker if clicked elsewhere. */
8115	_checkExternalClick: function( event ) {
8116		if ( !$.datepicker._curInst ) {
8117			return;
8118		}
8119
8120		var $target = $( event.target ),
8121			inst = $.datepicker._getInst( $target[ 0 ] );
8122
8123		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8124				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8125				!$target.hasClass( $.datepicker.markerClassName ) &&
8126				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8127				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8128			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8129				$.datepicker._hideDatepicker();
8130		}
8131	},
8132
8133	/* Adjust one of the date sub-fields. */
8134	_adjustDate: function( id, offset, period ) {
8135		var target = $( id ),
8136			inst = this._getInst( target[ 0 ] );
8137
8138		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8139			return;
8140		}
8141		this._adjustInstDate( inst, offset +
8142			( period === "M" ? this._get( inst, "showCurrentAtPos" ) : 0 ), // undo positioning
8143			period );
8144		this._updateDatepicker( inst );
8145	},
8146
8147	/* Action for current link. */
8148	_gotoToday: function( id ) {
8149		var date,
8150			target = $( id ),
8151			inst = this._getInst( target[ 0 ] );
8152
8153		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8154			inst.selectedDay = inst.currentDay;
8155			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8156			inst.drawYear = inst.selectedYear = inst.currentYear;
8157		} else {
8158			date = new Date();
8159			inst.selectedDay = date.getDate();
8160			inst.drawMonth = inst.selectedMonth = date.getMonth();
8161			inst.drawYear = inst.selectedYear = date.getFullYear();
8162		}
8163		this._notifyChange( inst );
8164		this._adjustDate( target );
8165	},
8166
8167	/* Action for selecting a new month/year. */
vendor: 2,372 bytes, lines 8168-8243
8168	_selectMonthYear: function( id, select, period ) {
8169		var target = $( id ),
8170			inst = this._getInst( target[ 0 ] );
8171
8172		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8173		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8174			parseInt( select.options[ select.selectedIndex ].value, 10 );
8175
8176		this._notifyChange( inst );
8177		this._adjustDate( target );
8178	},
8179
8180	/* Action for selecting a day. */
8181	_selectDay: function( id, month, year, td ) {
8182		var inst,
8183			target = $( id );
8184
8185		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8186			return;
8187		}
8188
8189		inst = this._getInst( target[ 0 ] );
8190		inst.selectedDay = inst.currentDay = $( "a", td ).html();
8191		inst.selectedMonth = inst.currentMonth = month;
8192		inst.selectedYear = inst.currentYear = year;
8193		this._selectDate( id, this._formatDate( inst,
8194			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8195	},
8196
8197	/* Erase the input field and hide the date picker. */
8198	_clearDate: function( id ) {
8199		var target = $( id );
8200		this._selectDate( target, "" );
8201	},
8202
8203	/* Update the input field with the selected date. */
8204	_selectDate: function( id, dateStr ) {
8205		var onSelect,
8206			target = $( id ),
8207			inst = this._getInst( target[ 0 ] );
8208
8209		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8210		if ( inst.input ) {
8211			inst.input.val( dateStr );
8212		}
8213		this._updateAlternate( inst );
8214
8215		onSelect = this._get( inst, "onSelect" );
8216		if ( onSelect ) {
8217			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8218		} else if ( inst.input ) {
8219			inst.input.trigger( "change" ); // fire the change event
8220		}
8221
8222		if ( inst.inline ) {
8223			this._updateDatepicker( inst );
8224		} else {
8225			this._hideDatepicker();
8226			this._lastInput = inst.input[ 0 ];
8227			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8228				inst.input.trigger( "focus" ); // restore focus
8229			}
8230			this._lastInput = null;
8231		}
8232	},
8233
8234	/* Update any alternate field to synchronise with the main field. */
8235	_updateAlternate: function( inst ) {
8236		var altFormat, date, dateStr,
8237			altField = this._get( inst, "altField" );
8238
8239		if ( altField ) { // update alternate field too
8240			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8241			date = this._getDate( inst );
8242			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8243			$
vendor: 13,647 bytes, lines 8243-8682
8243( altField ).val( dateStr );
8244		}
8245	},
8246
8247	/* Set as beforeShowDay function to prevent selection of weekends.
8248	 * @param  date  Date - the date to customise
8249	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8250	 */
8251	noWeekends: function( date ) {
8252		var day = date.getDay();
8253		return [ ( day > 0 && day < 6 ), "" ];
8254	},
8255
8256	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8257	 * @param  date  Date - the date to get the week for
8258	 * @return  number - the number of the week within the year that contains this date
8259	 */
8260	iso8601Week: function( date ) {
8261		var time,
8262			checkDate = new Date( date.getTime() );
8263
8264		// Find Thursday of this week starting on Monday
8265		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8266
8267		time = checkDate.getTime();
8268		checkDate.setMonth( 0 ); // Compare with Jan 1
8269		checkDate.setDate( 1 );
8270		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8271	},
8272
8273	/* Parse a string value into a date object.
8274	 * See formatDate below for the possible formats.
8275	 *
8276	 * @param  format string - the expected format of the date
8277	 * @param  value string - the date in the above format
8278	 * @param  settings Object - attributes include:
8279	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8280	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8281	 *					dayNames		string[7] - names of the days from Sunday (optional)
8282	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8283	 *					monthNames		string[12] - names of the months (optional)
8284	 * @return  Date - the extracted date value or null if value is blank
8285	 */
8286	parseDate: function( format, value, settings ) {
8287		if ( format == null || value == null ) {
8288			throw "Invalid arguments";
8289		}
8290
8291		value = ( typeof value === "object" ? value.toString() : value + "" );
8292		if ( value === "" ) {
8293			return null;
8294		}
8295
8296		var iFormat, dim, extra,
8297			iValue = 0,
8298			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8299			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8300				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8301			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8302			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8303			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8304			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8305			year = -1,
8306			month = -1,
8307			day = -1,
8308			doy = -1,
8309			literal = false,
8310			date,
8311
8312			// Check whether a format character is doubled
8313			lookAhead = function( match ) {
8314				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8315				if ( matches ) {
8316					iFormat++;
8317				}
8318				return matches;
8319			},
8320
8321			// Extract a number from the string value
8322			getNumber = function( match ) {
8323				var isDoubled = lookAhead( match ),
8324					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8325					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8326					minSize = ( match === "y" ? size : 1 ),
8327					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8328					num = value.substring( iValue ).match( digits );
8329				if ( !num ) {
8330					throw "Missing number at position " + iValue;
8331				}
8332				iValue += num[ 0 ].length;
8333				return parseInt( num[ 0 ], 10 );
8334			},
8335
8336			// Extract a name from the string value and convert to an index
8337			getName = function( match, shortNames, longNames ) {
8338				var index = -1,
8339					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8340						return [ [ k, v ] ];
8341					} ).sort( function( a, b ) {
8342						return -( a[ 1 ].length - b[ 1 ].length );
8343					} );
8344
8345				$.each( names, function( i, pair ) {
8346					var name = pair[ 1 ];
8347					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8348						index = pair[ 0 ];
8349						iValue += name.length;
8350						return false;
8351					}
8352				} );
8353				if ( index !== -1 ) {
8354					return index + 1;
8355				} else {
8356					throw "Unknown name at position " + iValue;
8357				}
8358			},
8359
8360			// Confirm that a literal character matches the string value
8361			checkLiteral = function() {
8362				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8363					throw "Unexpected literal at position " + iValue;
8364				}
8365				iValue++;
8366			};
8367
8368		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8369			if ( literal ) {
8370				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8371					literal = false;
8372				} else {
8373					checkLiteral();
8374				}
8375			} else {
8376				switch ( format.charAt( iFormat ) ) {
8377					case "d":
8378						day = getNumber( "d" );
8379						break;
8380					case "D":
8381						getName( "D", dayNamesShort, dayNames );
8382						break;
8383					case "o":
8384						doy = getNumber( "o" );
8385						break;
8386					case "m":
8387						month = getNumber( "m" );
8388						break;
8389					case "M":
8390						month = getName( "M", monthNamesShort, monthNames );
8391						break;
8392					case "y":
8393						year = getNumber( "y" );
8394						break;
8395					case "@":
8396						date = new Date( getNumber( "@" ) );
8397						year = date.getFullYear();
8398						month = date.getMonth() + 1;
8399						day = date.getDate();
8400						break;
8401					case "!":
8402						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8403						year = date.getFullYear();
8404						month = date.getMonth() + 1;
8405						day = date.getDate();
8406						break;
8407					case "'":
8408						if ( lookAhead( "'" ) ) {
8409							checkLiteral();
8410						} else {
8411							literal = true;
8412						}
8413						break;
8414					default:
8415						checkLiteral();
8416				}
8417			}
8418		}
8419
8420		if ( iValue < value.length ) {
8421			extra = value.substr( iValue );
8422			if ( !/^\s+/.test( extra ) ) {
8423				throw "Extra/unparsed characters found in date: " + extra;
8424			}
8425		}
8426
8427		if ( year === -1 ) {
8428			year = new Date().getFullYear();
8429		} else if ( year < 100 ) {
8430			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8431				( year <= shortYearCutoff ? 0 : -100 );
8432		}
8433
8434		if ( doy > -1 ) {
8435			month = 1;
8436			day = doy;
8437			do {
8438				dim = this._getDaysInMonth( year, month - 1 );
8439				if ( day <= dim ) {
8440					break;
8441				}
8442				month++;
8443				day -= dim;
8444			} while ( true );
8445		}
8446
8447		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8448		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8449			throw "Invalid date"; // E.g. 31/02/00
8450		}
8451		return date;
8452	},
8453
8454	/* Standard date formats. */
8455	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8456	COOKIE: "D, dd M yy",
8457	ISO_8601: "yy-mm-dd",
8458	RFC_822: "D, d M y",
8459	RFC_850: "DD, dd-M-y",
8460	RFC_1036: "D, d M y",
8461	RFC_1123: "D, d M yy",
8462	RFC_2822: "D, d M yy",
8463	RSS: "D, d M y", // RFC 822
8464	TICKS: "!",
8465	TIMESTAMP: "@",
8466	W3C: "yy-mm-dd", // ISO 8601
8467
8468	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8469		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8470
8471	/* Format a date object into a string value.
8472	 * The format can be combinations of the following:
8473	 * d  - day of month (no leading zero)
8474	 * dd - day of month (two digit)
8475	 * o  - day of year (no leading zeros)
8476	 * oo - day of year (three digit)
8477	 * D  - day name short
8478	 * DD - day name long
8479	 * m  - month of year (no leading zero)
8480	 * mm - month of year (two digit)
8481	 * M  - month name short
8482	 * MM - month name long
8483	 * y  - year (two digit)
8484	 * yy - year (four digit)
8485	 * @ - Unix timestamp (ms since 01/01/1970)
8486	 * ! - Windows ticks (100ns since 01/01/0001)
8487	 * "..." - literal text
8488	 * '' - single quote
8489	 *
8490	 * @param  format string - the desired format of the date
8491	 * @param  date Date - the date value to format
8492	 * @param  settings Object - attributes include:
8493	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8494	 *					dayNames		string[7] - names of the days from Sunday (optional)
8495	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8496	 *					monthNames		string[12] - names of the months (optional)
8497	 * @return  string - the date in the above format
8498	 */
8499	formatDate: function( format, date, settings ) {
8500		if ( !date ) {
8501			return "";
8502		}
8503
8504		var iFormat,
8505			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8506			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8507			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8508			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8509
8510			// Check whether a format character is doubled
8511			lookAhead = function( match ) {
8512				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8513				if ( matches ) {
8514					iFormat++;
8515				}
8516				return matches;
8517			},
8518
8519			// Format a number, with leading zero if necessary
8520			formatNumber = function( match, value, len ) {
8521				var num = "" + value;
8522				if ( lookAhead( match ) ) {
8523					while ( num.length < len ) {
8524						num = "0" + num;
8525					}
8526				}
8527				return num;
8528			},
8529
8530			// Format a name, short or long as requested
8531			formatName = function( match, value, shortNames, longNames ) {
8532				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8533			},
8534			output = "",
8535			literal = false;
8536
8537		if ( date ) {
8538			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8539				if ( literal ) {
8540					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8541						literal = false;
8542					} else {
8543						output += format.charAt( iFormat );
8544					}
8545				} else {
8546					switch ( format.charAt( iFormat ) ) {
8547						case "d":
8548							output += formatNumber( "d", date.getDate(), 2 );
8549							break;
8550						case "D":
8551							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8552							break;
8553						case "o":
8554							output += formatNumber( "o",
8555								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8556							break;
8557						case "m":
8558							output += formatNumber( "m", date.getMonth() + 1, 2 );
8559							break;
8560						case "M":
8561							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8562							break;
8563						case "y":
8564							output += ( lookAhead( "y" ) ? date.getFullYear() :
8565								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8566							break;
8567						case "@":
8568							output += date.getTime();
8569							break;
8570						case "!":
8571							output += date.getTime() * 10000 + this._ticksTo1970;
8572							break;
8573						case "'":
8574							if ( lookAhead( "'" ) ) {
8575								output += "'";
8576							} else {
8577								literal = true;
8578							}
8579							break;
8580						default:
8581							output += format.charAt( iFormat );
8582					}
8583				}
8584			}
8585		}
8586		return output;
8587	},
8588
8589	/* Extract all possible characters from the date format. */
8590	_possibleChars: function( format ) {
8591		var iFormat,
8592			chars = "",
8593			literal = false,
8594
8595			// Check whether a format character is doubled
8596			lookAhead = function( match ) {
8597				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8598				if ( matches ) {
8599					iFormat++;
8600				}
8601				return matches;
8602			};
8603
8604		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8605			if ( literal ) {
8606				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8607					literal = false;
8608				} else {
8609					chars += format.charAt( iFormat );
8610				}
8611			} else {
8612				switch ( format.charAt( iFormat ) ) {
8613					case "d": case "m": case "y": case "@":
8614						chars += "0123456789";
8615						break;
8616					case "D": case "M":
8617						return null; // Accept anything
8618					case "'":
8619						if ( lookAhead( "'" ) ) {
8620							chars += "'";
8621						} else {
8622							literal = true;
8623						}
8624						break;
8625					default:
8626						chars += format.charAt( iFormat );
8627				}
8628			}
8629		}
8630		return chars;
8631	},
8632
8633	/* Get a setting value, defaulting if necessary. */
8634	_get: function( inst, name ) {
8635		return inst.settings[ name ] !== undefined ?
8636			inst.settings[ name ] : this._defaults[ name ];
8637	},
8638
8639	/* Parse existing date and initialise date picker. */
8640	_setDateFromField: function( inst, noDefault ) {
8641		if ( inst.input.val() === inst.lastVal ) {
8642			return;
8643		}
8644
8645		var dateFormat = this._get( inst, "dateFormat" ),
8646			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8647			defaultDate = this._getDefaultDate( inst ),
8648			date = defaultDate,
8649			settings = this._getFormatConfig( inst );
8650
8651		try {
8652			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8653		} catch ( event ) {
8654			dates = ( noDefault ? "" : dates );
8655		}
8656		inst.selectedDay = date.getDate();
8657		inst.drawMonth = inst.selectedMonth = date.getMonth();
8658		inst.drawYear = inst.selectedYear = date.getFullYear();
8659		inst.currentDay = ( dates ? date.getDate() : 0 );
8660		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8661		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8662		this._adjustInstDate( inst );
8663	},
8664
8665	/* Retrieve the default date shown on opening. */
8666	_getDefaultDate: function( inst ) {
8667		return this._restrictMinMax( inst,
8668			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8669	},
8670
8671	/* A date may be specified as an exact value or a relative one. */
8672	_determineDate: function( inst, date, defaultDate ) {
8673		var offsetNumeric = function( offset ) {
8674				var date = new Date();
8675				date.setDate( date.getDate() + offset );
8676				return date;
8677			},
8678			offsetString = function( offset ) {
8679				try {
8680					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8681						offset, $.datepicker._getFormatConfig( inst ) );
8682				}
8682
8683				
vendor: 6,426 bytes, lines 8683-8857
8683catch ( e ) {
8684
8685					// Ignore
8686				}
8687
8688				var date = ( offset.toLowerCase().match( /^c/ ) ?
8689					$.datepicker._getDate( inst ) : null ) || new Date(),
8690					year = date.getFullYear(),
8691					month = date.getMonth(),
8692					day = date.getDate(),
8693					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8694					matches = pattern.exec( offset );
8695
8696				while ( matches ) {
8697					switch ( matches[ 2 ] || "d" ) {
8698						case "d" : case "D" :
8699							day += parseInt( matches[ 1 ], 10 ); break;
8700						case "w" : case "W" :
8701							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8702						case "m" : case "M" :
8703							month += parseInt( matches[ 1 ], 10 );
8704							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8705							break;
8706						case "y": case "Y" :
8707							year += parseInt( matches[ 1 ], 10 );
8708							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8709							break;
8710					}
8711					matches = pattern.exec( offset );
8712				}
8713				return new Date( year, month, day );
8714			},
8715			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8716				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8717
8718		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8719		if ( newDate ) {
8720			newDate.setHours( 0 );
8721			newDate.setMinutes( 0 );
8722			newDate.setSeconds( 0 );
8723			newDate.setMilliseconds( 0 );
8724		}
8725		return this._daylightSavingAdjust( newDate );
8726	},
8727
8728	/* Handle switch to/from daylight saving.
8729	 * Hours may be non-zero on daylight saving cut-over:
8730	 * > 12 when midnight changeover, but then cannot generate
8731	 * midnight datetime, so jump to 1AM, otherwise reset.
8732	 * @param  date  (Date) the date to check
8733	 * @return  (Date) the corrected date
8734	 */
8735	_daylightSavingAdjust: function( date ) {
8736		if ( !date ) {
8737			return null;
8738		}
8739		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8740		return date;
8741	},
8742
8743	/* Set the date(s) directly. */
8744	_setDate: function( inst, date, noChange ) {
8745		var clear = !date,
8746			origMonth = inst.selectedMonth,
8747			origYear = inst.selectedYear,
8748			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8749
8750		inst.selectedDay = inst.currentDay = newDate.getDate();
8751		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8752		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8753		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8754			this._notifyChange( inst );
8755		}
8756		this._adjustInstDate( inst );
8757		if ( inst.input ) {
8758			inst.input.val( clear ? "" : this._formatDate( inst ) );
8759		}
8760	},
8761
8762	/* Retrieve the date(s) directly. */
8763	_getDate: function( inst ) {
8764		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8765			this._daylightSavingAdjust( new Date(
8766			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8767			return startDate;
8768	},
8769
8770	/* Attach the onxxx handlers.  These are declared statically so
8771	 * they work with static code transformers like Caja.
8772	 */
8773	_attachHandlers: function( inst ) {
8774		var stepMonths = this._get( inst, "stepMonths" ),
8775			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8776		inst.dpDiv.find( "[data-handler]" ).map( function() {
8777			var handler = {
8778				prev: function() {
8779					$.datepicker._adjustDate( id, -stepMonths, "M" );
8780				},
8781				next: function() {
8782					$.datepicker._adjustDate( id, +stepMonths, "M" );
8783				},
8784				hide: function() {
8785					$.datepicker._hideDatepicker();
8786				},
8787				today: function() {
8788					$.datepicker._gotoToday( id );
8789				},
8790				selectDay: function() {
8791					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8792					return false;
8793				},
8794				selectMonth: function() {
8795					$.datepicker._selectMonthYear( id, this, "M" );
8796					return false;
8797				},
8798				selectYear: function() {
8799					$.datepicker._selectMonthYear( id, this, "Y" );
8800					return false;
8801				}
8802			};
8803			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8804		} );
8805	},
8806
8807	/* Generate the HTML for the current state of the date picker. */
8808	_generateHTML: function( inst ) {
8809		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8810			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8811			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8812			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8813			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8814			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8815			tempDate = new Date(),
8816			today = this._daylightSavingAdjust(
8817				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8818			isRTL = this._get( inst, "isRTL" ),
8819			showButtonPanel = this._get( inst, "showButtonPanel" ),
8820			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8821			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8822			numMonths = this._getNumberOfMonths( inst ),
8823			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8824			stepMonths = this._get( inst, "stepMonths" ),
8825			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8826			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8827				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8828			minDate = this._getMinMaxDate( inst, "min" ),
8829			maxDate = this._getMinMaxDate( inst, "max" ),
8830			drawMonth = inst.drawMonth - showCurrentAtPos,
8831			drawYear = inst.drawYear;
8832
8833		if ( drawMonth < 0 ) {
8834			drawMonth += 12;
8835			drawYear--;
8836		}
8837		if ( maxDate ) {
8838			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8839				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8840			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8841			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8842				drawMonth--;
8843				if ( drawMonth < 0 ) {
8844					drawMonth = 11;
8845					drawYear--;
8846				}
8847			}
8848		}
8849		inst.drawMonth = drawMonth;
8850		inst.drawYear = drawYear;
8851
8852		prevText = this._get( inst, "prevText" );
8853		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8854			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8855			this._getFormatConfig( inst ) ) );
8856
8857		
vendor: 3,273 bytes, lines 8857-8909
8857prev = ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ?
8858			"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
8859			" title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w" ) + "'>" + prevText + "</span></a>" :
8860			( 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>" ) );
8861
8862		nextText = this._get( inst, "nextText" );
8863		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8864			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8865			this._getFormatConfig( inst ) ) );
8866
8867		next = ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ?
8868			"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
8869			" title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e" ) + "'>" + nextText + "</span></a>" :
8870			( 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>" ) );
8871
8872		currentText = this._get( inst, "currentText" );
8873		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8874		currentText = ( !navigationAsDateFormat ? currentText :
8875			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8876
8877		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'>" +
8878			this._get( inst, "closeText" ) + "</button>" : "" );
8879
8880		buttonPanel = ( showButtonPanel ) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + ( isRTL ? controls : "" ) +
8881			( 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'" +
8882			">" + currentText + "</button>" : "" ) + ( isRTL ? "" : controls ) + "</div>" : "";
8883
8884		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8885		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8886
8887		showWeek = this._get( inst, "showWeek" );
8888		dayNames = this._get( inst, "dayNames" );
8889		dayNamesMin = this._get( inst, "dayNamesMin" );
8890		monthNames = this._get( inst, "monthNames" );
8891		monthNamesShort = this._get( inst, "monthNamesShort" );
8892		beforeShowDay = this._get( inst, "beforeShowDay" );
8893		showOtherMonths = this._get( inst, "showOtherMonths" );
8894		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8895		defaultDate = this._getDefaultDate( inst );
8896		html = "";
8897
8898		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8899			group = "";
8900			this.maxRows = 4;
8901			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8902				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8903				cornerClass = " ui-corner-all";
8904				calender = "";
8905				if ( isMultiMonth ) {
8906					calender += "<div class='ui-datepicker-group";
8907					if ( numMonths[ 1 ] > 1 ) {
8908						switch ( col ) {
8909							case 0: calender += " ui-datepicker-group-first";
vendor: 5,222 bytes, lines 8910-8988
8910								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8911							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8912								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8913							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8914						}
8915					}
8916					calender += "'>";
8917				}
8918				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8919					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8920					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8921					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8922					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8923					"</div><table class='ui-datepicker-calendar'><thead>" +
8924					"<tr>";
8925				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8926				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8927					day = ( dow + firstDay ) % 7;
8928					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8929						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8930				}
8931				calender += thead + "</tr></thead><tbody>";
8932				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8933				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8934					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
8935				}
8936				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
8937				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
8938				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
8939				this.maxRows = numRows;
8940				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
8941				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
8942					calender += "<tr>";
8943					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
8944						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
8945					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
8946						daySettings = ( beforeShowDay ?
8947							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
8948						otherMonth = ( printDate.getMonth() !== drawMonth );
8949						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
8950							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
8951						tbody += "<td class='" +
8952							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
8953							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
8954							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
8955							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
8956
8957							// or defaultDate is current printedDate and defaultDate is selectedDate
8958							" " + this._dayOverClass : "" ) + // highlight selected day
8959							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
8960							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
8961							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
8962							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
8963							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
8964							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
8965							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
8966							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
8967							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
8968							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
8969							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
8970							"' href='#'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
8971						printDate.setDate( printDate.getDate() + 1 );
8972						printDate = this._daylightSavingAdjust( printDate );
8973					}
8974					calender += tbody + "</tr>";
8975				}
8976				drawMonth++;
8977				if ( drawMonth > 11 ) {
8978					drawMonth = 0;
8979					drawYear++;
8980				}
8981				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
8982							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
8983				group += calender;
8984			}
8985			html += group;
8986		}
8987		html += buttonPanel;
8988		inst._keyEvent = false;
vendor: 10,686 bytes, lines 8989-9264
8989		return html;
8990	},
8991
8992	/* Generate the month and year header. */
8993	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
8994			secondary, monthNames, monthNamesShort ) {
8995
8996		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
8997			changeMonth = this._get( inst, "changeMonth" ),
8998			changeYear = this._get( inst, "changeYear" ),
8999			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
9000			html = "<div class='ui-datepicker-title'>",
9001			monthHtml = "";
9002
9003		// Month selection
9004		if ( secondary || !changeMonth ) {
9005			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9006		} else {
9007			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9008			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9009			monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9010			for ( month = 0; month < 12; month++ ) {
9011				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9012					monthHtml += "<option value='" + month + "'" +
9013						( month === drawMonth ? " selected='selected'" : "" ) +
9014						">" + monthNamesShort[ month ] + "</option>";
9015				}
9016			}
9017			monthHtml += "</select>";
9018		}
9019
9020		if ( !showMonthAfterYear ) {
9021			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9022		}
9023
9024		// Year selection
9025		if ( !inst.yearshtml ) {
9026			inst.yearshtml = "";
9027			if ( secondary || !changeYear ) {
9028				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9029			} else {
9030
9031				// determine range of years to display
9032				years = this._get( inst, "yearRange" ).split( ":" );
9033				thisYear = new Date().getFullYear();
9034				determineYear = function( value ) {
9035					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9036						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9037						parseInt( value, 10 ) ) );
9038					return ( isNaN( year ) ? thisYear : year );
9039				};
9040				year = determineYear( years[ 0 ] );
9041				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9042				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9043				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9044				inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9045				for ( ; year <= endYear; year++ ) {
9046					inst.yearshtml += "<option value='" + year + "'" +
9047						( year === drawYear ? " selected='selected'" : "" ) +
9048						">" + year + "</option>";
9049				}
9050				inst.yearshtml += "</select>";
9051
9052				html += inst.yearshtml;
9053				inst.yearshtml = null;
9054			}
9055		}
9056
9057		html += this._get( inst, "yearSuffix" );
9058		if ( showMonthAfterYear ) {
9059			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9060		}
9061		html += "</div>"; // Close datepicker_header
9062		return html;
9063	},
9064
9065	/* Adjust one of the date sub-fields. */
9066	_adjustInstDate: function( inst, offset, period ) {
9067		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9068			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9069			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9070			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9071
9072		inst.selectedDay = date.getDate();
9073		inst.drawMonth = inst.selectedMonth = date.getMonth();
9074		inst.drawYear = inst.selectedYear = date.getFullYear();
9075		if ( period === "M" || period === "Y" ) {
9076			this._notifyChange( inst );
9077		}
9078	},
9079
9080	/* Ensure a date is within any min/max bounds. */
9081	_restrictMinMax: function( inst, date ) {
9082		var minDate = this._getMinMaxDate( inst, "min" ),
9083			maxDate = this._getMinMaxDate( inst, "max" ),
9084			newDate = ( minDate && date < minDate ? minDate : date );
9085		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9086	},
9087
9088	/* Notify change of month/year. */
9089	_notifyChange: function( inst ) {
9090		var onChange = this._get( inst, "onChangeMonthYear" );
9091		if ( onChange ) {
9092			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9093				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9094		}
9095	},
9096
9097	/* Determine the number of months to show. */
9098	_getNumberOfMonths: function( inst ) {
9099		var numMonths = this._get( inst, "numberOfMonths" );
9100		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9101	},
9102
9103	/* Determine the current maximum date - ensure no time components are set. */
9104	_getMinMaxDate: function( inst, minMax ) {
9105		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9106	},
9107
9108	/* Find the number of days in a given month. */
9109	_getDaysInMonth: function( year, month ) {
9110		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9111	},
9112
9113	/* Find the day of the week of the first of a month. */
9114	_getFirstDayOfMonth: function( year, month ) {
9115		return new Date( year, month, 1 ).getDay();
9116	},
9117
9118	/* Determines if we should allow a "next/prev" month display change. */
9119	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9120		var numMonths = this._getNumberOfMonths( inst ),
9121			date = this._daylightSavingAdjust( new Date( curYear,
9122			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9123
9124		if ( offset < 0 ) {
9125			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9126		}
9127		return this._isInRange( inst, date );
9128	},
9129
9130	/* Is the given date in the accepted range? */
9131	_isInRange: function( inst, date ) {
9132		var yearSplit, currentYear,
9133			minDate = this._getMinMaxDate( inst, "min" ),
9134			maxDate = this._getMinMaxDate( inst, "max" ),
9135			minYear = null,
9136			maxYear = null,
9137			years = this._get( inst, "yearRange" );
9138			if ( years ) {
9139				yearSplit = years.split( ":" );
9140				currentYear = new Date().getFullYear();
9141				minYear = parseInt( yearSplit[ 0 ], 10 );
9142				maxYear = parseInt( yearSplit[ 1 ], 10 );
9143				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9144					minYear += currentYear;
9145				}
9146				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9147					maxYear += currentYear;
9148				}
9149			}
9150
9151		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9152			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9153			( !minYear || date.getFullYear() >= minYear ) &&
9154			( !maxYear || date.getFullYear() <= maxYear ) );
9155	},
9156
9157	/* Provide the configuration settings for formatting/parsing. */
9158	_getFormatConfig: function( inst ) {
9159		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9160		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9161			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9162		return { shortYearCutoff: shortYearCutoff,
9163			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9164			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9165	},
9166
9167	/* Format the given date for display. */
9168	_formatDate: function( inst, day, month, year ) {
9169		if ( !day ) {
9170			inst.currentDay = inst.selectedDay;
9171			inst.currentMonth = inst.selectedMonth;
9172			inst.currentYear = inst.selectedYear;
9173		}
9174		var date = ( day ? ( typeof day === "object" ? day :
9175			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9176			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9177		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9178	}
9179} );
9180
9181/*
9182 * Bind hover events for datepicker elements.
9183 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9184 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9185 */
9186function datepicker_bindHover( dpDiv ) {
9187	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9188	return dpDiv.on( "mouseout", selector, function() {
9189			$( this ).removeClass( "ui-state-hover" );
9190			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9191				$( this ).removeClass( "ui-datepicker-prev-hover" );
9192			}
9193			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9194				$( this ).removeClass( "ui-datepicker-next-hover" );
9195			}
9196		} )
9197		.on( "mouseover", selector, datepicker_handleMouseover );
9198}
9199
9200function datepicker_handleMouseover() {
9201	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9202		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9203		$( this ).addClass( "ui-state-hover" );
9204		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9205			$( this ).addClass( "ui-datepicker-prev-hover" );
9206		}
9207		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9208			$( this ).addClass( "ui-datepicker-next-hover" );
9209		}
9210	}
9211}
9212
9213/* jQuery extend now ignores nulls! */
9214function datepicker_extendRemove( target, props ) {
9215	$.extend( target, props );
9216	for ( var name in props ) {
9217		if ( props[ name ] == null ) {
9218			target[ name ] = props[ name ];
9219		}
9220	}
9221	return target;
9222}
9223
9224/* Invoke the datepicker functionality.
9225   @param  options  string - a command, optionally followed by additional parameters or
9226					Object - settings for attaching new datepicker functionality
9227   @return  jQuery object */
9228$.fn.datepicker = function( options ) {
9229
9230	/* Verify an empty collection wasn't passed - Fixes #6976 */
9231	if ( !this.length ) {
9232		return this;
9233	}
9234
9235	/* Initialise the date picker. */
9236	if ( !$.datepicker.initialized ) {
9237		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9238		$.datepicker.initialized = true;
9239	}
9240
9241	/* Append datepicker main container to body if not exist. */
9242	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9243		$( "body" ).append( $.datepicker.dpDiv );
9244	}
9245
9246	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9247	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9248		return $.datepicker[ "_" + options + "Datepicker" ].
9249			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9250	}
9251	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9252		return $.datepicker[ "_" + options + "Datepicker" ].
9253			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9254	}
9255	return this.each( function() {
9256		typeof options === "string" ?
9257			$.datepicker[ "_" + options + "Datepicker" ].
9258				apply( $.datepicker, [ this ].concat( otherArgs ) ) :
9259			$.datepicker._attachDatepicker( this, options );
9260	} );
9261};
9262
9263$.datepicker = new Datepicker(); // singleton instance
9264$.datepicker.initialized = false;
vendor: 11,796 bytes, lines 9265-9723
9265$.datepicker.uuid = new Date().getTime();
9266$.datepicker.version = "1.12.1";
9267
9268var widgetsDatepicker = $.datepicker;
9269
9270
9271
9272
9273// This file is deprecated
9274var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
9275
9276/*!
9277 * jQuery UI Mouse 1.12.1
9278 * http://jqueryui.com
9279 *
9280 * Copyright jQuery Foundation and other contributors
9281 * Released under the MIT license.
9282 * http://jquery.org/license
9283 */
9284
9285//>>label: Mouse
9286//>>group: Widgets
9287//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9288//>>docs: http://api.jqueryui.com/mouse/
9289
9290
9291
9292var mouseHandled = false;
9293$( document ).on( "mouseup", function() {
9294	mouseHandled = false;
9295} );
9296
9297var widgetsMouse = $.widget( "ui.mouse", {
9298	version: "1.12.1",
9299	options: {
9300		cancel: "input, textarea, button, select, option",
9301		distance: 1,
9302		delay: 0
9303	},
9304	_mouseInit: function() {
9305		var that = this;
9306
9307		this.element
9308			.on( "mousedown." + this.widgetName, function( event ) {
9309				return that._mouseDown( event );
9310			} )
9311			.on( "click." + this.widgetName, function( event ) {
9312				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9313					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9314					event.stopImmediatePropagation();
9315					return false;
9316				}
9317			} );
9318
9319		this.started = false;
9320	},
9321
9322	// TODO: make sure destroying one instance of mouse doesn't mess with
9323	// other instances of mouse
9324	_mouseDestroy: function() {
9325		this.element.off( "." + this.widgetName );
9326		if ( this._mouseMoveDelegate ) {
9327			this.document
9328				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9329				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9330		}
9331	},
9332
9333	_mouseDown: function( event ) {
9334
9335		// don't let more than one widget handle mouseStart
9336		if ( mouseHandled ) {
9337			return;
9338		}
9339
9340		this._mouseMoved = false;
9341
9342		// We may have missed mouseup (out of window)
9343		( this._mouseStarted && this._mouseUp( event ) );
9344
9345		this._mouseDownEvent = event;
9346
9347		var that = this,
9348			btnIsLeft = ( event.which === 1 ),
9349
9350			// event.target.nodeName works around a bug in IE 8 with
9351			// disabled inputs (#7620)
9352			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
9353				$( event.target ).closest( this.options.cancel ).length : false );
9354		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9355			return true;
9356		}
9357
9358		this.mouseDelayMet = !this.options.delay;
9359		if ( !this.mouseDelayMet ) {
9360			this._mouseDelayTimer = setTimeout( function() {
9361				that.mouseDelayMet = true;
9362			}, this.options.delay );
9363		}
9364
9365		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9366			this._mouseStarted = ( this._mouseStart( event ) !== false );
9367			if ( !this._mouseStarted ) {
9368				event.preventDefault();
9369				return true;
9370			}
9371		}
9372
9373		// Click event may never have fired (Gecko & Opera)
9374		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9375			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9376		}
9377
9378		// These delegates are required to keep context
9379		this._mouseMoveDelegate = function( event ) {
9380			return that._mouseMove( event );
9381		};
9382		this._mouseUpDelegate = function( event ) {
9383			return that._mouseUp( event );
9384		};
9385
9386		this.document
9387			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9388			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9389
9390		event.preventDefault();
9391
9392		mouseHandled = true;
9393		return true;
9394	},
9395
9396	_mouseMove: function( event ) {
9397
9398		// Only check for mouseups outside the document if you've moved inside the document
9399		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
9400		// fire a mousemove event if content is placed under the cursor. See #7778
9401		// Support: IE <9
9402		if ( this._mouseMoved ) {
9403
9404			// IE mouseup check - mouseup happened when mouse was out of window
9405			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
9406					!event.button ) {
9407				return this._mouseUp( event );
9408
9409			// Iframe mouseup check - mouseup occurred in another document
9410			} else if ( !event.which ) {
9411
9412				// Support: Safari <=8 - 9
9413				// Safari sets which to 0 if you press any of the following keys
9414				// during a drag (#14461)
9415				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9416						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9417					this.ignoreMissingWhich = true;
9418				} else if ( !this.ignoreMissingWhich ) {
9419					return this._mouseUp( event );
9420				}
9421			}
9422		}
9423
9424		if ( event.which || event.button ) {
9425			this._mouseMoved = true;
9426		}
9427
9428		if ( this._mouseStarted ) {
9429			this._mouseDrag( event );
9430			return event.preventDefault();
9431		}
9432
9433		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9434			this._mouseStarted =
9435				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9436			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
9437		}
9438
9439		return !this._mouseStarted;
9440	},
9441
9442	_mouseUp: function( event ) {
9443		this.document
9444			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9445			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9446
9447		if ( this._mouseStarted ) {
9448			this._mouseStarted = false;
9449
9450			if ( event.target === this._mouseDownEvent.target ) {
9451				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9452			}
9453
9454			this._mouseStop( event );
9455		}
9456
9457		if ( this._mouseDelayTimer ) {
9458			clearTimeout( this._mouseDelayTimer );
9459			delete this._mouseDelayTimer;
9460		}
9461
9462		this.ignoreMissingWhich = false;
9463		mouseHandled = false;
9464		event.preventDefault();
9465	},
9466
9467	_mouseDistanceMet: function( event ) {
9468		return ( Math.max(
9469				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9470				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9471			) >= this.options.distance
9472		);
9473	},
9474
9475	_mouseDelayMet: function( /* event */ ) {
9476		return this.mouseDelayMet;
9477	},
9478
9479	// These are placeholder methods, to be overriden by extending plugin
9480	_mouseStart: function( /* event */ ) {},
9481	_mouseDrag: function( /* event */ ) {},
9482	_mouseStop: function( /* event */ ) {},
9483	_mouseCapture: function( /* event */ ) { return true; }
9484} );
9485
9486
9487
9488
9489// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9490var plugin = $.ui.plugin = {
9491	add: function( module, option, set ) {
9492		var i,
9493			proto = $.ui[ module ].prototype;
9494		for ( i in set ) {
9495			proto.plugins[ i ] = proto.plugins[ i ] || [];
9496			proto.plugins[ i ].push( [ option, set[ i ] ] );
9497		}
9498	},
9499	call: function( instance, name, args, allowDisconnected ) {
9500		var i,
9501			set = instance.plugins[ name ];
9502
9503		if ( !set ) {
9504			return;
9505		}
9506
9507		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9508				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9509			return;
9510		}
9511
9512		for ( i = 0; i < set.length; i++ ) {
9513			if ( instance.options[ set[ i ][ 0 ] ] ) {
9514				set[ i ][ 1 ].apply( instance.element, args );
9515			}
9516		}
9517	}
9518};
9519
9520
9521
9522var safeBlur = $.ui.safeBlur = function( element ) {
9523
9524	// Support: IE9 - 10 only
9525	// If the <body> is blurred, IE will switch windows, see #9420
9526	if ( element && element.nodeName.toLowerCase() !== "body" ) {
9527		$( element ).trigger( "blur" );
9528	}
9529};
9530
9531
9532/*!
9533 * jQuery UI Draggable 1.12.1
9534 * http://jqueryui.com
9535 *
9536 * Copyright jQuery Foundation and other contributors
9537 * Released under the MIT license.
9538 * http://jquery.org/license
9539 */
9540
9541//>>label: Draggable
9542//>>group: Interactions
9543//>>description: Enables dragging functionality for any element.
9544//>>docs: http://api.jqueryui.com/draggable/
9545//>>demos: http://jqueryui.com/draggable/
9546//>>css.structure: ../../themes/base/draggable.css
9547
9548
9549
9550$.widget( "ui.draggable", $.ui.mouse, {
9551	version: "1.12.1",
9552	widgetEventPrefix: "drag",
9553	options: {
9554		addClasses: true,
9555		appendTo: "parent",
9556		axis: false,
9557		connectToSortable: false,
9558		containment: false,
9559		cursor: "auto",
9560		cursorAt: false,
9561		grid: false,
9562		handle: false,
9563		helper: "original",
9564		iframeFix: false,
9565		opacity: false,
9566		refreshPositions: false,
9567		revert: false,
9568		revertDuration: 500,
9569		scope: "default",
9570		scroll: true,
9571		scrollSensitivity: 20,
9572		scrollSpeed: 20,
9573		snap: false,
9574		snapMode: "both",
9575		snapTolerance: 20,
9576		stack: false,
9577		zIndex: false,
9578
9579		// Callbacks
9580		drag: null,
9581		start: null,
9582		stop: null
9583	},
9584	_create: function() {
9585
9586		if ( this.options.helper === "original" ) {
9587			this._setPositionRelative();
9588		}
9589		if ( this.options.addClasses ) {
9590			this._addClass( "ui-draggable" );
9591		}
9592		this._setHandleClassName();
9593
9594		this._mouseInit();
9595	},
9596
9597	_setOption: function( key, value ) {
9598		this._super( key, value );
9599		if ( key === "handle" ) {
9600			this._removeHandleClassName();
9601			this._setHandleClassName();
9602		}
9603	},
9604
9605	_destroy: function() {
9606		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9607			this.destroyOnClear = true;
9608			return;
9609		}
9610		this._removeHandleClassName();
9611		this._mouseDestroy();
9612	},
9613
9614	_mouseCapture: function( event ) {
9615		var o = this.options;
9616
9617		// Among others, prevent a drag on a resizable-handle
9618		if ( this.helper || o.disabled ||
9619				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9620			return false;
9621		}
9622
9623		//Quit if we're not on a valid handle
9624		this.handle = this._getHandle( event );
9625		if ( !this.handle ) {
9626			return false;
9627		}
9628
9629		this._blurActiveElement( event );
9630
9631		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9632
9633		return true;
9634
9635	},
9636
9637	_blockFrames: function( selector ) {
9638		this.iframeBlocks = this.document.find( selector ).map( function() {
9639			var iframe = $( this );
9640
9641			return $( "<div>" )
9642				.css( "position", "absolute" )
9643				.appendTo( iframe.parent() )
9644				.outerWidth( iframe.outerWidth() )
9645				.outerHeight( iframe.outerHeight() )
9646				.offset( iframe.offset() )[ 0 ];
9647		} );
9648	},
9649
9650	_unblockFrames: function() {
9651		if ( this.iframeBlocks ) {
9652			this.iframeBlocks.remove();
9653			delete this.iframeBlocks;
9654		}
9655	},
9656
9657	_blurActiveElement: function( event ) {
9658		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
9659			target = $( event.target );
9660
9661		// Don't blur if the event occurred on an element that is within
9662		// the currently focused element
9663		// See #10527, #12472
9664		if ( target.closest( activeElement ).length ) {
9665			return;
9666		}
9667
9668		// Blur any element that currently has focus, see #4261
9669		$.ui.safeBlur( activeElement );
9670	},
9671
9672	_mouseStart: function( event ) {
9673
9674		var o = this.options;
9675
9676		//Create and append the visible helper
9677		this.helper = this._createHelper( event );
9678
9679		this._addClass( this.helper, "ui-draggable-dragging" );
9680
9681		//Cache the helper size
9682		this._cacheHelperProportions();
9683
9684		//If ddmanager is used for droppables, set the global draggable
9685		if ( $.ui.ddmanager ) {
9686			$.ui.ddmanager.current = this;
9687		}
9688
9689		/*
9690		 * - Position generation -
9691		 * This block generates everything position related - it's the core of draggables.
9692		 */
9693
9694		//Cache the margins of the original element
9695		this._cacheMargins();
9696
9697		//Store the helper's css position
9698		this.cssPosition = this.helper.css( "position" );
9699		this.scrollParent = this.helper.scrollParent( true );
9700		this.offsetParent = this.helper.offsetParent();
9701		this.hasFixedAncestor = this.helper.parents().filter( function() {
9702				return $( this ).css( "position" ) === "fixed";
9703			} ).length > 0;
9704
9705		//The element's absolute position on the page minus margins
9706		this.positionAbs = this.element.offset();
9707		this._refreshOffsets( event );
9708
9709		//Generate the original position
9710		this.originalPosition = this.position = this._generatePosition( event, false );
9711		this.originalPageX = event.pageX;
9712		this.originalPageY = event.pageY;
9713
9714		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9715		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
9716
9717		//Set a containment if given in the options
9718		this._setContainment();
9719
9720		//Trigger event + callbacks
9721		if ( this._trigger( "start", event ) === false ) {
9722			this._clear();
9723			return false;
vendor: 5,171 bytes, lines 9724-9921
9724		}
9725
9726		//Recache the helper size
9727		this._cacheHelperProportions();
9728
9729		//Prepare the droppable offsets
9730		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9731			$.ui.ddmanager.prepareOffsets( this, event );
9732		}
9733
9734		// Execute the drag once - this causes the helper not to be visible before getting its
9735		// correct position
9736		this._mouseDrag( event, true );
9737
9738		// If the ddmanager is used for droppables, inform the manager that dragging has started
9739		// (see #5003)
9740		if ( $.ui.ddmanager ) {
9741			$.ui.ddmanager.dragStart( this, event );
9742		}
9743
9744		return true;
9745	},
9746
9747	_refreshOffsets: function( event ) {
9748		this.offset = {
9749			top: this.positionAbs.top - this.margins.top,
9750			left: this.positionAbs.left - this.margins.left,
9751			scroll: false,
9752			parent: this._getParentOffset(),
9753			relative: this._getRelativeOffset()
9754		};
9755
9756		this.offset.click = {
9757			left: event.pageX - this.offset.left,
9758			top: event.pageY - this.offset.top
9759		};
9760	},
9761
9762	_mouseDrag: function( event, noPropagation ) {
9763
9764		// reset any necessary cached properties (see #5009)
9765		if ( this.hasFixedAncestor ) {
9766			this.offset.parent = this._getParentOffset();
9767		}
9768
9769		//Compute the helpers position
9770		this.position = this._generatePosition( event, true );
9771		this.positionAbs = this._convertPositionTo( "absolute" );
9772
9773		//Call plugins and callbacks and use the resulting position if something is returned
9774		if ( !noPropagation ) {
9775			var ui = this._uiHash();
9776			if ( this._trigger( "drag", event, ui ) === false ) {
9777				this._mouseUp( new $.Event( "mouseup", event ) );
9778				return false;
9779			}
9780			this.position = ui.position;
9781		}
9782
9783		this.helper[ 0 ].style.left = this.position.left + "px";
9784		this.helper[ 0 ].style.top = this.position.top + "px";
9785
9786		if ( $.ui.ddmanager ) {
9787			$.ui.ddmanager.drag( this, event );
9788		}
9789
9790		return false;
9791	},
9792
9793	_mouseStop: function( event ) {
9794
9795		//If we are using droppables, inform the manager about the drop
9796		var that = this,
9797			dropped = false;
9798		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9799			dropped = $.ui.ddmanager.drop( this, event );
9800		}
9801
9802		//if a drop comes from outside (a sortable)
9803		if ( this.dropped ) {
9804			dropped = this.dropped;
9805			this.dropped = false;
9806		}
9807
9808		if ( ( this.options.revert === "invalid" && !dropped ) ||
9809				( this.options.revert === "valid" && dropped ) ||
9810				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
9811				this.options.revert.call( this.element, dropped ) )
9812		) {
9813			$( this.helper ).animate(
9814				this.originalPosition,
9815				parseInt( this.options.revertDuration, 10 ),
9816				function() {
9817					if ( that._trigger( "stop", event ) !== false ) {
9818						that._clear();
9819					}
9820				}
9821			);
9822		} else {
9823			if ( this._trigger( "stop", event ) !== false ) {
9824				this._clear();
9825			}
9826		}
9827
9828		return false;
9829	},
9830
9831	_mouseUp: function( event ) {
9832		this._unblockFrames();
9833
9834		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9835		// (see #5003)
9836		if ( $.ui.ddmanager ) {
9837			$.ui.ddmanager.dragStop( this, event );
9838		}
9839
9840		// Only need to focus if the event occurred on the draggable itself, see #10527
9841		if ( this.handleElement.is( event.target ) ) {
9842
9843			// The interaction is over; whether or not the click resulted in a drag,
9844			// focus the element
9845			this.element.trigger( "focus" );
9846		}
9847
9848		return $.ui.mouse.prototype._mouseUp.call( this, event );
9849	},
9850
9851	cancel: function() {
9852
9853		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9854			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9855		} else {
9856			this._clear();
9857		}
9858
9859		return this;
9860
9861	},
9862
9863	_getHandle: function( event ) {
9864		return this.options.handle ?
9865			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9866			true;
9867	},
9868
9869	_setHandleClassName: function() {
9870		this.handleElement = this.options.handle ?
9871			this.element.find( this.options.handle ) : this.element;
9872		this._addClass( this.handleElement, "ui-draggable-handle" );
9873	},
9874
9875	_removeHandleClassName: function() {
9876		this._removeClass( this.handleElement, "ui-draggable-handle" );
9877	},
9878
9879	_createHelper: function( event ) {
9880
9881		var o = this.options,
9882			helperIsFunction = $.isFunction( o.helper ),
9883			helper = helperIsFunction ?
9884				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9885				( o.helper === "clone" ?
9886					this.element.clone().removeAttr( "id" ) :
9887					this.element );
9888
9889		if ( !helper.parents( "body" ).length ) {
9890			helper.appendTo( ( o.appendTo === "parent" ?
9891				this.element[ 0 ].parentNode :
9892				o.appendTo ) );
9893		}
9894
9895		// Http://bugs.jqueryui.com/ticket/9446
9896		// a helper function can return the original element
9897		// which wouldn't have been set to relative in _create
9898		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9899			this._setPositionRelative();
9900		}
9901
9902		if ( helper[ 0 ] !== this.element[ 0 ] &&
9903				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9904			helper.css( "position", "absolute" );
9905		}
9906
9907		return helper;
9908
9909	},
9910
9911	_setPositionRelative: function() {
9912		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9913			this.element[ 0 ].style.position = "relative";
9914		}
9915	},
9916
9917	_adjustOffsetFromHelper: function( obj ) {
9918		if ( typeof obj === "string" ) {
9919			obj = obj.split( " " );
9920		}
9921		if ( $
vendor: 22,091 bytes, lines 9921-10630
9921.isArray( obj ) ) {
9922			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9923		}
9924		if ( "left" in obj ) {
9925			this.offset.click.left = obj.left + this.margins.left;
9926		}
9927		if ( "right" in obj ) {
9928			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9929		}
9930		if ( "top" in obj ) {
9931			this.offset.click.top = obj.top + this.margins.top;
9932		}
9933		if ( "bottom" in obj ) {
9934			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9935		}
9936	},
9937
9938	_isRootNode: function( element ) {
9939		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9940	},
9941
9942	_getParentOffset: function() {
9943
9944		//Get the offsetParent and cache its position
9945		var po = this.offsetParent.offset(),
9946			document = this.document[ 0 ];
9947
9948		// This is a special case where we need to modify a offset calculated on start, since the
9949		// following happened:
9950		// 1. The position of the helper is absolute, so it's position is calculated based on the
9951		// next positioned parent
9952		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
9953		// the document, which means that the scroll is included in the initial calculation of the
9954		// offset of the parent, and never recalculated upon drag
9955		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
9956				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
9957			po.left += this.scrollParent.scrollLeft();
9958			po.top += this.scrollParent.scrollTop();
9959		}
9960
9961		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
9962			po = { top: 0, left: 0 };
9963		}
9964
9965		return {
9966			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
9967			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
9968		};
9969
9970	},
9971
9972	_getRelativeOffset: function() {
9973		if ( this.cssPosition !== "relative" ) {
9974			return { top: 0, left: 0 };
9975		}
9976
9977		var p = this.element.position(),
9978			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
9979
9980		return {
9981			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
9982				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
9983			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
9984				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
9985		};
9986
9987	},
9988
9989	_cacheMargins: function() {
9990		this.margins = {
9991			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
9992			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
9993			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
9994			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
9995		};
9996	},
9997
9998	_cacheHelperProportions: function() {
9999		this.helperProportions = {
10000			width: this.helper.outerWidth(),
10001			height: this.helper.outerHeight()
10002		};
10003	},
10004
10005	_setContainment: function() {
10006
10007		var isUserScrollable, c, ce,
10008			o = this.options,
10009			document = this.document[ 0 ];
10010
10011		this.relativeContainer = null;
10012
10013		if ( !o.containment ) {
10014			this.containment = null;
10015			return;
10016		}
10017
10018		if ( o.containment === "window" ) {
10019			this.containment = [
10020				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10021				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10022				$( window ).scrollLeft() + $( window ).width() -
10023					this.helperProportions.width - this.margins.left,
10024				$( window ).scrollTop() +
10025					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10026					this.helperProportions.height - this.margins.top
10027			];
10028			return;
10029		}
10030
10031		if ( o.containment === "document" ) {
10032			this.containment = [
10033				0,
10034				0,
10035				$( document ).width() - this.helperProportions.width - this.margins.left,
10036				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10037					this.helperProportions.height - this.margins.top
10038			];
10039			return;
10040		}
10041
10042		if ( o.containment.constructor === Array ) {
10043			this.containment = o.containment;
10044			return;
10045		}
10046
10047		if ( o.containment === "parent" ) {
10048			o.containment = this.helper[ 0 ].parentNode;
10049		}
10050
10051		c = $( o.containment );
10052		ce = c[ 0 ];
10053
10054		if ( !ce ) {
10055			return;
10056		}
10057
10058		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10059
10060		this.containment = [
10061			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10062				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10063			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10064				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10065			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10066				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10067				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10068				this.helperProportions.width -
10069				this.margins.left -
10070				this.margins.right,
10071			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10072				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10073				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10074				this.helperProportions.height -
10075				this.margins.top -
10076				this.margins.bottom
10077		];
10078		this.relativeContainer = c;
10079	},
10080
10081	_convertPositionTo: function( d, pos ) {
10082
10083		if ( !pos ) {
10084			pos = this.position;
10085		}
10086
10087		var mod = d === "absolute" ? 1 : -1,
10088			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10089
10090		return {
10091			top: (
10092
10093				// The absolute mouse position
10094				pos.top	+
10095
10096				// Only for relative positioned nodes: Relative offset from element to offset parent
10097				this.offset.relative.top * mod +
10098
10099				// The offsetParent's offset without borders (offset + border)
10100				this.offset.parent.top * mod -
10101				( ( this.cssPosition === "fixed" ?
10102					-this.offset.scroll.top :
10103					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10104			),
10105			left: (
10106
10107				// The absolute mouse position
10108				pos.left +
10109
10110				// Only for relative positioned nodes: Relative offset from element to offset parent
10111				this.offset.relative.left * mod +
10112
10113				// The offsetParent's offset without borders (offset + border)
10114				this.offset.parent.left * mod	-
10115				( ( this.cssPosition === "fixed" ?
10116					-this.offset.scroll.left :
10117					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10118			)
10119		};
10120
10121	},
10122
10123	_generatePosition: function( event, constrainPosition ) {
10124
10125		var containment, co, top, left,
10126			o = this.options,
10127			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10128			pageX = event.pageX,
10129			pageY = event.pageY;
10130
10131		// Cache the scroll
10132		if ( !scrollIsRootNode || !this.offset.scroll ) {
10133			this.offset.scroll = {
10134				top: this.scrollParent.scrollTop(),
10135				left: this.scrollParent.scrollLeft()
10136			};
10137		}
10138
10139		/*
10140		 * - Position constraining -
10141		 * Constrain the position to a mix of grid, containment.
10142		 */
10143
10144		// If we are not dragging yet, we won't check for options
10145		if ( constrainPosition ) {
10146			if ( this.containment ) {
10147				if ( this.relativeContainer ) {
10148					co = this.relativeContainer.offset();
10149					containment = [
10150						this.containment[ 0 ] + co.left,
10151						this.containment[ 1 ] + co.top,
10152						this.containment[ 2 ] + co.left,
10153						this.containment[ 3 ] + co.top
10154					];
10155				} else {
10156					containment = this.containment;
10157				}
10158
10159				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10160					pageX = containment[ 0 ] + this.offset.click.left;
10161				}
10162				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10163					pageY = containment[ 1 ] + this.offset.click.top;
10164				}
10165				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10166					pageX = containment[ 2 ] + this.offset.click.left;
10167				}
10168				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10169					pageY = containment[ 3 ] + this.offset.click.top;
10170				}
10171			}
10172
10173			if ( o.grid ) {
10174
10175				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10176				// argument errors in IE (see ticket #6950)
10177				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10178					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10179				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10180					top - this.offset.click.top > containment[ 3 ] ) ?
10181						top :
10182						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10183							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10184
10185				left = o.grid[ 0 ] ? this.originalPageX +
10186					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10187					this.originalPageX;
10188				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10189					left - this.offset.click.left > containment[ 2 ] ) ?
10190						left :
10191						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10192							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10193			}
10194
10195			if ( o.axis === "y" ) {
10196				pageX = this.originalPageX;
10197			}
10198
10199			if ( o.axis === "x" ) {
10200				pageY = this.originalPageY;
10201			}
10202		}
10203
10204		return {
10205			top: (
10206
10207				// The absolute mouse position
10208				pageY -
10209
10210				// Click offset (relative to the element)
10211				this.offset.click.top -
10212
10213				// Only for relative positioned nodes: Relative offset from element to offset parent
10214				this.offset.relative.top -
10215
10216				// The offsetParent's offset without borders (offset + border)
10217				this.offset.parent.top +
10218				( this.cssPosition === "fixed" ?
10219					-this.offset.scroll.top :
10220					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10221			),
10222			left: (
10223
10224				// The absolute mouse position
10225				pageX -
10226
10227				// Click offset (relative to the element)
10228				this.offset.click.left -
10229
10230				// Only for relative positioned nodes: Relative offset from element to offset parent
10231				this.offset.relative.left -
10232
10233				// The offsetParent's offset without borders (offset + border)
10234				this.offset.parent.left +
10235				( this.cssPosition === "fixed" ?
10236					-this.offset.scroll.left :
10237					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10238			)
10239		};
10240
10241	},
10242
10243	_clear: function() {
10244		this._removeClass( this.helper, "ui-draggable-dragging" );
10245		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10246			this.helper.remove();
10247		}
10248		this.helper = null;
10249		this.cancelHelperRemoval = false;
10250		if ( this.destroyOnClear ) {
10251			this.destroy();
10252		}
10253	},
10254
10255	// From now on bulk stuff - mainly helpers
10256
10257	_trigger: function( type, event, ui ) {
10258		ui = ui || this._uiHash();
10259		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10260
10261		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10262		if ( /^(drag|start|stop)/.test( type ) ) {
10263			this.positionAbs = this._convertPositionTo( "absolute" );
10264			ui.offset = this.positionAbs;
10265		}
10266		return $.Widget.prototype._trigger.call( this, type, event, ui );
10267	},
10268
10269	plugins: {},
10270
10271	_uiHash: function() {
10272		return {
10273			helper: this.helper,
10274			position: this.position,
10275			originalPosition: this.originalPosition,
10276			offset: this.positionAbs
10277		};
10278	}
10279
10280} );
10281
10282$.ui.plugin.add( "draggable", "connectToSortable", {
10283	start: function( event, ui, draggable ) {
10284		var uiSortable = $.extend( {}, ui, {
10285			item: draggable.element
10286		} );
10287
10288		draggable.sortables = [];
10289		$( draggable.options.connectToSortable ).each( function() {
10290			var sortable = $( this ).sortable( "instance" );
10291
10292			if ( sortable && !sortable.options.disabled ) {
10293				draggable.sortables.push( sortable );
10294
10295				// RefreshPositions is called at drag start to refresh the containerCache
10296				// which is used in drag. This ensures it's initialized and synchronized
10297				// with any changes that might have happened on the page since initialization.
10298				sortable.refreshPositions();
10299				sortable._trigger( "activate", event, uiSortable );
10300			}
10301		} );
10302	},
10303	stop: function( event, ui, draggable ) {
10304		var uiSortable = $.extend( {}, ui, {
10305			item: draggable.element
10306		} );
10307
10308		draggable.cancelHelperRemoval = false;
10309
10310		$.each( draggable.sortables, function() {
10311			var sortable = this;
10312
10313			if ( sortable.isOver ) {
10314				sortable.isOver = 0;
10315
10316				// Allow this sortable to handle removing the helper
10317				draggable.cancelHelperRemoval = true;
10318				sortable.cancelHelperRemoval = false;
10319
10320				// Use _storedCSS To restore properties in the sortable,
10321				// as this also handles revert (#9675) since the draggable
10322				// may have modified them in unexpected ways (#8809)
10323				sortable._storedCSS = {
10324					position: sortable.placeholder.css( "position" ),
10325					top: sortable.placeholder.css( "top" ),
10326					left: sortable.placeholder.css( "left" )
10327				};
10328
10329				sortable._mouseStop( event );
10330
10331				// Once drag has ended, the sortable should return to using
10332				// its original helper, not the shared helper from draggable
10333				sortable.options.helper = sortable.options._helper;
10334			} else {
10335
10336				// Prevent this Sortable from removing the helper.
10337				// However, don't set the draggable to remove the helper
10338				// either as another connected Sortable may yet handle the removal.
10339				sortable.cancelHelperRemoval = true;
10340
10341				sortable._trigger( "deactivate", event, uiSortable );
10342			}
10343		} );
10344	},
10345	drag: function( event, ui, draggable ) {
10346		$.each( draggable.sortables, function() {
10347			var innermostIntersecting = false,
10348				sortable = this;
10349
10350			// Copy over variables that sortable's _intersectsWith uses
10351			sortable.positionAbs = draggable.positionAbs;
10352			sortable.helperProportions = draggable.helperProportions;
10353			sortable.offset.click = draggable.offset.click;
10354
10355			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10356				innermostIntersecting = true;
10357
10358				$.each( draggable.sortables, function() {
10359
10360					// Copy over variables that sortable's _intersectsWith uses
10361					this.positionAbs = draggable.positionAbs;
10362					this.helperProportions = draggable.helperProportions;
10363					this.offset.click = draggable.offset.click;
10364
10365					if ( this !== sortable &&
10366							this._intersectsWith( this.containerCache ) &&
10367							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10368						innermostIntersecting = false;
10369					}
10370
10371					return innermostIntersecting;
10372				} );
10373			}
10374
10375			if ( innermostIntersecting ) {
10376
10377				// If it intersects, we use a little isOver variable and set it once,
10378				// so that the move-in stuff gets fired only once.
10379				if ( !sortable.isOver ) {
10380					sortable.isOver = 1;
10381
10382					// Store draggable's parent in case we need to reappend to it later.
10383					draggable._parent = ui.helper.parent();
10384
10385					sortable.currentItem = ui.helper
10386						.appendTo( sortable.element )
10387						.data( "ui-sortable-item", true );
10388
10389					// Store helper option to later restore it
10390					sortable.options._helper = sortable.options.helper;
10391
10392					sortable.options.helper = function() {
10393						return ui.helper[ 0 ];
10394					};
10395
10396					// Fire the start events of the sortable with our passed browser event,
10397					// and our own helper (so it doesn't create a new one)
10398					event.target = sortable.currentItem[ 0 ];
10399					sortable._mouseCapture( event, true );
10400					sortable._mouseStart( event, true, true );
10401
10402					// Because the browser event is way off the new appended portlet,
10403					// modify necessary variables to reflect the changes
10404					sortable.offset.click.top = draggable.offset.click.top;
10405					sortable.offset.click.left = draggable.offset.click.left;
10406					sortable.offset.parent.left -= draggable.offset.parent.left -
10407						sortable.offset.parent.left;
10408					sortable.offset.parent.top -= draggable.offset.parent.top -
10409						sortable.offset.parent.top;
10410
10411					draggable._trigger( "toSortable", event );
10412
10413					// Inform draggable that the helper is in a valid drop zone,
10414					// used solely in the revert option to handle "valid/invalid".
10415					draggable.dropped = sortable.element;
10416
10417					// Need to refreshPositions of all sortables in the case that
10418					// adding to one sortable changes the location of the other sortables (#9675)
10419					$.each( draggable.sortables, function() {
10420						this.refreshPositions();
10421					} );
10422
10423					// Hack so receive/update callbacks work (mostly)
10424					draggable.currentItem = draggable.element;
10425					sortable.fromOutside = draggable;
10426				}
10427
10428				if ( sortable.currentItem ) {
10429					sortable._mouseDrag( event );
10430
10431					// Copy the sortable's position because the draggable's can potentially reflect
10432					// a relative position, while sortable is always absolute, which the dragged
10433					// element has now become. (#8809)
10434					ui.position = sortable.position;
10435				}
10436			} else {
10437
10438				// If it doesn't intersect with the sortable, and it intersected before,
10439				// we fake the drag stop of the sortable, but make sure it doesn't remove
10440				// the helper by using cancelHelperRemoval.
10441				if ( sortable.isOver ) {
10442
10443					sortable.isOver = 0;
10444					sortable.cancelHelperRemoval = true;
10445
10446					// Calling sortable's mouseStop would trigger a revert,
10447					// so revert must be temporarily false until after mouseStop is called.
10448					sortable.options._revert = sortable.options.revert;
10449					sortable.options.revert = false;
10450
10451					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10452					sortable._mouseStop( event, true );
10453
10454					// Restore sortable behaviors that were modfied
10455					// when the draggable entered the sortable area (#9481)
10456					sortable.options.revert = sortable.options._revert;
10457					sortable.options.helper = sortable.options._helper;
10458
10459					if ( sortable.placeholder ) {
10460						sortable.placeholder.remove();
10461					}
10462
10463					// Restore and recalculate the draggable's offset considering the sortable
10464					// may have modified them in unexpected ways. (#8809, #10669)
10465					ui.helper.appendTo( draggable._parent );
10466					draggable._refreshOffsets( event );
10467					ui.position = draggable._generatePosition( event, true );
10468
10469					draggable._trigger( "fromSortable", event );
10470
10471					// Inform draggable that the helper is no longer in a valid drop zone
10472					draggable.dropped = false;
10473
10474					// Need to refreshPositions of all sortables just in case removing
10475					// from one sortable changes the location of other sortables (#9675)
10476					$.each( draggable.sortables, function() {
10477						this.refreshPositions();
10478					} );
10479				}
10480			}
10481		} );
10482	}
10483} );
10484
10485$.ui.plugin.add( "draggable", "cursor", {
10486	start: function( event, ui, instance ) {
10487		var t = $( "body" ),
10488			o = instance.options;
10489
10490		if ( t.css( "cursor" ) ) {
10491			o._cursor = t.css( "cursor" );
10492		}
10493		t.css( "cursor", o.cursor );
10494	},
10495	stop: function( event, ui, instance ) {
10496		var o = instance.options;
10497		if ( o._cursor ) {
10498			$( "body" ).css( "cursor", o._cursor );
10499		}
10500	}
10501} );
10502
10503$.ui.plugin.add( "draggable", "opacity", {
10504	start: function( event, ui, instance ) {
10505		var t = $( ui.helper ),
10506			o = instance.options;
10507		if ( t.css( "opacity" ) ) {
10508			o._opacity = t.css( "opacity" );
10509		}
10510		t.css( "opacity", o.opacity );
10511	},
10512	stop: function( event, ui, instance ) {
10513		var o = instance.options;
10514		if ( o._opacity ) {
10515			$( ui.helper ).css( "opacity", o._opacity );
10516		}
10517	}
10518} );
10519
10520$.ui.plugin.add( "draggable", "scroll", {
10521	start: function( event, ui, i ) {
10522		if ( !i.scrollParentNotHidden ) {
10523			i.scrollParentNotHidden = i.helper.scrollParent( false );
10524		}
10525
10526		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10527				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10528			i.overflowOffset = i.scrollParentNotHidden.offset();
10529		}
10530	},
10531	drag: function( event, ui, i  ) {
10532
10533		var o = i.options,
10534			scrolled = false,
10535			scrollParent = i.scrollParentNotHidden[ 0 ],
10536			document = i.document[ 0 ];
10537
10538		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10539			if ( !o.axis || o.axis !== "x" ) {
10540				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10541						o.scrollSensitivity ) {
10542					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10543				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10544					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10545				}
10546			}
10547
10548			if ( !o.axis || o.axis !== "y" ) {
10549				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10550						o.scrollSensitivity ) {
10551					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10552				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10553					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10554				}
10555			}
10556
10557		} else {
10558
10559			if ( !o.axis || o.axis !== "x" ) {
10560				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10561					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10562				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10563						o.scrollSensitivity ) {
10564					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10565				}
10566			}
10567
10568			if ( !o.axis || o.axis !== "y" ) {
10569				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10570					scrolled = $( document ).scrollLeft(
10571						$( document ).scrollLeft() - o.scrollSpeed
10572					);
10573				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10574						o.scrollSensitivity ) {
10575					scrolled = $( document ).scrollLeft(
10576						$( document ).scrollLeft() + o.scrollSpeed
10577					);
10578				}
10579			}
10580
10581		}
10582
10583		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10584			$.ui.ddmanager.prepareOffsets( i, event );
10585		}
10586
10587	}
10588} );
10589
10590$.ui.plugin.add( "draggable", "snap", {
10591	start: function( event, ui, i ) {
10592
10593		var o = i.options;
10594
10595		i.snapElements = [];
10596
10597		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10598			.each( function() {
10599				var $t = $( this ),
10600					$o = $t.offset();
10601				if ( this !== i.element[ 0 ] ) {
10602					i.snapElements.push( {
10603						item: this,
10604						width: $t.outerWidth(), height: $t.outerHeight(),
10605						top: $o.top, left: $o.left
10606					} );
10607				}
10608			} );
10609
10610	},
10611	drag: function( event, ui, inst ) {
10612
10613		var ts, bs, ls, rs, l, r, t, b, i, first,
10614			o = inst.options,
10615			d = o.snapTolerance,
10616			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10617			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10618
10619		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10620
10621			l = inst.snapElements[ i ].left - inst.margins.left;
10622			r = l + inst.snapElements[ i ].width;
10623			t = inst.snapElements[ i ].top - inst.margins.top;
10624			b = t + inst.snapElements[ i ].height;
10625
10626			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10627					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10628					inst.snapElements[ i ].item ) ) {
10629				if ( inst.snapElements[ i ].snapping ) {
10630					
10630( inst.options.snap.release &&
10631						inst.options.snap.release.call(
10632							inst.element,
10633							event,
10634							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10635						) );
10636				}
10637				inst.snapElements[ i ].snapping = false;
vendor: 58,939 bytes, lines 10638-13027
10638				continue;
10639			}
10640
10641			if ( o.snapMode !== "inner" ) {
10642				ts = Math.abs( t - y2 ) <= d;
10643				bs = Math.abs( b - y1 ) <= d;
10644				ls = Math.abs( l - x2 ) <= d;
10645				rs = Math.abs( r - x1 ) <= d;
10646				if ( ts ) {
10647					ui.position.top = inst._convertPositionTo( "relative", {
10648						top: t - inst.helperProportions.height,
10649						left: 0
10650					} ).top;
10651				}
10652				if ( bs ) {
10653					ui.position.top = inst._convertPositionTo( "relative", {
10654						top: b,
10655						left: 0
10656					} ).top;
10657				}
10658				if ( ls ) {
10659					ui.position.left = inst._convertPositionTo( "relative", {
10660						top: 0,
10661						left: l - inst.helperProportions.width
10662					} ).left;
10663				}
10664				if ( rs ) {
10665					ui.position.left = inst._convertPositionTo( "relative", {
10666						top: 0,
10667						left: r
10668					} ).left;
10669				}
10670			}
10671
10672			first = ( ts || bs || ls || rs );
10673
10674			if ( o.snapMode !== "outer" ) {
10675				ts = Math.abs( t - y1 ) <= d;
10676				bs = Math.abs( b - y2 ) <= d;
10677				ls = Math.abs( l - x1 ) <= d;
10678				rs = Math.abs( r - x2 ) <= d;
10679				if ( ts ) {
10680					ui.position.top = inst._convertPositionTo( "relative", {
10681						top: t,
10682						left: 0
10683					} ).top;
10684				}
10685				if ( bs ) {
10686					ui.position.top = inst._convertPositionTo( "relative", {
10687						top: b - inst.helperProportions.height,
10688						left: 0
10689					} ).top;
10690				}
10691				if ( ls ) {
10692					ui.position.left = inst._convertPositionTo( "relative", {
10693						top: 0,
10694						left: l
10695					} ).left;
10696				}
10697				if ( rs ) {
10698					ui.position.left = inst._convertPositionTo( "relative", {
10699						top: 0,
10700						left: r - inst.helperProportions.width
10701					} ).left;
10702				}
10703			}
10704
10705			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10706				( inst.options.snap.snap &&
10707					inst.options.snap.snap.call(
10708						inst.element,
10709						event,
10710						$.extend( inst._uiHash(), {
10711							snapItem: inst.snapElements[ i ].item
10712						} ) ) );
10713			}
10714			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10715
10716		}
10717
10718	}
10719} );
10720
10721$.ui.plugin.add( "draggable", "stack", {
10722	start: function( event, ui, instance ) {
10723		var min,
10724			o = instance.options,
10725			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10726				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10727					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10728			} );
10729
10730		if ( !group.length ) { return; }
10731
10732		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10733		$( group ).each( function( i ) {
10734			$( this ).css( "zIndex", min + i );
10735		} );
10736		this.css( "zIndex", ( min + group.length ) );
10737	}
10738} );
10739
10740$.ui.plugin.add( "draggable", "zIndex", {
10741	start: function( event, ui, instance ) {
10742		var t = $( ui.helper ),
10743			o = instance.options;
10744
10745		if ( t.css( "zIndex" ) ) {
10746			o._zIndex = t.css( "zIndex" );
10747		}
10748		t.css( "zIndex", o.zIndex );
10749	},
10750	stop: function( event, ui, instance ) {
10751		var o = instance.options;
10752
10753		if ( o._zIndex ) {
10754			$( ui.helper ).css( "zIndex", o._zIndex );
10755		}
10756	}
10757} );
10758
10759var widgetsDraggable = $.ui.draggable;
10760
10761
10762/*!
10763 * jQuery UI Resizable 1.12.1
10764 * http://jqueryui.com
10765 *
10766 * Copyright jQuery Foundation and other contributors
10767 * Released under the MIT license.
10768 * http://jquery.org/license
10769 */
10770
10771//>>label: Resizable
10772//>>group: Interactions
10773//>>description: Enables resize functionality for any element.
10774//>>docs: http://api.jqueryui.com/resizable/
10775//>>demos: http://jqueryui.com/resizable/
10776//>>css.structure: ../../themes/base/core.css
10777//>>css.structure: ../../themes/base/resizable.css
10778//>>css.theme: ../../themes/base/theme.css
10779
10780
10781
10782$.widget( "ui.resizable", $.ui.mouse, {
10783	version: "1.12.1",
10784	widgetEventPrefix: "resize",
10785	options: {
10786		alsoResize: false,
10787		animate: false,
10788		animateDuration: "slow",
10789		animateEasing: "swing",
10790		aspectRatio: false,
10791		autoHide: false,
10792		classes: {
10793			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10794		},
10795		containment: false,
10796		ghost: false,
10797		grid: false,
10798		handles: "e,s,se",
10799		helper: false,
10800		maxHeight: null,
10801		maxWidth: null,
10802		minHeight: 10,
10803		minWidth: 10,
10804
10805		// See #7960
10806		zIndex: 90,
10807
10808		// Callbacks
10809		resize: null,
10810		start: null,
10811		stop: null
10812	},
10813
10814	_num: function( value ) {
10815		return parseFloat( value ) || 0;
10816	},
10817
10818	_isNumber: function( value ) {
10819		return !isNaN( parseFloat( value ) );
10820	},
10821
10822	_hasScroll: function( el, a ) {
10823
10824		if ( $( el ).css( "overflow" ) === "hidden" ) {
10825			return false;
10826		}
10827
10828		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
10829			has = false;
10830
10831		if ( el[ scroll ] > 0 ) {
10832			return true;
10833		}
10834
10835		// TODO: determine which cases actually cause this to happen
10836		// if the element doesn't have the scroll set, see if it's possible to
10837		// set the scroll
10838		el[ scroll ] = 1;
10839		has = ( el[ scroll ] > 0 );
10840		el[ scroll ] = 0;
10841		return has;
10842	},
10843
10844	_create: function() {
10845
10846		var margins,
10847			o = this.options,
10848			that = this;
10849		this._addClass( "ui-resizable" );
10850
10851		$.extend( this, {
10852			_aspectRatio: !!( o.aspectRatio ),
10853			aspectRatio: o.aspectRatio,
10854			originalElement: this.element,
10855			_proportionallyResizeElements: [],
10856			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10857		} );
10858
10859		// Wrap the element if it cannot hold child nodes
10860		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10861
10862			this.element.wrap(
10863				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
10864					position: this.element.css( "position" ),
10865					width: this.element.outerWidth(),
10866					height: this.element.outerHeight(),
10867					top: this.element.css( "top" ),
10868					left: this.element.css( "left" )
10869				} )
10870			);
10871
10872			this.element = this.element.parent().data(
10873				"ui-resizable", this.element.resizable( "instance" )
10874			);
10875
10876			this.elementIsWrapper = true;
10877
10878			margins = {
10879				marginTop: this.originalElement.css( "marginTop" ),
10880				marginRight: this.originalElement.css( "marginRight" ),
10881				marginBottom: this.originalElement.css( "marginBottom" ),
10882				marginLeft: this.originalElement.css( "marginLeft" )
10883			};
10884
10885			this.element.css( margins );
10886			this.originalElement.css( "margin", 0 );
10887
10888			// support: Safari
10889			// Prevent Safari textarea resize
10890			this.originalResizeStyle = this.originalElement.css( "resize" );
10891			this.originalElement.css( "resize", "none" );
10892
10893			this._proportionallyResizeElements.push( this.originalElement.css( {
10894				position: "static",
10895				zoom: 1,
10896				display: "block"
10897			} ) );
10898
10899			// Support: IE9
10900			// avoid IE jump (hard set the margin)
10901			this.originalElement.css( margins );
10902
10903			this._proportionallyResize();
10904		}
10905
10906		this._setupHandles();
10907
10908		if ( o.autoHide ) {
10909			$( this.element )
10910				.on( "mouseenter", function() {
10911					if ( o.disabled ) {
10912						return;
10913					}
10914					that._removeClass( "ui-resizable-autohide" );
10915					that._handles.show();
10916				} )
10917				.on( "mouseleave", function() {
10918					if ( o.disabled ) {
10919						return;
10920					}
10921					if ( !that.resizing ) {
10922						that._addClass( "ui-resizable-autohide" );
10923						that._handles.hide();
10924					}
10925				} );
10926		}
10927
10928		this._mouseInit();
10929	},
10930
10931	_destroy: function() {
10932
10933		this._mouseDestroy();
10934
10935		var wrapper,
10936			_destroy = function( exp ) {
10937				$( exp )
10938					.removeData( "resizable" )
10939					.removeData( "ui-resizable" )
10940					.off( ".resizable" )
10941					.find( ".ui-resizable-handle" )
10942						.remove();
10943			};
10944
10945		// TODO: Unwrap at same DOM position
10946		if ( this.elementIsWrapper ) {
10947			_destroy( this.element );
10948			wrapper = this.element;
10949			this.originalElement.css( {
10950				position: wrapper.css( "position" ),
10951				width: wrapper.outerWidth(),
10952				height: wrapper.outerHeight(),
10953				top: wrapper.css( "top" ),
10954				left: wrapper.css( "left" )
10955			} ).insertAfter( wrapper );
10956			wrapper.remove();
10957		}
10958
10959		this.originalElement.css( "resize", this.originalResizeStyle );
10960		_destroy( this.originalElement );
10961
10962		return this;
10963	},
10964
10965	_setOption: function( key, value ) {
10966		this._super( key, value );
10967
10968		switch ( key ) {
10969		case "handles":
10970			this._removeHandles();
10971			this._setupHandles();
10972			break;
10973		default:
10974			break;
10975		}
10976	},
10977
10978	_setupHandles: function() {
10979		var o = this.options, handle, i, n, hname, axis, that = this;
10980		this.handles = o.handles ||
10981			( !$( ".ui-resizable-handle", this.element ).length ?
10982				"e,s,se" : {
10983					n: ".ui-resizable-n",
10984					e: ".ui-resizable-e",
10985					s: ".ui-resizable-s",
10986					w: ".ui-resizable-w",
10987					se: ".ui-resizable-se",
10988					sw: ".ui-resizable-sw",
10989					ne: ".ui-resizable-ne",
10990					nw: ".ui-resizable-nw"
10991				} );
10992
10993		this._handles = $();
10994		if ( this.handles.constructor === String ) {
10995
10996			if ( this.handles === "all" ) {
10997				this.handles = "n,e,s,w,se,sw,ne,nw";
10998			}
10999
11000			n = this.handles.split( "," );
11001			this.handles = {};
11002
11003			for ( i = 0; i < n.length; i++ ) {
11004
11005				handle = $.trim( n[ i ] );
11006				hname = "ui-resizable-" + handle;
11007				axis = $( "<div>" );
11008				this._addClass( axis, "ui-resizable-handle " + hname );
11009
11010				axis.css( { zIndex: o.zIndex } );
11011
11012				this.handles[ handle ] = ".ui-resizable-" + handle;
11013				this.element.append( axis );
11014			}
11015
11016		}
11017
11018		this._renderAxis = function( target ) {
11019
11020			var i, axis, padPos, padWrapper;
11021
11022			target = target || this.element;
11023
11024			for ( i in this.handles ) {
11025
11026				if ( this.handles[ i ].constructor === String ) {
11027					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11028				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11029					this.handles[ i ] = $( this.handles[ i ] );
11030					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11031				}
11032
11033				if ( this.elementIsWrapper &&
11034						this.originalElement[ 0 ]
11035							.nodeName
11036							.match( /^(textarea|input|select|button)$/i ) ) {
11037					axis = $( this.handles[ i ], this.element );
11038
11039					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11040						axis.outerHeight() :
11041						axis.outerWidth();
11042
11043					padPos = [ "padding",
11044						/ne|nw|n/.test( i ) ? "Top" :
11045						/se|sw|s/.test( i ) ? "Bottom" :
11046						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11047
11048					target.css( padPos, padWrapper );
11049
11050					this._proportionallyResize();
11051				}
11052
11053				this._handles = this._handles.add( this.handles[ i ] );
11054			}
11055		};
11056
11057		// TODO: make renderAxis a prototype function
11058		this._renderAxis( this.element );
11059
11060		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11061		this._handles.disableSelection();
11062
11063		this._handles.on( "mouseover", function() {
11064			if ( !that.resizing ) {
11065				if ( this.className ) {
11066					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11067				}
11068				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11069			}
11070		} );
11071
11072		if ( o.autoHide ) {
11073			this._handles.hide();
11074			this._addClass( "ui-resizable-autohide" );
11075		}
11076	},
11077
11078	_removeHandles: function() {
11079		this._handles.remove();
11080	},
11081
11082	_mouseCapture: function( event ) {
11083		var i, handle,
11084			capture = false;
11085
11086		for ( i in this.handles ) {
11087			handle = $( this.handles[ i ] )[ 0 ];
11088			if ( handle === event.target || $.contains( handle, event.target ) ) {
11089				capture = true;
11090			}
11091		}
11092
11093		return !this.options.disabled && capture;
11094	},
11095
11096	_mouseStart: function( event ) {
11097
11098		var curleft, curtop, cursor,
11099			o = this.options,
11100			el = this.element;
11101
11102		this.resizing = true;
11103
11104		this._renderProxy();
11105
11106		curleft = this._num( this.helper.css( "left" ) );
11107		curtop = this._num( this.helper.css( "top" ) );
11108
11109		if ( o.containment ) {
11110			curleft += $( o.containment ).scrollLeft() || 0;
11111			curtop += $( o.containment ).scrollTop() || 0;
11112		}
11113
11114		this.offset = this.helper.offset();
11115		this.position = { left: curleft, top: curtop };
11116
11117		this.size = this._helper ? {
11118				width: this.helper.width(),
11119				height: this.helper.height()
11120			} : {
11121				width: el.width(),
11122				height: el.height()
11123			};
11124
11125		this.originalSize = this._helper ? {
11126				width: el.outerWidth(),
11127				height: el.outerHeight()
11128			} : {
11129				width: el.width(),
11130				height: el.height()
11131			};
11132
11133		this.sizeDiff = {
11134			width: el.outerWidth() - el.width(),
11135			height: el.outerHeight() - el.height()
11136		};
11137
11138		this.originalPosition = { left: curleft, top: curtop };
11139		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11140
11141		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11142			o.aspectRatio :
11143			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11144
11145		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11146		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11147
11148		this._addClass( "ui-resizable-resizing" );
11149		this._propagate( "start", event );
11150		return true;
11151	},
11152
11153	_mouseDrag: function( event ) {
11154
11155		var data, props,
11156			smp = this.originalMousePosition,
11157			a = this.axis,
11158			dx = ( event.pageX - smp.left ) || 0,
11159			dy = ( event.pageY - smp.top ) || 0,
11160			trigger = this._change[ a ];
11161
11162		this._updatePrevProperties();
11163
11164		if ( !trigger ) {
11165			return false;
11166		}
11167
11168		data = trigger.apply( this, [ event, dx, dy ] );
11169
11170		this._updateVirtualBoundaries( event.shiftKey );
11171		if ( this._aspectRatio || event.shiftKey ) {
11172			data = this._updateRatio( data, event );
11173		}
11174
11175		data = this._respectSize( data, event );
11176
11177		this._updateCache( data );
11178
11179		this._propagate( "resize", event );
11180
11181		props = this._applyChanges();
11182
11183		if ( !this._helper && this._proportionallyResizeElements.length ) {
11184			this._proportionallyResize();
11185		}
11186
11187		if ( !$.isEmptyObject( props ) ) {
11188			this._updatePrevProperties();
11189			this._trigger( "resize", event, this.ui() );
11190			this._applyChanges();
11191		}
11192
11193		return false;
11194	},
11195
11196	_mouseStop: function( event ) {
11197
11198		this.resizing = false;
11199		var pr, ista, soffseth, soffsetw, s, left, top,
11200			o = this.options, that = this;
11201
11202		if ( this._helper ) {
11203
11204			pr = this._proportionallyResizeElements;
11205			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11206			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11207			soffsetw = ista ? 0 : that.sizeDiff.width;
11208
11209			s = {
11210				width: ( that.helper.width()  - soffsetw ),
11211				height: ( that.helper.height() - soffseth )
11212			};
11213			left = ( parseFloat( that.element.css( "left" ) ) +
11214				( that.position.left - that.originalPosition.left ) ) || null;
11215			top = ( parseFloat( that.element.css( "top" ) ) +
11216				( that.position.top - that.originalPosition.top ) ) || null;
11217
11218			if ( !o.animate ) {
11219				this.element.css( $.extend( s, { top: top, left: left } ) );
11220			}
11221
11222			that.helper.height( that.size.height );
11223			that.helper.width( that.size.width );
11224
11225			if ( this._helper && !o.animate ) {
11226				this._proportionallyResize();
11227			}
11228		}
11229
11230		$( "body" ).css( "cursor", "auto" );
11231
11232		this._removeClass( "ui-resizable-resizing" );
11233
11234		this._propagate( "stop", event );
11235
11236		if ( this._helper ) {
11237			this.helper.remove();
11238		}
11239
11240		return false;
11241
11242	},
11243
11244	_updatePrevProperties: function() {
11245		this.prevPosition = {
11246			top: this.position.top,
11247			left: this.position.left
11248		};
11249		this.prevSize = {
11250			width: this.size.width,
11251			height: this.size.height
11252		};
11253	},
11254
11255	_applyChanges: function() {
11256		var props = {};
11257
11258		if ( this.position.top !== this.prevPosition.top ) {
11259			props.top = this.position.top + "px";
11260		}
11261		if ( this.position.left !== this.prevPosition.left ) {
11262			props.left = this.position.left + "px";
11263		}
11264		if ( this.size.width !== this.prevSize.width ) {
11265			props.width = this.size.width + "px";
11266		}
11267		if ( this.size.height !== this.prevSize.height ) {
11268			props.height = this.size.height + "px";
11269		}
11270
11271		this.helper.css( props );
11272
11273		return props;
11274	},
11275
11276	_updateVirtualBoundaries: function( forceAspectRatio ) {
11277		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11278			o = this.options;
11279
11280		b = {
11281			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11282			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11283			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11284			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11285		};
11286
11287		if ( this._aspectRatio || forceAspectRatio ) {
11288			pMinWidth = b.minHeight * this.aspectRatio;
11289			pMinHeight = b.minWidth / this.aspectRatio;
11290			pMaxWidth = b.maxHeight * this.aspectRatio;
11291			pMaxHeight = b.maxWidth / this.aspectRatio;
11292
11293			if ( pMinWidth > b.minWidth ) {
11294				b.minWidth = pMinWidth;
11295			}
11296			if ( pMinHeight > b.minHeight ) {
11297				b.minHeight = pMinHeight;
11298			}
11299			if ( pMaxWidth < b.maxWidth ) {
11300				b.maxWidth = pMaxWidth;
11301			}
11302			if ( pMaxHeight < b.maxHeight ) {
11303				b.maxHeight = pMaxHeight;
11304			}
11305		}
11306		this._vBoundaries = b;
11307	},
11308
11309	_updateCache: function( data ) {
11310		this.offset = this.helper.offset();
11311		if ( this._isNumber( data.left ) ) {
11312			this.position.left = data.left;
11313		}
11314		if ( this._isNumber( data.top ) ) {
11315			this.position.top = data.top;
11316		}
11317		if ( this._isNumber( data.height ) ) {
11318			this.size.height = data.height;
11319		}
11320		if ( this._isNumber( data.width ) ) {
11321			this.size.width = data.width;
11322		}
11323	},
11324
11325	_updateRatio: function( data ) {
11326
11327		var cpos = this.position,
11328			csize = this.size,
11329			a = this.axis;
11330
11331		if ( this._isNumber( data.height ) ) {
11332			data.width = ( data.height * this.aspectRatio );
11333		} else if ( this._isNumber( data.width ) ) {
11334			data.height = ( data.width / this.aspectRatio );
11335		}
11336
11337		if ( a === "sw" ) {
11338			data.left = cpos.left + ( csize.width - data.width );
11339			data.top = null;
11340		}
11341		if ( a === "nw" ) {
11342			data.top = cpos.top + ( csize.height - data.height );
11343			data.left = cpos.left + ( csize.width - data.width );
11344		}
11345
11346		return data;
11347	},
11348
11349	_respectSize: function( data ) {
11350
11351		var o = this._vBoundaries,
11352			a = this.axis,
11353			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11354			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11355			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11356			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11357			dw = this.originalPosition.left + this.originalSize.width,
11358			dh = this.originalPosition.top + this.originalSize.height,
11359			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11360		if ( isminw ) {
11361			data.width = o.minWidth;
11362		}
11363		if ( isminh ) {
11364			data.height = o.minHeight;
11365		}
11366		if ( ismaxw ) {
11367			data.width = o.maxWidth;
11368		}
11369		if ( ismaxh ) {
11370			data.height = o.maxHeight;
11371		}
11372
11373		if ( isminw && cw ) {
11374			data.left = dw - o.minWidth;
11375		}
11376		if ( ismaxw && cw ) {
11377			data.left = dw - o.maxWidth;
11378		}
11379		if ( isminh && ch ) {
11380			data.top = dh - o.minHeight;
11381		}
11382		if ( ismaxh && ch ) {
11383			data.top = dh - o.maxHeight;
11384		}
11385
11386		// Fixing jump error on top/left - bug #2330
11387		if ( !data.width && !data.height && !data.left && data.top ) {
11388			data.top = null;
11389		} else if ( !data.width && !data.height && !data.top && data.left ) {
11390			data.left = null;
11391		}
11392
11393		return data;
11394	},
11395
11396	_getPaddingPlusBorderDimensions: function( element ) {
11397		var i = 0,
11398			widths = [],
11399			borders = [
11400				element.css( "borderTopWidth" ),
11401				element.css( "borderRightWidth" ),
11402				element.css( "borderBottomWidth" ),
11403				element.css( "borderLeftWidth" )
11404			],
11405			paddings = [
11406				element.css( "paddingTop" ),
11407				element.css( "paddingRight" ),
11408				element.css( "paddingBottom" ),
11409				element.css( "paddingLeft" )
11410			];
11411
11412		for ( ; i < 4; i++ ) {
11413			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11414			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11415		}
11416
11417		return {
11418			height: widths[ 0 ] + widths[ 2 ],
11419			width: widths[ 1 ] + widths[ 3 ]
11420		};
11421	},
11422
11423	_proportionallyResize: function() {
11424
11425		if ( !this._proportionallyResizeElements.length ) {
11426			return;
11427		}
11428
11429		var prel,
11430			i = 0,
11431			element = this.helper || this.element;
11432
11433		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11434
11435			prel = this._proportionallyResizeElements[ i ];
11436
11437			// TODO: Seems like a bug to cache this.outerDimensions
11438			// considering that we are in a loop.
11439			if ( !this.outerDimensions ) {
11440				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11441			}
11442
11443			prel.css( {
11444				height: ( element.height() - this.outerDimensions.height ) || 0,
11445				width: ( element.width() - this.outerDimensions.width ) || 0
11446			} );
11447
11448		}
11449
11450	},
11451
11452	_renderProxy: function() {
11453
11454		var el = this.element, o = this.options;
11455		this.elementOffset = el.offset();
11456
11457		if ( this._helper ) {
11458
11459			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
11460
11461			this._addClass( this.helper, this._helper );
11462			this.helper.css( {
11463				width: this.element.outerWidth(),
11464				height: this.element.outerHeight(),
11465				position: "absolute",
11466				left: this.elementOffset.left + "px",
11467				top: this.elementOffset.top + "px",
11468				zIndex: ++o.zIndex //TODO: Don't modify option
11469			} );
11470
11471			this.helper
11472				.appendTo( "body" )
11473				.disableSelection();
11474
11475		} else {
11476			this.helper = this.element;
11477		}
11478
11479	},
11480
11481	_change: {
11482		e: function( event, dx ) {
11483			return { width: this.originalSize.width + dx };
11484		},
11485		w: function( event, dx ) {
11486			var cs = this.originalSize, sp = this.originalPosition;
11487			return { left: sp.left + dx, width: cs.width - dx };
11488		},
11489		n: function( event, dx, dy ) {
11490			var cs = this.originalSize, sp = this.originalPosition;
11491			return { top: sp.top + dy, height: cs.height - dy };
11492		},
11493		s: function( event, dx, dy ) {
11494			return { height: this.originalSize.height + dy };
11495		},
11496		se: function( event, dx, dy ) {
11497			return $.extend( this._change.s.apply( this, arguments ),
11498				this._change.e.apply( this, [ event, dx, dy ] ) );
11499		},
11500		sw: function( event, dx, dy ) {
11501			return $.extend( this._change.s.apply( this, arguments ),
11502				this._change.w.apply( this, [ event, dx, dy ] ) );
11503		},
11504		ne: function( event, dx, dy ) {
11505			return $.extend( this._change.n.apply( this, arguments ),
11506				this._change.e.apply( this, [ event, dx, dy ] ) );
11507		},
11508		nw: function( event, dx, dy ) {
11509			return $.extend( this._change.n.apply( this, arguments ),
11510				this._change.w.apply( this, [ event, dx, dy ] ) );
11511		}
11512	},
11513
11514	_propagate: function( n, event ) {
11515		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11516		( n !== "resize" && this._trigger( n, event, this.ui() ) );
11517	},
11518
11519	plugins: {},
11520
11521	ui: function() {
11522		return {
11523			originalElement: this.originalElement,
11524			element: this.element,
11525			helper: this.helper,
11526			position: this.position,
11527			size: this.size,
11528			originalSize: this.originalSize,
11529			originalPosition: this.originalPosition
11530		};
11531	}
11532
11533} );
11534
11535/*
11536 * Resizable Extensions
11537 */
11538
11539$.ui.plugin.add( "resizable", "animate", {
11540
11541	stop: function( event ) {
11542		var that = $( this ).resizable( "instance" ),
11543			o = that.options,
11544			pr = that._proportionallyResizeElements,
11545			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11546			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11547			soffsetw = ista ? 0 : that.sizeDiff.width,
11548			style = {
11549				width: ( that.size.width - soffsetw ),
11550				height: ( that.size.height - soffseth )
11551			},
11552			left = ( parseFloat( that.element.css( "left" ) ) +
11553				( that.position.left - that.originalPosition.left ) ) || null,
11554			top = ( parseFloat( that.element.css( "top" ) ) +
11555				( that.position.top - that.originalPosition.top ) ) || null;
11556
11557		that.element.animate(
11558			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11559				duration: o.animateDuration,
11560				easing: o.animateEasing,
11561				step: function() {
11562
11563					var data = {
11564						width: parseFloat( that.element.css( "width" ) ),
11565						height: parseFloat( that.element.css( "height" ) ),
11566						top: parseFloat( that.element.css( "top" ) ),
11567						left: parseFloat( that.element.css( "left" ) )
11568					};
11569
11570					if ( pr && pr.length ) {
11571						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11572					}
11573
11574					// Propagating resize, and updating values for each animation step
11575					that._updateCache( data );
11576					that._propagate( "resize", event );
11577
11578				}
11579			}
11580		);
11581	}
11582
11583} );
11584
11585$.ui.plugin.add( "resizable", "containment", {
11586
11587	start: function() {
11588		var element, p, co, ch, cw, width, height,
11589			that = $( this ).resizable( "instance" ),
11590			o = that.options,
11591			el = that.element,
11592			oc = o.containment,
11593
11594			ce = ( oc instanceof $ ) ?
11595				oc.get( 0 ) :
11596				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11597
11598		if ( !ce ) {
11599			return;
11600		}
11601
11602		that.containerElement = $( ce );
11603
11604		if ( /document/.test( oc ) || oc === document ) {
11605			that.containerOffset = {
11606				left: 0,
11607				top: 0
11608			};
11609			that.containerPosition = {
11610				left: 0,
11611				top: 0
11612			};
11613
11614			that.parentData = {
11615				element: $( document ),
11616				left: 0,
11617				top: 0,
11618				width: $( document ).width(),
11619				height: $( document ).height() || document.body.parentNode.scrollHeight
11620			};
11621		} else {
11622			element = $( ce );
11623			p = [];
11624			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11625				p[ i ] = that._num( element.css( "padding" + name ) );
11626			} );
11627
11628			that.containerOffset = element.offset();
11629			that.containerPosition = element.position();
11630			that.containerSize = {
11631				height: ( element.innerHeight() - p[ 3 ] ),
11632				width: ( element.innerWidth() - p[ 1 ] )
11633			};
11634
11635			co = that.containerOffset;
11636			ch = that.containerSize.height;
11637			cw = that.containerSize.width;
11638			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
11639			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
11640
11641			that.parentData = {
11642				element: ce,
11643				left: co.left,
11644				top: co.top,
11645				width: width,
11646				height: height
11647			};
11648		}
11649	},
11650
11651	resize: function( event ) {
11652		var woset, hoset, isParent, isOffsetRelative,
11653			that = $( this ).resizable( "instance" ),
11654			o = that.options,
11655			co = that.containerOffset,
11656			cp = that.position,
11657			pRatio = that._aspectRatio || event.shiftKey,
11658			cop = {
11659				top: 0,
11660				left: 0
11661			},
11662			ce = that.containerElement,
11663			continueResize = true;
11664
11665		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11666			cop = co;
11667		}
11668
11669		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11670			that.size.width = that.size.width +
11671				( that._helper ?
11672					( that.position.left - co.left ) :
11673					( that.position.left - cop.left ) );
11674
11675			if ( pRatio ) {
11676				that.size.height = that.size.width / that.aspectRatio;
11677				continueResize = false;
11678			}
11679			that.position.left = o.helper ? co.left : 0;
11680		}
11681
11682		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11683			that.size.height = that.size.height +
11684				( that._helper ?
11685					( that.position.top - co.top ) :
11686					that.position.top );
11687
11688			if ( pRatio ) {
11689				that.size.width = that.size.height * that.aspectRatio;
11690				continueResize = false;
11691			}
11692			that.position.top = that._helper ? co.top : 0;
11693		}
11694
11695		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11696		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11697
11698		if ( isParent && isOffsetRelative ) {
11699			that.offset.left = that.parentData.left + that.position.left;
11700			that.offset.top = that.parentData.top + that.position.top;
11701		} else {
11702			that.offset.left = that.element.offset().left;
11703			that.offset.top = that.element.offset().top;
11704		}
11705
11706		woset = Math.abs( that.sizeDiff.width +
11707			( that._helper ?
11708				that.offset.left - cop.left :
11709				( that.offset.left - co.left ) ) );
11710
11711		hoset = Math.abs( that.sizeDiff.height +
11712			( that._helper ?
11713				that.offset.top - cop.top :
11714				( that.offset.top - co.top ) ) );
11715
11716		if ( woset + that.size.width >= that.parentData.width ) {
11717			that.size.width = that.parentData.width - woset;
11718			if ( pRatio ) {
11719				that.size.height = that.size.width / that.aspectRatio;
11720				continueResize = false;
11721			}
11722		}
11723
11724		if ( hoset + that.size.height >= that.parentData.height ) {
11725			that.size.height = that.parentData.height - hoset;
11726			if ( pRatio ) {
11727				that.size.width = that.size.height * that.aspectRatio;
11728				continueResize = false;
11729			}
11730		}
11731
11732		if ( !continueResize ) {
11733			that.position.left = that.prevPosition.left;
11734			that.position.top = that.prevPosition.top;
11735			that.size.width = that.prevSize.width;
11736			that.size.height = that.prevSize.height;
11737		}
11738	},
11739
11740	stop: function() {
11741		var that = $( this ).resizable( "instance" ),
11742			o = that.options,
11743			co = that.containerOffset,
11744			cop = that.containerPosition,
11745			ce = that.containerElement,
11746			helper = $( that.helper ),
11747			ho = helper.offset(),
11748			w = helper.outerWidth() - that.sizeDiff.width,
11749			h = helper.outerHeight() - that.sizeDiff.height;
11750
11751		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11752			$( this ).css( {
11753				left: ho.left - cop.left - co.left,
11754				width: w,
11755				height: h
11756			} );
11757		}
11758
11759		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11760			$( this ).css( {
11761				left: ho.left - cop.left - co.left,
11762				width: w,
11763				height: h
11764			} );
11765		}
11766	}
11767} );
11768
11769$.ui.plugin.add( "resizable", "alsoResize", {
11770
11771	start: function() {
11772		var that = $( this ).resizable( "instance" ),
11773			o = that.options;
11774
11775		$( o.alsoResize ).each( function() {
11776			var el = $( this );
11777			el.data( "ui-resizable-alsoresize", {
11778				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
11779				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11780			} );
11781		} );
11782	},
11783
11784	resize: function( event, ui ) {
11785		var that = $( this ).resizable( "instance" ),
11786			o = that.options,
11787			os = that.originalSize,
11788			op = that.originalPosition,
11789			delta = {
11790				height: ( that.size.height - os.height ) || 0,
11791				width: ( that.size.width - os.width ) || 0,
11792				top: ( that.position.top - op.top ) || 0,
11793				left: ( that.position.left - op.left ) || 0
11794			};
11795
11796			$( o.alsoResize ).each( function() {
11797				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11798					css = el.parents( ui.originalElement[ 0 ] ).length ?
11799							[ "width", "height" ] :
11800							[ "width", "height", "top", "left" ];
11801
11802				$.each( css, function( i, prop ) {
11803					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11804					if ( sum && sum >= 0 ) {
11805						style[ prop ] = sum || null;
11806					}
11807				} );
11808
11809				el.css( style );
11810			} );
11811	},
11812
11813	stop: function() {
11814		$( this ).removeData( "ui-resizable-alsoresize" );
11815	}
11816} );
11817
11818$.ui.plugin.add( "resizable", "ghost", {
11819
11820	start: function() {
11821
11822		var that = $( this ).resizable( "instance" ), cs = that.size;
11823
11824		that.ghost = that.originalElement.clone();
11825		that.ghost.css( {
11826			opacity: 0.25,
11827			display: "block",
11828			position: "relative",
11829			height: cs.height,
11830			width: cs.width,
11831			margin: 0,
11832			left: 0,
11833			top: 0
11834		} );
11835
11836		that._addClass( that.ghost, "ui-resizable-ghost" );
11837
11838		// DEPRECATED
11839		// TODO: remove after 1.12
11840		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
11841
11842			// Ghost option
11843			that.ghost.addClass( this.options.ghost );
11844		}
11845
11846		that.ghost.appendTo( that.helper );
11847
11848	},
11849
11850	resize: function() {
11851		var that = $( this ).resizable( "instance" );
11852		if ( that.ghost ) {
11853			that.ghost.css( {
11854				position: "relative",
11855				height: that.size.height,
11856				width: that.size.width
11857			} );
11858		}
11859	},
11860
11861	stop: function() {
11862		var that = $( this ).resizable( "instance" );
11863		if ( that.ghost && that.helper ) {
11864			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11865		}
11866	}
11867
11868} );
11869
11870$.ui.plugin.add( "resizable", "grid", {
11871
11872	resize: function() {
11873		var outerDimensions,
11874			that = $( this ).resizable( "instance" ),
11875			o = that.options,
11876			cs = that.size,
11877			os = that.originalSize,
11878			op = that.originalPosition,
11879			a = that.axis,
11880			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
11881			gridX = ( grid[ 0 ] || 1 ),
11882			gridY = ( grid[ 1 ] || 1 ),
11883			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
11884			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
11885			newWidth = os.width + ox,
11886			newHeight = os.height + oy,
11887			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
11888			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
11889			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
11890			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
11891
11892		o.grid = grid;
11893
11894		if ( isMinWidth ) {
11895			newWidth += gridX;
11896		}
11897		if ( isMinHeight ) {
11898			newHeight += gridY;
11899		}
11900		if ( isMaxWidth ) {
11901			newWidth -= gridX;
11902		}
11903		if ( isMaxHeight ) {
11904			newHeight -= gridY;
11905		}
11906
11907		if ( /^(se|s|e)$/.test( a ) ) {
11908			that.size.width = newWidth;
11909			that.size.height = newHeight;
11910		} else if ( /^(ne)$/.test( a ) ) {
11911			that.size.width = newWidth;
11912			that.size.height = newHeight;
11913			that.position.top = op.top - oy;
11914		} else if ( /^(sw)$/.test( a ) ) {
11915			that.size.width = newWidth;
11916			that.size.height = newHeight;
11917			that.position.left = op.left - ox;
11918		} else {
11919			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
11920				outerDimensions = that._getPaddingPlusBorderDimensions( this );
11921			}
11922
11923			if ( newHeight - gridY > 0 ) {
11924				that.size.height = newHeight;
11925				that.position.top = op.top - oy;
11926			} else {
11927				newHeight = gridY - outerDimensions.height;
11928				that.size.height = newHeight;
11929				that.position.top = op.top + os.height - newHeight;
11930			}
11931			if ( newWidth - gridX > 0 ) {
11932				that.size.width = newWidth;
11933				that.position.left = op.left - ox;
11934			} else {
11935				newWidth = gridX - outerDimensions.width;
11936				that.size.width = newWidth;
11937				that.position.left = op.left + os.width - newWidth;
11938			}
11939		}
11940	}
11941
11942} );
11943
11944var widgetsResizable = $.ui.resizable;
11945
11946
11947/*!
11948 * jQuery UI Dialog 1.12.1
11949 * http://jqueryui.com
11950 *
11951 * Copyright jQuery Foundation and other contributors
11952 * Released under the MIT license.
11953 * http://jquery.org/license
11954 */
11955
11956//>>label: Dialog
11957//>>group: Widgets
11958//>>description: Displays customizable dialog windows.
11959//>>docs: http://api.jqueryui.com/dialog/
11960//>>demos: http://jqueryui.com/dialog/
11961//>>css.structure: ../../themes/base/core.css
11962//>>css.structure: ../../themes/base/dialog.css
11963//>>css.theme: ../../themes/base/theme.css
11964
11965
11966
11967$.widget( "ui.dialog", {
11968	version: "1.12.1",
11969	options: {
11970		appendTo: "body",
11971		autoOpen: true,
11972		buttons: [],
11973		classes: {
11974			"ui-dialog": "ui-corner-all",
11975			"ui-dialog-titlebar": "ui-corner-all"
11976		},
11977		closeOnEscape: true,
11978		closeText: "Close",
11979		draggable: true,
11980		hide: null,
11981		height: "auto",
11982		maxHeight: null,
11983		maxWidth: null,
11984		minHeight: 150,
11985		minWidth: 150,
11986		modal: false,
11987		position: {
11988			my: "center",
11989			at: "center",
11990			of: window,
11991			collision: "fit",
11992
11993			// Ensure the titlebar is always visible
11994			using: function( pos ) {
11995				var topOffset = $( this ).css( pos ).offset().top;
11996				if ( topOffset < 0 ) {
11997					$( this ).css( "top", pos.top - topOffset );
11998				}
11999			}
12000		},
12001		resizable: true,
12002		show: null,
12003		title: null,
12004		width: 300,
12005
12006		// Callbacks
12007		beforeClose: null,
12008		close: null,
12009		drag: null,
12010		dragStart: null,
12011		dragStop: null,
12012		focus: null,
12013		open: null,
12014		resize: null,
12015		resizeStart: null,
12016		resizeStop: null
12017	},
12018
12019	sizeRelatedOptions: {
12020		buttons: true,
12021		height: true,
12022		maxHeight: true,
12023		maxWidth: true,
12024		minHeight: true,
12025		minWidth: true,
12026		width: true
12027	},
12028
12029	resizableRelatedOptions: {
12030		maxHeight: true,
12031		maxWidth: true,
12032		minHeight: true,
12033		minWidth: true
12034	},
12035
12036	_create: function() {
12037		this.originalCss = {
12038			display: this.element[ 0 ].style.display,
12039			width: this.element[ 0 ].style.width,
12040			minHeight: this.element[ 0 ].style.minHeight,
12041			maxHeight: this.element[ 0 ].style.maxHeight,
12042			height: this.element[ 0 ].style.height
12043		};
12044		this.originalPosition = {
12045			parent: this.element.parent(),
12046			index: this.element.parent().children().index( this.element )
12047		};
12048		this.originalTitle = this.element.attr( "title" );
12049		if ( this.options.title == null && this.originalTitle != null ) {
12050			this.options.title = this.originalTitle;
12051		}
12052
12053		// Dialogs can't be disabled
12054		if ( this.options.disabled ) {
12055			this.options.disabled = false;
12056		}
12057
12058		this._createWrapper();
12059
12060		this.element
12061			.show()
12062			.removeAttr( "title" )
12063			.appendTo( this.uiDialog );
12064
12065		this._addClass( "ui-dialog-content", "ui-widget-content" );
12066
12067		this._createTitlebar();
12068		this._createButtonPane();
12069
12070		if ( this.options.draggable && $.fn.draggable ) {
12071			this._makeDraggable();
12072		}
12073		if ( this.options.resizable && $.fn.resizable ) {
12074			this._makeResizable();
12075		}
12076
12077		this._isOpen = false;
12078
12079		this._trackFocus();
12080	},
12081
12082	_init: function() {
12083		if ( this.options.autoOpen ) {
12084			this.open();
12085		}
12086	},
12087
12088	_appendTo: function() {
12089		var element = this.options.appendTo;
12090		if ( element && ( element.jquery || element.nodeType ) ) {
12091			return $( element );
12092		}
12093		return this.document.find( element || "body" ).eq( 0 );
12094	},
12095
12096	_destroy: function() {
12097		var next,
12098			originalPosition = this.originalPosition;
12099
12100		this._untrackInstance();
12101		this._destroyOverlay();
12102
12103		this.element
12104			.removeUniqueId()
12105			.css( this.originalCss )
12106
12107			// Without detaching first, the following becomes really slow
12108			.detach();
12109
12110		this.uiDialog.remove();
12111
12112		if ( this.originalTitle ) {
12113			this.element.attr( "title", this.originalTitle );
12114		}
12115
12116		next = originalPosition.parent.children().eq( originalPosition.index );
12117
12118		// Don't try to place the dialog next to itself (#8613)
12119		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12120			next.before( this.element );
12121		} else {
12122			originalPosition.parent.append( this.element );
12123		}
12124	},
12125
12126	widget: function() {
12127		return this.uiDialog;
12128	},
12129
12130	disable: $.noop,
12131	enable: $.noop,
12132
12133	close: function( event ) {
12134		var that = this;
12135
12136		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12137			return;
12138		}
12139
12140		this._isOpen = false;
12141		this._focusedElement = null;
12142		this._destroyOverlay();
12143		this._untrackInstance();
12144
12145		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12146
12147			// Hiding a focused element doesn't trigger blur in WebKit
12148			// so in case we have nothing to focus on, explicitly blur the active element
12149			// https://bugs.webkit.org/show_bug.cgi?id=47182
12150			$.ui.safeBlur( $.ui.safeActiveElement( this.document[ 0 ] ) );
12151		}
12152
12153		this._hide( this.uiDialog, this.options.hide, function() {
12154			that._trigger( "close", event );
12155		} );
12156	},
12157
12158	isOpen: function() {
12159		return this._isOpen;
12160	},
12161
12162	moveToTop: function() {
12163		this._moveToTop();
12164	},
12165
12166	_moveToTop: function( event, silent ) {
12167		var moved = false,
12168			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12169				return +$( this ).css( "z-index" );
12170			} ).get(),
12171			zIndexMax = Math.max.apply( null, zIndices );
12172
12173		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12174			this.uiDialog.css( "z-index", zIndexMax + 1 );
12175			moved = true;
12176		}
12177
12178		if ( moved && !silent ) {
12179			this._trigger( "focus", event );
12180		}
12181		return moved;
12182	},
12183
12184	open: function() {
12185		var that = this;
12186		if ( this._isOpen ) {
12187			if ( this._moveToTop() ) {
12188				this._focusTabbable();
12189			}
12190			return;
12191		}
12192
12193		this._isOpen = true;
12194		this.opener = $( $.ui.safeActiveElement( this.document[ 0 ] ) );
12195
12196		this._size();
12197		this._position();
12198		this._createOverlay();
12199		this._moveToTop( null, true );
12200
12201		// Ensure the overlay is moved to the top with the dialog, but only when
12202		// opening. The overlay shouldn't move after the dialog is open so that
12203		// modeless dialogs opened after the modal dialog stack properly.
12204		if ( this.overlay ) {
12205			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12206		}
12207
12208		this._show( this.uiDialog, this.options.show, function() {
12209			that._focusTabbable();
12210			that._trigger( "focus" );
12211		} );
12212
12213		// Track the dialog immediately upon openening in case a focus event
12214		// somehow occurs outside of the dialog before an element inside the
12215		// dialog is focused (#10152)
12216		this._makeFocusTarget();
12217
12218		this._trigger( "open" );
12219	},
12220
12221	_focusTabbable: function() {
12222
12223		// Set focus to the first match:
12224		// 1. An element that was focused previously
12225		// 2. First element inside the dialog matching [autofocus]
12226		// 3. Tabbable element inside the content element
12227		// 4. Tabbable element inside the buttonpane
12228		// 5. The close button
12229		// 6. The dialog itself
12230		var hasFocus = this._focusedElement;
12231		if ( !hasFocus ) {
12232			hasFocus = this.element.find( "[autofocus]" );
12233		}
12234		if ( !hasFocus.length ) {
12235			hasFocus = this.element.find( ":tabbable" );
12236		}
12237		if ( !hasFocus.length ) {
12238			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12239		}
12240		if ( !hasFocus.length ) {
12241			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12242		}
12243		if ( !hasFocus.length ) {
12244			hasFocus = this.uiDialog;
12245		}
12246		hasFocus.eq( 0 ).trigger( "focus" );
12247	},
12248
12249	_keepFocus: function( event ) {
12250		function checkFocus() {
12251			var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
12252				isActive = this.uiDialog[ 0 ] === activeElement ||
12253					$.contains( this.uiDialog[ 0 ], activeElement );
12254			if ( !isActive ) {
12255				this._focusTabbable();
12256			}
12257		}
12258		event.preventDefault();
12259		checkFocus.call( this );
12260
12261		// support: IE
12262		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
12263		// so we check again later
12264		this._delay( checkFocus );
12265	},
12266
12267	_createWrapper: function() {
12268		this.uiDialog = $( "<div>" )
12269			.hide()
12270			.attr( {
12271
12272				// Setting tabIndex makes the div focusable
12273				tabIndex: -1,
12274				role: "dialog"
12275			} )
12276			.appendTo( this._appendTo() );
12277
12278		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12279		this._on( this.uiDialog, {
12280			keydown: function( event ) {
12281				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12282						event.keyCode === $.ui.keyCode.ESCAPE ) {
12283					event.preventDefault();
12284					this.close( event );
12285					return;
12286				}
12287
12288				// Prevent tabbing out of dialogs
12289				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12290					return;
12291				}
12292				var tabbables = this.uiDialog.find( ":tabbable" ),
12293					first = tabbables.filter( ":first" ),
12294					last = tabbables.filter( ":last" );
12295
12296				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12297						!event.shiftKey ) {
12298					this._delay( function() {
12299						first.trigger( "focus" );
12300					} );
12301					event.preventDefault();
12302				} else if ( ( event.target === first[ 0 ] ||
12303						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12304					this._delay( function() {
12305						last.trigger( "focus" );
12306					} );
12307					event.preventDefault();
12308				}
12309			},
12310			mousedown: function( event ) {
12311				if ( this._moveToTop( event ) ) {
12312					this._focusTabbable();
12313				}
12314			}
12315		} );
12316
12317		// We assume that any existing aria-describedby attribute means
12318		// that the dialog content is marked up properly
12319		// otherwise we brute force the content as the description
12320		if ( !this.element.find( "[aria-describedby]" ).length ) {
12321			this.uiDialog.attr( {
12322				"aria-describedby": this.element.uniqueId().attr( "id" )
12323			} );
12324		}
12325	},
12326
12327	_createTitlebar: function() {
12328		var uiDialogTitle;
12329
12330		this.uiDialogTitlebar = $( "<div>" );
12331		this._addClass( this.uiDialogTitlebar,
12332			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12333		this._on( this.uiDialogTitlebar, {
12334			mousedown: function( event ) {
12335
12336				// Don't prevent click on close button (#8838)
12337				// Focusing a dialog that is partially scrolled out of view
12338				// causes the browser to scroll it into view, preventing the click event
12339				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12340
12341					// Dialog isn't getting focus when dragging (#8063)
12342					this.uiDialog.trigger( "focus" );
12343				}
12344			}
12345		} );
12346
12347		// Support: IE
12348		// Use type="button" to prevent enter keypresses in textboxes from closing the
12349		// dialog in IE (#9312)
12350		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12351			.button( {
12352				label: $( "<a>" ).text( this.options.closeText ).html(),
12353				icon: "ui-icon-closethick",
12354				showLabel: false
12355			} )
12356			.appendTo( this.uiDialogTitlebar );
12357
12358		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12359		this._on( this.uiDialogTitlebarClose, {
12360			click: function( event ) {
12361				event.preventDefault();
12362				this.close( event );
12363			}
12364		} );
12365
12366		uiDialogTitle = $( "<span>" ).uniqueId().prependTo( this.uiDialogTitlebar );
12367		this._addClass( uiDialogTitle, "ui-dialog-title" );
12368		this._title( uiDialogTitle );
12369
12370		this.uiDialogTitlebar.prependTo( this.uiDialog );
12371
12372		this.uiDialog.attr( {
12373			"aria-labelledby": uiDialogTitle.attr( "id" )
12374		} );
12375	},
12376
12377	_title: function( title ) {
12378		if ( this.options.title ) {
12379			title.text( this.options.title );
12380		} else {
12381			title.html( "&#160;" );
12382		}
12383	},
12384
12385	_createButtonPane: function() {
12386		this.uiDialogButtonPane = $( "<div>" );
12387		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12388			"ui-widget-content ui-helper-clearfix" );
12389
12390		this.uiButtonSet = $( "<div>" )
12391			.appendTo( this.uiDialogButtonPane );
12392		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12393
12394		this._createButtons();
12395	},
12396
12397	_createButtons: function() {
12398		var that = this,
12399			buttons = this.options.buttons;
12400
12401		// If we already have a button pane, remove it
12402		this.uiDialogButtonPane.remove();
12403		this.uiButtonSet.empty();
12404
12405		if ( $.isEmptyObject( buttons ) || ( $.isArray( buttons ) && !buttons.length ) ) {
12406			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12407			return;
12408		}
12409
12410		$.each( buttons, function( name, props ) {
12411			var click, buttonOptions;
12412			props = $.isFunction( props ) ?
12413				{ click: props, text: name } :
12414				props;
12415
12416			// Default to a non-submitting button
12417			props = $.extend( { type: "button" }, props );
12418
12419			// Change the context for the click callback to be the main element
12420			click = props.click;
12421			buttonOptions = {
12422				icon: props.icon,
12423				iconPosition: props.iconPosition,
12424				showLabel: props.showLabel,
12425
12426				// Deprecated options
12427				icons: props.icons,
12428				text: props.text
12429			};
12430
12431			delete props.click;
12432			delete props.icon;
12433			delete props.iconPosition;
12434			delete props.showLabel;
12435
12436			// Deprecated options
12437			delete props.icons;
12438			if ( typeof props.text === "boolean" ) {
12439				delete props.text;
12440			}
12441
12442			$( "<button></button>", props )
12443				.button( buttonOptions )
12444				.appendTo( that.uiButtonSet )
12445				.on( "click", function() {
12446					click.apply( that.element[ 0 ], arguments );
12447				} );
12448		} );
12449		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12450		this.uiDialogButtonPane.appendTo( this.uiDialog );
12451	},
12452
12453	_makeDraggable: function() {
12454		var that = this,
12455			options = this.options;
12456
12457		function filteredUi( ui ) {
12458			return {
12459				position: ui.position,
12460				offset: ui.offset
12461			};
12462		}
12463
12464		this.uiDialog.draggable( {
12465			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12466			handle: ".ui-dialog-titlebar",
12467			containment: "document",
12468			start: function( event, ui ) {
12469				that._addClass( $( this ), "ui-dialog-dragging" );
12470				that._blockFrames();
12471				that._trigger( "dragStart", event, filteredUi( ui ) );
12472			},
12473			drag: function( event, ui ) {
12474				that._trigger( "drag", event, filteredUi( ui ) );
12475			},
12476			stop: function( event, ui ) {
12477				var left = ui.offset.left - that.document.scrollLeft(),
12478					top = ui.offset.top - that.document.scrollTop();
12479
12480				options.position = {
12481					my: "left top",
12482					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12483						"top" + ( top >= 0 ? "+" : "" ) + top,
12484					of: that.window
12485				};
12486				that._removeClass( $( this ), "ui-dialog-dragging" );
12487				that._unblockFrames();
12488				that._trigger( "dragStop", event, filteredUi( ui ) );
12489			}
12490		} );
12491	},
12492
12493	_makeResizable: function() {
12494		var that = this,
12495			options = this.options,
12496			handles = options.resizable,
12497
12498			// .ui-resizable has position: relative defined in the stylesheet
12499			// but dialogs have to use absolute or fixed positioning
12500			position = this.uiDialog.css( "position" ),
12501			resizeHandles = typeof handles === "string" ?
12502				handles :
12503				"n,e,s,w,se,sw,ne,nw";
12504
12505		function filteredUi( ui ) {
12506			return {
12507				originalPosition: ui.originalPosition,
12508				originalSize: ui.originalSize,
12509				position: ui.position,
12510				size: ui.size
12511			};
12512		}
12513
12514		this.uiDialog.resizable( {
12515			cancel: ".ui-dialog-content",
12516			containment: "document",
12517			alsoResize: this.element,
12518			maxWidth: options.maxWidth,
12519			maxHeight: options.maxHeight,
12520			minWidth: options.minWidth,
12521			minHeight: this._minHeight(),
12522			handles: resizeHandles,
12523			start: function( event, ui ) {
12524				that._addClass( $( this ), "ui-dialog-resizing" );
12525				that._blockFrames();
12526				that._trigger( "resizeStart", event, filteredUi( ui ) );
12527			},
12528			resize: function( event, ui ) {
12529				that._trigger( "resize", event, filteredUi( ui ) );
12530			},
12531			stop: function( event, ui ) {
12532				var offset = that.uiDialog.offset(),
12533					left = offset.left - that.document.scrollLeft(),
12534					top = offset.top - that.document.scrollTop();
12535
12536				options.height = that.uiDialog.height();
12537				options.width = that.uiDialog.width();
12538				options.position = {
12539					my: "left top",
12540					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12541						"top" + ( top >= 0 ? "+" : "" ) + top,
12542					of: that.window
12543				};
12544				that._removeClass( $( this ), "ui-dialog-resizing" );
12545				that._unblockFrames();
12546				that._trigger( "resizeStop", event, filteredUi( ui ) );
12547			}
12548		} )
12549			.css( "position", position );
12550	},
12551
12552	_trackFocus: function() {
12553		this._on( this.widget(), {
12554			focusin: function( event ) {
12555				this._makeFocusTarget();
12556				this._focusedElement = $( event.target );
12557			}
12558		} );
12559	},
12560
12561	_makeFocusTarget: function() {
12562		this._untrackInstance();
12563		this._trackingInstances().unshift( this );
12564	},
12565
12566	_untrackInstance: function() {
12567		var instances = this._trackingInstances(),
12568			exists = $.inArray( this, instances );
12569		if ( exists !== -1 ) {
12570			instances.splice( exists, 1 );
12571		}
12572	},
12573
12574	_trackingInstances: function() {
12575		var instances = this.document.data( "ui-dialog-instances" );
12576		if ( !instances ) {
12577			instances = [];
12578			this.document.data( "ui-dialog-instances", instances );
12579		}
12580		return instances;
12581	},
12582
12583	_minHeight: function() {
12584		var options = this.options;
12585
12586		return options.height === "auto" ?
12587			options.minHeight :
12588			Math.min( options.minHeight, options.height );
12589	},
12590
12591	_position: function() {
12592
12593		// Need to show the dialog to get the actual offset in the position plugin
12594		var isVisible = this.uiDialog.is( ":visible" );
12595		if ( !isVisible ) {
12596			this.uiDialog.show();
12597		}
12598		this.uiDialog.position( this.options.position );
12599		if ( !isVisible ) {
12600			this.uiDialog.hide();
12601		}
12602	},
12603
12604	_setOptions: function( options ) {
12605		var that = this,
12606			resize = false,
12607			resizableOptions = {};
12608
12609		$.each( options, function( key, value ) {
12610			that._setOption( key, value );
12611
12612			if ( key in that.sizeRelatedOptions ) {
12613				resize = true;
12614			}
12615			if ( key in that.resizableRelatedOptions ) {
12616				resizableOptions[ key ] = value;
12617			}
12618		} );
12619
12620		if ( resize ) {
12621			this._size();
12622			this._position();
12623		}
12624		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12625			this.uiDialog.resizable( "option", resizableOptions );
12626		}
12627	},
12628
12629	_setOption: function( key, value ) {
12630		var isDraggable, isResizable,
12631			uiDialog = this.uiDialog;
12632
12633		if ( key === "disabled" ) {
12634			return;
12635		}
12636
12637		this._super( key, value );
12638
12639		if ( key === "appendTo" ) {
12640			this.uiDialog.appendTo( this._appendTo() );
12641		}
12642
12643		if ( key === "buttons" ) {
12644			this._createButtons();
12645		}
12646
12647		if ( key === "closeText" ) {
12648			this.uiDialogTitlebarClose.button( {
12649
12650				// Ensure that we always pass a string
12651				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12652			} );
12653		}
12654
12655		if ( key === "draggable" ) {
12656			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12657			if ( isDraggable && !value ) {
12658				uiDialog.draggable( "destroy" );
12659			}
12660
12661			if ( !isDraggable && value ) {
12662				this._makeDraggable();
12663			}
12664		}
12665
12666		if ( key === "position" ) {
12667			this._position();
12668		}
12669
12670		if ( key === "resizable" ) {
12671
12672			// currently resizable, becoming non-resizable
12673			isResizable = uiDialog.is( ":data(ui-resizable)" );
12674			if ( isResizable && !value ) {
12675				uiDialog.resizable( "destroy" );
12676			}
12677
12678			// Currently resizable, changing handles
12679			if ( isResizable && typeof value === "string" ) {
12680				uiDialog.resizable( "option", "handles", value );
12681			}
12682
12683			// Currently non-resizable, becoming resizable
12684			if ( !isResizable && value !== false ) {
12685				this._makeResizable();
12686			}
12687		}
12688
12689		if ( key === "title" ) {
12690			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12691		}
12692	},
12693
12694	_size: function() {
12695
12696		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12697		// divs will both have width and height set, so we need to reset them
12698		var nonContentHeight, minContentHeight, maxContentHeight,
12699			options = this.options;
12700
12701		// Reset content sizing
12702		this.element.show().css( {
12703			width: "auto",
12704			minHeight: 0,
12705			maxHeight: "none",
12706			height: 0
12707		} );
12708
12709		if ( options.minWidth > options.width ) {
12710			options.width = options.minWidth;
12711		}
12712
12713		// Reset wrapper sizing
12714		// determine the height of all the non-content elements
12715		nonContentHeight = this.uiDialog.css( {
12716			height: "auto",
12717			width: options.width
12718		} )
12719			.outerHeight();
12720		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12721		maxContentHeight = typeof options.maxHeight === "number" ?
12722			Math.max( 0, options.maxHeight - nonContentHeight ) :
12723			"none";
12724
12725		if ( options.height === "auto" ) {
12726			this.element.css( {
12727				minHeight: minContentHeight,
12728				maxHeight: maxContentHeight,
12729				height: "auto"
12730			} );
12731		} else {
12732			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12733		}
12734
12735		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12736			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12737		}
12738	},
12739
12740	_blockFrames: function() {
12741		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12742			var iframe = $( this );
12743
12744			return $( "<div>" )
12745				.css( {
12746					position: "absolute",
12747					width: iframe.outerWidth(),
12748					height: iframe.outerHeight()
12749				} )
12750				.appendTo( iframe.parent() )
12751				.offset( iframe.offset() )[ 0 ];
12752		} );
12753	},
12754
12755	_unblockFrames: function() {
12756		if ( this.iframeBlocks ) {
12757			this.iframeBlocks.remove();
12758			delete this.iframeBlocks;
12759		}
12760	},
12761
12762	_allowInteraction: function( event ) {
12763		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12764			return true;
12765		}
12766
12767		// TODO: Remove hack when datepicker implements
12768		// the .ui-front logic (#8989)
12769		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12770	},
12771
12772	_createOverlay: function() {
12773		if ( !this.options.modal ) {
12774			return;
12775		}
12776
12777		// We use a delay in case the overlay is created from an
12778		// event that we're going to be cancelling (#2804)
12779		var isOpening = true;
12780		this._delay( function() {
12781			isOpening = false;
12782		} );
12783
12784		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12785
12786			// Prevent use of anchors and inputs
12787			// Using _on() for an event handler shared across many instances is
12788			// safe because the dialogs stack and must be closed in reverse order
12789			this._on( this.document, {
12790				focusin: function( event ) {
12791					if ( isOpening ) {
12792						return;
12793					}
12794
12795					if ( !this._allowInteraction( event ) ) {
12796						event.preventDefault();
12797						this._trackingInstances()[ 0 ]._focusTabbable();
12798					}
12799				}
12800			} );
12801		}
12802
12803		this.overlay = $( "<div>" )
12804			.appendTo( this._appendTo() );
12805
12806		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12807		this._on( this.overlay, {
12808			mousedown: "_keepFocus"
12809		} );
12810		this.document.data( "ui-dialog-overlays",
12811			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12812	},
12813
12814	_destroyOverlay: function() {
12815		if ( !this.options.modal ) {
12816			return;
12817		}
12818
12819		if ( this.overlay ) {
12820			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12821
12822			if ( !overlays ) {
12823				this._off( this.document, "focusin" );
12824				this.document.removeData( "ui-dialog-overlays" );
12825			} else {
12826				this.document.data( "ui-dialog-overlays", overlays );
12827			}
12828
12829			this.overlay.remove();
12830			this.overlay = null;
12831		}
12832	}
12833} );
12834
12835// DEPRECATED
12836// TODO: switch return back to widget declaration at top of file when this is removed
12837if ( $.uiBackCompat !== false ) {
12838
12839	// Backcompat for dialogClass option
12840	$.widget( "ui.dialog", $.ui.dialog, {
12841		options: {
12842			dialogClass: ""
12843		},
12844		_createWrapper: function() {
12845			this._super();
12846			this.uiDialog.addClass( this.options.dialogClass );
12847		},
12848		_setOption: function( key, value ) {
12849			if ( key === "dialogClass" ) {
12850				this.uiDialog
12851					.removeClass( this.options.dialogClass )
12852					.addClass( value );
12853			}
12854			this._superApply( arguments );
12855		}
12856	} );
12857}
12858
12859var widgetsDialog = $.ui.dialog;
12860
12861
12862/*!
12863 * jQuery UI Droppable 1.12.1
12864 * http://jqueryui.com
12865 *
12866 * Copyright jQuery Foundation and other contributors
12867 * Released under the MIT license.
12868 * http://jquery.org/license
12869 */
12870
12871//>>label: Droppable
12872//>>group: Interactions
12873//>>description: Enables drop targets for draggable elements.
12874//>>docs: http://api.jqueryui.com/droppable/
12875//>>demos: http://jqueryui.com/droppable/
12876
12877
12878
12879$.widget( "ui.droppable", {
12880	version: "1.12.1",
12881	widgetEventPrefix: "drop",
12882	options: {
12883		accept: "*",
12884		addClasses: true,
12885		greedy: false,
12886		scope: "default",
12887		tolerance: "intersect",
12888
12889		// Callbacks
12890		activate: null,
12891		deactivate: null,
12892		drop: null,
12893		out: null,
12894		over: null
12895	},
12896	_create: function() {
12897
12898		var proportions,
12899			o = this.options,
12900			accept = o.accept;
12901
12902		this.isover = false;
12903		this.isout = true;
12904
12905		this.accept = $.isFunction( accept ) ? accept : function( d ) {
12906			return d.is( accept );
12907		};
12908
12909		this.proportions = function( /* valueToWrite */ ) {
12910			if ( arguments.length ) {
12911
12912				// Store the droppable's proportions
12913				proportions = arguments[ 0 ];
12914			} else {
12915
12916				// Retrieve or derive the droppable's proportions
12917				return proportions ?
12918					proportions :
12919					proportions = {
12920						width: this.element[ 0 ].offsetWidth,
12921						height: this.element[ 0 ].offsetHeight
12922					};
12923			}
12924		};
12925
12926		this._addToManager( o.scope );
12927
12928		o.addClasses && this._addClass( "ui-droppable" );
12929
12930	},
12931
12932	_addToManager: function( scope ) {
12933
12934		// Add the reference and positions to the manager
12935		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
12936		$.ui.ddmanager.droppables[ scope ].push( this );
12937	},
12938
12939	_splice: function( drop ) {
12940		var i = 0;
12941		for ( ; i < drop.length; i++ ) {
12942			if ( drop[ i ] === this ) {
12943				drop.splice( i, 1 );
12944			}
12945		}
12946	},
12947
12948	_destroy: function() {
12949		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12950
12951		this._splice( drop );
12952	},
12953
12954	_setOption: function( key, value ) {
12955
12956		if ( key === "accept" ) {
12957			this.accept = $.isFunction( value ) ? value : function( d ) {
12958				return d.is( value );
12959			};
12960		} else if ( key === "scope" ) {
12961			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
12962
12963			this._splice( drop );
12964			this._addToManager( value );
12965		}
12966
12967		this._super( key, value );
12968	},
12969
12970	_activate: function( event ) {
12971		var draggable = $.ui.ddmanager.current;
12972
12973		this._addActiveClass();
12974		if ( draggable ) {
12975			this._trigger( "activate", event, this.ui( draggable ) );
12976		}
12977	},
12978
12979	_deactivate: function( event ) {
12980		var draggable = $.ui.ddmanager.current;
12981
12982		this._removeActiveClass();
12983		if ( draggable ) {
12984			this._trigger( "deactivate", event, this.ui( draggable ) );
12985		}
12986	},
12987
12988	_over: function( event ) {
12989
12990		var draggable = $.ui.ddmanager.current;
12991
12992		// Bail if draggable and droppable are same element
12993		if ( !draggable || ( draggable.currentItem ||
12994				draggable.element )[ 0 ] === this.element[ 0 ] ) {
12995			return;
12996		}
12997
12998		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
12999				draggable.element ) ) ) {
13000			this._addHoverClass();
13001			this._trigger( "over", event, this.ui( draggable ) );
13002		}
13003
13004	},
13005
13006	_out: function( event ) {
13007
13008		var draggable = $.ui.ddmanager.current;
13009
13010		// Bail if draggable and droppable are same element
13011		if ( !draggable || ( draggable.currentItem ||
13012				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13013			return;
13014		}
13015
13016		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13017				draggable.element ) ) ) {
13018			this._removeHoverClass();
13019			this._trigger( "out", event, this.ui( draggable ) );
13020		}
13021
13022	},
13023
13024	_drop: function( event, custom ) {
13025
13026		var draggable = custom || $.ui.ddmanager.current,
13027			childrenIntersection = false;
vendor: 4,744 bytes, lines 13028-13200
13028
13029		// Bail if draggable and droppable are same element
13030		if ( !draggable || ( draggable.currentItem ||
13031				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13032			return false;
13033		}
13034
13035		this.element
13036			.find( ":data(ui-droppable)" )
13037			.not( ".ui-draggable-dragging" )
13038			.each( function() {
13039				var inst = $( this ).droppable( "instance" );
13040				if (
13041					inst.options.greedy &&
13042					!inst.options.disabled &&
13043					inst.options.scope === draggable.options.scope &&
13044					inst.accept.call(
13045						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13046					) &&
13047					intersect(
13048						draggable,
13049						$.extend( inst, { offset: inst.element.offset() } ),
13050						inst.options.tolerance, event
13051					)
13052				) {
13053					childrenIntersection = true;
13054					return false; }
13055			} );
13056		if ( childrenIntersection ) {
13057			return false;
13058		}
13059
13060		if ( this.accept.call( this.element[ 0 ],
13061				( draggable.currentItem || draggable.element ) ) ) {
13062			this._removeActiveClass();
13063			this._removeHoverClass();
13064
13065			this._trigger( "drop", event, this.ui( draggable ) );
13066			return this.element;
13067		}
13068
13069		return false;
13070
13071	},
13072
13073	ui: function( c ) {
13074		return {
13075			draggable: ( c.currentItem || c.element ),
13076			helper: c.helper,
13077			position: c.position,
13078			offset: c.positionAbs
13079		};
13080	},
13081
13082	// Extension points just to make backcompat sane and avoid duplicating logic
13083	// TODO: Remove in 1.13 along with call to it below
13084	_addHoverClass: function() {
13085		this._addClass( "ui-droppable-hover" );
13086	},
13087
13088	_removeHoverClass: function() {
13089		this._removeClass( "ui-droppable-hover" );
13090	},
13091
13092	_addActiveClass: function() {
13093		this._addClass( "ui-droppable-active" );
13094	},
13095
13096	_removeActiveClass: function() {
13097		this._removeClass( "ui-droppable-active" );
13098	}
13099} );
13100
13101var intersect = $.ui.intersect = ( function() {
13102	function isOverAxis( x, reference, size ) {
13103		return ( x >= reference ) && ( x < ( reference + size ) );
13104	}
13105
13106	return function( draggable, droppable, toleranceMode, event ) {
13107
13108		if ( !droppable.offset ) {
13109			return false;
13110		}
13111
13112		var x1 = ( draggable.positionAbs ||
13113				draggable.position.absolute ).left + draggable.margins.left,
13114			y1 = ( draggable.positionAbs ||
13115				draggable.position.absolute ).top + draggable.margins.top,
13116			x2 = x1 + draggable.helperProportions.width,
13117			y2 = y1 + draggable.helperProportions.height,
13118			l = droppable.offset.left,
13119			t = droppable.offset.top,
13120			r = l + droppable.proportions().width,
13121			b = t + droppable.proportions().height;
13122
13123		switch ( toleranceMode ) {
13124		case "fit":
13125			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13126		case "intersect":
13127			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13128				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13129				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13130				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13131		case "pointer":
13132			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13133				isOverAxis( event.pageX, l, droppable.proportions().width );
13134		case "touch":
13135			return (
13136				( y1 >= t && y1 <= b ) || // Top edge touching
13137				( y2 >= t && y2 <= b ) || // Bottom edge touching
13138				( y1 < t && y2 > b ) // Surrounded vertically
13139			) && (
13140				( x1 >= l && x1 <= r ) || // Left edge touching
13141				( x2 >= l && x2 <= r ) || // Right edge touching
13142				( x1 < l && x2 > r ) // Surrounded horizontally
13143			);
13144		default:
13145			return false;
13146		}
13147	};
13148} )();
13149
13150/*
13151	This manager tracks offsets of draggables and droppables
13152*/
13153$.ui.ddmanager = {
13154	current: null,
13155	droppables: { "default": [] },
13156	prepareOffsets: function( t, event ) {
13157
13158		var i, j,
13159			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13160			type = event ? event.type : null, // workaround for #2317
13161			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13162
13163		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13164
13165			// No disabled and non-accepted
13166			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13167					( t.currentItem || t.element ) ) ) ) {
13168				continue;
13169			}
13170
13171			// Filter out elements in the current dragged item
13172			for ( j = 0; j < list.length; j++ ) {
13173				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13174					m[ i ].proportions().height = 0;
13175					continue droppablesLoop;
13176				}
13177			}
13178
13179			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13180			if ( !m[ i ].visible ) {
13181				continue;
13182			}
13183
13184			// Activate the droppable if used directly from draggables
13185			if ( type === "mousedown" ) {
13186				m[ i ]._activate.call( m[ i ], event );
13187			}
13188
13189			m[ i ].offset = m[ i ].element.offset();
13190			m[ i ].proportions( {
13191				width: m[ i ].element[ 0 ].offsetWidth,
13192				height: m[ i ].element[ 0 ].offsetHeight
13193			} );
13194
13195		}
13196
13197	},
13198	drop: function( draggable, event ) {
13199
13200		var dropped = false;
vendor: 4,444 bytes, lines 13201-13355
13201
13202		// Create a copy of the droppables in case the list changes during the drop (#9116)
13203		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13204
13205			if ( !this.options ) {
13206				return;
13207			}
13208			if ( !this.options.disabled && this.visible &&
13209					intersect( draggable, this, this.options.tolerance, event ) ) {
13210				dropped = this._drop.call( this, event ) || dropped;
13211			}
13212
13213			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13214					( draggable.currentItem || draggable.element ) ) ) {
13215				this.isout = true;
13216				this.isover = false;
13217				this._deactivate.call( this, event );
13218			}
13219
13220		} );
13221		return dropped;
13222
13223	},
13224	dragStart: function( draggable, event ) {
13225
13226		// Listen for scrolling so that if the dragging causes scrolling the position of the
13227		// droppables can be recalculated (see #5003)
13228		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13229			if ( !draggable.options.refreshPositions ) {
13230				$.ui.ddmanager.prepareOffsets( draggable, event );
13231			}
13232		} );
13233	},
13234	drag: function( draggable, event ) {
13235
13236		// If you have a highly dynamic page, you might try this option. It renders positions
13237		// every time you move the mouse.
13238		if ( draggable.options.refreshPositions ) {
13239			$.ui.ddmanager.prepareOffsets( draggable, event );
13240		}
13241
13242		// Run through all droppables and check their positions based on specific tolerance options
13243		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13244
13245			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13246				return;
13247			}
13248
13249			var parentInstance, scope, parent,
13250				intersects = intersect( draggable, this, this.options.tolerance, event ),
13251				c = !intersects && this.isover ?
13252					"isout" :
13253					( intersects && !this.isover ? "isover" : null );
13254			if ( !c ) {
13255				return;
13256			}
13257
13258			if ( this.options.greedy ) {
13259
13260				// find droppable parents with same scope
13261				scope = this.options.scope;
13262				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13263					return $( this ).droppable( "instance" ).options.scope === scope;
13264				} );
13265
13266				if ( parent.length ) {
13267					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13268					parentInstance.greedyChild = ( c === "isover" );
13269				}
13270			}
13271
13272			// We just moved into a greedy child
13273			if ( parentInstance && c === "isover" ) {
13274				parentInstance.isover = false;
13275				parentInstance.isout = true;
13276				parentInstance._out.call( parentInstance, event );
13277			}
13278
13279			this[ c ] = true;
13280			this[ c === "isout" ? "isover" : "isout" ] = false;
13281			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13282
13283			// We just moved out of a greedy child
13284			if ( parentInstance && c === "isout" ) {
13285				parentInstance.isout = false;
13286				parentInstance.isover = true;
13287				parentInstance._over.call( parentInstance, event );
13288			}
13289		} );
13290
13291	},
13292	dragStop: function( draggable, event ) {
13293		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13294
13295		// Call prepareOffsets one final time since IE does not fire return scroll events when
13296		// overflow was caused by drag (see #5003)
13297		if ( !draggable.options.refreshPositions ) {
13298			$.ui.ddmanager.prepareOffsets( draggable, event );
13299		}
13300	}
13301};
13302
13303// DEPRECATED
13304// TODO: switch return back to widget declaration at top of file when this is removed
13305if ( $.uiBackCompat !== false ) {
13306
13307	// Backcompat for activeClass and hoverClass options
13308	$.widget( "ui.droppable", $.ui.droppable, {
13309		options: {
13310			hoverClass: false,
13311			activeClass: false
13312		},
13313		_addActiveClass: function() {
13314			this._super();
13315			if ( this.options.activeClass ) {
13316				this.element.addClass( this.options.activeClass );
13317			}
13318		},
13319		_removeActiveClass: function() {
13320			this._super();
13321			if ( this.options.activeClass ) {
13322				this.element.removeClass( this.options.activeClass );
13323			}
13324		},
13325		_addHoverClass: function() {
13326			this._super();
13327			if ( this.options.hoverClass ) {
13328				this.element.addClass( this.options.hoverClass );
13329			}
13330		},
13331		_removeHoverClass: function() {
13332			this._super();
13333			if ( this.options.hoverClass ) {
13334				this.element.removeClass( this.options.hoverClass );
13335			}
13336		}
13337	} );
13338}
13339
13340var widgetsDroppable = $.ui.droppable;
13341
13342
13343/*!
13344 * jQuery UI Progressbar 1.12.1
13345 * http://jqueryui.com
13346 *
13347 * Copyright jQuery Foundation and other contributors
13348 * Released under the MIT license.
13349 * http://jquery.org/license
13350 */
13351
13352//>>label: Progressbar
13353//>>group: Widgets
13354// jscs:disable maximumLineLength
13355//>>
vendor: 15,214 bytes, lines 13355-13948
13355description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13356// jscs:enable maximumLineLength
13357//>>docs: http://api.jqueryui.com/progressbar/
13358//>>demos: http://jqueryui.com/progressbar/
13359//>>css.structure: ../../themes/base/core.css
13360//>>css.structure: ../../themes/base/progressbar.css
13361//>>css.theme: ../../themes/base/theme.css
13362
13363
13364
13365var widgetsProgressbar = $.widget( "ui.progressbar", {
13366	version: "1.12.1",
13367	options: {
13368		classes: {
13369			"ui-progressbar": "ui-corner-all",
13370			"ui-progressbar-value": "ui-corner-left",
13371			"ui-progressbar-complete": "ui-corner-right"
13372		},
13373		max: 100,
13374		value: 0,
13375
13376		change: null,
13377		complete: null
13378	},
13379
13380	min: 0,
13381
13382	_create: function() {
13383
13384		// Constrain initial value
13385		this.oldValue = this.options.value = this._constrainedValue();
13386
13387		this.element.attr( {
13388
13389			// Only set static values; aria-valuenow and aria-valuemax are
13390			// set inside _refreshValue()
13391			role: "progressbar",
13392			"aria-valuemin": this.min
13393		} );
13394		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13395
13396		this.valueDiv = $( "<div>" ).appendTo( this.element );
13397		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13398		this._refreshValue();
13399	},
13400
13401	_destroy: function() {
13402		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13403
13404		this.valueDiv.remove();
13405	},
13406
13407	value: function( newValue ) {
13408		if ( newValue === undefined ) {
13409			return this.options.value;
13410		}
13411
13412		this.options.value = this._constrainedValue( newValue );
13413		this._refreshValue();
13414	},
13415
13416	_constrainedValue: function( newValue ) {
13417		if ( newValue === undefined ) {
13418			newValue = this.options.value;
13419		}
13420
13421		this.indeterminate = newValue === false;
13422
13423		// Sanitize value
13424		if ( typeof newValue !== "number" ) {
13425			newValue = 0;
13426		}
13427
13428		return this.indeterminate ? false :
13429			Math.min( this.options.max, Math.max( this.min, newValue ) );
13430	},
13431
13432	_setOptions: function( options ) {
13433
13434		// Ensure "value" option is set after other values (like max)
13435		var value = options.value;
13436		delete options.value;
13437
13438		this._super( options );
13439
13440		this.options.value = this._constrainedValue( value );
13441		this._refreshValue();
13442	},
13443
13444	_setOption: function( key, value ) {
13445		if ( key === "max" ) {
13446
13447			// Don't allow a max less than min
13448			value = Math.max( this.min, value );
13449		}
13450		this._super( key, value );
13451	},
13452
13453	_setOptionDisabled: function( value ) {
13454		this._super( value );
13455
13456		this.element.attr( "aria-disabled", value );
13457		this._toggleClass( null, "ui-state-disabled", !!value );
13458	},
13459
13460	_percentage: function() {
13461		return this.indeterminate ?
13462			100 :
13463			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13464	},
13465
13466	_refreshValue: function() {
13467		var value = this.options.value,
13468			percentage = this._percentage();
13469
13470		this.valueDiv
13471			.toggle( this.indeterminate || value > this.min )
13472			.width( percentage.toFixed( 0 ) + "%" );
13473
13474		this
13475			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13476				value === this.options.max )
13477			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13478
13479		if ( this.indeterminate ) {
13480			this.element.removeAttr( "aria-valuenow" );
13481			if ( !this.overlayDiv ) {
13482				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13483				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13484			}
13485		} else {
13486			this.element.attr( {
13487				"aria-valuemax": this.options.max,
13488				"aria-valuenow": value
13489			} );
13490			if ( this.overlayDiv ) {
13491				this.overlayDiv.remove();
13492				this.overlayDiv = null;
13493			}
13494		}
13495
13496		if ( this.oldValue !== value ) {
13497			this.oldValue = value;
13498			this._trigger( "change" );
13499		}
13500		if ( value === this.options.max ) {
13501			this._trigger( "complete" );
13502		}
13503	}
13504} );
13505
13506
13507/*!
13508 * jQuery UI Selectable 1.12.1
13509 * http://jqueryui.com
13510 *
13511 * Copyright jQuery Foundation and other contributors
13512 * Released under the MIT license.
13513 * http://jquery.org/license
13514 */
13515
13516//>>label: Selectable
13517//>>group: Interactions
13518//>>description: Allows groups of elements to be selected with the mouse.
13519//>>docs: http://api.jqueryui.com/selectable/
13520//>>demos: http://jqueryui.com/selectable/
13521//>>css.structure: ../../themes/base/selectable.css
13522
13523
13524
13525var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13526	version: "1.12.1",
13527	options: {
13528		appendTo: "body",
13529		autoRefresh: true,
13530		distance: 0,
13531		filter: "*",
13532		tolerance: "touch",
13533
13534		// Callbacks
13535		selected: null,
13536		selecting: null,
13537		start: null,
13538		stop: null,
13539		unselected: null,
13540		unselecting: null
13541	},
13542	_create: function() {
13543		var that = this;
13544
13545		this._addClass( "ui-selectable" );
13546
13547		this.dragged = false;
13548
13549		// Cache selectee children based on filter
13550		this.refresh = function() {
13551			that.elementPos = $( that.element[ 0 ] ).offset();
13552			that.selectees = $( that.options.filter, that.element[ 0 ] );
13553			that._addClass( that.selectees, "ui-selectee" );
13554			that.selectees.each( function() {
13555				var $this = $( this ),
13556					selecteeOffset = $this.offset(),
13557					pos = {
13558						left: selecteeOffset.left - that.elementPos.left,
13559						top: selecteeOffset.top - that.elementPos.top
13560					};
13561				$.data( this, "selectable-item", {
13562					element: this,
13563					$element: $this,
13564					left: pos.left,
13565					top: pos.top,
13566					right: pos.left + $this.outerWidth(),
13567					bottom: pos.top + $this.outerHeight(),
13568					startselected: false,
13569					selected: $this.hasClass( "ui-selected" ),
13570					selecting: $this.hasClass( "ui-selecting" ),
13571					unselecting: $this.hasClass( "ui-unselecting" )
13572				} );
13573			} );
13574		};
13575		this.refresh();
13576
13577		this._mouseInit();
13578
13579		this.helper = $( "<div>" );
13580		this._addClass( this.helper, "ui-selectable-helper" );
13581	},
13582
13583	_destroy: function() {
13584		this.selectees.removeData( "selectable-item" );
13585		this._mouseDestroy();
13586	},
13587
13588	_mouseStart: function( event ) {
13589		var that = this,
13590			options = this.options;
13591
13592		this.opos = [ event.pageX, event.pageY ];
13593		this.elementPos = $( this.element[ 0 ] ).offset();
13594
13595		if ( this.options.disabled ) {
13596			return;
13597		}
13598
13599		this.selectees = $( options.filter, this.element[ 0 ] );
13600
13601		this._trigger( "start", event );
13602
13603		$( options.appendTo ).append( this.helper );
13604
13605		// position helper (lasso)
13606		this.helper.css( {
13607			"left": event.pageX,
13608			"top": event.pageY,
13609			"width": 0,
13610			"height": 0
13611		} );
13612
13613		if ( options.autoRefresh ) {
13614			this.refresh();
13615		}
13616
13617		this.selectees.filter( ".ui-selected" ).each( function() {
13618			var selectee = $.data( this, "selectable-item" );
13619			selectee.startselected = true;
13620			if ( !event.metaKey && !event.ctrlKey ) {
13621				that._removeClass( selectee.$element, "ui-selected" );
13622				selectee.selected = false;
13623				that._addClass( selectee.$element, "ui-unselecting" );
13624				selectee.unselecting = true;
13625
13626				// selectable UNSELECTING callback
13627				that._trigger( "unselecting", event, {
13628					unselecting: selectee.element
13629				} );
13630			}
13631		} );
13632
13633		$( event.target ).parents().addBack().each( function() {
13634			var doSelect,
13635				selectee = $.data( this, "selectable-item" );
13636			if ( selectee ) {
13637				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13638					!selectee.$element.hasClass( "ui-selected" );
13639				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13640					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13641				selectee.unselecting = !doSelect;
13642				selectee.selecting = doSelect;
13643				selectee.selected = doSelect;
13644
13645				// selectable (UN)SELECTING callback
13646				if ( doSelect ) {
13647					that._trigger( "selecting", event, {
13648						selecting: selectee.element
13649					} );
13650				} else {
13651					that._trigger( "unselecting", event, {
13652						unselecting: selectee.element
13653					} );
13654				}
13655				return false;
13656			}
13657		} );
13658
13659	},
13660
13661	_mouseDrag: function( event ) {
13662
13663		this.dragged = true;
13664
13665		if ( this.options.disabled ) {
13666			return;
13667		}
13668
13669		var tmp,
13670			that = this,
13671			options = this.options,
13672			x1 = this.opos[ 0 ],
13673			y1 = this.opos[ 1 ],
13674			x2 = event.pageX,
13675			y2 = event.pageY;
13676
13677		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
13678		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
13679		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13680
13681		this.selectees.each( function() {
13682			var selectee = $.data( this, "selectable-item" ),
13683				hit = false,
13684				offset = {};
13685
13686			//prevent helper from being selected if appendTo: selectable
13687			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13688				return;
13689			}
13690
13691			offset.left   = selectee.left   + that.elementPos.left;
13692			offset.right  = selectee.right  + that.elementPos.left;
13693			offset.top    = selectee.top    + that.elementPos.top;
13694			offset.bottom = selectee.bottom + that.elementPos.top;
13695
13696			if ( options.tolerance === "touch" ) {
13697				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13698                    offset.bottom < y1 ) );
13699			} else if ( options.tolerance === "fit" ) {
13700				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13701                    offset.bottom < y2 );
13702			}
13703
13704			if ( hit ) {
13705
13706				// SELECT
13707				if ( selectee.selected ) {
13708					that._removeClass( selectee.$element, "ui-selected" );
13709					selectee.selected = false;
13710				}
13711				if ( selectee.unselecting ) {
13712					that._removeClass( selectee.$element, "ui-unselecting" );
13713					selectee.unselecting = false;
13714				}
13715				if ( !selectee.selecting ) {
13716					that._addClass( selectee.$element, "ui-selecting" );
13717					selectee.selecting = true;
13718
13719					// selectable SELECTING callback
13720					that._trigger( "selecting", event, {
13721						selecting: selectee.element
13722					} );
13723				}
13724			} else {
13725
13726				// UNSELECT
13727				if ( selectee.selecting ) {
13728					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13729						that._removeClass( selectee.$element, "ui-selecting" );
13730						selectee.selecting = false;
13731						that._addClass( selectee.$element, "ui-selected" );
13732						selectee.selected = true;
13733					} else {
13734						that._removeClass( selectee.$element, "ui-selecting" );
13735						selectee.selecting = false;
13736						if ( selectee.startselected ) {
13737							that._addClass( selectee.$element, "ui-unselecting" );
13738							selectee.unselecting = true;
13739						}
13740
13741						// selectable UNSELECTING callback
13742						that._trigger( "unselecting", event, {
13743							unselecting: selectee.element
13744						} );
13745					}
13746				}
13747				if ( selectee.selected ) {
13748					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13749						that._removeClass( selectee.$element, "ui-selected" );
13750						selectee.selected = false;
13751
13752						that._addClass( selectee.$element, "ui-unselecting" );
13753						selectee.unselecting = true;
13754
13755						// selectable UNSELECTING callback
13756						that._trigger( "unselecting", event, {
13757							unselecting: selectee.element
13758						} );
13759					}
13760				}
13761			}
13762		} );
13763
13764		return false;
13765	},
13766
13767	_mouseStop: function( event ) {
13768		var that = this;
13769
13770		this.dragged = false;
13771
13772		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13773			var selectee = $.data( this, "selectable-item" );
13774			that._removeClass( selectee.$element, "ui-unselecting" );
13775			selectee.unselecting = false;
13776			selectee.startselected = false;
13777			that._trigger( "unselected", event, {
13778				unselected: selectee.element
13779			} );
13780		} );
13781		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13782			var selectee = $.data( this, "selectable-item" );
13783			that._removeClass( selectee.$element, "ui-selecting" )
13784				._addClass( selectee.$element, "ui-selected" );
13785			selectee.selecting = false;
13786			selectee.selected = true;
13787			selectee.startselected = true;
13788			that._trigger( "selected", event, {
13789				selected: selectee.element
13790			} );
13791		} );
13792		this._trigger( "stop", event );
13793
13794		this.helper.remove();
13795
13796		return false;
13797	}
13798
13799} );
13800
13801
13802/*!
13803 * jQuery UI Selectmenu 1.12.1
13804 * http://jqueryui.com
13805 *
13806 * Copyright jQuery Foundation and other contributors
13807 * Released under the MIT license.
13808 * http://jquery.org/license
13809 */
13810
13811//>>label: Selectmenu
13812//>>group: Widgets
13813// jscs:disable maximumLineLength
13814//>>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.
13815// jscs:enable maximumLineLength
13816//>>docs: http://api.jqueryui.com/selectmenu/
13817//>>demos: http://jqueryui.com/selectmenu/
13818//>>css.structure: ../../themes/base/core.css
13819//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13820//>>css.theme: ../../themes/base/theme.css
13821
13822
13823
13824var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13825	version: "1.12.1",
13826	defaultElement: "<select>",
13827	options: {
13828		appendTo: null,
13829		classes: {
13830			"ui-selectmenu-button-open": "ui-corner-top",
13831			"ui-selectmenu-button-closed": "ui-corner-all"
13832		},
13833		disabled: null,
13834		icons: {
13835			button: "ui-icon-triangle-1-s"
13836		},
13837		position: {
13838			my: "left top",
13839			at: "left bottom",
13840			collision: "none"
13841		},
13842		width: false,
13843
13844		// Callbacks
13845		change: null,
13846		close: null,
13847		focus: null,
13848		open: null,
13849		select: null
13850	},
13851
13852	_create: function() {
13853		var selectmenuId = this.element.uniqueId().attr( "id" );
13854		this.ids = {
13855			element: selectmenuId,
13856			button: selectmenuId + "-button",
13857			menu: selectmenuId + "-menu"
13858		};
13859
13860		this._drawButton();
13861		this._drawMenu();
13862		this._bindFormResetHandler();
13863
13864		this._rendered = false;
13865		this.menuItems = $();
13866	},
13867
13868	_drawButton: function() {
13869		var icon,
13870			that = this,
13871			item = this._parseOption(
13872				this.element.find( "option:selected" ),
13873				this.element[ 0 ].selectedIndex
13874			);
13875
13876		// Associate existing label with the new button
13877		this.labels = this.element.labels().attr( "for", this.ids.button );
13878		this._on( this.labels, {
13879			click: function( event ) {
13880				this.button.focus();
13881				event.preventDefault();
13882			}
13883		} );
13884
13885		// Hide original select element
13886		this.element.hide();
13887
13888		// Create button
13889		this.button = $( "<span>", {
13890			tabindex: this.options.disabled ? -1 : 0,
13891			id: this.ids.button,
13892			role: "combobox",
13893			"aria-expanded": "false",
13894			"aria-autocomplete": "list",
13895			"aria-owns": this.ids.menu,
13896			"aria-haspopup": "true",
13897			title: this.element.attr( "title" )
13898		} )
13899			.insertAfter( this.element );
13900
13901		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
13902			"ui-button ui-widget" );
13903
13904		icon = $( "<span>" ).appendTo( this.button );
13905		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
13906		this.buttonItem = this._renderButtonItem( item )
13907			.appendTo( this.button );
13908
13909		if ( this.options.width !== false ) {
13910			this._resizeButton();
13911		}
13912
13913		this._on( this.button, this._buttonEvents );
13914		this.button.one( "focusin", function() {
13915
13916			// Delay rendering the menu items until the button receives focus.
13917			// The menu may have already been rendered via a programmatic open.
13918			if ( !that._rendered ) {
13919				that._refreshMenu();
13920			}
13921		} );
13922	},
13923
13924	_drawMenu: function() {
13925		var that = this;
13926
13927		// Create menu
13928		this.menu = $( "<ul>", {
13929			"aria-hidden": "true",
13930			"aria-labelledby": this.ids.button,
13931			id: this.ids.menu
13932		} );
13933
13934		// Wrap menu
13935		this.menuWrap = $( "<div>" ).append( this.menu );
13936		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
13937		this.menuWrap.appendTo( this._appendTo() );
13938
13939		// Initialize menu widget
13940		this.menuInstance = this.menu
13941			.menu( {
13942				classes: {
13943					"ui-menu": "ui-corner-bottom"
13944				},
13945				role: "listbox",
13946				select: function( event, ui ) {
13947					event.preventDefault();
13948
vendor: 5,595 bytes, lines 13949-14189
13949					// Support: IE8
13950					// If the item was selected via a click, the text selection
13951					// will be destroyed in IE
13952					that._setSelection();
13953
13954					that._select( ui.item.data( "ui-selectmenu-item" ), event );
13955				},
13956				focus: function( event, ui ) {
13957					var item = ui.item.data( "ui-selectmenu-item" );
13958
13959					// Prevent inital focus from firing and check if its a newly focused item
13960					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
13961						that._trigger( "focus", event, { item: item } );
13962						if ( !that.isOpen ) {
13963							that._select( item, event );
13964						}
13965					}
13966					that.focusIndex = item.index;
13967
13968					that.button.attr( "aria-activedescendant",
13969						that.menuItems.eq( item.index ).attr( "id" ) );
13970				}
13971			} )
13972			.menu( "instance" );
13973
13974		// Don't close the menu on mouseleave
13975		this.menuInstance._off( this.menu, "mouseleave" );
13976
13977		// Cancel the menu's collapseAll on document click
13978		this.menuInstance._closeOnDocumentClick = function() {
13979			return false;
13980		};
13981
13982		// Selects often contain empty items, but never contain dividers
13983		this.menuInstance._isDivider = function() {
13984			return false;
13985		};
13986	},
13987
13988	refresh: function() {
13989		this._refreshMenu();
13990		this.buttonItem.replaceWith(
13991			this.buttonItem = this._renderButtonItem(
13992
13993				// Fall back to an empty object in case there are no options
13994				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
13995			)
13996		);
13997		if ( this.options.width === null ) {
13998			this._resizeButton();
13999		}
14000	},
14001
14002	_refreshMenu: function() {
14003		var item,
14004			options = this.element.find( "option" );
14005
14006		this.menu.empty();
14007
14008		this._parseOptions( options );
14009		this._renderMenu( this.menu, this.items );
14010
14011		this.menuInstance.refresh();
14012		this.menuItems = this.menu.find( "li" )
14013			.not( ".ui-selectmenu-optgroup" )
14014				.find( ".ui-menu-item-wrapper" );
14015
14016		this._rendered = true;
14017
14018		if ( !options.length ) {
14019			return;
14020		}
14021
14022		item = this._getSelectedItem();
14023
14024		// Update the menu to have the correct item focused
14025		this.menuInstance.focus( null, item );
14026		this._setAria( item.data( "ui-selectmenu-item" ) );
14027
14028		// Set disabled state
14029		this._setOption( "disabled", this.element.prop( "disabled" ) );
14030	},
14031
14032	open: function( event ) {
14033		if ( this.options.disabled ) {
14034			return;
14035		}
14036
14037		// If this is the first time the menu is being opened, render the items
14038		if ( !this._rendered ) {
14039			this._refreshMenu();
14040		} else {
14041
14042			// Menu clears focus on close, reset focus to selected item
14043			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14044			this.menuInstance.focus( null, this._getSelectedItem() );
14045		}
14046
14047		// If there are no options, don't open the menu
14048		if ( !this.menuItems.length ) {
14049			return;
14050		}
14051
14052		this.isOpen = true;
14053		this._toggleAttr();
14054		this._resizeMenu();
14055		this._position();
14056
14057		this._on( this.document, this._documentClick );
14058
14059		this._trigger( "open", event );
14060	},
14061
14062	_position: function() {
14063		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14064	},
14065
14066	close: function( event ) {
14067		if ( !this.isOpen ) {
14068			return;
14069		}
14070
14071		this.isOpen = false;
14072		this._toggleAttr();
14073
14074		this.range = null;
14075		this._off( this.document );
14076
14077		this._trigger( "close", event );
14078	},
14079
14080	widget: function() {
14081		return this.button;
14082	},
14083
14084	menuWidget: function() {
14085		return this.menu;
14086	},
14087
14088	_renderButtonItem: function( item ) {
14089		var buttonItem = $( "<span>" );
14090
14091		this._setText( buttonItem, item.label );
14092		this._addClass( buttonItem, "ui-selectmenu-text" );
14093
14094		return buttonItem;
14095	},
14096
14097	_renderMenu: function( ul, items ) {
14098		var that = this,
14099			currentOptgroup = "";
14100
14101		$.each( items, function( index, item ) {
14102			var li;
14103
14104			if ( item.optgroup !== currentOptgroup ) {
14105				li = $( "<li>", {
14106					text: item.optgroup
14107				} );
14108				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14109					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14110						" ui-state-disabled" :
14111						"" ) );
14112
14113				li.appendTo( ul );
14114
14115				currentOptgroup = item.optgroup;
14116			}
14117
14118			that._renderItemData( ul, item );
14119		} );
14120	},
14121
14122	_renderItemData: function( ul, item ) {
14123		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14124	},
14125
14126	_renderItem: function( ul, item ) {
14127		var li = $( "<li>" ),
14128			wrapper = $( "<div>", {
14129				title: item.element.attr( "title" )
14130			} );
14131
14132		if ( item.disabled ) {
14133			this._addClass( li, null, "ui-state-disabled" );
14134		}
14135		this._setText( wrapper, item.label );
14136
14137		return li.append( wrapper ).appendTo( ul );
14138	},
14139
14140	_setText: function( element, value ) {
14141		if ( value ) {
14142			element.text( value );
14143		} else {
14144			element.html( "&#160;" );
14145		}
14146	},
14147
14148	_move: function( direction, event ) {
14149		var item, next,
14150			filter = ".ui-menu-item";
14151
14152		if ( this.isOpen ) {
14153			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14154		} else {
14155			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14156			filter += ":not(.ui-state-disabled)";
14157		}
14158
14159		if ( direction === "first" || direction === "last" ) {
14160			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14161		} else {
14162			next = item[ direction + "All" ]( filter ).eq( 0 );
14163		}
14164
14165		if ( next.length ) {
14166			this.menuInstance.focus( event, next );
14167		}
14168	},
14169
14170	_getSelectedItem: function() {
14171		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14172	},
14173
14174	_toggle: function( event ) {
14175		this[ this.isOpen ? "close" : "open" ]( event );
14176	},
14177
14178	_setSelection: function() {
14179		var selection;
14180
14181		if ( !this.range ) {
14182			return;
14183		}
14184
14185		if ( window.getSelection ) {
14186			selection = window.getSelection();
14187			selection.removeAllRanges();
14188			selection.addRange( this.range );
14189
14190		// Support: IE8
14191		} else {
14192			this.range.select();
14193		}
14194
14195		// Support: IE
14196		// Setting the text selection kills the button focus in IE, but
14197		// restoring the focus doesn't kill the selection.
14198		this.button.focus();
14199	},
14200
14201	_documentClick: {
14202		mousedown: function( event ) {
14203			if ( !this.isOpen ) {
14204				return;
14205			}
14206
14207			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14208					$.ui
vendor: 5,768 bytes, lines 14208-14452
14208.escapeSelector( this.ids.button ) ).length ) {
14209				this.close( event );
14210			}
14211		}
14212	},
14213
14214	_buttonEvents: {
14215
14216		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14217		mousedown: function() {
14218			var selection;
14219
14220			if ( window.getSelection ) {
14221				selection = window.getSelection();
14222				if ( selection.rangeCount ) {
14223					this.range = selection.getRangeAt( 0 );
14224				}
14225
14226			// Support: IE8
14227			} else {
14228				this.range = document.selection.createRange();
14229			}
14230		},
14231
14232		click: function( event ) {
14233			this._setSelection();
14234			this._toggle( event );
14235		},
14236
14237		keydown: function( event ) {
14238			var preventDefault = true;
14239			switch ( event.keyCode ) {
14240			case $.ui.keyCode.TAB:
14241			case $.ui.keyCode.ESCAPE:
14242				this.close( event );
14243				preventDefault = false;
14244				break;
14245			case $.ui.keyCode.ENTER:
14246				if ( this.isOpen ) {
14247					this._selectFocusedItem( event );
14248				}
14249				break;
14250			case $.ui.keyCode.UP:
14251				if ( event.altKey ) {
14252					this._toggle( event );
14253				} else {
14254					this._move( "prev", event );
14255				}
14256				break;
14257			case $.ui.keyCode.DOWN:
14258				if ( event.altKey ) {
14259					this._toggle( event );
14260				} else {
14261					this._move( "next", event );
14262				}
14263				break;
14264			case $.ui.keyCode.SPACE:
14265				if ( this.isOpen ) {
14266					this._selectFocusedItem( event );
14267				} else {
14268					this._toggle( event );
14269				}
14270				break;
14271			case $.ui.keyCode.LEFT:
14272				this._move( "prev", event );
14273				break;
14274			case $.ui.keyCode.RIGHT:
14275				this._move( "next", event );
14276				break;
14277			case $.ui.keyCode.HOME:
14278			case $.ui.keyCode.PAGE_UP:
14279				this._move( "first", event );
14280				break;
14281			case $.ui.keyCode.END:
14282			case $.ui.keyCode.PAGE_DOWN:
14283				this._move( "last", event );
14284				break;
14285			default:
14286				this.menu.trigger( event );
14287				preventDefault = false;
14288			}
14289
14290			if ( preventDefault ) {
14291				event.preventDefault();
14292			}
14293		}
14294	},
14295
14296	_selectFocusedItem: function( event ) {
14297		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14298		if ( !item.hasClass( "ui-state-disabled" ) ) {
14299			this._select( item.data( "ui-selectmenu-item" ), event );
14300		}
14301	},
14302
14303	_select: function( item, event ) {
14304		var oldIndex = this.element[ 0 ].selectedIndex;
14305
14306		// Change native select element
14307		this.element[ 0 ].selectedIndex = item.index;
14308		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14309		this._setAria( item );
14310		this._trigger( "select", event, { item: item } );
14311
14312		if ( item.index !== oldIndex ) {
14313			this._trigger( "change", event, { item: item } );
14314		}
14315
14316		this.close( event );
14317	},
14318
14319	_setAria: function( item ) {
14320		var id = this.menuItems.eq( item.index ).attr( "id" );
14321
14322		this.button.attr( {
14323			"aria-labelledby": id,
14324			"aria-activedescendant": id
14325		} );
14326		this.menu.attr( "aria-activedescendant", id );
14327	},
14328
14329	_setOption: function( key, value ) {
14330		if ( key === "icons" ) {
14331			var icon = this.button.find( "span.ui-icon" );
14332			this._removeClass( icon, null, this.options.icons.button )
14333				._addClass( icon, null, value.button );
14334		}
14335
14336		this._super( key, value );
14337
14338		if ( key === "appendTo" ) {
14339			this.menuWrap.appendTo( this._appendTo() );
14340		}
14341
14342		if ( key === "width" ) {
14343			this._resizeButton();
14344		}
14345	},
14346
14347	_setOptionDisabled: function( value ) {
14348		this._super( value );
14349
14350		this.menuInstance.option( "disabled", value );
14351		this.button.attr( "aria-disabled", value );
14352		this._toggleClass( this.button, null, "ui-state-disabled", value );
14353
14354		this.element.prop( "disabled", value );
14355		if ( value ) {
14356			this.button.attr( "tabindex", -1 );
14357			this.close();
14358		} else {
14359			this.button.attr( "tabindex", 0 );
14360		}
14361	},
14362
14363	_appendTo: function() {
14364		var element = this.options.appendTo;
14365
14366		if ( element ) {
14367			element = element.jquery || element.nodeType ?
14368				$( element ) :
14369				this.document.find( element ).eq( 0 );
14370		}
14371
14372		if ( !element || !element[ 0 ] ) {
14373			element = this.element.closest( ".ui-front, dialog" );
14374		}
14375
14376		if ( !element.length ) {
14377			element = this.document[ 0 ].body;
14378		}
14379
14380		return element;
14381	},
14382
14383	_toggleAttr: function() {
14384		this.button.attr( "aria-expanded", this.isOpen );
14385
14386		// We can't use two _toggleClass() calls here, because we need to make sure
14387		// we always remove classes first and add them second, otherwise if both classes have the
14388		// same theme class, it will be removed after we add it.
14389		this._removeClass( this.button, "ui-selectmenu-button-" +
14390			( this.isOpen ? "closed" : "open" ) )
14391			._addClass( this.button, "ui-selectmenu-button-" +
14392				( this.isOpen ? "open" : "closed" ) )
14393			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14394
14395		this.menu.attr( "aria-hidden", !this.isOpen );
14396	},
14397
14398	_resizeButton: function() {
14399		var width = this.options.width;
14400
14401		// For `width: false`, just remove inline style and stop
14402		if ( width === false ) {
14403			this.button.css( "width", "" );
14404			return;
14405		}
14406
14407		// For `width: null`, match the width of the original element
14408		if ( width === null ) {
14409			width = this.element.show().outerWidth();
14410			this.element.hide();
14411		}
14412
14413		this.button.outerWidth( width );
14414	},
14415
14416	_resizeMenu: function() {
14417		this.menu.outerWidth( Math.max(
14418			this.button.outerWidth(),
14419
14420			// Support: IE10
14421			// IE10 wraps long text (possibly a rounding bug)
14422			// so we add 1px to avoid the wrapping
14423			this.menu.width( "" ).outerWidth() + 1
14424		) );
14425	},
14426
14427	_getCreateOptions: function() {
14428		var options = this._super();
14429
14430		options.disabled = this.element.prop( "disabled" );
14431
14432		return options;
14433	},
14434
14435	_parseOptions: function( options ) {
14436		var that = this,
14437			data = [];
14438		options.each( function( index, item ) {
14439			data.push( that._parseOption( $( item ), index ) );
14440		} );
14441		this.items = data;
14442	},
14443
14444	_parseOption: function( option, index ) {
14445		var optgroup = option.parent( "optgroup" );
14446
14447		return {
14448			element: option,
14449			index: index,
14450			value: option.val(),
14451			label: option.text(),
14452			
14452optgroup: optgroup.attr( "label" ) || "",
14453			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14454		};
14455	},
14456
14457	_destroy: function() {
14458		this._unbindFormResetHandler();
14459		this.menuWrap.remove();
14460		this.button.remove();
14461		this.element.show();
14462		this.element.removeUniqueId();
14463		this.labels.attr( "for", this.ids.element );
14464	}
14465} ]
vendor: 19,267 bytes, lines 14465-15203
14465 );
14466
14467
14468/*!
14469 * jQuery UI Slider 1.12.1
14470 * http://jqueryui.com
14471 *
14472 * Copyright jQuery Foundation and other contributors
14473 * Released under the MIT license.
14474 * http://jquery.org/license
14475 */
14476
14477//>>label: Slider
14478//>>group: Widgets
14479//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14480//>>docs: http://api.jqueryui.com/slider/
14481//>>demos: http://jqueryui.com/slider/
14482//>>css.structure: ../../themes/base/core.css
14483//>>css.structure: ../../themes/base/slider.css
14484//>>css.theme: ../../themes/base/theme.css
14485
14486
14487
14488var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14489	version: "1.12.1",
14490	widgetEventPrefix: "slide",
14491
14492	options: {
14493		animate: false,
14494		classes: {
14495			"ui-slider": "ui-corner-all",
14496			"ui-slider-handle": "ui-corner-all",
14497
14498			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14499			// element, but worked best visually with a variety of themes
14500			"ui-slider-range": "ui-corner-all ui-widget-header"
14501		},
14502		distance: 0,
14503		max: 100,
14504		min: 0,
14505		orientation: "horizontal",
14506		range: false,
14507		step: 1,
14508		value: 0,
14509		values: null,
14510
14511		// Callbacks
14512		change: null,
14513		slide: null,
14514		start: null,
14515		stop: null
14516	},
14517
14518	// Number of pages in a slider
14519	// (how many times can you page up/down to go through the whole range)
14520	numPages: 5,
14521
14522	_create: function() {
14523		this._keySliding = false;
14524		this._mouseSliding = false;
14525		this._animateOff = true;
14526		this._handleIndex = null;
14527		this._detectOrientation();
14528		this._mouseInit();
14529		this._calculateNewMax();
14530
14531		this._addClass( "ui-slider ui-slider-" + this.orientation,
14532			"ui-widget ui-widget-content" );
14533
14534		this._refresh();
14535
14536		this._animateOff = false;
14537	},
14538
14539	_refresh: function() {
14540		this._createRange();
14541		this._createHandles();
14542		this._setupEvents();
14543		this._refreshValue();
14544	},
14545
14546	_createHandles: function() {
14547		var i, handleCount,
14548			options = this.options,
14549			existingHandles = this.element.find( ".ui-slider-handle" ),
14550			handle = "<span tabindex='0'></span>",
14551			handles = [];
14552
14553		handleCount = ( options.values && options.values.length ) || 1;
14554
14555		if ( existingHandles.length > handleCount ) {
14556			existingHandles.slice( handleCount ).remove();
14557			existingHandles = existingHandles.slice( 0, handleCount );
14558		}
14559
14560		for ( i = existingHandles.length; i < handleCount; i++ ) {
14561			handles.push( handle );
14562		}
14563
14564		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14565
14566		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14567
14568		this.handle = this.handles.eq( 0 );
14569
14570		this.handles.each( function( i ) {
14571			$( this )
14572				.data( "ui-slider-handle-index", i )
14573				.attr( "tabIndex", 0 );
14574		} );
14575	},
14576
14577	_createRange: function() {
14578		var options = this.options;
14579
14580		if ( options.range ) {
14581			if ( options.range === true ) {
14582				if ( !options.values ) {
14583					options.values = [ this._valueMin(), this._valueMin() ];
14584				} else if ( options.values.length && options.values.length !== 2 ) {
14585					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14586				} else if ( $.isArray( options.values ) ) {
14587					options.values = options.values.slice( 0 );
14588				}
14589			}
14590
14591			if ( !this.range || !this.range.length ) {
14592				this.range = $( "<div>" )
14593					.appendTo( this.element );
14594
14595				this._addClass( this.range, "ui-slider-range" );
14596			} else {
14597				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14598
14599				// Handle range switching from true to min/max
14600				this.range.css( {
14601					"left": "",
14602					"bottom": ""
14603				} );
14604			}
14605			if ( options.range === "min" || options.range === "max" ) {
14606				this._addClass( this.range, "ui-slider-range-" + options.range );
14607			}
14608		} else {
14609			if ( this.range ) {
14610				this.range.remove();
14611			}
14612			this.range = null;
14613		}
14614	},
14615
14616	_setupEvents: function() {
14617		this._off( this.handles );
14618		this._on( this.handles, this._handleEvents );
14619		this._hoverable( this.handles );
14620		this._focusable( this.handles );
14621	},
14622
14623	_destroy: function() {
14624		this.handles.remove();
14625		if ( this.range ) {
14626			this.range.remove();
14627		}
14628
14629		this._mouseDestroy();
14630	},
14631
14632	_mouseCapture: function( event ) {
14633		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14634			that = this,
14635			o = this.options;
14636
14637		if ( o.disabled ) {
14638			return false;
14639		}
14640
14641		this.elementSize = {
14642			width: this.element.outerWidth(),
14643			height: this.element.outerHeight()
14644		};
14645		this.elementOffset = this.element.offset();
14646
14647		position = { x: event.pageX, y: event.pageY };
14648		normValue = this._normValueFromMouse( position );
14649		distance = this._valueMax() - this._valueMin() + 1;
14650		this.handles.each( function( i ) {
14651			var thisDistance = Math.abs( normValue - that.values( i ) );
14652			if ( ( distance > thisDistance ) ||
14653				( distance === thisDistance &&
14654					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14655				distance = thisDistance;
14656				closestHandle = $( this );
14657				index = i;
14658			}
14659		} );
14660
14661		allowed = this._start( event, index );
14662		if ( allowed === false ) {
14663			return false;
14664		}
14665		this._mouseSliding = true;
14666
14667		this._handleIndex = index;
14668
14669		this._addClass( closestHandle, null, "ui-state-active" );
14670		closestHandle.trigger( "focus" );
14671
14672		offset = closestHandle.offset();
14673		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14674		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14675			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14676			top: event.pageY - offset.top -
14677				( closestHandle.height() / 2 ) -
14678				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14679				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14680				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14681		};
14682
14683		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14684			this._slide( event, index, normValue );
14685		}
14686		this._animateOff = true;
14687		return true;
14688	},
14689
14690	_mouseStart: function() {
14691		return true;
14692	},
14693
14694	_mouseDrag: function( event ) {
14695		var position = { x: event.pageX, y: event.pageY },
14696			normValue = this._normValueFromMouse( position );
14697
14698		this._slide( event, this._handleIndex, normValue );
14699
14700		return false;
14701	},
14702
14703	_mouseStop: function( event ) {
14704		this._removeClass( this.handles, null, "ui-state-active" );
14705		this._mouseSliding = false;
14706
14707		this._stop( event, this._handleIndex );
14708		this._change( event, this._handleIndex );
14709
14710		this._handleIndex = null;
14711		this._clickOffset = null;
14712		this._animateOff = false;
14713
14714		return false;
14715	},
14716
14717	_detectOrientation: function() {
14718		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14719	},
14720
14721	_normValueFromMouse: function( position ) {
14722		var pixelTotal,
14723			pixelMouse,
14724			percentMouse,
14725			valueTotal,
14726			valueMouse;
14727
14728		if ( this.orientation === "horizontal" ) {
14729			pixelTotal = this.elementSize.width;
14730			pixelMouse = position.x - this.elementOffset.left -
14731				( this._clickOffset ? this._clickOffset.left : 0 );
14732		} else {
14733			pixelTotal = this.elementSize.height;
14734			pixelMouse = position.y - this.elementOffset.top -
14735				( this._clickOffset ? this._clickOffset.top : 0 );
14736		}
14737
14738		percentMouse = ( pixelMouse / pixelTotal );
14739		if ( percentMouse > 1 ) {
14740			percentMouse = 1;
14741		}
14742		if ( percentMouse < 0 ) {
14743			percentMouse = 0;
14744		}
14745		if ( this.orientation === "vertical" ) {
14746			percentMouse = 1 - percentMouse;
14747		}
14748
14749		valueTotal = this._valueMax() - this._valueMin();
14750		valueMouse = this._valueMin() + percentMouse * valueTotal;
14751
14752		return this._trimAlignValue( valueMouse );
14753	},
14754
14755	_uiHash: function( index, value, values ) {
14756		var uiHash = {
14757			handle: this.handles[ index ],
14758			handleIndex: index,
14759			value: value !== undefined ? value : this.value()
14760		};
14761
14762		if ( this._hasMultipleValues() ) {
14763			uiHash.value = value !== undefined ? value : this.values( index );
14764			uiHash.values = values || this.values();
14765		}
14766
14767		return uiHash;
14768	},
14769
14770	_hasMultipleValues: function() {
14771		return this.options.values && this.options.values.length;
14772	},
14773
14774	_start: function( event, index ) {
14775		return this._trigger( "start", event, this._uiHash( index ) );
14776	},
14777
14778	_slide: function( event, index, newVal ) {
14779		var allowed, otherVal,
14780			currentValue = this.value(),
14781			newValues = this.values();
14782
14783		if ( this._hasMultipleValues() ) {
14784			otherVal = this.values( index ? 0 : 1 );
14785			currentValue = this.values( index );
14786
14787			if ( this.options.values.length === 2 && this.options.range === true ) {
14788				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14789			}
14790
14791			newValues[ index ] = newVal;
14792		}
14793
14794		if ( newVal === currentValue ) {
14795			return;
14796		}
14797
14798		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14799
14800		// A slide can be canceled by returning false from the slide callback
14801		if ( allowed === false ) {
14802			return;
14803		}
14804
14805		if ( this._hasMultipleValues() ) {
14806			this.values( index, newVal );
14807		} else {
14808			this.value( newVal );
14809		}
14810	},
14811
14812	_stop: function( event, index ) {
14813		this._trigger( "stop", event, this._uiHash( index ) );
14814	},
14815
14816	_change: function( event, index ) {
14817		if ( !this._keySliding && !this._mouseSliding ) {
14818
14819			//store the last changed value index for reference when handles overlap
14820			this._lastChangedValue = index;
14821			this._trigger( "change", event, this._uiHash( index ) );
14822		}
14823	},
14824
14825	value: function( newValue ) {
14826		if ( arguments.length ) {
14827			this.options.value = this._trimAlignValue( newValue );
14828			this._refreshValue();
14829			this._change( null, 0 );
14830			return;
14831		}
14832
14833		return this._value();
14834	},
14835
14836	values: function( index, newValue ) {
14837		var vals,
14838			newValues,
14839			i;
14840
14841		if ( arguments.length > 1 ) {
14842			this.options.values[ index ] = this._trimAlignValue( newValue );
14843			this._refreshValue();
14844			this._change( null, index );
14845			return;
14846		}
14847
14848		if ( arguments.length ) {
14849			if ( $.isArray( arguments[ 0 ] ) ) {
14850				vals = this.options.values;
14851				newValues = arguments[ 0 ];
14852				for ( i = 0; i < vals.length; i += 1 ) {
14853					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14854					this._change( null, i );
14855				}
14856				this._refreshValue();
14857			} else {
14858				if ( this._hasMultipleValues() ) {
14859					return this._values( index );
14860				} else {
14861					return this.value();
14862				}
14863			}
14864		} else {
14865			return this._values();
14866		}
14867	},
14868
14869	_setOption: function( key, value ) {
14870		var i,
14871			valsLength = 0;
14872
14873		if ( key === "range" && this.options.range === true ) {
14874			if ( value === "min" ) {
14875				this.options.value = this._values( 0 );
14876				this.options.values = null;
14877			} else if ( value === "max" ) {
14878				this.options.value = this._values( this.options.values.length - 1 );
14879				this.options.values = null;
14880			}
14881		}
14882
14883		if ( $.isArray( this.options.values ) ) {
14884			valsLength = this.options.values.length;
14885		}
14886
14887		this._super( key, value );
14888
14889		switch ( key ) {
14890			case "orientation":
14891				this._detectOrientation();
14892				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14893					._addClass( "ui-slider-" + this.orientation );
14894				this._refreshValue();
14895				if ( this.options.range ) {
14896					this._refreshRange( value );
14897				}
14898
14899				// Reset positioning from previous orientation
14900				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
14901				break;
14902			case "value":
14903				this._animateOff = true;
14904				this._refreshValue();
14905				this._change( null, 0 );
14906				this._animateOff = false;
14907				break;
14908			case "values":
14909				this._animateOff = true;
14910				this._refreshValue();
14911
14912				// Start from the last handle to prevent unreachable handles (#9046)
14913				for ( i = valsLength - 1; i >= 0; i-- ) {
14914					this._change( null, i );
14915				}
14916				this._animateOff = false;
14917				break;
14918			case "step":
14919			case "min":
14920			case "max":
14921				this._animateOff = true;
14922				this._calculateNewMax();
14923				this._refreshValue();
14924				this._animateOff = false;
14925				break;
14926			case "range":
14927				this._animateOff = true;
14928				this._refresh();
14929				this._animateOff = false;
14930				break;
14931		}
14932	},
14933
14934	_setOptionDisabled: function( value ) {
14935		this._super( value );
14936
14937		this._toggleClass( null, "ui-state-disabled", !!value );
14938	},
14939
14940	//internal value getter
14941	// _value() returns value trimmed by min and max, aligned by step
14942	_value: function() {
14943		var val = this.options.value;
14944		val = this._trimAlignValue( val );
14945
14946		return val;
14947	},
14948
14949	//internal values getter
14950	// _values() returns array of values trimmed by min and max, aligned by step
14951	// _values( index ) returns single value trimmed by min and max, aligned by step
14952	_values: function( index ) {
14953		var val,
14954			vals,
14955			i;
14956
14957		if ( arguments.length ) {
14958			val = this.options.values[ index ];
14959			val = this._trimAlignValue( val );
14960
14961			return val;
14962		} else if ( this._hasMultipleValues() ) {
14963
14964			// .slice() creates a copy of the array
14965			// this copy gets trimmed by min and max and then returned
14966			vals = this.options.values.slice();
14967			for ( i = 0; i < vals.length; i += 1 ) {
14968				vals[ i ] = this._trimAlignValue( vals[ i ] );
14969			}
14970
14971			return vals;
14972		} else {
14973			return [];
14974		}
14975	},
14976
14977	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
14978	_trimAlignValue: function( val ) {
14979		if ( val <= this._valueMin() ) {
14980			return this._valueMin();
14981		}
14982		if ( val >= this._valueMax() ) {
14983			return this._valueMax();
14984		}
14985		var step = ( this.options.step > 0 ) ? this.options.step : 1,
14986			valModStep = ( val - this._valueMin() ) % step,
14987			alignValue = val - valModStep;
14988
14989		if ( Math.abs( valModStep ) * 2 >= step ) {
14990			alignValue += ( valModStep > 0 ) ? step : ( -step );
14991		}
14992
14993		// Since JavaScript has problems with large floats, round
14994		// the final value to 5 digits after the decimal point (see #4124)
14995		return parseFloat( alignValue.toFixed( 5 ) );
14996	},
14997
14998	_calculateNewMax: function() {
14999		var max = this.options.max,
15000			min = this._valueMin(),
15001			step = this.options.step,
15002			aboveMin = Math.round( ( max - min ) / step ) * step;
15003		max = aboveMin + min;
15004		if ( max > this.options.max ) {
15005
15006			//If max is not divisible by step, rounding off may increase its value
15007			max -= step;
15008		}
15009		this.max = parseFloat( max.toFixed( this._precision() ) );
15010	},
15011
15012	_precision: function() {
15013		var precision = this._precisionOf( this.options.step );
15014		if ( this.options.min !== null ) {
15015			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15016		}
15017		return precision;
15018	},
15019
15020	_precisionOf: function( num ) {
15021		var str = num.toString(),
15022			decimal = str.indexOf( "." );
15023		return decimal === -1 ? 0 : str.length - decimal - 1;
15024	},
15025
15026	_valueMin: function() {
15027		return this.options.min;
15028	},
15029
15030	_valueMax: function() {
15031		return this.max;
15032	},
15033
15034	_refreshRange: function( orientation ) {
15035		if ( orientation === "vertical" ) {
15036			this.range.css( { "width": "", "left": "" } );
15037		}
15038		if ( orientation === "horizontal" ) {
15039			this.range.css( { "height": "", "bottom": "" } );
15040		}
15041	},
15042
15043	_refreshValue: function() {
15044		var lastValPercent, valPercent, value, valueMin, valueMax,
15045			oRange = this.options.range,
15046			o = this.options,
15047			that = this,
15048			animate = ( !this._animateOff ) ? o.animate : false,
15049			_set = {};
15050
15051		if ( this._hasMultipleValues() ) {
15052			this.handles.each( function( i ) {
15053				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15054					that._valueMin() ) * 100;
15055				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15056				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15057				if ( that.options.range === true ) {
15058					if ( that.orientation === "horizontal" ) {
15059						if ( i === 0 ) {
15060							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15061								left: valPercent + "%"
15062							}, o.animate );
15063						}
15064						if ( i === 1 ) {
15065							that.range[ animate ? "animate" : "css" ]( {
15066								width: ( valPercent - lastValPercent ) + "%"
15067							}, {
15068								queue: false,
15069								duration: o.animate
15070							} );
15071						}
15072					} else {
15073						if ( i === 0 ) {
15074							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15075								bottom: ( valPercent ) + "%"
15076							}, o.animate );
15077						}
15078						if ( i === 1 ) {
15079							that.range[ animate ? "animate" : "css" ]( {
15080								height: ( valPercent - lastValPercent ) + "%"
15081							}, {
15082								queue: false,
15083								duration: o.animate
15084							} );
15085						}
15086					}
15087				}
15088				lastValPercent = valPercent;
15089			} );
15090		} else {
15091			value = this.value();
15092			valueMin = this._valueMin();
15093			valueMax = this._valueMax();
15094			valPercent = ( valueMax !== valueMin ) ?
15095					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15096					0;
15097			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15098			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15099
15100			if ( oRange === "min" && this.orientation === "horizontal" ) {
15101				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15102					width: valPercent + "%"
15103				}, o.animate );
15104			}
15105			if ( oRange === "max" && this.orientation === "horizontal" ) {
15106				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15107					width: ( 100 - valPercent ) + "%"
15108				}, o.animate );
15109			}
15110			if ( oRange === "min" && this.orientation === "vertical" ) {
15111				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15112					height: valPercent + "%"
15113				}, o.animate );
15114			}
15115			if ( oRange === "max" && this.orientation === "vertical" ) {
15116				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15117					height: ( 100 - valPercent ) + "%"
15118				}, o.animate );
15119			}
15120		}
15121	},
15122
15123	_handleEvents: {
15124		keydown: function( event ) {
15125			var allowed, curVal, newVal, step,
15126				index = $( event.target ).data( "ui-slider-handle-index" );
15127
15128			switch ( event.keyCode ) {
15129				case $.ui.keyCode.HOME:
15130				case $.ui.keyCode.END:
15131				case $.ui.keyCode.PAGE_UP:
15132				case $.ui.keyCode.PAGE_DOWN:
15133				case $.ui.keyCode.UP:
15134				case $.ui.keyCode.RIGHT:
15135				case $.ui.keyCode.DOWN:
15136				case $.ui.keyCode.LEFT:
15137					event.preventDefault();
15138					if ( !this._keySliding ) {
15139						this._keySliding = true;
15140						this._addClass( $( event.target ), null, "ui-state-active" );
15141						allowed = this._start( event, index );
15142						if ( allowed === false ) {
15143							return;
15144						}
15145					}
15146					break;
15147			}
15148
15149			step = this.options.step;
15150			if ( this._hasMultipleValues() ) {
15151				curVal = newVal = this.values( index );
15152			} else {
15153				curVal = newVal = this.value();
15154			}
15155
15156			switch ( event.keyCode ) {
15157				case $.ui.keyCode.HOME:
15158					newVal = this._valueMin();
15159					break;
15160				case $.ui.keyCode.END:
15161					newVal = this._valueMax();
15162					break;
15163				case $.ui.keyCode.PAGE_UP:
15164					newVal = this._trimAlignValue(
15165						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15166					);
15167					break;
15168				case $.ui.keyCode.PAGE_DOWN:
15169					newVal = this._trimAlignValue(
15170						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15171					break;
15172				case $.ui.keyCode.UP:
15173				case $.ui.keyCode.RIGHT:
15174					if ( curVal === this._valueMax() ) {
15175						return;
15176					}
15177					newVal = this._trimAlignValue( curVal + step );
15178					break;
15179				case $.ui.keyCode.DOWN:
15180				case $.ui.keyCode.LEFT:
15181					if ( curVal === this._valueMin() ) {
15182						return;
15183					}
15184					newVal = this._trimAlignValue( curVal - step );
15185					break;
15186			}
15187
15188			this._slide( event, index, newVal );
15189		},
15190		keyup: function( event ) {
15191			var index = $( event.target ).data( "ui-slider-handle-index" );
15192
15193			if ( this._keySliding ) {
15194				this._keySliding = false;
15195				this._stop( event, index );
15196				this._change( event, index );
15197				this._removeClass( $( event.target ), null, "ui-state-active" );
15198			}
15199		}
15200	}
15201} );
15202
15203
vendor: 3,521 bytes, lines 15204-15362
15204/*!
15205 * jQuery UI Sortable 1.12.1
15206 * http://jqueryui.com
15207 *
15208 * Copyright jQuery Foundation and other contributors
15209 * Released under the MIT license.
15210 * http://jquery.org/license
15211 */
15212
15213//>>label: Sortable
15214//>>group: Interactions
15215//>>description: Enables items in a list to be sorted using the mouse.
15216//>>docs: http://api.jqueryui.com/sortable/
15217//>>demos: http://jqueryui.com/sortable/
15218//>>css.structure: ../../themes/base/sortable.css
15219
15220
15221
15222var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15223	version: "1.12.1",
15224	widgetEventPrefix: "sort",
15225	ready: false,
15226	options: {
15227		appendTo: "parent",
15228		axis: false,
15229		connectWith: false,
15230		containment: false,
15231		cursor: "auto",
15232		cursorAt: false,
15233		dropOnEmpty: true,
15234		forcePlaceholderSize: false,
15235		forceHelperSize: false,
15236		grid: false,
15237		handle: false,
15238		helper: "original",
15239		items: "> *",
15240		opacity: false,
15241		placeholder: false,
15242		revert: false,
15243		scroll: true,
15244		scrollSensitivity: 20,
15245		scrollSpeed: 20,
15246		scope: "default",
15247		tolerance: "intersect",
15248		zIndex: 1000,
15249
15250		// Callbacks
15251		activate: null,
15252		beforeStop: null,
15253		change: null,
15254		deactivate: null,
15255		out: null,
15256		over: null,
15257		receive: null,
15258		remove: null,
15259		sort: null,
15260		start: null,
15261		stop: null,
15262		update: null
15263	},
15264
15265	_isOverAxis: function( x, reference, size ) {
15266		return ( x >= reference ) && ( x < ( reference + size ) );
15267	},
15268
15269	_isFloating: function( item ) {
15270		return ( /left|right/ ).test( item.css( "float" ) ) ||
15271			( /inline|table-cell/ ).test( item.css( "display" ) );
15272	},
15273
15274	_create: function() {
15275		this.containerCache = {};
15276		this._addClass( "ui-sortable" );
15277
15278		//Get the items
15279		this.refresh();
15280
15281		//Let's determine the parent's offset
15282		this.offset = this.element.offset();
15283
15284		//Initialize mouse events for interaction
15285		this._mouseInit();
15286
15287		this._setHandleClassName();
15288
15289		//We're ready to go
15290		this.ready = true;
15291
15292	},
15293
15294	_setOption: function( key, value ) {
15295		this._super( key, value );
15296
15297		if ( key === "handle" ) {
15298			this._setHandleClassName();
15299		}
15300	},
15301
15302	_setHandleClassName: function() {
15303		var that = this;
15304		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15305		$.each( this.items, function() {
15306			that._addClass(
15307				this.instance.options.handle ?
15308					this.item.find( this.instance.options.handle ) :
15309					this.item,
15310				"ui-sortable-handle"
15311			);
15312		} );
15313	},
15314
15315	_destroy: function() {
15316		this._mouseDestroy();
15317
15318		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15319			this.items[ i ].item.removeData( this.widgetName + "-item" );
15320		}
15321
15322		return this;
15323	},
15324
15325	_mouseCapture: function( event, overrideHandle ) {
15326		var currentItem = null,
15327			validHandle = false,
15328			that = this;
15329
15330		if ( this.reverting ) {
15331			return false;
15332		}
15333
15334		if ( this.options.disabled || this.options.type === "static" ) {
15335			return false;
15336		}
15337
15338		//We have to refresh the items data once first
15339		this._refreshItems( event );
15340
15341		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15342		$( event.target ).parents().each( function() {
15343			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15344				currentItem = $( this );
15345				return false;
15346			}
15347		} );
15348		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15349			currentItem = $( event.target );
15350		}
15351
15352		if ( !currentItem ) {
15353			return false;
15354		}
15355		if ( this.options.handle && !overrideHandle ) {
15356			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15357				if ( this === event.target ) {
15358					validHandle = true;
15359				}
15360			} );
15361			if ( !validHandle ) {
15362				return false;
vendor: 8,227 bytes, lines 15363-15628
15363			}
15364		}
15365
15366		this.currentItem = currentItem;
15367		this._removeCurrentsFromItems();
15368		return true;
15369
15370	},
15371
15372	_mouseStart: function( event, overrideHandle, noActivation ) {
15373
15374		var i, body,
15375			o = this.options;
15376
15377		this.currentContainer = this;
15378
15379		//We only need to call refreshPositions, because the refreshItems call has been moved to
15380		// mouseCapture
15381		this.refreshPositions();
15382
15383		//Create and append the visible helper
15384		this.helper = this._createHelper( event );
15385
15386		//Cache the helper size
15387		this._cacheHelperProportions();
15388
15389		/*
15390		 * - Position generation -
15391		 * This block generates everything position related - it's the core of draggables.
15392		 */
15393
15394		//Cache the margins of the original element
15395		this._cacheMargins();
15396
15397		//Get the next scrolling parent
15398		this.scrollParent = this.helper.scrollParent();
15399
15400		//The element's absolute position on the page minus margins
15401		this.offset = this.currentItem.offset();
15402		this.offset = {
15403			top: this.offset.top - this.margins.top,
15404			left: this.offset.left - this.margins.left
15405		};
15406
15407		$.extend( this.offset, {
15408			click: { //Where the click happened, relative to the element
15409				left: event.pageX - this.offset.left,
15410				top: event.pageY - this.offset.top
15411			},
15412			parent: this._getParentOffset(),
15413
15414			// This is a relative to absolute position minus the actual position calculation -
15415			// only used for relative positioned helper
15416			relative: this._getRelativeOffset()
15417		} );
15418
15419		// Only after we got the offset, we can change the helper's position to absolute
15420		// TODO: Still need to figure out a way to make relative sorting possible
15421		this.helper.css( "position", "absolute" );
15422		this.cssPosition = this.helper.css( "position" );
15423
15424		//Generate the original position
15425		this.originalPosition = this._generatePosition( event );
15426		this.originalPageX = event.pageX;
15427		this.originalPageY = event.pageY;
15428
15429		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15430		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
15431
15432		//Cache the former DOM position
15433		this.domPosition = {
15434			prev: this.currentItem.prev()[ 0 ],
15435			parent: this.currentItem.parent()[ 0 ]
15436		};
15437
15438		// If the helper is not the original, hide the original so it's not playing any role during
15439		// the drag, won't cause anything bad this way
15440		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15441			this.currentItem.hide();
15442		}
15443
15444		//Create the placeholder
15445		this._createPlaceholder();
15446
15447		//Set a containment if given in the options
15448		if ( o.containment ) {
15449			this._setContainment();
15450		}
15451
15452		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15453			body = this.document.find( "body" );
15454
15455			// Support: IE
15456			this.storedCursor = body.css( "cursor" );
15457			body.css( "cursor", o.cursor );
15458
15459			this.storedStylesheet =
15460				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15461		}
15462
15463		if ( o.opacity ) { // opacity option
15464			if ( this.helper.css( "opacity" ) ) {
15465				this._storedOpacity = this.helper.css( "opacity" );
15466			}
15467			this.helper.css( "opacity", o.opacity );
15468		}
15469
15470		if ( o.zIndex ) { // zIndex option
15471			if ( this.helper.css( "zIndex" ) ) {
15472				this._storedZIndex = this.helper.css( "zIndex" );
15473			}
15474			this.helper.css( "zIndex", o.zIndex );
15475		}
15476
15477		//Prepare scrolling
15478		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15479				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15480			this.overflowOffset = this.scrollParent.offset();
15481		}
15482
15483		//Call callbacks
15484		this._trigger( "start", event, this._uiHash() );
15485
15486		//Recache the helper size
15487		if ( !this._preserveHelperProportions ) {
15488			this._cacheHelperProportions();
15489		}
15490
15491		//Post "activate" events to possible containers
15492		if ( !noActivation ) {
15493			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15494				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15495			}
15496		}
15497
15498		//Prepare possible droppables
15499		if ( $.ui.ddmanager ) {
15500			$.ui.ddmanager.current = this;
15501		}
15502
15503		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15504			$.ui.ddmanager.prepareOffsets( this, event );
15505		}
15506
15507		this.dragging = true;
15508
15509		this._addClass( this.helper, "ui-sortable-helper" );
15510
15511		// Execute the drag once - this causes the helper not to be visiblebefore getting its
15512		// correct position
15513		this._mouseDrag( event );
15514		return true;
15515
15516	},
15517
15518	_mouseDrag: function( event ) {
15519		var i, item, itemElement, intersection,
15520			o = this.options,
15521			scrolled = false;
15522
15523		//Compute the helpers position
15524		this.position = this._generatePosition( event );
15525		this.positionAbs = this._convertPositionTo( "absolute" );
15526
15527		if ( !this.lastPositionAbs ) {
15528			this.lastPositionAbs = this.positionAbs;
15529		}
15530
15531		//Do scrolling
15532		if ( this.options.scroll ) {
15533			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15534					this.scrollParent[ 0 ].tagName !== "HTML" ) {
15535
15536				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15537						event.pageY < o.scrollSensitivity ) {
15538					this.scrollParent[ 0 ].scrollTop =
15539						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15540				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15541					this.scrollParent[ 0 ].scrollTop =
15542						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15543				}
15544
15545				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15546						event.pageX < o.scrollSensitivity ) {
15547					this.scrollParent[ 0 ].scrollLeft = scrolled =
15548						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15549				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15550					this.scrollParent[ 0 ].scrollLeft = scrolled =
15551						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15552				}
15553
15554			} else {
15555
15556				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15557					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15558				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15559						o.scrollSensitivity ) {
15560					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15561				}
15562
15563				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15564					scrolled = this.document.scrollLeft(
15565						this.document.scrollLeft() - o.scrollSpeed
15566					);
15567				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15568						o.scrollSensitivity ) {
15569					scrolled = this.document.scrollLeft(
15570						this.document.scrollLeft() + o.scrollSpeed
15571					);
15572				}
15573
15574			}
15575
15576			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
15577				$.ui.ddmanager.prepareOffsets( this, event );
15578			}
15579		}
15580
15581		//Regenerate the absolute position used for position checks
15582		this.positionAbs = this._convertPositionTo( "absolute" );
15583
15584		//Set the helper position
15585		if ( !this.options.axis || this.options.axis !== "y" ) {
15586			this.helper[ 0 ].style.left = this.position.left + "px";
15587		}
15588		if ( !this.options.axis || this.options.axis !== "x" ) {
15589			this.helper[ 0 ].style.top = this.position.top + "px";
15590		}
15591
15592		//Rearrange
15593		for ( i = this.items.length - 1; i >= 0; i-- ) {
15594
15595			//Cache variables and intersection, continue if no intersection
15596			item = this.items[ i ];
15597			itemElement = item.item[ 0 ];
15598			intersection = this._intersectsWithPointer( item );
15599			if ( !intersection ) {
15600				continue;
15601			}
15602
15603			// Only put the placeholder inside the current Container, skip all
15604			// items from other containers. This works because when moving
15605			// an item from one container to another the
15606			// currentContainer is switched before the placeholder is moved.
15607			//
15608			// Without this, moving items in "sub-sortables" can cause
15609			// the placeholder to jitter between the outer and inner container.
15610			if ( item.instance !== this.currentContainer ) {
15611				continue;
15612			}
15613
15614			// Cannot intersect with itself
15615			// no useless actions that have been done before
15616			// no action if the item moved is the parent of the item checked
15617			if ( itemElement !== this.currentItem[ 0 ] &&
15618				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
15619				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15620				( this.options.type === "semi-dynamic" ?
15621					!$.contains( this.element[ 0 ], itemElement ) :
15622					true
15623				)
15624			) {
15625
15626				this.direction = intersection === 1 ? "down" : "up";
15627
15628				if ( this.options.tolerance === "pointer" || 
vendor: 5,576 bytes, lines 15628-15844
15628this._intersectsWithSides( item ) ) {
15629					this._rearrange( event, item );
15630				} else {
15631					break;
15632				}
15633
15634				this._trigger( "change", event, this._uiHash() );
15635				break;
15636			}
15637		}
15638
15639		//Post events to containers
15640		this._contactContainers( event );
15641
15642		//Interconnect with droppables
15643		if ( $.ui.ddmanager ) {
15644			$.ui.ddmanager.drag( this, event );
15645		}
15646
15647		//Call callbacks
15648		this._trigger( "sort", event, this._uiHash() );
15649
15650		this.lastPositionAbs = this.positionAbs;
15651		return false;
15652
15653	},
15654
15655	_mouseStop: function( event, noPropagation ) {
15656
15657		if ( !event ) {
15658			return;
15659		}
15660
15661		//If we are using droppables, inform the manager about the drop
15662		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15663			$.ui.ddmanager.drop( this, event );
15664		}
15665
15666		if ( this.options.revert ) {
15667			var that = this,
15668				cur = this.placeholder.offset(),
15669				axis = this.options.axis,
15670				animation = {};
15671
15672			if ( !axis || axis === "x" ) {
15673				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15674					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15675						0 :
15676						this.offsetParent[ 0 ].scrollLeft
15677					);
15678			}
15679			if ( !axis || axis === "y" ) {
15680				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15681					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15682						0 :
15683						this.offsetParent[ 0 ].scrollTop
15684					);
15685			}
15686			this.reverting = true;
15687			$( this.helper ).animate(
15688				animation,
15689				parseInt( this.options.revert, 10 ) || 500,
15690				function() {
15691					that._clear( event );
15692				}
15693			);
15694		} else {
15695			this._clear( event, noPropagation );
15696		}
15697
15698		return false;
15699
15700	},
15701
15702	cancel: function() {
15703
15704		if ( this.dragging ) {
15705
15706			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15707
15708			if ( this.options.helper === "original" ) {
15709				this.currentItem.css( this._storedCSS );
15710				this._removeClass( this.currentItem, "ui-sortable-helper" );
15711			} else {
15712				this.currentItem.show();
15713			}
15714
15715			//Post deactivating events to containers
15716			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15717				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15718				if ( this.containers[ i ].containerCache.over ) {
15719					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15720					this.containers[ i ].containerCache.over = 0;
15721				}
15722			}
15723
15724		}
15725
15726		if ( this.placeholder ) {
15727
15728			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15729			// it unbinds ALL events from the original node!
15730			if ( this.placeholder[ 0 ].parentNode ) {
15731				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15732			}
15733			if ( this.options.helper !== "original" && this.helper &&
15734					this.helper[ 0 ].parentNode ) {
15735				this.helper.remove();
15736			}
15737
15738			$.extend( this, {
15739				helper: null,
15740				dragging: false,
15741				reverting: false,
15742				_noFinalSort: null
15743			} );
15744
15745			if ( this.domPosition.prev ) {
15746				$( this.domPosition.prev ).after( this.currentItem );
15747			} else {
15748				$( this.domPosition.parent ).prepend( this.currentItem );
15749			}
15750		}
15751
15752		return this;
15753
15754	},
15755
15756	serialize: function( o ) {
15757
15758		var items = this._getItemsAsjQuery( o && o.connected ),
15759			str = [];
15760		o = o || {};
15761
15762		$( items ).each( function() {
15763			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15764				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15765			if ( res ) {
15766				str.push(
15767					( o.key || res[ 1 ] + "[]" ) +
15768					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15769			}
15770		} );
15771
15772		if ( !str.length && o.key ) {
15773			str.push( o.key + "=" );
15774		}
15775
15776		return str.join( "&" );
15777
15778	},
15779
15780	toArray: function( o ) {
15781
15782		var items = this._getItemsAsjQuery( o && o.connected ),
15783			ret = [];
15784
15785		o = o || {};
15786
15787		items.each( function() {
15788			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15789		} );
15790		return ret;
15791
15792	},
15793
15794	/* Be careful with the following core functions */
15795	_intersectsWith: function( item ) {
15796
15797		var x1 = this.positionAbs.left,
15798			x2 = x1 + this.helperProportions.width,
15799			y1 = this.positionAbs.top,
15800			y2 = y1 + this.helperProportions.height,
15801			l = item.left,
15802			r = l + item.width,
15803			t = item.top,
15804			b = t + item.height,
15805			dyClick = this.offset.click.top,
15806			dxClick = this.offset.click.left,
15807			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15808				( y1 + dyClick ) < b ),
15809			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15810				( x1 + dxClick ) < r ),
15811			isOverElement = isOverElementHeight && isOverElementWidth;
15812
15813		if ( this.options.tolerance === "pointer" ||
15814			this.options.forcePointerForContainers ||
15815			( this.options.tolerance !== "pointer" &&
15816				this.helperProportions[ this.floating ? "width" : "height" ] >
15817				item[ this.floating ? "width" : "height" ] )
15818		) {
15819			return isOverElement;
15820		} else {
15821
15822			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15823				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15824				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15825				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15826
15827		}
15828	},
15829
15830	_intersectsWithPointer: function( item ) {
15831		var verticalDirection, horizontalDirection,
15832			isOverElementHeight = ( this.options.axis === "x" ) ||
15833				this._isOverAxis(
15834					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15835			isOverElementWidth = ( this.options.axis === "y" ) ||
15836				this._isOverAxis(
15837					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15838			isOverElement = isOverElementHeight && isOverElementWidth;
15839
15840		if ( !isOverElement ) {
15841			return false;
15842		}
15843
15844		verticalDirection = this.
vendor: 13,806 bytes, lines 15844-16291
15844_getDragVerticalDirection();
15845		horizontalDirection = this._getDragHorizontalDirection();
15846
15847		return this.floating ?
15848			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
15849			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15850
15851	},
15852
15853	_intersectsWithSides: function( item ) {
15854
15855		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15856				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15857			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15858				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15859			verticalDirection = this._getDragVerticalDirection(),
15860			horizontalDirection = this._getDragHorizontalDirection();
15861
15862		if ( this.floating && horizontalDirection ) {
15863			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15864				( horizontalDirection === "left" && !isOverRightHalf ) );
15865		} else {
15866			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
15867				( verticalDirection === "up" && !isOverBottomHalf ) );
15868		}
15869
15870	},
15871
15872	_getDragVerticalDirection: function() {
15873		var delta = this.positionAbs.top - this.lastPositionAbs.top;
15874		return delta !== 0 && ( delta > 0 ? "down" : "up" );
15875	},
15876
15877	_getDragHorizontalDirection: function() {
15878		var delta = this.positionAbs.left - this.lastPositionAbs.left;
15879		return delta !== 0 && ( delta > 0 ? "right" : "left" );
15880	},
15881
15882	refresh: function( event ) {
15883		this._refreshItems( event );
15884		this._setHandleClassName();
15885		this.refreshPositions();
15886		return this;
15887	},
15888
15889	_connectWith: function() {
15890		var options = this.options;
15891		return options.connectWith.constructor === String ?
15892			[ options.connectWith ] :
15893			options.connectWith;
15894	},
15895
15896	_getItemsAsjQuery: function( connected ) {
15897
15898		var i, j, cur, inst,
15899			items = [],
15900			queries = [],
15901			connectWith = this._connectWith();
15902
15903		if ( connectWith && connected ) {
15904			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15905				cur = $( connectWith[ i ], this.document[ 0 ] );
15906				for ( j = cur.length - 1; j >= 0; j-- ) {
15907					inst = $.data( cur[ j ], this.widgetFullName );
15908					if ( inst && inst !== this && !inst.options.disabled ) {
15909						queries.push( [ $.isFunction( inst.options.items ) ?
15910							inst.options.items.call( inst.element ) :
15911							$( inst.options.items, inst.element )
15912								.not( ".ui-sortable-helper" )
15913								.not( ".ui-sortable-placeholder" ), inst ] );
15914					}
15915				}
15916			}
15917		}
15918
15919		queries.push( [ $.isFunction( this.options.items ) ?
15920			this.options.items
15921				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
15922			$( this.options.items, this.element )
15923				.not( ".ui-sortable-helper" )
15924				.not( ".ui-sortable-placeholder" ), this ] );
15925
15926		function addItems() {
15927			items.push( this );
15928		}
15929		for ( i = queries.length - 1; i >= 0; i-- ) {
15930			queries[ i ][ 0 ].each( addItems );
15931		}
15932
15933		return $( items );
15934
15935	},
15936
15937	_removeCurrentsFromItems: function() {
15938
15939		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
15940
15941		this.items = $.grep( this.items, function( item ) {
15942			for ( var j = 0; j < list.length; j++ ) {
15943				if ( list[ j ] === item.item[ 0 ] ) {
15944					return false;
15945				}
15946			}
15947			return true;
15948		} );
15949
15950	},
15951
15952	_refreshItems: function( event ) {
15953
15954		this.items = [];
15955		this.containers = [ this ];
15956
15957		var i, j, cur, inst, targetData, _queries, item, queriesLength,
15958			items = this.items,
15959			queries = [ [ $.isFunction( this.options.items ) ?
15960				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
15961				$( this.options.items, this.element ), this ] ],
15962			connectWith = this._connectWith();
15963
15964		//Shouldn't be run the first time through due to massive slow-down
15965		if ( connectWith && this.ready ) {
15966			for ( i = connectWith.length - 1; i >= 0; i-- ) {
15967				cur = $( connectWith[ i ], this.document[ 0 ] );
15968				for ( j = cur.length - 1; j >= 0; j-- ) {
15969					inst = $.data( cur[ j ], this.widgetFullName );
15970					if ( inst && inst !== this && !inst.options.disabled ) {
15971						queries.push( [ $.isFunction( inst.options.items ) ?
15972							inst.options.items
15973								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
15974							$( inst.options.items, inst.element ), inst ] );
15975						this.containers.push( inst );
15976					}
15977				}
15978			}
15979		}
15980
15981		for ( i = queries.length - 1; i >= 0; i-- ) {
15982			targetData = queries[ i ][ 1 ];
15983			_queries = queries[ i ][ 0 ];
15984
15985			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
15986				item = $( _queries[ j ] );
15987
15988				// Data for target checking (mouse manager)
15989				item.data( this.widgetName + "-item", targetData );
15990
15991				items.push( {
15992					item: item,
15993					instance: targetData,
15994					width: 0, height: 0,
15995					left: 0, top: 0
15996				} );
15997			}
15998		}
15999
16000	},
16001
16002	refreshPositions: function( fast ) {
16003
16004		// Determine whether items are being displayed horizontally
16005		this.floating = this.items.length ?
16006			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16007			false;
16008
16009		//This has to be redone because due to the item being moved out/into the offsetParent,
16010		// the offsetParent's position will change
16011		if ( this.offsetParent && this.helper ) {
16012			this.offset.parent = this._getParentOffset();
16013		}
16014
16015		var i, item, t, p;
16016
16017		for ( i = this.items.length - 1; i >= 0; i-- ) {
16018			item = this.items[ i ];
16019
16020			//We ignore calculating positions of all connected containers when we're not over them
16021			if ( item.instance !== this.currentContainer && this.currentContainer &&
16022					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16023				continue;
16024			}
16025
16026			t = this.options.toleranceElement ?
16027				$( this.options.toleranceElement, item.item ) :
16028				item.item;
16029
16030			if ( !fast ) {
16031				item.width = t.outerWidth();
16032				item.height = t.outerHeight();
16033			}
16034
16035			p = t.offset();
16036			item.left = p.left;
16037			item.top = p.top;
16038		}
16039
16040		if ( this.options.custom && this.options.custom.refreshContainers ) {
16041			this.options.custom.refreshContainers.call( this );
16042		} else {
16043			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16044				p = this.containers[ i ].element.offset();
16045				this.containers[ i ].containerCache.left = p.left;
16046				this.containers[ i ].containerCache.top = p.top;
16047				this.containers[ i ].containerCache.width =
16048					this.containers[ i ].element.outerWidth();
16049				this.containers[ i ].containerCache.height =
16050					this.containers[ i ].element.outerHeight();
16051			}
16052		}
16053
16054		return this;
16055	},
16056
16057	_createPlaceholder: function( that ) {
16058		that = that || this;
16059		var className,
16060			o = that.options;
16061
16062		if ( !o.placeholder || o.placeholder.constructor === String ) {
16063			className = o.placeholder;
16064			o.placeholder = {
16065				element: function() {
16066
16067					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
16068						element = $( "<" + nodeName + ">", that.document[ 0 ] );
16069
16070						that._addClass( element, "ui-sortable-placeholder",
16071								className || that.currentItem[ 0 ].className )
16072							._removeClass( element, "ui-sortable-helper" );
16073
16074					if ( nodeName === "tbody" ) {
16075						that._createTrPlaceholder(
16076							that.currentItem.find( "tr" ).eq( 0 ),
16077							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16078						);
16079					} else if ( nodeName === "tr" ) {
16080						that._createTrPlaceholder( that.currentItem, element );
16081					} else if ( nodeName === "img" ) {
16082						element.attr( "src", that.currentItem.attr( "src" ) );
16083					}
16084
16085					if ( !className ) {
16086						element.css( "visibility", "hidden" );
16087					}
16088
16089					return element;
16090				},
16091				update: function( container, p ) {
16092
16093					// 1. If a className is set as 'placeholder option, we don't force sizes -
16094					// the class is responsible for that
16095					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16096					// class name is specified
16097					if ( className && !o.forcePlaceholderSize ) {
16098						return;
16099					}
16100
16101					//If the element doesn't have a actual height by itself (without styles coming
16102					// from a stylesheet), it receives the inline height from the dragged item
16103					if ( !p.height() ) {
16104						p.height(
16105							that.currentItem.innerHeight() -
16106							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16107							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16108					}
16109					if ( !p.width() ) {
16110						p.width(
16111							that.currentItem.innerWidth() -
16112							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16113							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16114					}
16115				}
16116			};
16117		}
16118
16119		//Create the placeholder
16120		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16121
16122		//Append it after the actual current item
16123		that.currentItem.after( that.placeholder );
16124
16125		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16126		o.placeholder.update( that, that.placeholder );
16127
16128	},
16129
16130	_createTrPlaceholder: function( sourceTr, targetTr ) {
16131		var that = this;
16132
16133		sourceTr.children().each( function() {
16134			$( "<td>&#160;</td>", that.document[ 0 ] )
16135				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16136				.appendTo( targetTr );
16137		} );
16138	},
16139
16140	_contactContainers: function( event ) {
16141		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16142			floating, axis,
16143			innermostContainer = null,
16144			innermostIndex = null;
16145
16146		// Get innermost container that intersects with item
16147		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16148
16149			// Never consider a container that's located within the item itself
16150			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16151				continue;
16152			}
16153
16154			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16155
16156				// If we've already found a container and it's more "inner" than this, then continue
16157				if ( innermostContainer &&
16158						$.contains(
16159							this.containers[ i ].element[ 0 ],
16160							innermostContainer.element[ 0 ] ) ) {
16161					continue;
16162				}
16163
16164				innermostContainer = this.containers[ i ];
16165				innermostIndex = i;
16166
16167			} else {
16168
16169				// container doesn't intersect. trigger "out" event if necessary
16170				if ( this.containers[ i ].containerCache.over ) {
16171					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16172					this.containers[ i ].containerCache.over = 0;
16173				}
16174			}
16175
16176		}
16177
16178		// If no intersecting containers found, return
16179		if ( !innermostContainer ) {
16180			return;
16181		}
16182
16183		// Move the item into the container if it's not there already
16184		if ( this.containers.length === 1 ) {
16185			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16186				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16187				this.containers[ innermostIndex ].containerCache.over = 1;
16188			}
16189		} else {
16190
16191			// When entering a new container, we will find the item with the least distance and
16192			// append our item near it
16193			dist = 10000;
16194			itemWithLeastDistance = null;
16195			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16196			posProperty = floating ? "left" : "top";
16197			sizeProperty = floating ? "width" : "height";
16198			axis = floating ? "pageX" : "pageY";
16199
16200			for ( j = this.items.length - 1; j >= 0; j-- ) {
16201				if ( !$.contains(
16202						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16203				) {
16204					continue;
16205				}
16206				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16207					continue;
16208				}
16209
16210				cur = this.items[ j ].item.offset()[ posProperty ];
16211				nearBottom = false;
16212				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16213					nearBottom = true;
16214				}
16215
16216				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16217					dist = Math.abs( event[ axis ] - cur );
16218					itemWithLeastDistance = this.items[ j ];
16219					this.direction = nearBottom ? "up" : "down";
16220				}
16221			}
16222
16223			//Check if dropOnEmpty is enabled
16224			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16225				return;
16226			}
16227
16228			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16229				if ( !this.currentContainer.containerCache.over ) {
16230					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16231					this.currentContainer.containerCache.over = 1;
16232				}
16233				return;
16234			}
16235
16236			itemWithLeastDistance ?
16237				this._rearrange( event, itemWithLeastDistance, null, true ) :
16238				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16239			this._trigger( "change", event, this._uiHash() );
16240			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16241			this.currentContainer = this.containers[ innermostIndex ];
16242
16243			//Update the placeholder
16244			this.options.placeholder.update( this.currentContainer, this.placeholder );
16245
16246			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16247			this.containers[ innermostIndex ].containerCache.over = 1;
16248		}
16249
16250	},
16251
16252	_createHelper: function( event ) {
16253
16254		var o = this.options,
16255			helper = $.isFunction( o.helper ) ?
16256				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16257				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16258
16259		//Add the helper to the DOM if that didn't happen already
16260		if ( !helper.parents( "body" ).length ) {
16261			$( o.appendTo !== "parent" ?
16262				o.appendTo :
16263				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
16264		}
16265
16266		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16267			this._storedCSS = {
16268				width: this.currentItem[ 0 ].style.width,
16269				height: this.currentItem[ 0 ].style.height,
16270				position: this.currentItem.css( "position" ),
16271				top: this.currentItem.css( "top" ),
16272				left: this.currentItem.css( "left" )
16273			};
16274		}
16275
16276		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16277			helper.width( this.currentItem.width() );
16278		}
16279		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16280			helper.height( this.currentItem.height() );
16281		}
16282
16283		return helper;
16284
16285	},
16286
16287	_adjustOffsetFromHelper: function( obj ) {
16288		if ( typeof obj === "string" ) {
16289			obj = obj.split( " " );
16290		}
16291		if ( $
vendor: 9,476 bytes, lines 16291-16571
16291.isArray( obj ) ) {
16292			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16293		}
16294		if ( "left" in obj ) {
16295			this.offset.click.left = obj.left + this.margins.left;
16296		}
16297		if ( "right" in obj ) {
16298			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16299		}
16300		if ( "top" in obj ) {
16301			this.offset.click.top = obj.top + this.margins.top;
16302		}
16303		if ( "bottom" in obj ) {
16304			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16305		}
16306	},
16307
16308	_getParentOffset: function() {
16309
16310		//Get the offsetParent and cache its position
16311		this.offsetParent = this.helper.offsetParent();
16312		var po = this.offsetParent.offset();
16313
16314		// This is a special case where we need to modify a offset calculated on start, since the
16315		// following happened:
16316		// 1. The position of the helper is absolute, so it's position is calculated based on the
16317		// next positioned parent
16318		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16319		// the document, which means that the scroll is included in the initial calculation of the
16320		// offset of the parent, and never recalculated upon drag
16321		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16322				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16323			po.left += this.scrollParent.scrollLeft();
16324			po.top += this.scrollParent.scrollTop();
16325		}
16326
16327		// This needs to be actually done for all browsers, since pageX/pageY includes this
16328		// information with an ugly IE fix
16329		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
16330				( this.offsetParent[ 0 ].tagName &&
16331				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
16332			po = { top: 0, left: 0 };
16333		}
16334
16335		return {
16336			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16337			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16338		};
16339
16340	},
16341
16342	_getRelativeOffset: function() {
16343
16344		if ( this.cssPosition === "relative" ) {
16345			var p = this.currentItem.position();
16346			return {
16347				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16348					this.scrollParent.scrollTop(),
16349				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16350					this.scrollParent.scrollLeft()
16351			};
16352		} else {
16353			return { top: 0, left: 0 };
16354		}
16355
16356	},
16357
16358	_cacheMargins: function() {
16359		this.margins = {
16360			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16361			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16362		};
16363	},
16364
16365	_cacheHelperProportions: function() {
16366		this.helperProportions = {
16367			width: this.helper.outerWidth(),
16368			height: this.helper.outerHeight()
16369		};
16370	},
16371
16372	_setContainment: function() {
16373
16374		var ce, co, over,
16375			o = this.options;
16376		if ( o.containment === "parent" ) {
16377			o.containment = this.helper[ 0 ].parentNode;
16378		}
16379		if ( o.containment === "document" || o.containment === "window" ) {
16380			this.containment = [
16381				0 - this.offset.relative.left - this.offset.parent.left,
16382				0 - this.offset.relative.top - this.offset.parent.top,
16383				o.containment === "document" ?
16384					this.document.width() :
16385					this.window.width() - this.helperProportions.width - this.margins.left,
16386				( o.containment === "document" ?
16387					( this.document.height() || document.body.parentNode.scrollHeight ) :
16388					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16389				) - this.helperProportions.height - this.margins.top
16390			];
16391		}
16392
16393		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16394			ce = $( o.containment )[ 0 ];
16395			co = $( o.containment ).offset();
16396			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16397
16398			this.containment = [
16399				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16400					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16401				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16402					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16403				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
16404					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16405					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16406					this.helperProportions.width - this.margins.left,
16407				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16408					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16409					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16410					this.helperProportions.height - this.margins.top
16411			];
16412		}
16413
16414	},
16415
16416	_convertPositionTo: function( d, pos ) {
16417
16418		if ( !pos ) {
16419			pos = this.position;
16420		}
16421		var mod = d === "absolute" ? 1 : -1,
16422			scroll = this.cssPosition === "absolute" &&
16423				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16424				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16425					this.offsetParent :
16426					this.scrollParent,
16427			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16428
16429		return {
16430			top: (
16431
16432				// The absolute mouse position
16433				pos.top	+
16434
16435				// Only for relative positioned nodes: Relative offset from element to offset parent
16436				this.offset.relative.top * mod +
16437
16438				// The offsetParent's offset without borders (offset + border)
16439				this.offset.parent.top * mod -
16440				( ( this.cssPosition === "fixed" ?
16441					-this.scrollParent.scrollTop() :
16442					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16443			),
16444			left: (
16445
16446				// The absolute mouse position
16447				pos.left +
16448
16449				// Only for relative positioned nodes: Relative offset from element to offset parent
16450				this.offset.relative.left * mod +
16451
16452				// The offsetParent's offset without borders (offset + border)
16453				this.offset.parent.left * mod	-
16454				( ( this.cssPosition === "fixed" ?
16455					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16456					scroll.scrollLeft() ) * mod )
16457			)
16458		};
16459
16460	},
16461
16462	_generatePosition: function( event ) {
16463
16464		var top, left,
16465			o = this.options,
16466			pageX = event.pageX,
16467			pageY = event.pageY,
16468			scroll = this.cssPosition === "absolute" &&
16469				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16470				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16471					this.offsetParent :
16472					this.scrollParent,
16473				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16474
16475		// This is another very weird special case that only happens for relative elements:
16476		// 1. If the css position is relative
16477		// 2. and the scroll parent is the document or similar to the offset parent
16478		// we have to refresh the relative offset during the scroll so there are no jumps
16479		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16480				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16481			this.offset.relative = this._getRelativeOffset();
16482		}
16483
16484		/*
16485		 * - Position constraining -
16486		 * Constrain the position to a mix of grid, containment.
16487		 */
16488
16489		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16490
16491			if ( this.containment ) {
16492				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16493					pageX = this.containment[ 0 ] + this.offset.click.left;
16494				}
16495				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16496					pageY = this.containment[ 1 ] + this.offset.click.top;
16497				}
16498				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16499					pageX = this.containment[ 2 ] + this.offset.click.left;
16500				}
16501				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16502					pageY = this.containment[ 3 ] + this.offset.click.top;
16503				}
16504			}
16505
16506			if ( o.grid ) {
16507				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16508					o.grid[ 1 ] ) * o.grid[ 1 ];
16509				pageY = this.containment ?
16510					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16511						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16512							top :
16513							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16514								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16515								top;
16516
16517				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16518					o.grid[ 0 ] ) * o.grid[ 0 ];
16519				pageX = this.containment ?
16520					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16521						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16522							left :
16523							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16524								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16525								left;
16526			}
16527
16528		}
16529
16530		return {
16531			top: (
16532
16533				// The absolute mouse position
16534				pageY -
16535
16536				// Click offset (relative to the element)
16537				this.offset.click.top -
16538
16539				// Only for relative positioned nodes: Relative offset from element to offset parent
16540				this.offset.relative.top -
16541
16542				// The offsetParent's offset without borders (offset + border)
16543				this.offset.parent.top +
16544				( ( this.cssPosition === "fixed" ?
16545					-this.scrollParent.scrollTop() :
16546					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16547			),
16548			left: (
16549
16550				// The absolute mouse position
16551				pageX -
16552
16553				// Click offset (relative to the element)
16554				this.offset.click.left -
16555
16556				// Only for relative positioned nodes: Relative offset from element to offset parent
16557				this.offset.relative.left -
16558
16559				// The offsetParent's offset without borders (offset + border)
16560				this.offset.parent.left +
16561				( ( this.cssPosition === "fixed" ?
16562					-this.scrollParent.scrollLeft() :
16563					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16564			)
16565		};
16566
16567	},
16568
16569	_rearrange: function( event, i, a, hardRefresh ) {
16570
16571		
16571a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
16572			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16573				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
vendor: 5,013 bytes, lines 16573-16741
16573
16574
16575		//Various things done here to improve the performance:
16576		// 1. we create a setTimeout, that calls refreshPositions
16577		// 2. on the instance, we have a counter variable, that get's higher after every append
16578		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16579		// if it's still the same
16580		// 4. this lets only the last addition to the timeout stack through
16581		this.counter = this.counter ? ++this.counter : 1;
16582		var counter = this.counter;
16583
16584		this._delay( function() {
16585			if ( counter === this.counter ) {
16586
16587				//Precompute after each DOM insertion, NOT on mousemove
16588				this.refreshPositions( !hardRefresh );
16589			}
16590		} );
16591
16592	},
16593
16594	_clear: function( event, noPropagation ) {
16595
16596		this.reverting = false;
16597
16598		// We delay all events that have to be triggered to after the point where the placeholder
16599		// has been removed and everything else normalized again
16600		var i,
16601			delayedTriggers = [];
16602
16603		// We first have to update the dom position of the actual currentItem
16604		// Note: don't do it if the current item is already removed (by a user), or it gets
16605		// reappended (see #4088)
16606		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16607			this.placeholder.before( this.currentItem );
16608		}
16609		this._noFinalSort = null;
16610
16611		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16612			for ( i in this._storedCSS ) {
16613				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16614					this._storedCSS[ i ] = "";
16615				}
16616			}
16617			this.currentItem.css( this._storedCSS );
16618			this._removeClass( this.currentItem, "ui-sortable-helper" );
16619		} else {
16620			this.currentItem.show();
16621		}
16622
16623		if ( this.fromOutside && !noPropagation ) {
16624			delayedTriggers.push( function( event ) {
16625				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16626			} );
16627		}
16628		if ( ( this.fromOutside ||
16629				this.domPosition.prev !==
16630				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16631				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16632
16633			// Trigger update callback if the DOM position has changed
16634			delayedTriggers.push( function( event ) {
16635				this._trigger( "update", event, this._uiHash() );
16636			} );
16637		}
16638
16639		// Check if the items Container has Changed and trigger appropriate
16640		// events.
16641		if ( this !== this.currentContainer ) {
16642			if ( !noPropagation ) {
16643				delayedTriggers.push( function( event ) {
16644					this._trigger( "remove", event, this._uiHash() );
16645				} );
16646				delayedTriggers.push( ( function( c ) {
16647					return function( event ) {
16648						c._trigger( "receive", event, this._uiHash( this ) );
16649					};
16650				} ).call( this, this.currentContainer ) );
16651				delayedTriggers.push( ( function( c ) {
16652					return function( event ) {
16653						c._trigger( "update", event, this._uiHash( this ) );
16654					};
16655				} ).call( this, this.currentContainer ) );
16656			}
16657		}
16658
16659		//Post events to containers
16660		function delayEvent( type, instance, container ) {
16661			return function( event ) {
16662				container._trigger( type, event, instance._uiHash( instance ) );
16663			};
16664		}
16665		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16666			if ( !noPropagation ) {
16667				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16668			}
16669			if ( this.containers[ i ].containerCache.over ) {
16670				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16671				this.containers[ i ].containerCache.over = 0;
16672			}
16673		}
16674
16675		//Do what was originally in plugins
16676		if ( this.storedCursor ) {
16677			this.document.find( "body" ).css( "cursor", this.storedCursor );
16678			this.storedStylesheet.remove();
16679		}
16680		if ( this._storedOpacity ) {
16681			this.helper.css( "opacity", this._storedOpacity );
16682		}
16683		if ( this._storedZIndex ) {
16684			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16685		}
16686
16687		this.dragging = false;
16688
16689		if ( !noPropagation ) {
16690			this._trigger( "beforeStop", event, this._uiHash() );
16691		}
16692
16693		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16694		// it unbinds ALL events from the original node!
16695		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16696
16697		if ( !this.cancelHelperRemoval ) {
16698			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16699				this.helper.remove();
16700			}
16701			this.helper = null;
16702		}
16703
16704		if ( !noPropagation ) {
16705			for ( i = 0; i < delayedTriggers.length; i++ ) {
16706
16707				// Trigger all delayed events
16708				delayedTriggers[ i ].call( this, event );
16709			}
16710			this._trigger( "stop", event, this._uiHash() );
16711		}
16712
16713		this.fromOutside = false;
16714		return !this.cancelHelperRemoval;
16715
16716	},
16717
16718	_trigger: function() {
16719		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16720			this.cancel();
16721		}
16722	},
16723
16724	_uiHash: function( _inst ) {
16725		var inst = _inst || this;
16726		return {
16727			helper: inst.helper,
16728			placeholder: inst.placeholder || $( [] ),
16729			position: inst.position,
16730			originalPosition: inst.originalPosition,
16731			offset: inst.positionAbs,
16732			item: inst.currentItem,
16733			sender: _inst ? _inst.element : null
16734		};
16735	}
16736
16737} );
16738
16739
16740/*!
16741 * jQuery UI Spinner 1.1
vendor: 26,644 bytes, lines 16741-17785
167412.1
16742 * http://jqueryui.com
16743 *
16744 * Copyright jQuery Foundation and other contributors
16745 * Released under the MIT license.
16746 * http://jquery.org/license
16747 */
16748
16749//>>label: Spinner
16750//>>group: Widgets
16751//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16752//>>docs: http://api.jqueryui.com/spinner/
16753//>>demos: http://jqueryui.com/spinner/
16754//>>css.structure: ../../themes/base/core.css
16755//>>css.structure: ../../themes/base/spinner.css
16756//>>css.theme: ../../themes/base/theme.css
16757
16758
16759
16760function spinnerModifer( fn ) {
16761	return function() {
16762		var previous = this.element.val();
16763		fn.apply( this, arguments );
16764		this._refresh();
16765		if ( previous !== this.element.val() ) {
16766			this._trigger( "change" );
16767		}
16768	};
16769}
16770
16771$.widget( "ui.spinner", {
16772	version: "1.12.1",
16773	defaultElement: "<input>",
16774	widgetEventPrefix: "spin",
16775	options: {
16776		classes: {
16777			"ui-spinner": "ui-corner-all",
16778			"ui-spinner-down": "ui-corner-br",
16779			"ui-spinner-up": "ui-corner-tr"
16780		},
16781		culture: null,
16782		icons: {
16783			down: "ui-icon-triangle-1-s",
16784			up: "ui-icon-triangle-1-n"
16785		},
16786		incremental: true,
16787		max: null,
16788		min: null,
16789		numberFormat: null,
16790		page: 10,
16791		step: 1,
16792
16793		change: null,
16794		spin: null,
16795		start: null,
16796		stop: null
16797	},
16798
16799	_create: function() {
16800
16801		// handle string values that need to be parsed
16802		this._setOption( "max", this.options.max );
16803		this._setOption( "min", this.options.min );
16804		this._setOption( "step", this.options.step );
16805
16806		// Only format if there is a value, prevents the field from being marked
16807		// as invalid in Firefox, see #9573.
16808		if ( this.value() !== "" ) {
16809
16810			// Format the value, but don't constrain.
16811			this._value( this.element.val(), true );
16812		}
16813
16814		this._draw();
16815		this._on( this._events );
16816		this._refresh();
16817
16818		// Turning off autocomplete prevents the browser from remembering the
16819		// value when navigating through history, so we re-enable autocomplete
16820		// if the page is unloaded before the widget is destroyed. #7790
16821		this._on( this.window, {
16822			beforeunload: function() {
16823				this.element.removeAttr( "autocomplete" );
16824			}
16825		} );
16826	},
16827
16828	_getCreateOptions: function() {
16829		var options = this._super();
16830		var element = this.element;
16831
16832		$.each( [ "min", "max", "step" ], function( i, option ) {
16833			var value = element.attr( option );
16834			if ( value != null && value.length ) {
16835				options[ option ] = value;
16836			}
16837		} );
16838
16839		return options;
16840	},
16841
16842	_events: {
16843		keydown: function( event ) {
16844			if ( this._start( event ) && this._keydown( event ) ) {
16845				event.preventDefault();
16846			}
16847		},
16848		keyup: "_stop",
16849		focus: function() {
16850			this.previous = this.element.val();
16851		},
16852		blur: function( event ) {
16853			if ( this.cancelBlur ) {
16854				delete this.cancelBlur;
16855				return;
16856			}
16857
16858			this._stop();
16859			this._refresh();
16860			if ( this.previous !== this.element.val() ) {
16861				this._trigger( "change", event );
16862			}
16863		},
16864		mousewheel: function( event, delta ) {
16865			if ( !delta ) {
16866				return;
16867			}
16868			if ( !this.spinning && !this._start( event ) ) {
16869				return false;
16870			}
16871
16872			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
16873			clearTimeout( this.mousewheelTimer );
16874			this.mousewheelTimer = this._delay( function() {
16875				if ( this.spinning ) {
16876					this._stop( event );
16877				}
16878			}, 100 );
16879			event.preventDefault();
16880		},
16881		"mousedown .ui-spinner-button": function( event ) {
16882			var previous;
16883
16884			// We never want the buttons to have focus; whenever the user is
16885			// interacting with the spinner, the focus should be on the input.
16886			// If the input is focused then this.previous is properly set from
16887			// when the input first received focus. If the input is not focused
16888			// then we need to set this.previous based on the value before spinning.
16889			previous = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] ) ?
16890				this.previous : this.element.val();
16891			function checkFocus() {
16892				var isActive = this.element[ 0 ] === $.ui.safeActiveElement( this.document[ 0 ] );
16893				if ( !isActive ) {
16894					this.element.trigger( "focus" );
16895					this.previous = previous;
16896
16897					// support: IE
16898					// IE sets focus asynchronously, so we need to check if focus
16899					// moved off of the input because the user clicked on the button.
16900					this._delay( function() {
16901						this.previous = previous;
16902					} );
16903				}
16904			}
16905
16906			// Ensure focus is on (or stays on) the text field
16907			event.preventDefault();
16908			checkFocus.call( this );
16909
16910			// Support: IE
16911			// IE doesn't prevent moving focus even with event.preventDefault()
16912			// so we set a flag to know when we should ignore the blur event
16913			// and check (again) if focus moved off of the input.
16914			this.cancelBlur = true;
16915			this._delay( function() {
16916				delete this.cancelBlur;
16917				checkFocus.call( this );
16918			} );
16919
16920			if ( this._start( event ) === false ) {
16921				return;
16922			}
16923
16924			this._repeat( null, $( event.currentTarget )
16925				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16926		},
16927		"mouseup .ui-spinner-button": "_stop",
16928		"mouseenter .ui-spinner-button": function( event ) {
16929
16930			// button will add ui-state-active if mouse was down while mouseleave and kept down
16931			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
16932				return;
16933			}
16934
16935			if ( this._start( event ) === false ) {
16936				return false;
16937			}
16938			this._repeat( null, $( event.currentTarget )
16939				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
16940		},
16941
16942		// TODO: do we really want to consider this a stop?
16943		// shouldn't we just stop the repeater and wait until mouseup before
16944		// we trigger the stop event?
16945		"mouseleave .ui-spinner-button": "_stop"
16946	},
16947
16948	// Support mobile enhanced option and make backcompat more sane
16949	_enhance: function() {
16950		this.uiSpinner = this.element
16951			.attr( "autocomplete", "off" )
16952			.wrap( "<span>" )
16953			.parent()
16954
16955				// Add buttons
16956				.append(
16957					"<a></a><a></a>"
16958				);
16959	},
16960
16961	_draw: function() {
16962		this._enhance();
16963
16964		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
16965		this._addClass( "ui-spinner-input" );
16966
16967		this.element.attr( "role", "spinbutton" );
16968
16969		// Button bindings
16970		this.buttons = this.uiSpinner.children( "a" )
16971			.attr( "tabIndex", -1 )
16972			.attr( "aria-hidden", true )
16973			.button( {
16974				classes: {
16975					"ui-button": ""
16976				}
16977			} );
16978
16979		// TODO: Right now button does not support classes this is already updated in button PR
16980		this._removeClass( this.buttons, "ui-corner-all" );
16981
16982		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
16983		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
16984		this.buttons.first().button( {
16985			"icon": this.options.icons.up,
16986			"showLabel": false
16987		} );
16988		this.buttons.last().button( {
16989			"icon": this.options.icons.down,
16990			"showLabel": false
16991		} );
16992
16993		// IE 6 doesn't understand height: 50% for the buttons
16994		// unless the wrapper has an explicit height
16995		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
16996				this.uiSpinner.height() > 0 ) {
16997			this.uiSpinner.height( this.uiSpinner.height() );
16998		}
16999	},
17000
17001	_keydown: function( event ) {
17002		var options = this.options,
17003			keyCode = $.ui.keyCode;
17004
17005		switch ( event.keyCode ) {
17006		case keyCode.UP:
17007			this._repeat( null, 1, event );
17008			return true;
17009		case keyCode.DOWN:
17010			this._repeat( null, -1, event );
17011			return true;
17012		case keyCode.PAGE_UP:
17013			this._repeat( null, options.page, event );
17014			return true;
17015		case keyCode.PAGE_DOWN:
17016			this._repeat( null, -options.page, event );
17017			return true;
17018		}
17019
17020		return false;
17021	},
17022
17023	_start: function( event ) {
17024		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17025			return false;
17026		}
17027
17028		if ( !this.counter ) {
17029			this.counter = 1;
17030		}
17031		this.spinning = true;
17032		return true;
17033	},
17034
17035	_repeat: function( i, steps, event ) {
17036		i = i || 500;
17037
17038		clearTimeout( this.timer );
17039		this.timer = this._delay( function() {
17040			this._repeat( 40, steps, event );
17041		}, i );
17042
17043		this._spin( steps * this.options.step, event );
17044	},
17045
17046	_spin: function( step, event ) {
17047		var value = this.value() || 0;
17048
17049		if ( !this.counter ) {
17050			this.counter = 1;
17051		}
17052
17053		value = this._adjustValue( value + step * this._increment( this.counter ) );
17054
17055		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17056			this._value( value );
17057			this.counter++;
17058		}
17059	},
17060
17061	_increment: function( i ) {
17062		var incremental = this.options.incremental;
17063
17064		if ( incremental ) {
17065			return $.isFunction( incremental ) ?
17066				incremental( i ) :
17067				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17068		}
17069
17070		return 1;
17071	},
17072
17073	_precision: function() {
17074		var precision = this._precisionOf( this.options.step );
17075		if ( this.options.min !== null ) {
17076			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17077		}
17078		return precision;
17079	},
17080
17081	_precisionOf: function( num ) {
17082		var str = num.toString(),
17083			decimal = str.indexOf( "." );
17084		return decimal === -1 ? 0 : str.length - decimal - 1;
17085	},
17086
17087	_adjustValue: function( value ) {
17088		var base, aboveMin,
17089			options = this.options;
17090
17091		// Make sure we're at a valid step
17092		// - find out where we are relative to the base (min or 0)
17093		base = options.min !== null ? options.min : 0;
17094		aboveMin = value - base;
17095
17096		// - round to the nearest step
17097		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17098
17099		// - rounding is based on 0, so adjust back to our base
17100		value = base + aboveMin;
17101
17102		// Fix precision from bad JS floating point math
17103		value = parseFloat( value.toFixed( this._precision() ) );
17104
17105		// Clamp the value
17106		if ( options.max !== null && value > options.max ) {
17107			return options.max;
17108		}
17109		if ( options.min !== null && value < options.min ) {
17110			return options.min;
17111		}
17112
17113		return value;
17114	},
17115
17116	_stop: function( event ) {
17117		if ( !this.spinning ) {
17118			return;
17119		}
17120
17121		clearTimeout( this.timer );
17122		clearTimeout( this.mousewheelTimer );
17123		this.counter = 0;
17124		this.spinning = false;
17125		this._trigger( "stop", event );
17126	},
17127
17128	_setOption: function( key, value ) {
17129		var prevValue, first, last;
17130
17131		if ( key === "culture" || key === "numberFormat" ) {
17132			prevValue = this._parse( this.element.val() );
17133			this.options[ key ] = value;
17134			this.element.val( this._format( prevValue ) );
17135			return;
17136		}
17137
17138		if ( key === "max" || key === "min" || key === "step" ) {
17139			if ( typeof value === "string" ) {
17140				value = this._parse( value );
17141			}
17142		}
17143		if ( key === "icons" ) {
17144			first = this.buttons.first().find( ".ui-icon" );
17145			this._removeClass( first, null, this.options.icons.up );
17146			this._addClass( first, null, value.up );
17147			last = this.buttons.last().find( ".ui-icon" );
17148			this._removeClass( last, null, this.options.icons.down );
17149			this._addClass( last, null, value.down );
17150		}
17151
17152		this._super( key, value );
17153	},
17154
17155	_setOptionDisabled: function( value ) {
17156		this._super( value );
17157
17158		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17159		this.element.prop( "disabled", !!value );
17160		this.buttons.button( value ? "disable" : "enable" );
17161	},
17162
17163	_setOptions: spinnerModifer( function( options ) {
17164		this._super( options );
17165	} ),
17166
17167	_parse: function( val ) {
17168		if ( typeof val === "string" && val !== "" ) {
17169			val = window.Globalize && this.options.numberFormat ?
17170				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17171		}
17172		return val === "" || isNaN( val ) ? null : val;
17173	},
17174
17175	_format: function( value ) {
17176		if ( value === "" ) {
17177			return "";
17178		}
17179		return window.Globalize && this.options.numberFormat ?
17180			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17181			value;
17182	},
17183
17184	_refresh: function() {
17185		this.element.attr( {
17186			"aria-valuemin": this.options.min,
17187			"aria-valuemax": this.options.max,
17188
17189			// TODO: what should we do with values that can't be parsed?
17190			"aria-valuenow": this._parse( this.element.val() )
17191		} );
17192	},
17193
17194	isValid: function() {
17195		var value = this.value();
17196
17197		// Null is invalid
17198		if ( value === null ) {
17199			return false;
17200		}
17201
17202		// If value gets adjusted, it's invalid
17203		return value === this._adjustValue( value );
17204	},
17205
17206	// Update the value without triggering change
17207	_value: function( value, allowAny ) {
17208		var parsed;
17209		if ( value !== "" ) {
17210			parsed = this._parse( value );
17211			if ( parsed !== null ) {
17212				if ( !allowAny ) {
17213					parsed = this._adjustValue( parsed );
17214				}
17215				value = this._format( parsed );
17216			}
17217		}
17218		this.element.val( value );
17219		this._refresh();
17220	},
17221
17222	_destroy: function() {
17223		this.element
17224			.prop( "disabled", false )
17225			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17226
17227		this.uiSpinner.replaceWith( this.element );
17228	},
17229
17230	stepUp: spinnerModifer( function( steps ) {
17231		this._stepUp( steps );
17232	} ),
17233	_stepUp: function( steps ) {
17234		if ( this._start() ) {
17235			this._spin( ( steps || 1 ) * this.options.step );
17236			this._stop();
17237		}
17238	},
17239
17240	stepDown: spinnerModifer( function( steps ) {
17241		this._stepDown( steps );
17242	} ),
17243	_stepDown: function( steps ) {
17244		if ( this._start() ) {
17245			this._spin( ( steps || 1 ) * -this.options.step );
17246			this._stop();
17247		}
17248	},
17249
17250	pageUp: spinnerModifer( function( pages ) {
17251		this._stepUp( ( pages || 1 ) * this.options.page );
17252	} ),
17253
17254	pageDown: spinnerModifer( function( pages ) {
17255		this._stepDown( ( pages || 1 ) * this.options.page );
17256	} ),
17257
17258	value: function( newVal ) {
17259		if ( !arguments.length ) {
17260			return this._parse( this.element.val() );
17261		}
17262		spinnerModifer( this._value ).call( this, newVal );
17263	},
17264
17265	widget: function() {
17266		return this.uiSpinner;
17267	}
17268} );
17269
17270// DEPRECATED
17271// TODO: switch return back to widget declaration at top of file when this is removed
17272if ( $.uiBackCompat !== false ) {
17273
17274	// Backcompat for spinner html extension points
17275	$.widget( "ui.spinner", $.ui.spinner, {
17276		_enhance: function() {
17277			this.uiSpinner = this.element
17278				.attr( "autocomplete", "off" )
17279				.wrap( this._uiSpinnerHtml() )
17280				.parent()
17281
17282					// Add buttons
17283					.append( this._buttonHtml() );
17284		},
17285		_uiSpinnerHtml: function() {
17286			return "<span>";
17287		},
17288
17289		_buttonHtml: function() {
17290			return "<a></a><a></a>";
17291		}
17292	} );
17293}
17294
17295var widgetsSpinner = $.ui.spinner;
17296
17297
17298/*!
17299 * jQuery UI Tabs 1.12.1
17300 * http://jqueryui.com
17301 *
17302 * Copyright jQuery Foundation and other contributors
17303 * Released under the MIT license.
17304 * http://jquery.org/license
17305 */
17306
17307//>>label: Tabs
17308//>>group: Widgets
17309//>>description: Transforms a set of container elements into a tab structure.
17310//>>docs: http://api.jqueryui.com/tabs/
17311//>>demos: http://jqueryui.com/tabs/
17312//>>css.structure: ../../themes/base/core.css
17313//>>css.structure: ../../themes/base/tabs.css
17314//>>css.theme: ../../themes/base/theme.css
17315
17316
17317
17318$.widget( "ui.tabs", {
17319	version: "1.12.1",
17320	delay: 300,
17321	options: {
17322		active: null,
17323		classes: {
17324			"ui-tabs": "ui-corner-all",
17325			"ui-tabs-nav": "ui-corner-all",
17326			"ui-tabs-panel": "ui-corner-bottom",
17327			"ui-tabs-tab": "ui-corner-top"
17328		},
17329		collapsible: false,
17330		event: "click",
17331		heightStyle: "content",
17332		hide: null,
17333		show: null,
17334
17335		// Callbacks
17336		activate: null,
17337		beforeActivate: null,
17338		beforeLoad: null,
17339		load: null
17340	},
17341
17342	_isLocal: ( function() {
17343		var rhash = /#.*$/;
17344
17345		return function( anchor ) {
17346			var anchorUrl, locationUrl;
17347
17348			anchorUrl = anchor.href.replace( rhash, "" );
17349			locationUrl = location.href.replace( rhash, "" );
17350
17351			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17352			try {
17353				anchorUrl = decodeURIComponent( anchorUrl );
17354			} catch ( error ) {}
17355			try {
17356				locationUrl = decodeURIComponent( locationUrl );
17357			} catch ( error ) {}
17358
17359			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17360		};
17361	} )(),
17362
17363	_create: function() {
17364		var that = this,
17365			options = this.options;
17366
17367		this.running = false;
17368
17369		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17370		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17371
17372		this._processTabs();
17373		options.active = this._initialActive();
17374
17375		// Take disabling tabs via class attribute from HTML
17376		// into account and update option properly.
17377		if ( $.isArray( options.disabled ) ) {
17378			options.disabled = $.unique( options.disabled.concat(
17379				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17380					return that.tabs.index( li );
17381				} )
17382			) ).sort();
17383		}
17384
17385		// Check for length avoids error when initializing empty list
17386		if ( this.options.active !== false && this.anchors.length ) {
17387			this.active = this._findActive( options.active );
17388		} else {
17389			this.active = $();
17390		}
17391
17392		this._refresh();
17393
17394		if ( this.active.length ) {
17395			this.load( options.active );
17396		}
17397	},
17398
17399	_initialActive: function() {
17400		var active = this.options.active,
17401			collapsible = this.options.collapsible,
17402			locationHash = location.hash.substring( 1 );
17403
17404		if ( active === null ) {
17405
17406			// check the fragment identifier in the URL
17407			if ( locationHash ) {
17408				this.tabs.each( function( i, tab ) {
17409					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
17410						active = i;
17411						return false;
17412					}
17413				} );
17414			}
17415
17416			// Check for a tab marked active via a class
17417			if ( active === null ) {
17418				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17419			}
17420
17421			// No active tab, set to false
17422			if ( active === null || active === -1 ) {
17423				active = this.tabs.length ? 0 : false;
17424			}
17425		}
17426
17427		// Handle numbers: negative, out of range
17428		if ( active !== false ) {
17429			active = this.tabs.index( this.tabs.eq( active ) );
17430			if ( active === -1 ) {
17431				active = collapsible ? false : 0;
17432			}
17433		}
17434
17435		// Don't allow collapsible: false and active: false
17436		if ( !collapsible && active === false && this.anchors.length ) {
17437			active = 0;
17438		}
17439
17440		return active;
17441	},
17442
17443	_getCreateEventData: function() {
17444		return {
17445			tab: this.active,
17446			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17447		};
17448	},
17449
17450	_tabKeydown: function( event ) {
17451		var focusedTab = $( $.ui.safeActiveElement( this.document[ 0 ] ) ).closest( "li" ),
17452			selectedIndex = this.tabs.index( focusedTab ),
17453			goingForward = true;
17454
17455		if ( this._handlePageNav( event ) ) {
17456			return;
17457		}
17458
17459		switch ( event.keyCode ) {
17460		case $.ui.keyCode.RIGHT:
17461		case $.ui.keyCode.DOWN:
17462			selectedIndex++;
17463			break;
17464		case $.ui.keyCode.UP:
17465		case $.ui.keyCode.LEFT:
17466			goingForward = false;
17467			selectedIndex--;
17468			break;
17469		case $.ui.keyCode.END:
17470			selectedIndex = this.anchors.length - 1;
17471			break;
17472		case $.ui.keyCode.HOME:
17473			selectedIndex = 0;
17474			break;
17475		case $.ui.keyCode.SPACE:
17476
17477			// Activate only, no collapsing
17478			event.preventDefault();
17479			clearTimeout( this.activating );
17480			this._activate( selectedIndex );
17481			return;
17482		case $.ui.keyCode.ENTER:
17483
17484			// Toggle (cancel delayed activation, allow collapsing)
17485			event.preventDefault();
17486			clearTimeout( this.activating );
17487
17488			// Determine if we should collapse or activate
17489			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17490			return;
17491		default:
17492			return;
17493		}
17494
17495		// Focus the appropriate tab, based on which key was pressed
17496		event.preventDefault();
17497		clearTimeout( this.activating );
17498		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17499
17500		// Navigating with control/command key will prevent automatic activation
17501		if ( !event.ctrlKey && !event.metaKey ) {
17502
17503			// Update aria-selected immediately so that AT think the tab is already selected.
17504			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17505			// but the tab will already be activated by the time the announcement finishes.
17506			focusedTab.attr( "aria-selected", "false" );
17507			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17508
17509			this.activating = this._delay( function() {
17510				this.option( "active", selectedIndex );
17511			}, this.delay );
17512		}
17513	},
17514
17515	_panelKeydown: function( event ) {
17516		if ( this._handlePageNav( event ) ) {
17517			return;
17518		}
17519
17520		// Ctrl+up moves focus to the current tab
17521		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17522			event.preventDefault();
17523			this.active.trigger( "focus" );
17524		}
17525	},
17526
17527	// Alt+page up/down moves focus to the previous/next tab (and activates)
17528	_handlePageNav: function( event ) {
17529		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17530			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17531			return true;
17532		}
17533		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17534			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17535			return true;
17536		}
17537	},
17538
17539	_findNextTab: function( index, goingForward ) {
17540		var lastTabIndex = this.tabs.length - 1;
17541
17542		function constrain() {
17543			if ( index > lastTabIndex ) {
17544				index = 0;
17545			}
17546			if ( index < 0 ) {
17547				index = lastTabIndex;
17548			}
17549			return index;
17550		}
17551
17552		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17553			index = goingForward ? index + 1 : index - 1;
17554		}
17555
17556		return index;
17557	},
17558
17559	_focusNextTab: function( index, goingForward ) {
17560		index = this._findNextTab( index, goingForward );
17561		this.tabs.eq( index ).trigger( "focus" );
17562		return index;
17563	},
17564
17565	_setOption: function( key, value ) {
17566		if ( key === "active" ) {
17567
17568			// _activate() will handle invalid values and update this.options
17569			this._activate( value );
17570			return;
17571		}
17572
17573		this._super( key, value );
17574
17575		if ( key === "collapsible" ) {
17576			this._toggleClass( "ui-tabs-collapsible", null, value );
17577
17578			// Setting collapsible: false while collapsed; open first panel
17579			if ( !value && this.options.active === false ) {
17580				this._activate( 0 );
17581			}
17582		}
17583
17584		if ( key === "event" ) {
17585			this._setupEvents( value );
17586		}
17587
17588		if ( key === "heightStyle" ) {
17589			this._setupHeightStyle( value );
17590		}
17591	},
17592
17593	_sanitizeSelector: function( hash ) {
17594		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
17595	},
17596
17597	refresh: function() {
17598		var options = this.options,
17599			lis = this.tablist.children( ":has(a[href])" );
17600
17601		// Get disabled tabs from class attribute from HTML
17602		// this will get converted to a boolean if needed in _refresh()
17603		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17604			return lis.index( tab );
17605		} );
17606
17607		this._processTabs();
17608
17609		// Was collapsed or no tabs
17610		if ( options.active === false || !this.anchors.length ) {
17611			options.active = false;
17612			this.active = $();
17613
17614		// was active, but active tab is gone
17615		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17616
17617			// all remaining tabs are disabled
17618			if ( this.tabs.length === options.disabled.length ) {
17619				options.active = false;
17620				this.active = $();
17621
17622			// activate previous tab
17623			} else {
17624				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17625			}
17626
17627		// was active, active tab still exists
17628		} else {
17629
17630			// make sure active index is correct
17631			options.active = this.tabs.index( this.active );
17632		}
17633
17634		this._refresh();
17635	},
17636
17637	_refresh: function() {
17638		this._setOptionDisabled( this.options.disabled );
17639		this._setupEvents( this.options.event );
17640		this._setupHeightStyle( this.options.heightStyle );
17641
17642		this.tabs.not( this.active ).attr( {
17643			"aria-selected": "false",
17644			"aria-expanded": "false",
17645			tabIndex: -1
17646		} );
17647		this.panels.not( this._getPanelForTab( this.active ) )
17648			.hide()
17649			.attr( {
17650				"aria-hidden": "true"
17651			} );
17652
17653		// Make sure one tab is in the tab order
17654		if ( !this.active.length ) {
17655			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17656		} else {
17657			this.active
17658				.attr( {
17659					"aria-selected": "true",
17660					"aria-expanded": "true",
17661					tabIndex: 0
17662				} );
17663			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17664			this._getPanelForTab( this.active )
17665				.show()
17666				.attr( {
17667					"aria-hidden": "false"
17668				} );
17669		}
17670	},
17671
17672	_processTabs: function() {
17673		var that = this,
17674			prevTabs = this.tabs,
17675			prevAnchors = this.anchors,
17676			prevPanels = this.panels;
17677
17678		this.tablist = this._getList().attr( "role", "tablist" );
17679		this._addClass( this.tablist, "ui-tabs-nav",
17680			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17681
17682		// Prevent users from focusing disabled tabs via click
17683		this.tablist
17684			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17685				if ( $( this ).is( ".ui-state-disabled" ) ) {
17686					event.preventDefault();
17687				}
17688			} )
17689
17690			// Support: IE <9
17691			// Preventing the default action in mousedown doesn't prevent IE
17692			// from focusing the element, so if the anchor gets focused, blur.
17693			// We don't have to worry about focusing the previously focused
17694			// element since clicking on a non-focusable element should focus
17695			// the body anyway.
17696			.on( "focus" + this.eventNamespace, ".ui-tabs-anchor", function() {
17697				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
17698					this.blur();
17699				}
17700			} );
17701
17702		this.tabs = this.tablist.find( "> li:has(a[href])" )
17703			.attr( {
17704				role: "tab",
17705				tabIndex: -1
17706			} );
17707		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17708
17709		this.anchors = this.tabs.map( function() {
17710			return $( "a", this )[ 0 ];
17711		} )
17712			.attr( {
17713				role: "presentation",
17714				tabIndex: -1
17715			} );
17716		this._addClass( this.anchors, "ui-tabs-anchor" );
17717
17718		this.panels = $();
17719
17720		this.anchors.each( function( i, anchor ) {
17721			var selector, panel, panelId,
17722				anchorId = $( anchor ).uniqueId().attr( "id" ),
17723				tab = $( anchor ).closest( "li" ),
17724				originalAriaControls = tab.attr( "aria-controls" );
17725
17726			// Inline tab
17727			if ( that._isLocal( anchor ) ) {
17728				selector = anchor.hash;
17729				panelId = selector.substring( 1 );
17730				panel = that.element.find( that._sanitizeSelector( selector ) );
17731
17732			// remote tab
17733			} else {
17734
17735				// If the tab doesn't already have aria-controls,
17736				// generate an id by using a throw-away element
17737				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17738				selector = "#" + panelId;
17739				panel = that.element.find( selector );
17740				if ( !panel.length ) {
17741					panel = that._createPanel( panelId );
17742					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17743				}
17744				panel.attr( "aria-live", "polite" );
17745			}
17746
17747			if ( panel.length ) {
17748				that.panels = that.panels.add( panel );
17749			}
17750			if ( originalAriaControls ) {
17751				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17752			}
17753			tab.attr( {
17754				"aria-controls": panelId,
17755				"aria-labelledby": anchorId
17756			} );
17757			panel.attr( "aria-labelledby", anchorId );
17758		} );
17759
17760		this.panels.attr( "role", "tabpanel" );
17761		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17762
17763		// Avoid memory leaks (#10056)
17764		if ( prevTabs ) {
17765			this._off( prevTabs.not( this.tabs ) );
17766			this._off( prevAnchors.not( this.anchors ) );
17767			this._off( prevPanels.not( this.panels ) );
17768		}
17769	},
17770
17771	// Allow overriding how to find the list for rare usage scenarios (#7715)
17772	_getList: function() {
17773		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17774	},
17775
17776	_createPanel: function( id ) {
17777		return $( "<div>" )
17778			.attr( "id", id )
17779			.data( "ui-tabs-destroy", true );
17780	},
17781
17782	_setOptionDisabled: function( disabled ) {
17783		var currentItem, li, i;
17784
17785		if ( $
vendor: 6,224 bytes, lines 17785-18016
17785.isArray( disabled ) ) {
17786			if ( !disabled.length ) {
17787				disabled = false;
17788			} else if ( disabled.length === this.anchors.length ) {
17789				disabled = true;
17790			}
17791		}
17792
17793		// Disable tabs
17794		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17795			currentItem = $( li );
17796			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17797				currentItem.attr( "aria-disabled", "true" );
17798				this._addClass( currentItem, null, "ui-state-disabled" );
17799			} else {
17800				currentItem.removeAttr( "aria-disabled" );
17801				this._removeClass( currentItem, null, "ui-state-disabled" );
17802			}
17803		}
17804
17805		this.options.disabled = disabled;
17806
17807		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17808			disabled === true );
17809	},
17810
17811	_setupEvents: function( event ) {
17812		var events = {};
17813		if ( event ) {
17814			$.each( event.split( " " ), function( index, eventName ) {
17815				events[ eventName ] = "_eventHandler";
17816			} );
17817		}
17818
17819		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17820
17821		// Always prevent the default action, even when disabled
17822		this._on( true, this.anchors, {
17823			click: function( event ) {
17824				event.preventDefault();
17825			}
17826		} );
17827		this._on( this.anchors, events );
17828		this._on( this.tabs, { keydown: "_tabKeydown" } );
17829		this._on( this.panels, { keydown: "_panelKeydown" } );
17830
17831		this._focusable( this.tabs );
17832		this._hoverable( this.tabs );
17833	},
17834
17835	_setupHeightStyle: function( heightStyle ) {
17836		var maxHeight,
17837			parent = this.element.parent();
17838
17839		if ( heightStyle === "fill" ) {
17840			maxHeight = parent.height();
17841			maxHeight -= this.element.outerHeight() - this.element.height();
17842
17843			this.element.siblings( ":visible" ).each( function() {
17844				var elem = $( this ),
17845					position = elem.css( "position" );
17846
17847				if ( position === "absolute" || position === "fixed" ) {
17848					return;
17849				}
17850				maxHeight -= elem.outerHeight( true );
17851			} );
17852
17853			this.element.children().not( this.panels ).each( function() {
17854				maxHeight -= $( this ).outerHeight( true );
17855			} );
17856
17857			this.panels.each( function() {
17858				$( this ).height( Math.max( 0, maxHeight -
17859					$( this ).innerHeight() + $( this ).height() ) );
17860			} )
17861				.css( "overflow", "auto" );
17862		} else if ( heightStyle === "auto" ) {
17863			maxHeight = 0;
17864			this.panels.each( function() {
17865				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17866			} ).height( maxHeight );
17867		}
17868	},
17869
17870	_eventHandler: function( event ) {
17871		var options = this.options,
17872			active = this.active,
17873			anchor = $( event.currentTarget ),
17874			tab = anchor.closest( "li" ),
17875			clickedIsActive = tab[ 0 ] === active[ 0 ],
17876			collapsing = clickedIsActive && options.collapsible,
17877			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17878			toHide = !active.length ? $() : this._getPanelForTab( active ),
17879			eventData = {
17880				oldTab: active,
17881				oldPanel: toHide,
17882				newTab: collapsing ? $() : tab,
17883				newPanel: toShow
17884			};
17885
17886		event.preventDefault();
17887
17888		if ( tab.hasClass( "ui-state-disabled" ) ||
17889
17890				// tab is already loading
17891				tab.hasClass( "ui-tabs-loading" ) ||
17892
17893				// can't switch durning an animation
17894				this.running ||
17895
17896				// click on active header, but not collapsible
17897				( clickedIsActive && !options.collapsible ) ||
17898
17899				// allow canceling activation
17900				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
17901			return;
17902		}
17903
17904		options.active = collapsing ? false : this.tabs.index( tab );
17905
17906		this.active = clickedIsActive ? $() : tab;
17907		if ( this.xhr ) {
17908			this.xhr.abort();
17909		}
17910
17911		if ( !toHide.length && !toShow.length ) {
17912			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
17913		}
17914
17915		if ( toShow.length ) {
17916			this.load( this.tabs.index( tab ), event );
17917		}
17918		this._toggle( event, eventData );
17919	},
17920
17921	// Handles show/hide for selecting tabs
17922	_toggle: function( event, eventData ) {
17923		var that = this,
17924			toShow = eventData.newPanel,
17925			toHide = eventData.oldPanel;
17926
17927		this.running = true;
17928
17929		function complete() {
17930			that.running = false;
17931			that._trigger( "activate", event, eventData );
17932		}
17933
17934		function show() {
17935			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
17936
17937			if ( toShow.length && that.options.show ) {
17938				that._show( toShow, that.options.show, complete );
17939			} else {
17940				toShow.show();
17941				complete();
17942			}
17943		}
17944
17945		// Start out by hiding, then showing, then completing
17946		if ( toHide.length && this.options.hide ) {
17947			this._hide( toHide, this.options.hide, function() {
17948				that._removeClass( eventData.oldTab.closest( "li" ),
17949					"ui-tabs-active", "ui-state-active" );
17950				show();
17951			} );
17952		} else {
17953			this._removeClass( eventData.oldTab.closest( "li" ),
17954				"ui-tabs-active", "ui-state-active" );
17955			toHide.hide();
17956			show();
17957		}
17958
17959		toHide.attr( "aria-hidden", "true" );
17960		eventData.oldTab.attr( {
17961			"aria-selected": "false",
17962			"aria-expanded": "false"
17963		} );
17964
17965		// If we're switching tabs, remove the old tab from the tab order.
17966		// If we're opening from collapsed state, remove the previous tab from the tab order.
17967		// If we're collapsing, then keep the collapsing tab in the tab order.
17968		if ( toShow.length && toHide.length ) {
17969			eventData.oldTab.attr( "tabIndex", -1 );
17970		} else if ( toShow.length ) {
17971			this.tabs.filter( function() {
17972				return $( this ).attr( "tabIndex" ) === 0;
17973			} )
17974				.attr( "tabIndex", -1 );
17975		}
17976
17977		toShow.attr( "aria-hidden", "false" );
17978		eventData.newTab.attr( {
17979			"aria-selected": "true",
17980			"aria-expanded": "true",
17981			tabIndex: 0
17982		} );
17983	},
17984
17985	_activate: function( index ) {
17986		var anchor,
17987			active = this._findActive( index );
17988
17989		// Trying to activate the already active panel
17990		if ( active[ 0 ] === this.active[ 0 ] ) {
17991			return;
17992		}
17993
17994		// Trying to collapse, simulate a click on the current active header
17995		if ( !active.length ) {
17996			active = this.active;
17997		}
17998
17999		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
18000		this._eventHandler( {
18001			target: anchor,
18002			currentTarget: anchor,
18003			preventDefault: $.noop
18004		} );
18005	},
18006
18007	_findActive: function( index ) {
18008		return index === false ? $() : this.tabs.eq( index );
18009	},
18010
18011	_getIndex: function( index ) {
18012
18013		// meta-function to give users option to provide a href string instead of a numerical index.
18014		if ( typeof index === "string" ) {
18015			index = this.anchors.index( this.anchors.filter( "[href$='" +
18016				$.
vendor: 18,388 bytes, lines 18016-18709
18016ui.escapeSelector( index ) + "']" ) );
18017		}
18018
18019		return index;
18020	},
18021
18022	_destroy: function() {
18023		if ( this.xhr ) {
18024			this.xhr.abort();
18025		}
18026
18027		this.tablist
18028			.removeAttr( "role" )
18029			.off( this.eventNamespace );
18030
18031		this.anchors
18032			.removeAttr( "role tabIndex" )
18033			.removeUniqueId();
18034
18035		this.tabs.add( this.panels ).each( function() {
18036			if ( $.data( this, "ui-tabs-destroy" ) ) {
18037				$( this ).remove();
18038			} else {
18039				$( this ).removeAttr( "role tabIndex " +
18040					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18041			}
18042		} );
18043
18044		this.tabs.each( function() {
18045			var li = $( this ),
18046				prev = li.data( "ui-tabs-aria-controls" );
18047			if ( prev ) {
18048				li
18049					.attr( "aria-controls", prev )
18050					.removeData( "ui-tabs-aria-controls" );
18051			} else {
18052				li.removeAttr( "aria-controls" );
18053			}
18054		} );
18055
18056		this.panels.show();
18057
18058		if ( this.options.heightStyle !== "content" ) {
18059			this.panels.css( "height", "" );
18060		}
18061	},
18062
18063	enable: function( index ) {
18064		var disabled = this.options.disabled;
18065		if ( disabled === false ) {
18066			return;
18067		}
18068
18069		if ( index === undefined ) {
18070			disabled = false;
18071		} else {
18072			index = this._getIndex( index );
18073			if ( $.isArray( disabled ) ) {
18074				disabled = $.map( disabled, function( num ) {
18075					return num !== index ? num : null;
18076				} );
18077			} else {
18078				disabled = $.map( this.tabs, function( li, num ) {
18079					return num !== index ? num : null;
18080				} );
18081			}
18082		}
18083		this._setOptionDisabled( disabled );
18084	},
18085
18086	disable: function( index ) {
18087		var disabled = this.options.disabled;
18088		if ( disabled === true ) {
18089			return;
18090		}
18091
18092		if ( index === undefined ) {
18093			disabled = true;
18094		} else {
18095			index = this._getIndex( index );
18096			if ( $.inArray( index, disabled ) !== -1 ) {
18097				return;
18098			}
18099			if ( $.isArray( disabled ) ) {
18100				disabled = $.merge( [ index ], disabled ).sort();
18101			} else {
18102				disabled = [ index ];
18103			}
18104		}
18105		this._setOptionDisabled( disabled );
18106	},
18107
18108	load: function( index, event ) {
18109		index = this._getIndex( index );
18110		var that = this,
18111			tab = this.tabs.eq( index ),
18112			anchor = tab.find( ".ui-tabs-anchor" ),
18113			panel = this._getPanelForTab( tab ),
18114			eventData = {
18115				tab: tab,
18116				panel: panel
18117			},
18118			complete = function( jqXHR, status ) {
18119				if ( status === "abort" ) {
18120					that.panels.stop( false, true );
18121				}
18122
18123				that._removeClass( tab, "ui-tabs-loading" );
18124				panel.removeAttr( "aria-busy" );
18125
18126				if ( jqXHR === that.xhr ) {
18127					delete that.xhr;
18128				}
18129			};
18130
18131		// Not remote
18132		if ( this._isLocal( anchor[ 0 ] ) ) {
18133			return;
18134		}
18135
18136		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18137
18138		// Support: jQuery <1.8
18139		// jQuery <1.8 returns false if the request is canceled in beforeSend,
18140		// but as of 1.8, $.ajax() always returns a jqXHR object.
18141		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
18142			this._addClass( tab, "ui-tabs-loading" );
18143			panel.attr( "aria-busy", "true" );
18144
18145			this.xhr
18146				.done( function( response, status, jqXHR ) {
18147
18148					// support: jQuery <1.8
18149					// http://bugs.jquery.com/ticket/11778
18150					setTimeout( function() {
18151						panel.html( response );
18152						that._trigger( "load", event, eventData );
18153
18154						complete( jqXHR, status );
18155					}, 1 );
18156				} )
18157				.fail( function( jqXHR, status ) {
18158
18159					// support: jQuery <1.8
18160					// http://bugs.jquery.com/ticket/11778
18161					setTimeout( function() {
18162						complete( jqXHR, status );
18163					}, 1 );
18164				} );
18165		}
18166	},
18167
18168	_ajaxSettings: function( anchor, event, eventData ) {
18169		var that = this;
18170		return {
18171
18172			// Support: IE <11 only
18173			// Strip any hash that exists to prevent errors with the Ajax request
18174			url: anchor.attr( "href" ).replace( /#.*$/, "" ),
18175			beforeSend: function( jqXHR, settings ) {
18176				return that._trigger( "beforeLoad", event,
18177					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18178			}
18179		};
18180	},
18181
18182	_getPanelForTab: function( tab ) {
18183		var id = $( tab ).attr( "aria-controls" );
18184		return this.element.find( this._sanitizeSelector( "#" + id ) );
18185	}
18186} );
18187
18188// DEPRECATED
18189// TODO: Switch return back to widget declaration at top of file when this is removed
18190if ( $.uiBackCompat !== false ) {
18191
18192	// Backcompat for ui-tab class (now ui-tabs-tab)
18193	$.widget( "ui.tabs", $.ui.tabs, {
18194		_processTabs: function() {
18195			this._superApply( arguments );
18196			this._addClass( this.tabs, "ui-tab" );
18197		}
18198	} );
18199}
18200
18201var widgetsTabs = $.ui.tabs;
18202
18203
18204/*!
18205 * jQuery UI Tooltip 1.12.1
18206 * http://jqueryui.com
18207 *
18208 * Copyright jQuery Foundation and other contributors
18209 * Released under the MIT license.
18210 * http://jquery.org/license
18211 */
18212
18213//>>label: Tooltip
18214//>>group: Widgets
18215//>>description: Shows additional information for any element on hover or focus.
18216//>>docs: http://api.jqueryui.com/tooltip/
18217//>>demos: http://jqueryui.com/tooltip/
18218//>>css.structure: ../../themes/base/core.css
18219//>>css.structure: ../../themes/base/tooltip.css
18220//>>css.theme: ../../themes/base/theme.css
18221
18222
18223
18224$.widget( "ui.tooltip", {
18225	version: "1.12.1",
18226	options: {
18227		classes: {
18228			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18229		},
18230		content: function() {
18231
18232			// support: IE<9, Opera in jQuery <1.7
18233			// .text() can't accept undefined, so coerce to a string
18234			var title = $( this ).attr( "title" ) || "";
18235
18236			// Escape title, since we're going from an attribute to raw HTML
18237			return $( "<a>" ).text( title ).html();
18238		},
18239		hide: true,
18240
18241		// Disabled elements have inconsistent behavior across browsers (#8661)
18242		items: "[title]:not([disabled])",
18243		position: {
18244			my: "left top+15",
18245			at: "left bottom",
18246			collision: "flipfit flip"
18247		},
18248		show: true,
18249		track: false,
18250
18251		// Callbacks
18252		close: null,
18253		open: null
18254	},
18255
18256	_addDescribedBy: function( elem, id ) {
18257		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18258		describedby.push( id );
18259		elem
18260			.data( "ui-tooltip-id", id )
18261			.attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
18262	},
18263
18264	_removeDescribedBy: function( elem ) {
18265		var id = elem.data( "ui-tooltip-id" ),
18266			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18267			index = $.inArray( id, describedby );
18268
18269		if ( index !== -1 ) {
18270			describedby.splice( index, 1 );
18271		}
18272
18273		elem.removeData( "ui-tooltip-id" );
18274		describedby = $.trim( describedby.join( " " ) );
18275		if ( describedby ) {
18276			elem.attr( "aria-describedby", describedby );
18277		} else {
18278			elem.removeAttr( "aria-describedby" );
18279		}
18280	},
18281
18282	_create: function() {
18283		this._on( {
18284			mouseover: "open",
18285			focusin: "open"
18286		} );
18287
18288		// IDs of generated tooltips, needed for destroy
18289		this.tooltips = {};
18290
18291		// IDs of parent tooltips where we removed the title attribute
18292		this.parents = {};
18293
18294		// Append the aria-live region so tooltips announce correctly
18295		this.liveRegion = $( "<div>" )
18296			.attr( {
18297				role: "log",
18298				"aria-live": "assertive",
18299				"aria-relevant": "additions"
18300			} )
18301			.appendTo( this.document[ 0 ].body );
18302		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18303
18304		this.disabledTitles = $( [] );
18305	},
18306
18307	_setOption: function( key, value ) {
18308		var that = this;
18309
18310		this._super( key, value );
18311
18312		if ( key === "content" ) {
18313			$.each( this.tooltips, function( id, tooltipData ) {
18314				that._updateContent( tooltipData.element );
18315			} );
18316		}
18317	},
18318
18319	_setOptionDisabled: function( value ) {
18320		this[ value ? "_disable" : "_enable" ]();
18321	},
18322
18323	_disable: function() {
18324		var that = this;
18325
18326		// Close open tooltips
18327		$.each( this.tooltips, function( id, tooltipData ) {
18328			var event = $.Event( "blur" );
18329			event.target = event.currentTarget = tooltipData.element[ 0 ];
18330			that.close( event, true );
18331		} );
18332
18333		// Remove title attributes to prevent native tooltips
18334		this.disabledTitles = this.disabledTitles.add(
18335			this.element.find( this.options.items ).addBack()
18336				.filter( function() {
18337					var element = $( this );
18338					if ( element.is( "[title]" ) ) {
18339						return element
18340							.data( "ui-tooltip-title", element.attr( "title" ) )
18341							.removeAttr( "title" );
18342					}
18343				} )
18344		);
18345	},
18346
18347	_enable: function() {
18348
18349		// restore title attributes
18350		this.disabledTitles.each( function() {
18351			var element = $( this );
18352			if ( element.data( "ui-tooltip-title" ) ) {
18353				element.attr( "title", element.data( "ui-tooltip-title" ) );
18354			}
18355		} );
18356		this.disabledTitles = $( [] );
18357	},
18358
18359	open: function( event ) {
18360		var that = this,
18361			target = $( event ? event.target : this.element )
18362
18363				// we need closest here due to mouseover bubbling,
18364				// but always pointing at the same event target
18365				.closest( this.options.items );
18366
18367		// No element to show a tooltip for or the tooltip is already open
18368		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18369			return;
18370		}
18371
18372		if ( target.attr( "title" ) ) {
18373			target.data( "ui-tooltip-title", target.attr( "title" ) );
18374		}
18375
18376		target.data( "ui-tooltip-open", true );
18377
18378		// Kill parent tooltips, custom or native, for hover
18379		if ( event && event.type === "mouseover" ) {
18380			target.parents().each( function() {
18381				var parent = $( this ),
18382					blurEvent;
18383				if ( parent.data( "ui-tooltip-open" ) ) {
18384					blurEvent = $.Event( "blur" );
18385					blurEvent.target = blurEvent.currentTarget = this;
18386					that.close( blurEvent, true );
18387				}
18388				if ( parent.attr( "title" ) ) {
18389					parent.uniqueId();
18390					that.parents[ this.id ] = {
18391						element: this,
18392						title: parent.attr( "title" )
18393					};
18394					parent.attr( "title", "" );
18395				}
18396			} );
18397		}
18398
18399		this._registerCloseHandlers( event, target );
18400		this._updateContent( target, event );
18401	},
18402
18403	_updateContent: function( target, event ) {
18404		var content,
18405			contentOption = this.options.content,
18406			that = this,
18407			eventType = event ? event.type : null;
18408
18409		if ( typeof contentOption === "string" || contentOption.nodeType ||
18410				contentOption.jquery ) {
18411			return this._open( event, target, contentOption );
18412		}
18413
18414		content = contentOption.call( target[ 0 ], function( response ) {
18415
18416			// IE may instantly serve a cached response for ajax requests
18417			// delay this call to _open so the other call to _open runs first
18418			that._delay( function() {
18419
18420				// Ignore async response if tooltip was closed already
18421				if ( !target.data( "ui-tooltip-open" ) ) {
18422					return;
18423				}
18424
18425				// JQuery creates a special event for focusin when it doesn't
18426				// exist natively. To improve performance, the native event
18427				// object is reused and the type is changed. Therefore, we can't
18428				// rely on the type being correct after the event finished
18429				// bubbling, so we set it back to the previous value. (#8740)
18430				if ( event ) {
18431					event.type = eventType;
18432				}
18433				this._open( event, target, response );
18434			} );
18435		} );
18436		if ( content ) {
18437			this._open( event, target, content );
18438		}
18439	},
18440
18441	_open: function( event, target, content ) {
18442		var tooltipData, tooltip, delayedShow, a11yContent,
18443			positionOption = $.extend( {}, this.options.position );
18444
18445		if ( !content ) {
18446			return;
18447		}
18448
18449		// Content can be updated multiple times. If the tooltip already
18450		// exists, then just update the content and bail.
18451		tooltipData = this._find( target );
18452		if ( tooltipData ) {
18453			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18454			return;
18455		}
18456
18457		// If we have a title, clear it to prevent the native tooltip
18458		// we have to check first to avoid defining a title if none exists
18459		// (we don't want to cause an element to start matching [title])
18460		//
18461		// We use removeAttr only for key events, to allow IE to export the correct
18462		// accessible attributes. For mouse events, set to empty string to avoid
18463		// native tooltip showing up (happens only when removing inside mouseover).
18464		if ( target.is( "[title]" ) ) {
18465			if ( event && event.type === "mouseover" ) {
18466				target.attr( "title", "" );
18467			} else {
18468				target.removeAttr( "title" );
18469			}
18470		}
18471
18472		tooltipData = this._tooltip( target );
18473		tooltip = tooltipData.tooltip;
18474		this._addDescribedBy( target, tooltip.attr( "id" ) );
18475		tooltip.find( ".ui-tooltip-content" ).html( content );
18476
18477		// Support: Voiceover on OS X, JAWS on IE <= 9
18478		// JAWS announces deletions even when aria-relevant="additions"
18479		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18480		this.liveRegion.children().hide();
18481		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18482		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18483		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18484		a11yContent.appendTo( this.liveRegion );
18485
18486		function position( event ) {
18487			positionOption.of = event;
18488			if ( tooltip.is( ":hidden" ) ) {
18489				return;
18490			}
18491			tooltip.position( positionOption );
18492		}
18493		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18494			this._on( this.document, {
18495				mousemove: position
18496			} );
18497
18498			// trigger once to override element-relative positioning
18499			position( event );
18500		} else {
18501			tooltip.position( $.extend( {
18502				of: target
18503			}, this.options.position ) );
18504		}
18505
18506		tooltip.hide();
18507
18508		this._show( tooltip, this.options.show );
18509
18510		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18511		// as the tooltip is visible, position the tooltip using the most recent
18512		// event.
18513		// Adds the check to add the timers only when both delay and track options are set (#14682)
18514		if ( this.options.track && this.options.show && this.options.show.delay ) {
18515			delayedShow = this.delayedShow = setInterval( function() {
18516				if ( tooltip.is( ":visible" ) ) {
18517					position( positionOption.of );
18518					clearInterval( delayedShow );
18519				}
18520			}, $.fx.interval );
18521		}
18522
18523		this._trigger( "open", event, { tooltip: tooltip } );
18524	},
18525
18526	_registerCloseHandlers: function( event, target ) {
18527		var events = {
18528			keyup: function( event ) {
18529				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18530					var fakeEvent = $.Event( event );
18531					fakeEvent.currentTarget = target[ 0 ];
18532					this.close( fakeEvent, true );
18533				}
18534			}
18535		};
18536
18537		// Only bind remove handler for delegated targets. Non-delegated
18538		// tooltips will handle this in destroy.
18539		if ( target[ 0 ] !== this.element[ 0 ] ) {
18540			events.remove = function() {
18541				this._removeTooltip( this._find( target ).tooltip );
18542			};
18543		}
18544
18545		if ( !event || event.type === "mouseover" ) {
18546			events.mouseleave = "close";
18547		}
18548		if ( !event || event.type === "focusin" ) {
18549			events.focusout = "close";
18550		}
18551		this._on( true, target, events );
18552	},
18553
18554	close: function( event ) {
18555		var tooltip,
18556			that = this,
18557			target = $( event ? event.currentTarget : this.element ),
18558			tooltipData = this._find( target );
18559
18560		// The tooltip may already be closed
18561		if ( !tooltipData ) {
18562
18563			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18564			// additional data once there's actually content to show (in _open()). So even if the
18565			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18566			// the period between open() and _open().
18567			target.removeData( "ui-tooltip-open" );
18568			return;
18569		}
18570
18571		tooltip = tooltipData.tooltip;
18572
18573		// Disabling closes the tooltip, so we need to track when we're closing
18574		// to avoid an infinite loop in case the tooltip becomes disabled on close
18575		if ( tooltipData.closing ) {
18576			return;
18577		}
18578
18579		// Clear the interval for delayed tracking tooltips
18580		clearInterval( this.delayedShow );
18581
18582		// Only set title if we had one before (see comment in _open())
18583		// If the title attribute has changed since open(), don't restore
18584		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18585			target.attr( "title", target.data( "ui-tooltip-title" ) );
18586		}
18587
18588		this._removeDescribedBy( target );
18589
18590		tooltipData.hiding = true;
18591		tooltip.stop( true );
18592		this._hide( tooltip, this.options.hide, function() {
18593			that._removeTooltip( $( this ) );
18594		} );
18595
18596		target.removeData( "ui-tooltip-open" );
18597		this._off( target, "mouseleave focusout keyup" );
18598
18599		// Remove 'remove' binding only on delegated targets
18600		if ( target[ 0 ] !== this.element[ 0 ] ) {
18601			this._off( target, "remove" );
18602		}
18603		this._off( this.document, "mousemove" );
18604
18605		if ( event && event.type === "mouseleave" ) {
18606			$.each( this.parents, function( id, parent ) {
18607				$( parent.element ).attr( "title", parent.title );
18608				delete that.parents[ id ];
18609			} );
18610		}
18611
18612		tooltipData.closing = true;
18613		this._trigger( "close", event, { tooltip: tooltip } );
18614		if ( !tooltipData.hiding ) {
18615			tooltipData.closing = false;
18616		}
18617	},
18618
18619	_tooltip: function( element ) {
18620		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18621			content = $( "<div>" ).appendTo( tooltip ),
18622			id = tooltip.uniqueId().attr( "id" );
18623
18624		this._addClass( content, "ui-tooltip-content" );
18625		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18626
18627		tooltip.appendTo( this._appendTo( element ) );
18628
18629		return this.tooltips[ id ] = {
18630			element: element,
18631			tooltip: tooltip
18632		};
18633	},
18634
18635	_find: function( target ) {
18636		var id = target.data( "ui-tooltip-id" );
18637		return id ? this.tooltips[ id ] : null;
18638	},
18639
18640	_removeTooltip: function( tooltip ) {
18641		tooltip.remove();
18642		delete this.tooltips[ tooltip.attr( "id" ) ];
18643	},
18644
18645	_appendTo: function( target ) {
18646		var element = target.closest( ".ui-front, dialog" );
18647
18648		if ( !element.length ) {
18649			element = this.document[ 0 ].body;
18650		}
18651
18652		return element;
18653	},
18654
18655	_destroy: function() {
18656		var that = this;
18657
18658		// Close open tooltips
18659		$.each( this.tooltips, function( id, tooltipData ) {
18660
18661			// Delegate to close method to handle common cleanup
18662			var event = $.Event( "blur" ),
18663				element = tooltipData.element;
18664			event.target = event.currentTarget = element[ 0 ];
18665			that.close( event, true );
18666
18667			// Remove immediately; destroying an open tooltip doesn't use the
18668			// hide animation
18669			$( "#" + id ).remove();
18670
18671			// Restore the title
18672			if ( element.data( "ui-tooltip-title" ) ) {
18673
18674				// If the title attribute has changed since open(), don't restore
18675				if ( !element.attr( "title" ) ) {
18676					element.attr( "title", element.data( "ui-tooltip-title" ) );
18677				}
18678				element.removeData( "ui-tooltip-title" );
18679			}
18680		} );
18681		this.liveRegion.remove();
18682	}
18683} );
18684
18685// DEPRECATED
18686// TODO: Switch return back to widget declaration at top of file when this is removed
18687if ( $.uiBackCompat !== false ) {
18688
18689	// Backcompat for tooltipClass option
18690	$.widget( "ui.tooltip", $.ui.tooltip, {
18691		options: {
18692			tooltipClass: null
18693		},
18694		_tooltip: function() {
18695			var tooltipData = this._superApply( arguments );
18696			if ( this.options.tooltipClass ) {
18697				tooltipData.tooltip.addClass( this.options.tooltipClass );
18698			}
18699			return tooltipData;
18700		}
18701	} );
18702}
18703
18704var widgetsTooltip = $.ui.tooltip;
18705
18706
18707
18708
18709}));

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.