PageSourceSearch

https://www.praha11.cz/js/jquery-ui-114.js?ver=20260925061204

js praha11.cz collected 2026-09-25 05:05:19 UTC 521,054 bytes, 18,809 lines download raw bytes

1/*! jQuery UI - v1.14.1 - 2024-10-30
2* https://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-patch.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 OpenJS Foundation and other contributors; Licensed MIT */
5
6( function( factory ) {
7	"use strict";
8
9	if ( typeof define === "function" && define.amd ) {
10
11		// AMD. Register as an anonymous module.
12		define( [ "jquery" ], factory );
13	} else {
14
15		// Browser globals
16		factory( jQuery );
17	}
18} )( function( $ ) {
19"use strict";
20
21$.ui = $.ui || {};
22
23var version = $.ui.version = "1.14.1";
24
25
26/*!
27 * jQuery UI Widget 1.14.1
vendor: 20,126 bytes, lines 27-772
27
28 * https://jqueryui.com
29 *
30 * Copyright OpenJS Foundation and other contributors
31 * Released under the MIT license.
32 * https://jquery.org/license
33 */
34
35//>>label: Widget
36//>>group: Core
37//>>description: Provides a factory for creating stateful widgets with a common API.
38//>>docs: https://api.jqueryui.com/jQuery.widget/
39//>>demos: https://jqueryui.com/widget/
40
41
42var widgetUuid = 0;
43var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
44var widgetSlice = Array.prototype.slice;
45
46$.cleanData = ( function( orig ) {
47	return function( elems ) {
48		var events, elem, i;
49		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
50
51			// Only trigger remove when necessary to save time
52			events = $._data( elem, "events" );
53			if ( events && events.remove ) {
54				$( elem ).triggerHandler( "remove" );
55			}
56		}
57		orig( elems );
58	};
59} )( $.cleanData );
60
61$.widget = function( name, base, prototype ) {
62	var existingConstructor, constructor, basePrototype;
63
64	// ProxiedPrototype allows the provided prototype to remain unmodified
65	// so that it can be used as a mixin for multiple widgets (#8876)
66	var proxiedPrototype = {};
67
68	var namespace = name.split( "." )[ 0 ];
69	name = name.split( "." )[ 1 ];
70	if ( name === "__proto__" || name === "constructor" ) {
71		return $.error( "Invalid widget name: " + name );
72	}
73	var fullName = namespace + "-" + name;
74
75	if ( !prototype ) {
76		prototype = base;
77		base = $.Widget;
78	}
79
80	if ( Array.isArray( prototype ) ) {
81		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
82	}
83
84	// Create selector for plugin
85	$.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) {
86		return !!$.data( elem, fullName );
87	};
88
89	$[ namespace ] = $[ namespace ] || {};
90	existingConstructor = $[ namespace ][ name ];
91	constructor = $[ namespace ][ name ] = function( options, element ) {
92
93		// Allow instantiation without "new" keyword
94		if ( !this || !this._createWidget ) {
95			return new constructor( options, element );
96		}
97
98		// Allow instantiation without initializing for simple inheritance
99		// must use "new" keyword (the code above always passes args)
100		if ( arguments.length ) {
101			this._createWidget( options, element );
102		}
103	};
104
105	// Extend with the existing constructor to carry over any static properties
106	$.extend( constructor, existingConstructor, {
107		version: prototype.version,
108
109		// Copy the object used to create the prototype in case we need to
110		// redefine the widget later
111		_proto: $.extend( {}, prototype ),
112
113		// Track widgets that inherit from this widget in case this widget is
114		// redefined after a widget inherits from it
115		_childConstructors: []
116	} );
117
118	basePrototype = new base();
119
120	// We need to make the options hash a property directly on the new instance
121	// otherwise we'll modify the options hash on the prototype that we're
122	// inheriting from
123	basePrototype.options = $.widget.extend( {}, basePrototype.options );
124	$.each( prototype, function( prop, value ) {
125		if ( typeof value !== "function" ) {
126			proxiedPrototype[ prop ] = value;
127			return;
128		}
129		proxiedPrototype[ prop ] = ( function() {
130			function _super() {
131				return base.prototype[ prop ].apply( this, arguments );
132			}
133
134			function _superApply( args ) {
135				return base.prototype[ prop ].apply( this, args );
136			}
137
138			return function() {
139				var __super = this._super;
140				var __superApply = this._superApply;
141				var returnValue;
142
143				this._super = _super;
144				this._superApply = _superApply;
145
146				returnValue = value.apply( this, arguments );
147
148				this._super = __super;
149				this._superApply = __superApply;
150
151				return returnValue;
152			};
153		} )();
154	} );
155	constructor.prototype = $.widget.extend( basePrototype, {
156
157		// TODO: remove support for widgetEventPrefix
158		// always use the name + a colon as the prefix, e.g., draggable:start
159		// don't prefix for widgets that aren't DOM-based
160		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
161	}, proxiedPrototype, {
162		constructor: constructor,
163		namespace: namespace,
164		widgetName: name,
165		widgetFullName: fullName
166	} );
167
168	// If this widget is being redefined then we need to find all widgets that
169	// are inheriting from it and redefine all of them so that they inherit from
170	// the new version of this widget. We're essentially trying to replace one
171	// level in the prototype chain.
172	if ( existingConstructor ) {
173		$.each( existingConstructor._childConstructors, function( i, child ) {
174			var childPrototype = child.prototype;
175
176			// Redefine the child widget using the same prototype that was
177			// originally used, but inherit from the new version of the base
178			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
179				child._proto );
180		} );
181
182		// Remove the list of existing child constructors from the old constructor
183		// so the old child constructors can be garbage collected
184		delete existingConstructor._childConstructors;
185	} else {
186		base._childConstructors.push( constructor );
187	}
188
189	$.widget.bridge( name, constructor );
190
191	return constructor;
192};
193
194$.widget.extend = function( target ) {
195	var input = widgetSlice.call( arguments, 1 );
196	var inputIndex = 0;
197	var inputLength = input.length;
198	var key;
199	var value;
200
201	for ( ; inputIndex < inputLength; inputIndex++ ) {
202		for ( key in input[ inputIndex ] ) {
203			value = input[ inputIndex ][ key ];
204			if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) {
205
206				// Clone objects
207				if ( $.isPlainObject( value ) ) {
208					target[ key ] = $.isPlainObject( target[ key ] ) ?
209						$.widget.extend( {}, target[ key ], value ) :
210
211						// Don't extend strings, arrays, etc. with objects
212						$.widget.extend( {}, value );
213
214				// Copy everything else by reference
215				} else {
216					target[ key ] = value;
217				}
218			}
219		}
220	}
221	return target;
222};
223
224$.widget.bridge = function( name, object ) {
225	var fullName = object.prototype.widgetFullName || name;
226	$.fn[ name ] = function( options ) {
227		var isMethodCall = typeof options === "string";
228		var args = widgetSlice.call( arguments, 1 );
229		var returnValue = this;
230
231		if ( isMethodCall ) {
232
233			// If this is an empty collection, we need to have the instance method
234			// return undefined instead of the jQuery instance
235			if ( !this.length && options === "instance" ) {
236				returnValue = undefined;
237			} else {
238				this.each( function() {
239					var methodValue;
240					var instance = $.data( this, fullName );
241
242					if ( options === "instance" ) {
243						returnValue = instance;
244						return false;
245					}
246
247					if ( !instance ) {
248						return $.error( "cannot call methods on " + name +
249							" prior to initialization; " +
250							"attempted to call method '" + options + "'" );
251					}
252
253					if ( typeof instance[ options ] !== "function" ||
254						options.charAt( 0 ) === "_" ) {
255						return $.error( "no such method '" + options + "' for " + name +
256							" widget instance" );
257					}
258
259					methodValue = instance[ options ].apply( instance, args );
260
261					if ( methodValue !== instance && methodValue !== undefined ) {
262						returnValue = methodValue && methodValue.jquery ?
263							returnValue.pushStack( methodValue.get() ) :
264							methodValue;
265						return false;
266					}
267				} );
268			}
269		} else {
270
271			// Allow multiple hashes to be passed on init
272			if ( args.length ) {
273				options = $.widget.extend.apply( null, [ options ].concat( args ) );
274			}
275
276			this.each( function() {
277				var instance = $.data( this, fullName );
278				if ( instance ) {
279					instance.option( options || {} );
280					if ( instance._init ) {
281						instance._init();
282					}
283				} else {
284					$.data( this, fullName, new object( options, this ) );
285				}
286			} );
287		}
288
289		return returnValue;
290	};
291};
292
293$.Widget = function( /* options, element */ ) {};
294$.Widget._childConstructors = [];
295
296$.Widget.prototype = {
297	widgetName: "widget",
298	widgetEventPrefix: "",
299	defaultElement: "<div>",
300
301	options: {
302		classes: {},
303		disabled: false,
304
305		// Callbacks
306		create: null
307	},
308
309	_createWidget: function( options, element ) {
310		element = $( element || this.defaultElement || this )[ 0 ];
311		this.element = $( element );
312		this.uuid = widgetUuid++;
313		this.eventNamespace = "." + this.widgetName + this.uuid;
314
315		this.bindings = $();
316		this.hoverable = $();
317		this.focusable = $();
318		this.classesElementLookup = {};
319
320		if ( element !== this ) {
321			$.data( element, this.widgetFullName, this );
322			this._on( true, this.element, {
323				remove: function( event ) {
324					if ( event.target === element ) {
325						this.destroy();
326					}
327				}
328			} );
329			this.document = $( element.style ?
330
331				// Element within the document
332				element.ownerDocument :
333
334				// Element is window or document
335				element.document || element );
336			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
337		}
338
339		this.options = $.widget.extend( {},
340			this.options,
341			this._getCreateOptions(),
342			options );
343
344		this._create();
345
346		if ( this.options.disabled ) {
347			this._setOptionDisabled( this.options.disabled );
348		}
349
350		this._trigger( "create", null, this._getCreateEventData() );
351		this._init();
352	},
353
354	_getCreateOptions: function() {
355		return {};
356	},
357
358	_getCreateEventData: $.noop,
359
360	_create: $.noop,
361
362	_init: $.noop,
363
364	destroy: function() {
365		var that = this;
366
367		this._destroy();
368		$.each( this.classesElementLookup, function( key, value ) {
369			that._removeClass( value, key );
370		} );
371
372		// We can probably remove the unbind calls in 2.0
373		// all event bindings should go through this._on()
374		this.element
375			.off( this.eventNamespace )
376			.removeData( this.widgetFullName );
377		this.widget()
378			.off( this.eventNamespace )
379			.removeAttr( "aria-disabled" );
380
381		// Clean up events and states
382		this.bindings.off( this.eventNamespace );
383	},
384
385	_destroy: $.noop,
386
387	widget: function() {
388		return this.element;
389	},
390
391	option: function( key, value ) {
392		var options = key;
393		var parts;
394		var curOption;
395		var i;
396
397		if ( arguments.length === 0 ) {
398
399			// Don't return a reference to the internal hash
400			return $.widget.extend( {}, this.options );
401		}
402
403		if ( typeof key === "string" ) {
404
405			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
406			options = {};
407			parts = key.split( "." );
408			key = parts.shift();
409			if ( parts.length ) {
410				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
411				for ( i = 0; i < parts.length - 1; i++ ) {
412					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
413					curOption = curOption[ parts[ i ] ];
414				}
415				key = parts.pop();
416				if ( arguments.length === 1 ) {
417					return curOption[ key ] === undefined ? null : curOption[ key ];
418				}
419				curOption[ key ] = value;
420			} else {
421				if ( arguments.length === 1 ) {
422					return this.options[ key ] === undefined ? null : this.options[ key ];
423				}
424				options[ key ] = value;
425			}
426		}
427
428		this._setOptions( options );
429
430		return this;
431	},
432
433	_setOptions: function( options ) {
434		var key;
435
436		for ( key in options ) {
437			this._setOption( key, options[ key ] );
438		}
439
440		return this;
441	},
442
443	_setOption: function( key, value ) {
444		if ( key === "classes" ) {
445			this._setOptionClasses( value );
446		}
447
448		this.options[ key ] = value;
449
450		if ( key === "disabled" ) {
451			this._setOptionDisabled( value );
452		}
453
454		return this;
455	},
456
457	_setOptionClasses: function( value ) {
458		var classKey, elements, currentElements;
459
460		for ( classKey in value ) {
461			currentElements = this.classesElementLookup[ classKey ];
462			if ( value[ classKey ] === this.options.classes[ classKey ] ||
463					!currentElements ||
464					!currentElements.length ) {
465				continue;
466			}
467
468			// We are doing this to create a new jQuery object because the _removeClass() call
469			// on the next line is going to destroy the reference to the current elements being
470			// tracked. We need to save a copy of this collection so that we can add the new classes
471			// below.
472			elements = $( currentElements.get() );
473			this._removeClass( currentElements, classKey );
474
475			// We don't use _addClass() here, because that uses this.options.classes
476			// for generating the string of classes. We want to use the value passed in from
477			// _setOption(), this is the new value of the classes option which was passed to
478			// _setOption(). We pass this value directly to _classes().
479			elements.addClass( this._classes( {
480				element: elements,
481				keys: classKey,
482				classes: value,
483				add: true
484			} ) );
485		}
486	},
487
488	_setOptionDisabled: function( value ) {
489		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
490
491		// If the widget is becoming disabled, then nothing is interactive
492		if ( value ) {
493			this._removeClass( this.hoverable, null, "ui-state-hover" );
494			this._removeClass( this.focusable, null, "ui-state-focus" );
495		}
496	},
497
498	enable: function() {
499		return this._setOptions( { disabled: false } );
500	},
501
502	disable: function() {
503		return this._setOptions( { disabled: true } );
504	},
505
506	_classes: function( options ) {
507		var full = [];
508		var that = this;
509
510		options = $.extend( {
511			element: this.element,
512			classes: this.options.classes || {}
513		}, options );
514
515		function bindRemoveEvent() {
516			var nodesToBind = [];
517
518			options.element.each( function( _, element ) {
519				var isTracked = $.map( that.classesElementLookup, function( elements ) {
520					return elements;
521				} )
522					.some( function( elements ) {
523						return elements.is( element );
524					} );
525
526				if ( !isTracked ) {
527					nodesToBind.push( element );
528				}
529			} );
530
531			that._on( $( nodesToBind ), {
532				remove: "_untrackClassesElement"
533			} );
534		}
535
536		function processClassString( classes, checkOption ) {
537			var current, i;
538			for ( i = 0; i < classes.length; i++ ) {
539				current = that.classesElementLookup[ classes[ i ] ] || $();
540				if ( options.add ) {
541					bindRemoveEvent();
542					current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) );
543				} else {
544					current = $( current.not( options.element ).get() );
545				}
546				that.classesElementLookup[ classes[ i ] ] = current;
547				full.push( classes[ i ] );
548				if ( checkOption && options.classes[ classes[ i ] ] ) {
549					full.push( options.classes[ classes[ i ] ] );
550				}
551			}
552		}
553
554		if ( options.keys ) {
555			processClassString( options.keys.match( /\S+/g ) || [], true );
556		}
557		if ( options.extra ) {
558			processClassString( options.extra.match( /\S+/g ) || [] );
559		}
560
561		return full.join( " " );
562	},
563
564	_untrackClassesElement: function( event ) {
565		var that = this;
566		$.each( that.classesElementLookup, function( key, value ) {
567			if ( $.inArray( event.target, value ) !== -1 ) {
568				that.classesElementLookup[ key ] = $( value.not( event.target ).get() );
569			}
570		} );
571
572		this._off( $( event.target ) );
573	},
574
575	_removeClass: function( element, keys, extra ) {
576		return this._toggleClass( element, keys, extra, false );
577	},
578
579	_addClass: function( element, keys, extra ) {
580		return this._toggleClass( element, keys, extra, true );
581	},
582
583	_toggleClass: function( element, keys, extra, add ) {
584		add = ( typeof add === "boolean" ) ? add : extra;
585		var shift = ( typeof element === "string" || element === null ),
586			options = {
587				extra: shift ? keys : extra,
588				keys: shift ? element : keys,
589				element: shift ? this.element : element,
590				add: add
591			};
592		options.element.toggleClass( this._classes( options ), add );
593		return this;
594	},
595
596	_on: function( suppressDisabledCheck, element, handlers ) {
597		var delegateElement;
598		var instance = this;
599
600		// No suppressDisabledCheck flag, shuffle arguments
601		if ( typeof suppressDisabledCheck !== "boolean" ) {
602			handlers = element;
603			element = suppressDisabledCheck;
604			suppressDisabledCheck = false;
605		}
606
607		// No element argument, shuffle and use this.element
608		if ( !handlers ) {
609			handlers = element;
610			element = this.element;
611			delegateElement = this.widget();
612		} else {
613			element = delegateElement = $( element );
614			this.bindings = this.bindings.add( element );
615		}
616
617		$.each( handlers, function( event, handler ) {
618			function handlerProxy() {
619
620				// Allow widgets to customize the disabled handling
621				// - disabled as an array instead of boolean
622				// - disabled class as method for disabling individual parts
623				if ( !suppressDisabledCheck &&
624						( instance.options.disabled === true ||
625						$( this ).hasClass( "ui-state-disabled" ) ) ) {
626					return;
627				}
628				return ( typeof handler === "string" ? instance[ handler ] : handler )
629					.apply( instance, arguments );
630			}
631
632			// Copy the guid so direct unbinding works
633			if ( typeof handler !== "string" ) {
634				handlerProxy.guid = handler.guid =
635					handler.guid || handlerProxy.guid || $.guid++;
636			}
637
638			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
639			var eventName = match[ 1 ] + instance.eventNamespace;
640			var selector = match[ 2 ];
641
642			if ( selector ) {
643				delegateElement.on( eventName, selector, handlerProxy );
644			} else {
645				element.on( eventName, handlerProxy );
646			}
647		} );
648	},
649
650	_off: function( element, eventName ) {
651		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
652			this.eventNamespace;
653		element.off( eventName );
654
655		// Clear the stack to avoid memory leaks (#10056)
656		this.bindings = $( this.bindings.not( element ).get() );
657		this.focusable = $( this.focusable.not( element ).get() );
658		this.hoverable = $( this.hoverable.not( element ).get() );
659	},
660
661	_delay: function( handler, delay ) {
662		function handlerProxy() {
663			return ( typeof handler === "string" ? instance[ handler ] : handler )
664				.apply( instance, arguments );
665		}
666		var instance = this;
667		return setTimeout( handlerProxy, delay || 0 );
668	},
669
670	_hoverable: function( element ) {
671		this.hoverable = this.hoverable.add( element );
672		this._on( element, {
673			mouseenter: function( event ) {
674				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
675			},
676			mouseleave: function( event ) {
677				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
678			}
679		} );
680	},
681
682	_focusable: function( element ) {
683		this.focusable = this.focusable.add( element );
684		this._on( element, {
685			focusin: function( event ) {
686				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
687			},
688			focusout: function( event ) {
689				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
690			}
691		} );
692	},
693
694	_trigger: function( type, event, data ) {
695		var prop, orig;
696		var callback = this.options[ type ];
697
698		data = data || {};
699		event = $.Event( event );
700		event.type = ( type === this.widgetEventPrefix ?
701			type :
702			this.widgetEventPrefix + type ).toLowerCase();
703
704		// The original event may come from any element
705		// so we need to reset the target on the new event
706		event.target = this.element[ 0 ];
707
708		// Copy original event properties over to the new event
709		orig = event.originalEvent;
710		if ( orig ) {
711			for ( prop in orig ) {
712				if ( !( prop in event ) ) {
713					event[ prop ] = orig[ prop ];
714				}
715			}
716		}
717
718		this.element.trigger( event, data );
719		return !( typeof callback === "function" &&
720			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
721			event.isDefaultPrevented() );
722	}
723};
724
725$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
726	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
727		if ( typeof options === "string" ) {
728			options = { effect: options };
729		}
730
731		var hasOptions;
732		var effectName = !options ?
733			method :
734			options === true || typeof options === "number" ?
735				defaultEffect :
736				options.effect || defaultEffect;
737
738		options = options || {};
739		if ( typeof options === "number" ) {
740			options = { duration: options };
741		} else if ( options === true ) {
742			options = {};
743		}
744
745		hasOptions = !$.isEmptyObject( options );
746		options.complete = callback;
747
748		if ( options.delay ) {
749			element.delay( options.delay );
750		}
751
752		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
753			element[ method ]( options );
754		} else if ( effectName !== method && element[ effectName ] ) {
755			element[ effectName ]( options.duration, options.easing, callback );
756		} else {
757			element.queue( function( next ) {
758				$( this )[ method ]();
759				if ( callback ) {
760					callback.call( element[ 0 ] );
761				}
762				next();
763			} );
764		}
765	};
766} );
767
768var widget = $.widget;
769
770
771/*!
772 * jQuery UI Position 1.14.
vendor: 3,861 bytes, lines 772-915
7721
773 * https://jqueryui.com
774 *
775 * Copyright OpenJS Foundation and other contributors
776 * Released under the MIT license.
777 * https://jquery.org/license
778 *
779 * https://api.jqueryui.com/position/
780 */
781
782//>>label: Position
783//>>group: Core
784//>>description: Positions elements relative to other elements.
785//>>docs: https://api.jqueryui.com/position/
786//>>demos: https://jqueryui.com/position/
787
788
789( function() {
790var cachedScrollbarWidth,
791	max = Math.max,
792	abs = Math.abs,
793	rhorizontal = /left|center|right/,
794	rvertical = /top|center|bottom/,
795	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
796	rposition = /^\w+/,
797	rpercent = /%$/,
798	_position = $.fn.position;
799
800function getOffsets( offsets, width, height ) {
801	return [
802		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
803		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
804	];
805}
806
807function parseCss( element, property ) {
808	return parseInt( $.css( element, property ), 10 ) || 0;
809}
810
811function isWindow( obj ) {
812	return obj != null && obj === obj.window;
813}
814
815function getDimensions( elem ) {
816	var raw = elem[ 0 ];
817	if ( raw.nodeType === 9 ) {
818		return {
819			width: elem.width(),
820			height: elem.height(),
821			offset: { top: 0, left: 0 }
822		};
823	}
824	if ( isWindow( raw ) ) {
825		return {
826			width: elem.width(),
827			height: elem.height(),
828			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
829		};
830	}
831	if ( raw.preventDefault ) {
832		return {
833			width: 0,
834			height: 0,
835			offset: { top: raw.pageY, left: raw.pageX }
836		};
837	}
838	return {
839		width: elem.outerWidth(),
840		height: elem.outerHeight(),
841		offset: elem.offset()
842	};
843}
844
845$.position = {
846	scrollbarWidth: function() {
847		if ( cachedScrollbarWidth !== undefined ) {
848			return cachedScrollbarWidth;
849		}
850		var w1, w2,
851			div = $( "<div style=" +
852				"'display:block;position:absolute;width:200px;height:200px;overflow:hidden;'>" +
853				"<div style='height:300px;width:auto;'></div></div>" ),
854			innerDiv = div.children()[ 0 ];
855
856		$( "body" ).append( div );
857		w1 = innerDiv.offsetWidth;
858		div.css( "overflow", "scroll" );
859
860		w2 = innerDiv.offsetWidth;
861
862		if ( w1 === w2 ) {
863			w2 = div[ 0 ].clientWidth;
864		}
865
866		div.remove();
867
868		return ( cachedScrollbarWidth = w1 - w2 );
869	},
870	getScrollInfo: function( within ) {
871		var overflowX = within.isWindow || within.isDocument ? "" :
872				within.element.css( "overflow-x" ),
873			overflowY = within.isWindow || within.isDocument ? "" :
874				within.element.css( "overflow-y" ),
875			hasOverflowX = overflowX === "scroll" ||
876				( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ),
877			hasOverflowY = overflowY === "scroll" ||
878				( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight );
879		return {
880			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
881			height: hasOverflowX ? $.position.scrollbarWidth() : 0
882		};
883	},
884	getWithinInfo: function( element ) {
885		var withinElement = $( element || window ),
886			isElemWindow = isWindow( withinElement[ 0 ] ),
887			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9,
888			hasOffset = !isElemWindow && !isDocument;
889		return {
890			element: withinElement,
891			isWindow: isElemWindow,
892			isDocument: isDocument,
893			offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 },
894			scrollLeft: withinElement.scrollLeft(),
895			scrollTop: withinElement.scrollTop(),
896			width: withinElement.outerWidth(),
897			height: withinElement.outerHeight()
898		};
899	}
900};
901
902$.fn.position = function( options ) {
903	if ( !options || !options.of ) {
904		return _position.apply( this, arguments );
905	}
906
907	// Make a copy, we don't want to modify arguments
908	options = $.extend( {}, options );
909
910	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
911
912		// Make sure string options are treated as CSS selectors
913		target = typeof options.of === "string" ?
914			$( document ).find( options.of ) :
915			$( options.of ),
vendor: 10,992 bytes, lines 916-1269
916
917		within = $.position.getWithinInfo( options.within ),
918		scrollInfo = $.position.getScrollInfo( within ),
919		collision = ( options.collision || "flip" ).split( " " ),
920		offsets = {};
921
922	dimensions = getDimensions( target );
923	if ( target[ 0 ].preventDefault ) {
924
925		// Force left top to allow flipping
926		options.at = "left top";
927	}
928	targetWidth = dimensions.width;
929	targetHeight = dimensions.height;
930	targetOffset = dimensions.offset;
931
932	// Clone to reuse original targetOffset later
933	basePosition = $.extend( {}, targetOffset );
934
935	// Force my and at to have valid horizontal and vertical positions
936	// if a value is missing or invalid, it will be converted to center
937	$.each( [ "my", "at" ], function() {
938		var pos = ( options[ this ] || "" ).split( " " ),
939			horizontalOffset,
940			verticalOffset;
941
942		if ( pos.length === 1 ) {
943			pos = rhorizontal.test( pos[ 0 ] ) ?
944				pos.concat( [ "center" ] ) :
945				rvertical.test( pos[ 0 ] ) ?
946					[ "center" ].concat( pos ) :
947					[ "center", "center" ];
948		}
949		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
950		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
951
952		// Calculate offsets
953		horizontalOffset = roffset.exec( pos[ 0 ] );
954		verticalOffset = roffset.exec( pos[ 1 ] );
955		offsets[ this ] = [
956			horizontalOffset ? horizontalOffset[ 0 ] : 0,
957			verticalOffset ? verticalOffset[ 0 ] : 0
958		];
959
960		// Reduce to just the positions without the offsets
961		options[ this ] = [
962			rposition.exec( pos[ 0 ] )[ 0 ],
963			rposition.exec( pos[ 1 ] )[ 0 ]
964		];
965	} );
966
967	// Normalize collision option
968	if ( collision.length === 1 ) {
969		collision[ 1 ] = collision[ 0 ];
970	}
971
972	if ( options.at[ 0 ] === "right" ) {
973		basePosition.left += targetWidth;
974	} else if ( options.at[ 0 ] === "center" ) {
975		basePosition.left += targetWidth / 2;
976	}
977
978	if ( options.at[ 1 ] === "bottom" ) {
979		basePosition.top += targetHeight;
980	} else if ( options.at[ 1 ] === "center" ) {
981		basePosition.top += targetHeight / 2;
982	}
983
984	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
985	basePosition.left += atOffset[ 0 ];
986	basePosition.top += atOffset[ 1 ];
987
988	return this.each( function() {
989		var collisionPosition, using,
990			elem = $( this ),
991			elemWidth = elem.outerWidth(),
992			elemHeight = elem.outerHeight(),
993			marginLeft = parseCss( this, "marginLeft" ),
994			marginTop = parseCss( this, "marginTop" ),
995			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) +
996				scrollInfo.width,
997			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) +
998				scrollInfo.height,
999			position = $.extend( {}, basePosition ),
1000			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
1001
1002		if ( options.my[ 0 ] === "right" ) {
1003			position.left -= elemWidth;
1004		} else if ( options.my[ 0 ] === "center" ) {
1005			position.left -= elemWidth / 2;
1006		}
1007
1008		if ( options.my[ 1 ] === "bottom" ) {
1009			position.top -= elemHeight;
1010		} else if ( options.my[ 1 ] === "center" ) {
1011			position.top -= elemHeight / 2;
1012		}
1013
1014		position.left += myOffset[ 0 ];
1015		position.top += myOffset[ 1 ];
1016
1017		collisionPosition = {
1018			marginLeft: marginLeft,
1019			marginTop: marginTop
1020		};
1021
1022		$.each( [ "left", "top" ], function( i, dir ) {
1023			if ( $.ui.position[ collision[ i ] ] ) {
1024				$.ui.position[ collision[ i ] ][ dir ]( position, {
1025					targetWidth: targetWidth,
1026					targetHeight: targetHeight,
1027					elemWidth: elemWidth,
1028					elemHeight: elemHeight,
1029					collisionPosition: collisionPosition,
1030					collisionWidth: collisionWidth,
1031					collisionHeight: collisionHeight,
1032					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
1033					my: options.my,
1034					at: options.at,
1035					within: within,
1036					elem: elem
1037				} );
1038			}
1039		} );
1040
1041		if ( options.using ) {
1042
1043			// Adds feedback as second argument to using callback, if present
1044			using = function( props ) {
1045				var left = targetOffset.left - position.left,
1046					right = left + targetWidth - elemWidth,
1047					top = targetOffset.top - position.top,
1048					bottom = top + targetHeight - elemHeight,
1049					feedback = {
1050						target: {
1051							element: target,
1052							left: targetOffset.left,
1053							top: targetOffset.top,
1054							width: targetWidth,
1055							height: targetHeight
1056						},
1057						element: {
1058							element: elem,
1059							left: position.left,
1060							top: position.top,
1061							width: elemWidth,
1062							height: elemHeight
1063						},
1064						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
1065						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
1066					};
1067				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
1068					feedback.horizontal = "center";
1069				}
1070				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
1071					feedback.vertical = "middle";
1072				}
1073				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
1074					feedback.important = "horizontal";
1075				} else {
1076					feedback.important = "vertical";
1077				}
1078				options.using.call( this, props, feedback );
1079			};
1080		}
1081
1082		elem.offset( $.extend( position, { using: using } ) );
1083	} );
1084};
1085
1086$.ui.position = {
1087	fit: {
1088		left: function( position, data ) {
1089			var within = data.within,
1090				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
1091				outerWidth = within.width,
1092				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1093				overLeft = withinOffset - collisionPosLeft,
1094				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
1095				newOverRight;
1096
1097			// Element is wider than within
1098			if ( data.collisionWidth > outerWidth ) {
1099
1100				// Element is initially over the left side of within
1101				if ( overLeft > 0 && overRight <= 0 ) {
1102					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth -
1103						withinOffset;
1104					position.left += overLeft - newOverRight;
1105
1106				// Element is initially over right side of within
1107				} else if ( overRight > 0 && overLeft <= 0 ) {
1108					position.left = withinOffset;
1109
1110				// Element is initially over both left and right sides of within
1111				} else {
1112					if ( overLeft > overRight ) {
1113						position.left = withinOffset + outerWidth - data.collisionWidth;
1114					} else {
1115						position.left = withinOffset;
1116					}
1117				}
1118
1119			// Too far left -> align with left edge
1120			} else if ( overLeft > 0 ) {
1121				position.left += overLeft;
1122
1123			// Too far right -> align with right edge
1124			} else if ( overRight > 0 ) {
1125				position.left -= overRight;
1126
1127			// Adjust based on position and margin
1128			} else {
1129				position.left = max( position.left - collisionPosLeft, position.left );
1130			}
1131		},
1132		top: function( position, data ) {
1133			var within = data.within,
1134				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
1135				outerHeight = data.within.height,
1136				collisionPosTop = position.top - data.collisionPosition.marginTop,
1137				overTop = withinOffset - collisionPosTop,
1138				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
1139				newOverBottom;
1140
1141			// Element is taller than within
1142			if ( data.collisionHeight > outerHeight ) {
1143
1144				// Element is initially over the top of within
1145				if ( overTop > 0 && overBottom <= 0 ) {
1146					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight -
1147						withinOffset;
1148					position.top += overTop - newOverBottom;
1149
1150				// Element is initially over bottom of within
1151				} else if ( overBottom > 0 && overTop <= 0 ) {
1152					position.top = withinOffset;
1153
1154				// Element is initially over both top and bottom of within
1155				} else {
1156					if ( overTop > overBottom ) {
1157						position.top = withinOffset + outerHeight - data.collisionHeight;
1158					} else {
1159						position.top = withinOffset;
1160					}
1161				}
1162
1163			// Too far up -> align with top
1164			} else if ( overTop > 0 ) {
1165				position.top += overTop;
1166
1167			// Too far down -> align with bottom edge
1168			} else if ( overBottom > 0 ) {
1169				position.top -= overBottom;
1170
1171			// Adjust based on position and margin
1172			} else {
1173				position.top = max( position.top - collisionPosTop, position.top );
1174			}
1175		}
1176	},
1177	flip: {
1178		left: function( position, data ) {
1179			var within = data.within,
1180				withinOffset = within.offset.left + within.scrollLeft,
1181				outerWidth = within.width,
1182				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
1183				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
1184				overLeft = collisionPosLeft - offsetLeft,
1185				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
1186				myOffset = data.my[ 0 ] === "left" ?
1187					-data.elemWidth :
1188					data.my[ 0 ] === "right" ?
1189						data.elemWidth :
1190						0,
1191				atOffset = data.at[ 0 ] === "left" ?
1192					data.targetWidth :
1193					data.at[ 0 ] === "right" ?
1194						-data.targetWidth :
1195						0,
1196				offset = -2 * data.offset[ 0 ],
1197				newOverRight,
1198				newOverLeft;
1199
1200			if ( overLeft < 0 ) {
1201				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth -
1202					outerWidth - withinOffset;
1203				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
1204					position.left += myOffset + atOffset + offset;
1205				}
1206			} else if ( overRight > 0 ) {
1207				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset +
1208					atOffset + offset - offsetLeft;
1209				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
1210					position.left += myOffset + atOffset + offset;
1211				}
1212			}
1213		},
1214		top: function( position, data ) {
1215			var within = data.within,
1216				withinOffset = within.offset.top + within.scrollTop,
1217				outerHeight = within.height,
1218				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
1219				collisionPosTop = position.top - data.collisionPosition.marginTop,
1220				overTop = collisionPosTop - offsetTop,
1221				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
1222				top = data.my[ 1 ] === "top",
1223				myOffset = top ?
1224					-data.elemHeight :
1225					data.my[ 1 ] === "bottom" ?
1226						data.elemHeight :
1227						0,
1228				atOffset = data.at[ 1 ] === "top" ?
1229					data.targetHeight :
1230					data.at[ 1 ] === "bottom" ?
1231						-data.targetHeight :
1232						0,
1233				offset = -2 * data.offset[ 1 ],
1234				newOverTop,
1235				newOverBottom;
1236			if ( overTop < 0 ) {
1237				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight -
1238					outerHeight - withinOffset;
1239				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
1240					position.top += myOffset + atOffset + offset;
1241				}
1242			} else if ( overBottom > 0 ) {
1243				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset +
1244					offset - offsetTop;
1245				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
1246					position.top += myOffset + atOffset + offset;
1247				}
1248			}
1249		}
1250	},
1251	flipfit: {
1252		left: function() {
1253			$.ui.position.flip.left.apply( this, arguments );
1254			$.ui.position.fit.left.apply( this, arguments );
1255		},
1256		top: function() {
1257			$.ui.position.flip.top.apply( this, arguments );
1258			$.ui.position.fit.top.apply( this, arguments );
1259		}
1260	}
1261};
1262
1263} )();
1264
1265var position = $.ui.position;
1266
1267
1268/*!
1269 * jQuery UI :data 1.1
12694.1
1270 * https://jqueryui.com
1271 *
1272 * Copyright OpenJS Foundation and other contributors
1273 * Released under the MIT license.
1274 * https://jquery.org/license
1275 */
1276
1277//>>label: :data Selector
1278//>>group: Core
1279//>>description: Selects elements which have data stored under the specified key.
1280//>>docs: https://api.jqueryui.com/data-selector/
1281
1282
1283var data = $.extend( $.expr.pseudos, {
1284	data: $.expr.createPseudo( function( dataName ) {
1285		return function( elem ) {
1286			return !!$.data( elem, dataName );
1287		};
1288	} )
1289} );
1290
1291/*!
1292 * jQuery UI Disable Selection 1.14.1
vendor: 16,993 bytes, lines 1292-2012
1292
1293 * https://jqueryui.com
1294 *
1295 * Copyright OpenJS Foundation and other contributors
1296 * Released under the MIT license.
1297 * https://jquery.org/license
1298 */
1299
1300//>>label: disableSelection
1301//>>group: Core
1302//>>description: Disable selection of text content within the set of matched elements.
1303//>>docs: https://api.jqueryui.com/disableSelection/
1304
1305// This file is deprecated
1306
1307var disableSelection = $.fn.extend( {
1308	disableSelection: ( function() {
1309		var eventType = "onselectstart" in document.createElement( "div" ) ?
1310			"selectstart" :
1311			"mousedown";
1312
1313		return function() {
1314			return this.on( eventType + ".ui-disableSelection", function( event ) {
1315				event.preventDefault();
1316			} );
1317		};
1318	} )(),
1319
1320	enableSelection: function() {
1321		return this.off( ".ui-disableSelection" );
1322	}
1323} );
1324
1325
1326
1327// Create a local jQuery because jQuery Color relies on it and the
1328// global may not exist with AMD and a custom build (#10199).
1329// This module is a noop if used as a regular AMD module.
1330// eslint-disable-next-line no-unused-vars
1331var jQuery = $;
1332
1333
1334/*!
1335 * jQuery Color Animations v3.0.0
1336 * https://github.com/jquery/jquery-color
1337 *
1338 * Copyright OpenJS Foundation and other contributors
1339 * Released under the MIT license.
1340 * https://jquery.org/license
1341 *
1342 * Date: Wed May 15 16:49:44 2024 +0200
1343 */
1344
1345
1346	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
1347		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
1348
1349	class2type = {},
1350	toString = class2type.toString,
1351
1352	// plusequals test for += 100 -= 100
1353	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
1354
1355	// a set of RE's that can match strings and generate color tuples.
1356	stringParsers = [ {
1357			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1358			parse: function( execResult ) {
1359				return [
1360					execResult[ 1 ],
1361					execResult[ 2 ],
1362					execResult[ 3 ],
1363					execResult[ 4 ]
1364				];
1365			}
1366		}, {
1367			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1368			parse: function( execResult ) {
1369				return [
1370					execResult[ 1 ] * 2.55,
1371					execResult[ 2 ] * 2.55,
1372					execResult[ 3 ] * 2.55,
1373					execResult[ 4 ]
1374				];
1375			}
1376		}, {
1377
1378			// this regex ignores A-F because it's compared against an already lowercased string
1379			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/,
1380			parse: function( execResult ) {
1381				return [
1382					parseInt( execResult[ 1 ], 16 ),
1383					parseInt( execResult[ 2 ], 16 ),
1384					parseInt( execResult[ 3 ], 16 ),
1385					execResult[ 4 ] ?
1386						( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) :
1387						1
1388				];
1389			}
1390		}, {
1391
1392			// this regex ignores A-F because it's compared against an already lowercased string
1393			re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/,
1394			parse: function( execResult ) {
1395				return [
1396					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
1397					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
1398					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ),
1399					execResult[ 4 ] ?
1400						( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 )
1401							.toFixed( 2 ) :
1402						1
1403				];
1404			}
1405		}, {
1406			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
1407			space: "hsla",
1408			parse: function( execResult ) {
1409				return [
1410					execResult[ 1 ],
1411					execResult[ 2 ] / 100,
1412					execResult[ 3 ] / 100,
1413					execResult[ 4 ]
1414				];
1415			}
1416		} ],
1417
1418	// jQuery.Color( )
1419	color = jQuery.Color = function( color, green, blue, alpha ) {
1420		return new jQuery.Color.fn.parse( color, green, blue, alpha );
1421	},
1422	spaces = {
1423		rgba: {
1424			props: {
1425				red: {
1426					idx: 0,
1427					type: "byte"
1428				},
1429				green: {
1430					idx: 1,
1431					type: "byte"
1432				},
1433				blue: {
1434					idx: 2,
1435					type: "byte"
1436				}
1437			}
1438		},
1439
1440		hsla: {
1441			props: {
1442				hue: {
1443					idx: 0,
1444					type: "degrees"
1445				},
1446				saturation: {
1447					idx: 1,
1448					type: "percent"
1449				},
1450				lightness: {
1451					idx: 2,
1452					type: "percent"
1453				}
1454			}
1455		}
1456	},
1457	propTypes = {
1458		"byte": {
1459			floor: true,
1460			max: 255
1461		},
1462		"percent": {
1463			max: 1
1464		},
1465		"degrees": {
1466			mod: 360,
1467			floor: true
1468		}
1469	},
1470
1471	// colors = jQuery.Color.names
1472	colors,
1473
1474	// local aliases of functions called often
1475	each = jQuery.each;
1476
1477// define cache name and alpha properties
1478// for rgba and hsla spaces
1479each( spaces, function( spaceName, space ) {
1480	space.cache = "_" + spaceName;
1481	space.props.alpha = {
1482		idx: 3,
1483		type: "percent",
1484		def: 1
1485	};
1486} );
1487
1488// Populate the class2type map
1489jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
1490	function( _i, name ) {
1491		class2type[ "[object " + name + "]" ] = name.toLowerCase();
1492	} );
1493
1494function getType( obj ) {
1495	if ( obj == null ) {
1496		return obj + "";
1497	}
1498
1499	return typeof obj === "object" ?
1500		class2type[ toString.call( obj ) ] || "object" :
1501		typeof obj;
1502}
1503
1504function clamp( value, prop, allowEmpty ) {
1505	var type = propTypes[ prop.type ] || {};
1506
1507	if ( value == null ) {
1508		return ( allowEmpty || !prop.def ) ? null : prop.def;
1509	}
1510
1511	// ~~ is an short way of doing floor for positive numbers
1512	value = type.floor ? ~~value : parseFloat( value );
1513
1514	if ( type.mod ) {
1515
1516		// we add mod before modding to make sure that negatives values
1517		// get converted properly: -10 -> 350
1518		return ( value + type.mod ) % type.mod;
1519	}
1520
1521	// for now all property types without mod have min and max
1522	return Math.min( type.max, Math.max( 0, value ) );
1523}
1524
1525function stringParse( string ) {
1526	var inst = color(),
1527		rgba = inst._rgba = [];
1528
1529	string = string.toLowerCase();
1530
1531	each( stringParsers, function( _i, parser ) {
1532		var parsed,
1533			match = parser.re.exec( string ),
1534			values = match && parser.parse( match ),
1535			spaceName = parser.space || "rgba";
1536
1537		if ( values ) {
1538			parsed = inst[ spaceName ]( values );
1539
1540			// if this was an rgba parse the assignment might happen twice
1541			// oh well....
1542			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
1543			rgba = inst._rgba = parsed._rgba;
1544
1545			// exit each( stringParsers ) here because we matched
1546			return false;
1547		}
1548	} );
1549
1550	// Found a stringParser that handled it
1551	if ( rgba.length ) {
1552
1553		// if this came from a parsed string, force "transparent" when alpha is 0
1554		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
1555		if ( rgba.join() === "0,0,0,0" ) {
1556			jQuery.extend( rgba, colors.transparent );
1557		}
1558		return inst;
1559	}
1560
1561	// named colors
1562	return colors[ string ];
1563}
1564
1565color.fn = jQuery.extend( color.prototype, {
1566	parse: function( red, green, blue, alpha ) {
1567		if ( red === undefined ) {
1568			this._rgba = [ null, null, null, null ];
1569			return this;
1570		}
1571		if ( red.jquery || red.nodeType ) {
1572			red = jQuery( red ).css( green );
1573			green = undefined;
1574		}
1575
1576		var inst = this,
1577			type = getType( red ),
1578			rgba = this._rgba = [];
1579
1580		// more than 1 argument specified - assume ( red, green, blue, alpha )
1581		if ( green !== undefined ) {
1582			red = [ red, green, blue, alpha ];
1583			type = "array";
1584		}
1585
1586		if ( type === "string" ) {
1587			return this.parse( stringParse( red ) || colors._default );
1588		}
1589
1590		if ( type === "array" ) {
1591			each( spaces.rgba.props, function( _key, prop ) {
1592				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
1593			} );
1594			return this;
1595		}
1596
1597		if ( type === "object" ) {
1598			if ( red instanceof color ) {
1599				each( spaces, function( _spaceName, space ) {
1600					if ( red[ space.cache ] ) {
1601						inst[ space.cache ] = red[ space.cache ].slice();
1602					}
1603				} );
1604			} else {
1605				each( spaces, function( _spaceName, space ) {
1606					var cache = space.cache;
1607					each( space.props, function( key, prop ) {
1608
1609						// if the cache doesn't exist, and we know how to convert
1610						if ( !inst[ cache ] && space.to ) {
1611
1612							// if the value was null, we don't need to copy it
1613							// if the key was alpha, we don't need to copy it either
1614							if ( key === "alpha" || red[ key ] == null ) {
1615								return;
1616							}
1617							inst[ cache ] = space.to( inst._rgba );
1618						}
1619
1620						// this is the only case where we allow nulls for ALL properties.
1621						// call clamp with alwaysAllowEmpty
1622						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
1623					} );
1624
1625					// everything defined but alpha?
1626					if ( inst[ cache ] && jQuery.inArray(
1627						null,
1628						inst[ cache ].slice( 0, 3 )
1629					) < 0 ) {
1630
1631						// use the default of 1
1632						if ( inst[ cache ][ 3 ] == null ) {
1633							inst[ cache ][ 3 ] = 1;
1634						}
1635
1636						if ( space.from ) {
1637							inst._rgba = space.from( inst[ cache ] );
1638						}
1639					}
1640				} );
1641			}
1642			return this;
1643		}
1644	},
1645	is: function( compare ) {
1646		var is = color( compare ),
1647			same = true,
1648			inst = this;
1649
1650		each( spaces, function( _, space ) {
1651			var localCache,
1652				isCache = is[ space.cache ];
1653			if ( isCache ) {
1654				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
1655				each( space.props, function( _, prop ) {
1656					if ( isCache[ prop.idx ] != null ) {
1657						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
1658						return same;
1659					}
1660				} );
1661			}
1662			return same;
1663		} );
1664		return same;
1665	},
1666	_space: function() {
1667		var used = [],
1668			inst = this;
1669		each( spaces, function( spaceName, space ) {
1670			if ( inst[ space.cache ] ) {
1671				used.push( spaceName );
1672			}
1673		} );
1674		return used.pop();
1675	},
1676	transition: function( other, distance ) {
1677		var end = color( other ),
1678			spaceName = end._space(),
1679			space = spaces[ spaceName ],
1680			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
1681			start = startColor[ space.cache ] || space.to( startColor._rgba ),
1682			result = start.slice();
1683
1684		end = end[ space.cache ];
1685		each( space.props, function( _key, prop ) {
1686			var index = prop.idx,
1687				startValue = start[ index ],
1688				endValue = end[ index ],
1689				type = propTypes[ prop.type ] || {};
1690
1691			// if null, don't override start value
1692			if ( endValue === null ) {
1693				return;
1694			}
1695
1696			// if null - use end
1697			if ( startValue === null ) {
1698				result[ index ] = endValue;
1699			} else {
1700				if ( type.mod ) {
1701					if ( endValue - startValue > type.mod / 2 ) {
1702						startValue += type.mod;
1703					} else if ( startValue - endValue > type.mod / 2 ) {
1704						startValue -= type.mod;
1705					}
1706				}
1707				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
1708			}
1709		} );
1710		return this[ spaceName ]( result );
1711	},
1712	blend: function( opaque ) {
1713
1714		// if we are already opaque - return ourself
1715		if ( this._rgba[ 3 ] === 1 ) {
1716			return this;
1717		}
1718
1719		var rgb = this._rgba.slice(),
1720			a = rgb.pop(),
1721			blend = color( opaque )._rgba;
1722
1723		return color( jQuery.map( rgb, function( v, i ) {
1724			return ( 1 - a ) * blend[ i ] + a * v;
1725		} ) );
1726	},
1727	toRgbaString: function() {
1728		var prefix = "rgba(",
1729			rgba = jQuery.map( this._rgba, function( v, i ) {
1730				if ( v != null ) {
1731					return v;
1732				}
1733				return i > 2 ? 1 : 0;
1734			} );
1735
1736		if ( rgba[ 3 ] === 1 ) {
1737			rgba.pop();
1738			prefix = "rgb(";
1739		}
1740
1741		return prefix + rgba.join( ", " ) + ")";
1742	},
1743	toHslaString: function() {
1744		var prefix = "hsla(",
1745			hsla = jQuery.map( this.hsla(), function( v, i ) {
1746				if ( v == null ) {
1747					v = i > 2 ? 1 : 0;
1748				}
1749
1750				// catch 1 and 2
1751				if ( i && i < 3 ) {
1752					v = Math.round( v * 100 ) + "%";
1753				}
1754				return v;
1755			} );
1756
1757		if ( hsla[ 3 ] === 1 ) {
1758			hsla.pop();
1759			prefix = "hsl(";
1760		}
1761		return prefix + hsla.join( ", " ) + ")";
1762	},
1763	toHexString: function( includeAlpha ) {
1764		var rgba = this._rgba.slice(),
1765			alpha = rgba.pop();
1766
1767		if ( includeAlpha ) {
1768			rgba.push( ~~( alpha * 255 ) );
1769		}
1770
1771		return "#" + jQuery.map( rgba, function( v ) {
1772
1773			// default to 0 when nulls exist
1774			return ( "0" + ( v || 0 ).toString( 16 ) ).substr( -2 );
1775		} ).join( "" );
1776	},
1777	toString: function() {
1778		return this.toRgbaString();
1779	}
1780} );
1781color.fn.parse.prototype = color.fn;
1782
1783// hsla conversions adapted from:
1784// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
1785
1786function hue2rgb( p, q, h ) {
1787	h = ( h + 1 ) % 1;
1788	if ( h * 6 < 1 ) {
1789		return p + ( q - p ) * h * 6;
1790	}
1791	if ( h * 2 < 1 ) {
1792		return q;
1793	}
1794	if ( h * 3 < 2 ) {
1795		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
1796	}
1797	return p;
1798}
1799
1800spaces.hsla.to = function( rgba ) {
1801	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
1802		return [ null, null, null, rgba[ 3 ] ];
1803	}
1804	var r = rgba[ 0 ] / 255,
1805		g = rgba[ 1 ] / 255,
1806		b = rgba[ 2 ] / 255,
1807		a = rgba[ 3 ],
1808		max = Math.max( r, g, b ),
1809		min = Math.min( r, g, b ),
1810		diff = max - min,
1811		add = max + min,
1812		l = add * 0.5,
1813		h, s;
1814
1815	if ( min === max ) {
1816		h = 0;
1817	} else if ( r === max ) {
1818		h = ( 60 * ( g - b ) / diff ) + 360;
1819	} else if ( g === max ) {
1820		h = ( 60 * ( b - r ) / diff ) + 120;
1821	} else {
1822		h = ( 60 * ( r - g ) / diff ) + 240;
1823	}
1824
1825	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
1826	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
1827	if ( diff === 0 ) {
1828		s = 0;
1829	} else if ( l <= 0.5 ) {
1830		s = diff / add;
1831	} else {
1832		s = diff / ( 2 - add );
1833	}
1834	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
1835};
1836
1837spaces.hsla.from = function( hsla ) {
1838	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
1839		return [ null, null, null, hsla[ 3 ] ];
1840	}
1841	var h = hsla[ 0 ] / 360,
1842		s = hsla[ 1 ],
1843		l = hsla[ 2 ],
1844		a = hsla[ 3 ],
1845		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
1846		p = 2 * l - q;
1847
1848	return [
1849		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
1850		Math.round( hue2rgb( p, q, h ) * 255 ),
1851		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
1852		a
1853	];
1854};
1855
1856
1857each( spaces, function( spaceName, space ) {
1858	var props = space.props,
1859		cache = space.cache,
1860		to = space.to,
1861		from = space.from;
1862
1863	// makes rgba() and hsla()
1864	color.fn[ spaceName ] = function( value ) {
1865
1866		// generate a cache for this space if it doesn't exist
1867		if ( to && !this[ cache ] ) {
1868			this[ cache ] = to( this._rgba );
1869		}
1870		if ( value === undefined ) {
1871			return this[ cache ].slice();
1872		}
1873
1874		var ret,
1875			type = getType( value ),
1876			arr = ( type === "array" || type === "object" ) ? value : arguments,
1877			local = this[ cache ].slice();
1878
1879		each( props, function( key, prop ) {
1880			var val = arr[ type === "object" ? key : prop.idx ];
1881			if ( val == null ) {
1882				val = local[ prop.idx ];
1883			}
1884			local[ prop.idx ] = clamp( val, prop );
1885		} );
1886
1887		if ( from ) {
1888			ret = color( from( local ) );
1889			ret[ cache ] = local;
1890			return ret;
1891		} else {
1892			return color( local );
1893		}
1894	};
1895
1896	// makes red() green() blue() alpha() hue() saturation() lightness()
1897	each( props, function( key, prop ) {
1898
1899		// alpha is included in more than one space
1900		if ( color.fn[ key ] ) {
1901			return;
1902		}
1903		color.fn[ key ] = function( value ) {
1904			var local, cur, match, fn,
1905				vtype = getType( value );
1906
1907			if ( key === "alpha" ) {
1908				fn = this._hsla ? "hsla" : "rgba";
1909			} else {
1910				fn = spaceName;
1911			}
1912			local = this[ fn ]();
1913			cur = local[ prop.idx ];
1914
1915			if ( vtype === "undefined" ) {
1916				return cur;
1917			}
1918
1919			if ( vtype === "function" ) {
1920				value = value.call( this, cur );
1921				vtype = getType( value );
1922			}
1923			if ( value == null && prop.empty ) {
1924				return this;
1925			}
1926			if ( vtype === "string" ) {
1927				match = rplusequals.exec( value );
1928				if ( match ) {
1929					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
1930				}
1931			}
1932			local[ prop.idx ] = value;
1933			return this[ fn ]( local );
1934		};
1935	} );
1936} );
1937
1938// add cssHook and .fx.step function for each named hook.
1939// accept a space separated string of properties
1940color.hook = function( hook ) {
1941	var hooks = hook.split( " " );
1942	each( hooks, function( _i, hook ) {
1943		jQuery.cssHooks[ hook ] = {
1944			set: function( elem, value ) {
1945				var parsed;
1946
1947				if ( value !== "transparent" &&
1948					( getType( value ) !== "string" ||
1949						( parsed = stringParse( value ) ) ) ) {
1950					value = color( parsed || value );
1951					value = value.toRgbaString();
1952				}
1953				elem.style[ hook ] = value;
1954			}
1955		};
1956		jQuery.fx.step[ hook ] = function( fx ) {
1957			if ( !fx.colorInit ) {
1958				fx.start = color( fx.elem, hook );
1959				fx.end = color( fx.end );
1960				fx.colorInit = true;
1961			}
1962			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
1963		};
1964	} );
1965
1966};
1967
1968color.hook( stepHooks );
1969
1970jQuery.cssHooks.borderColor = {
1971	expand: function( value ) {
1972		var expanded = {};
1973
1974		each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) {
1975			expanded[ "border" + part + "Color" ] = value;
1976		} );
1977		return expanded;
1978	}
1979};
1980
1981// Basic color names only.
1982// Usage of any of the other color names requires adding yourself or including
1983// jquery.color.svg-names.js.
1984colors = jQuery.Color.names = {
1985
1986	// 4.1. Basic color keywords
1987	aqua: "#00ffff",
1988	black: "#000000",
1989	blue: "#0000ff",
1990	fuchsia: "#ff00ff",
1991	gray: "#808080",
1992	green: "#008000",
1993	lime: "#00ff00",
1994	maroon: "#800000",
1995	navy: "#000080",
1996	olive: "#808000",
1997	purple: "#800080",
1998	red: "#ff0000",
1999	silver: "#c0c0c0",
2000	teal: "#008080",
2001	white: "#ffffff",
2002	yellow: "#ffff00",
2003
2004	// 4.2.3. "transparent" color keyword
2005	transparent: [ null, null, null, 0 ],
2006
2007	_default: "#ffffff"
2008};
2009
2010
2011/*!
2012 * jQuery UI Effects 1.14.
20121
2013 * https://jqueryui.com
2014 *
2015 * Copyright OpenJS Foundation and other contributors
2016 * Released under the MIT license.
2017 * https://jquery.org/license
2018 */
2019
2020//>>label: Effects Core
2021//>>group: Effects
2022/* eslint-disable max-len */
2023//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
2024/* eslint-enable max-len */
vendor: 7,523 bytes, lines 2024-2314
2024
2025//>>docs: https://api.jqueryui.com/category/effects-core/
2026//>>demos: https://jqueryui.com/effect/
2027
2028
2029var dataSpace = "ui-effects-",
2030	dataSpaceStyle = "ui-effects-style",
2031	dataSpaceAnimated = "ui-effects-animated";
2032
2033$.effects = {
2034	effect: {}
2035};
2036
2037/******************************************************************************/
2038/****************************** CLASS ANIMATIONS ******************************/
2039/******************************************************************************/
2040( function() {
2041
2042var classAnimationActions = [ "add", "remove", "toggle" ],
2043	shorthandStyles = {
2044		border: 1,
2045		borderBottom: 1,
2046		borderColor: 1,
2047		borderLeft: 1,
2048		borderRight: 1,
2049		borderTop: 1,
2050		borderWidth: 1,
2051		margin: 1,
2052		padding: 1
2053	};
2054
2055$.each(
2056	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
2057	function( _, prop ) {
2058		$.fx.step[ prop ] = function( fx ) {
2059			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
2060				jQuery.style( fx.elem, prop, fx.end );
2061				fx.setAttr = true;
2062			}
2063		};
2064	}
2065);
2066
2067function camelCase( string ) {
2068	return string.replace( /-([\da-z])/gi, function( all, letter ) {
2069		return letter.toUpperCase();
2070	} );
2071}
2072
2073function getElementStyles( elem ) {
2074	var key, len,
2075		style = elem.ownerDocument.defaultView.getComputedStyle( elem ),
2076		styles = {};
2077
2078	len = style.length;
2079	while ( len-- ) {
2080		key = style[ len ];
2081		if ( typeof style[ key ] === "string" ) {
2082			styles[ camelCase( key ) ] = style[ key ];
2083		}
2084	}
2085
2086	return styles;
2087}
2088
2089function styleDifference( oldStyle, newStyle ) {
2090	var diff = {},
2091		name, value;
2092
2093	for ( name in newStyle ) {
2094		value = newStyle[ name ];
2095		if ( oldStyle[ name ] !== value ) {
2096			if ( !shorthandStyles[ name ] ) {
2097				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
2098					diff[ name ] = value;
2099				}
2100			}
2101		}
2102	}
2103
2104	return diff;
2105}
2106
2107$.effects.animateClass = function( value, duration, easing, callback ) {
2108	var o = $.speed( duration, easing, callback );
2109
2110	return this.queue( function() {
2111		var animated = $( this ),
2112			baseClass = animated.attr( "class" ) || "",
2113			applyClassChange,
2114			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
2115
2116		// Map the animated objects to store the original styles.
2117		allAnimations = allAnimations.map( function() {
2118			var el = $( this );
2119			return {
2120				el: el,
2121				start: getElementStyles( this )
2122			};
2123		} );
2124
2125		// Apply class change
2126		applyClassChange = function() {
2127			$.each( classAnimationActions, function( i, action ) {
2128				if ( value[ action ] ) {
2129					animated[ action + "Class" ]( value[ action ] );
2130				}
2131			} );
2132		};
2133		applyClassChange();
2134
2135		// Map all animated objects again - calculate new styles and diff
2136		allAnimations = allAnimations.map( function() {
2137			this.end = getElementStyles( this.el[ 0 ] );
2138			this.diff = styleDifference( this.start, this.end );
2139			return this;
2140		} );
2141
2142		// Apply original class
2143		animated.attr( "class", baseClass );
2144
2145		// Map all animated objects again - this time collecting a promise
2146		allAnimations = allAnimations.map( function() {
2147			var styleInfo = this,
2148				dfd = $.Deferred(),
2149				opts = $.extend( {}, o, {
2150					queue: false,
2151					complete: function() {
2152						dfd.resolve( styleInfo );
2153					}
2154				} );
2155
2156			this.el.animate( this.diff, opts );
2157			return dfd.promise();
2158		} );
2159
2160		// Once all animations have completed:
2161		$.when.apply( $, allAnimations.get() ).done( function() {
2162
2163			// Set the final class
2164			applyClassChange();
2165
2166			// For each animated element,
2167			// clear all css properties that were animated
2168			$.each( arguments, function() {
2169				var el = this.el;
2170				$.each( this.diff, function( key ) {
2171					el.css( key, "" );
2172				} );
2173			} );
2174
2175			// This is guarnteed to be there if you use jQuery.speed()
2176			// it also handles dequeuing the next anim...
2177			o.complete.call( animated[ 0 ] );
2178		} );
2179	} );
2180};
2181
2182$.fn.extend( {
2183	addClass: ( function( orig ) {
2184		return function( classNames, speed, easing, callback ) {
2185			return speed ?
2186				$.effects.animateClass.call( this,
2187					{ add: classNames }, speed, easing, callback ) :
2188				orig.apply( this, arguments );
2189		};
2190	} )( $.fn.addClass ),
2191
2192	removeClass: ( function( orig ) {
2193		return function( classNames, speed, easing, callback ) {
2194			return arguments.length > 1 ?
2195				$.effects.animateClass.call( this,
2196					{ remove: classNames }, speed, easing, callback ) :
2197				orig.apply( this, arguments );
2198		};
2199	} )( $.fn.removeClass ),
2200
2201	toggleClass: ( function( orig ) {
2202		return function( classNames, force, speed, easing, callback ) {
2203			if ( typeof force === "boolean" || force === undefined ) {
2204				if ( !speed ) {
2205
2206					// Without speed parameter
2207					return orig.apply( this, arguments );
2208				} else {
2209					return $.effects.animateClass.call( this,
2210						( force ? { add: classNames } : { remove: classNames } ),
2211						speed, easing, callback );
2212				}
2213			} else {
2214
2215				// Without force parameter
2216				return $.effects.animateClass.call( this,
2217					{ toggle: classNames }, force, speed, easing );
2218			}
2219		};
2220	} )( $.fn.toggleClass ),
2221
2222	switchClass: function( remove, add, speed, easing, callback ) {
2223		return $.effects.animateClass.call( this, {
2224			add: add,
2225			remove: remove
2226		}, speed, easing, callback );
2227	}
2228} );
2229
2230} )();
2231
2232/******************************************************************************/
2233/*********************************** EFFECTS **********************************/
2234/******************************************************************************/
2235
2236( function() {
2237
2238if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
2239	$.expr.pseudos.animated = ( function( orig ) {
2240		return function( elem ) {
2241			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
2242		};
2243	} )( $.expr.pseudos.animated );
2244}
2245
2246if ( $.uiBackCompat === true ) {
2247	$.extend( $.effects, {
2248
2249		// Saves a set of properties in a data storage
2250		save: function( element, set ) {
2251			var i = 0, length = set.length;
2252			for ( ; i < length; i++ ) {
2253				if ( set[ i ] !== null ) {
2254					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
2255				}
2256			}
2257		},
2258
2259		// Restores a set of previously saved properties from a data storage
2260		restore: function( element, set ) {
2261			var val, i = 0, length = set.length;
2262			for ( ; i < length; i++ ) {
2263				if ( set[ i ] !== null ) {
2264					val = element.data( dataSpace + set[ i ] );
2265					element.css( set[ i ], val );
2266				}
2267			}
2268		},
2269
2270		setMode: function( el, mode ) {
2271			if ( mode === "toggle" ) {
2272				mode = el.is( ":hidden" ) ? "show" : "hide";
2273			}
2274			return mode;
2275		},
2276
2277		// Wraps the element around a wrapper that copies position properties
2278		createWrapper: function( element ) {
2279
2280			// If the element is already wrapped, return it
2281			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2282				return element.parent();
2283			}
2284
2285			// Wrap the element
2286			var props = {
2287					width: element.outerWidth( true ),
2288					height: element.outerHeight( true ),
2289					"float": element.css( "float" )
2290				},
2291				wrapper = $( "<div></div>" )
2292					.addClass( "ui-effects-wrapper" )
2293					.css( {
2294						fontSize: "100%",
2295						background: "transparent",
2296						border: "none",
2297						margin: 0,
2298						padding: 0
2299					} ),
2300
2301				// Store the size in case width/height are defined in % - Fixes #5245
2302				size = {
2303					width: element.width(),
2304					height: element.height()
2305				},
2306				active = document.activeElement;
2307
2308			// Support: Firefox
2309			// Firefox incorrectly exposes anonymous content
2310			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
2311			try {
2312				// eslint-disable-next-line no-unused-expressions
2313				active.id;
2314			} catch ( 
vendor: 1,550 bytes, lines 2314-2375
2314e ) {
2315				active = document.body;
2316			}
2317
2318			element.wrap( wrapper );
2319
2320			// Fixes #7595 - Elements lose focus when wrapped.
2321			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2322				$( active ).trigger( "focus" );
2323			}
2324
2325			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
2326			// lose the reference to the wrapped element
2327			wrapper = element.parent();
2328
2329			// Transfer positioning properties to the wrapper
2330			if ( element.css( "position" ) === "static" ) {
2331				wrapper.css( { position: "relative" } );
2332				element.css( { position: "relative" } );
2333			} else {
2334				$.extend( props, {
2335					position: element.css( "position" ),
2336					zIndex: element.css( "z-index" )
2337				} );
2338				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
2339					props[ pos ] = element.css( pos );
2340					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
2341						props[ pos ] = "auto";
2342					}
2343				} );
2344				element.css( {
2345					position: "relative",
2346					top: 0,
2347					left: 0,
2348					right: "auto",
2349					bottom: "auto"
2350				} );
2351			}
2352			element.css( size );
2353
2354			return wrapper.css( props ).show();
2355		},
2356
2357		removeWrapper: function( element ) {
2358			var active = document.activeElement;
2359
2360			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
2361				element.parent().replaceWith( element );
2362
2363				// Fixes #7595 - Elements lose focus when wrapped.
2364				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
2365					$( active ).trigger( "focus" );
2366				}
2367			}
2368
2369			return element;
2370		}
2371	} );
2372}
2373
2374$.extend( $.effects, {
2375	version: "1.14.1
vendor: 14,339 bytes, lines 2375-2943
2375",
2376
2377	define: function( name, mode, effect ) {
2378		if ( !effect ) {
2379			effect = mode;
2380			mode = "effect";
2381		}
2382
2383		$.effects.effect[ name ] = effect;
2384		$.effects.effect[ name ].mode = mode;
2385
2386		return effect;
2387	},
2388
2389	scaledDimensions: function( element, percent, direction ) {
2390		if ( percent === 0 ) {
2391			return {
2392				height: 0,
2393				width: 0,
2394				outerHeight: 0,
2395				outerWidth: 0
2396			};
2397		}
2398
2399		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
2400			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
2401
2402		return {
2403			height: element.height() * y,
2404			width: element.width() * x,
2405			outerHeight: element.outerHeight() * y,
2406			outerWidth: element.outerWidth() * x
2407		};
2408
2409	},
2410
2411	clipToBox: function( animation ) {
2412		return {
2413			width: animation.clip.right - animation.clip.left,
2414			height: animation.clip.bottom - animation.clip.top,
2415			left: animation.clip.left,
2416			top: animation.clip.top
2417		};
2418	},
2419
2420	// Injects recently queued functions to be first in line (after "inprogress")
2421	unshift: function( element, queueLength, count ) {
2422		var queue = element.queue();
2423
2424		if ( queueLength > 1 ) {
2425			queue.splice.apply( queue,
2426				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
2427		}
2428		element.dequeue();
2429	},
2430
2431	saveStyle: function( element ) {
2432		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
2433	},
2434
2435	restoreStyle: function( element ) {
2436		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
2437		element.removeData( dataSpaceStyle );
2438	},
2439
2440	mode: function( element, mode ) {
2441		var hidden = element.is( ":hidden" );
2442
2443		if ( mode === "toggle" ) {
2444			mode = hidden ? "show" : "hide";
2445		}
2446		if ( hidden ? mode === "hide" : mode === "show" ) {
2447			mode = "none";
2448		}
2449		return mode;
2450	},
2451
2452	// Translates a [top,left] array into a baseline value
2453	getBaseline: function( origin, original ) {
2454		var y, x;
2455
2456		switch ( origin[ 0 ] ) {
2457		case "top":
2458			y = 0;
2459			break;
2460		case "middle":
2461			y = 0.5;
2462			break;
2463		case "bottom":
2464			y = 1;
2465			break;
2466		default:
2467			y = origin[ 0 ] / original.height;
2468		}
2469
2470		switch ( origin[ 1 ] ) {
2471		case "left":
2472			x = 0;
2473			break;
2474		case "center":
2475			x = 0.5;
2476			break;
2477		case "right":
2478			x = 1;
2479			break;
2480		default:
2481			x = origin[ 1 ] / original.width;
2482		}
2483
2484		return {
2485			x: x,
2486			y: y
2487		};
2488	},
2489
2490	// Creates a placeholder element so that the original element can be made absolute
2491	createPlaceholder: function( element ) {
2492		var placeholder,
2493			cssPosition = element.css( "position" ),
2494			position = element.position();
2495
2496		// Lock in margins first to account for form elements, which
2497		// will change margin if you explicitly set height
2498		// see: https://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
2499		// Support: Safari
2500		element.css( {
2501			marginTop: element.css( "marginTop" ),
2502			marginBottom: element.css( "marginBottom" ),
2503			marginLeft: element.css( "marginLeft" ),
2504			marginRight: element.css( "marginRight" )
2505		} )
2506		.outerWidth( element.outerWidth() )
2507		.outerHeight( element.outerHeight() );
2508
2509		if ( /^(static|relative)/.test( cssPosition ) ) {
2510			cssPosition = "absolute";
2511
2512			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
2513
2514				// Convert inline to inline block to account for inline elements
2515				// that turn to inline block based on content (like img)
2516				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
2517					"inline-block" :
2518					"block",
2519				visibility: "hidden",
2520
2521				// Margins need to be set to account for margin collapse
2522				marginTop: element.css( "marginTop" ),
2523				marginBottom: element.css( "marginBottom" ),
2524				marginLeft: element.css( "marginLeft" ),
2525				marginRight: element.css( "marginRight" ),
2526				"float": element.css( "float" )
2527			} )
2528			.outerWidth( element.outerWidth() )
2529			.outerHeight( element.outerHeight() )
2530			.addClass( "ui-effects-placeholder" );
2531
2532			element.data( dataSpace + "placeholder", placeholder );
2533		}
2534
2535		element.css( {
2536			position: cssPosition,
2537			left: position.left,
2538			top: position.top
2539		} );
2540
2541		return placeholder;
2542	},
2543
2544	removePlaceholder: function( element ) {
2545		var dataKey = dataSpace + "placeholder",
2546				placeholder = element.data( dataKey );
2547
2548		if ( placeholder ) {
2549			placeholder.remove();
2550			element.removeData( dataKey );
2551		}
2552	},
2553
2554	// Removes a placeholder if it exists and restores
2555	// properties that were modified during placeholder creation
2556	cleanUp: function( element ) {
2557		$.effects.restoreStyle( element );
2558		$.effects.removePlaceholder( element );
2559	},
2560
2561	setTransition: function( element, list, factor, value ) {
2562		value = value || {};
2563		$.each( list, function( i, x ) {
2564			var unit = element.cssUnit( x );
2565			if ( unit[ 0 ] > 0 ) {
2566				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
2567			}
2568		} );
2569		return value;
2570	}
2571} );
2572
2573// Return an effect options object for the given parameters:
2574function _normalizeArguments( effect, options, speed, callback ) {
2575
2576	// Allow passing all options as the first parameter
2577	if ( $.isPlainObject( effect ) ) {
2578		options = effect;
2579		effect = effect.effect;
2580	}
2581
2582	// Convert to an object
2583	effect = { effect: effect };
2584
2585	// Catch (effect, null, ...)
2586	if ( options == null ) {
2587		options = {};
2588	}
2589
2590	// Catch (effect, callback)
2591	if ( typeof options === "function" ) {
2592		callback = options;
2593		speed = null;
2594		options = {};
2595	}
2596
2597	// Catch (effect, speed, ?)
2598	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
2599		callback = speed;
2600		speed = options;
2601		options = {};
2602	}
2603
2604	// Catch (effect, options, callback)
2605	if ( typeof speed === "function" ) {
2606		callback = speed;
2607		speed = null;
2608	}
2609
2610	// Add options to effect
2611	if ( options ) {
2612		$.extend( effect, options );
2613	}
2614
2615	speed = speed || options.duration;
2616	effect.duration = $.fx.off ? 0 :
2617		typeof speed === "number" ? speed :
2618		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
2619		$.fx.speeds._default;
2620
2621	effect.complete = callback || options.complete;
2622
2623	return effect;
2624}
2625
2626function standardAnimationOption( option ) {
2627
2628	// Valid standard speeds (nothing, number, named speed)
2629	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
2630		return true;
2631	}
2632
2633	// Invalid strings - treat as "normal" speed
2634	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
2635		return true;
2636	}
2637
2638	// Complete callback
2639	if ( typeof option === "function" ) {
2640		return true;
2641	}
2642
2643	// Options hash (but not naming an effect)
2644	if ( typeof option === "object" && !option.effect ) {
2645		return true;
2646	}
2647
2648	// Didn't match any standard API
2649	return false;
2650}
2651
2652$.fn.extend( {
2653	effect: function( /* effect, options, speed, callback */ ) {
2654		var args = _normalizeArguments.apply( this, arguments ),
2655			effectMethod = $.effects.effect[ args.effect ],
2656			defaultMode = effectMethod.mode,
2657			queue = args.queue,
2658			queueName = queue || "fx",
2659			complete = args.complete,
2660			mode = args.mode,
2661			modes = [],
2662			prefilter = function( next ) {
2663				var el = $( this ),
2664					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
2665
2666				// Sentinel for duck-punching the :animated pseudo-selector
2667				el.data( dataSpaceAnimated, true );
2668
2669				// Save effect mode for later use,
2670				// we can't just call $.effects.mode again later,
2671				// as the .show() below destroys the initial state
2672				modes.push( normalizedMode );
2673
2674				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.14
2675				if ( defaultMode && ( normalizedMode === "show" ||
2676						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
2677					el.show();
2678				}
2679
2680				if ( !defaultMode || normalizedMode !== "none" ) {
2681					$.effects.saveStyle( el );
2682				}
2683
2684				if ( typeof next === "function" ) {
2685					next();
2686				}
2687			};
2688
2689		if ( $.fx.off || !effectMethod ) {
2690
2691			// Delegate to the original method (e.g., .show()) if possible
2692			if ( mode ) {
2693				return this[ mode ]( args.duration, complete );
2694			} else {
2695				return this.each( function() {
2696					if ( complete ) {
2697						complete.call( this );
2698					}
2699				} );
2700			}
2701		}
2702
2703		function run( next ) {
2704			var elem = $( this );
2705
2706			function cleanup() {
2707				elem.removeData( dataSpaceAnimated );
2708
2709				$.effects.cleanUp( elem );
2710
2711				if ( args.mode === "hide" ) {
2712					elem.hide();
2713				}
2714
2715				done();
2716			}
2717
2718			function done() {
2719				if ( typeof complete === "function" ) {
2720					complete.call( elem[ 0 ] );
2721				}
2722
2723				if ( typeof next === "function" ) {
2724					next();
2725				}
2726			}
2727
2728			// Override mode option on a per element basis,
2729			// as toggle can be either show or hide depending on element state
2730			args.mode = modes.shift();
2731
2732			if ( $.uiBackCompat === true && !defaultMode ) {
2733				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
2734
2735					// Call the core method to track "olddisplay" properly
2736					elem[ mode ]();
2737					done();
2738				} else {
2739					effectMethod.call( elem[ 0 ], args, done );
2740				}
2741			} else {
2742				if ( args.mode === "none" ) {
2743
2744					// Call the core method to track "olddisplay" properly
2745					elem[ mode ]();
2746					done();
2747				} else {
2748					effectMethod.call( elem[ 0 ], args, cleanup );
2749				}
2750			}
2751		}
2752
2753		// Run prefilter on all elements first to ensure that
2754		// any showing or hiding happens before placeholder creation,
2755		// which ensures that any layout changes are correctly captured.
2756		return queue === false ?
2757			this.each( prefilter ).each( run ) :
2758			this.queue( queueName, prefilter ).queue( queueName, run );
2759	},
2760
2761	show: ( function( orig ) {
2762		return function( option ) {
2763			if ( standardAnimationOption( option ) ) {
2764				return orig.apply( this, arguments );
2765			} else {
2766				var args = _normalizeArguments.apply( this, arguments );
2767				args.mode = "show";
2768				return this.effect.call( this, args );
2769			}
2770		};
2771	} )( $.fn.show ),
2772
2773	hide: ( function( orig ) {
2774		return function( option ) {
2775			if ( standardAnimationOption( option ) ) {
2776				return orig.apply( this, arguments );
2777			} else {
2778				var args = _normalizeArguments.apply( this, arguments );
2779				args.mode = "hide";
2780				return this.effect.call( this, args );
2781			}
2782		};
2783	} )( $.fn.hide ),
2784
2785	toggle: ( function( orig ) {
2786		return function( option ) {
2787			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
2788				return orig.apply( this, arguments );
2789			} else {
2790				var args = _normalizeArguments.apply( this, arguments );
2791				args.mode = "toggle";
2792				return this.effect.call( this, args );
2793			}
2794		};
2795	} )( $.fn.toggle ),
2796
2797	cssUnit: function( key ) {
2798		var style = this.css( key ),
2799			val = [];
2800
2801		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
2802			if ( style.indexOf( unit ) > 0 ) {
2803				val = [ parseFloat( style ), unit ];
2804			}
2805		} );
2806		return val;
2807	},
2808
2809	cssClip: function( clipObj ) {
2810		if ( clipObj ) {
2811			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
2812				clipObj.bottom + "px " + clipObj.left + "px)" );
2813		}
2814		return parseClip( this.css( "clip" ), this );
2815	},
2816
2817	transfer: function( options, done ) {
2818		var element = $( this ),
2819			target = $( options.to ),
2820			targetFixed = target.css( "position" ) === "fixed",
2821			body = $( "body" ),
2822			fixTop = targetFixed ? body.scrollTop() : 0,
2823			fixLeft = targetFixed ? body.scrollLeft() : 0,
2824			endPosition = target.offset(),
2825			animation = {
2826				top: endPosition.top - fixTop,
2827				left: endPosition.left - fixLeft,
2828				height: target.innerHeight(),
2829				width: target.innerWidth()
2830			},
2831			startPosition = element.offset(),
2832			transfer = $( "<div class='ui-effects-transfer'></div>" );
2833
2834		transfer
2835			.appendTo( "body" )
2836			.addClass( options.className )
2837			.css( {
2838				top: startPosition.top - fixTop,
2839				left: startPosition.left - fixLeft,
2840				height: element.innerHeight(),
2841				width: element.innerWidth(),
2842				position: targetFixed ? "fixed" : "absolute"
2843			} )
2844			.animate( animation, options.duration, options.easing, function() {
2845				transfer.remove();
2846				if ( typeof done === "function" ) {
2847					done();
2848				}
2849			} );
2850	}
2851} );
2852
2853function parseClip( str, element ) {
2854		var outerWidth = element.outerWidth(),
2855			outerHeight = element.outerHeight(),
2856			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)\)$/,
2857			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
2858
2859		return {
2860			top: parseFloat( values[ 1 ] ) || 0,
2861			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
2862			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
2863			left: parseFloat( values[ 4 ] ) || 0
2864		};
2865}
2866
2867$.fx.step.clip = function( fx ) {
2868	if ( !fx.clipInit ) {
2869		fx.start = $( fx.elem ).cssClip();
2870		if ( typeof fx.end === "string" ) {
2871			fx.end = parseClip( fx.end, fx.elem );
2872		}
2873		fx.clipInit = true;
2874	}
2875
2876	$( fx.elem ).cssClip( {
2877		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
2878		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
2879		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
2880		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
2881	} );
2882};
2883
2884} )();
2885
2886/******************************************************************************/
2887/*********************************** EASING ***********************************/
2888/******************************************************************************/
2889
2890( function() {
2891
2892// Based on easing equations from Robert Penner (http://robertpenner.com/easing)
2893
2894var baseEasings = {};
2895
2896$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
2897	baseEasings[ name ] = function( p ) {
2898		return Math.pow( p, i + 2 );
2899	};
2900} );
2901
2902$.extend( baseEasings, {
2903	Sine: function( p ) {
2904		return 1 - Math.cos( p * Math.PI / 2 );
2905	},
2906	Circ: function( p ) {
2907		return 1 - Math.sqrt( 1 - p * p );
2908	},
2909	Elastic: function( p ) {
2910		return p === 0 || p === 1 ? p :
2911			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
2912	},
2913	Back: function( p ) {
2914		return p * p * ( 3 * p - 2 );
2915	},
2916	Bounce: function( p ) {
2917		var pow2,
2918			bounce = 4;
2919
2920		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
2921		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
2922	}
2923} );
2924
2925$.each( baseEasings, function( name, easeIn ) {
2926	$.easing[ "easeIn" + name ] = easeIn;
2927	$.easing[ "easeOut" + name ] = function( p ) {
2928		return 1 - easeIn( 1 - p );
2929	};
2930	$.easing[ "easeInOut" + name ] = function( p ) {
2931		return p < 0.5 ?
2932			easeIn( p * 2 ) / 2 :
2933			1 - easeIn( p * -2 + 2 ) / 2;
2934	};
2935} );
2936
2937} )();
2938
2939var effect = $.effects;
2940
2941
2942/*!
2943 * jQuery UI Effects Blind 1.14.
vendor: 33,753 bytes, lines 2943-4252
29431
2944 * https://jqueryui.com
2945 *
2946 * Copyright OpenJS Foundation and other contributors
2947 * Released under the MIT license.
2948 * https://jquery.org/license
2949 */
2950
2951//>>label: Blind Effect
2952//>>group: Effects
2953//>>description: Blinds the element.
2954//>>docs: https://api.jqueryui.com/blind-effect/
2955//>>demos: https://jqueryui.com/effect/
2956
2957
2958var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
2959	var map = {
2960			up: [ "bottom", "top" ],
2961			vertical: [ "bottom", "top" ],
2962			down: [ "top", "bottom" ],
2963			left: [ "right", "left" ],
2964			horizontal: [ "right", "left" ],
2965			right: [ "left", "right" ]
2966		},
2967		element = $( this ),
2968		direction = options.direction || "up",
2969		start = element.cssClip(),
2970		animate = { clip: $.extend( {}, start ) },
2971		placeholder = $.effects.createPlaceholder( element );
2972
2973	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
2974
2975	if ( options.mode === "show" ) {
2976		element.cssClip( animate.clip );
2977		if ( placeholder ) {
2978			placeholder.css( $.effects.clipToBox( animate ) );
2979		}
2980
2981		animate.clip = start;
2982	}
2983
2984	if ( placeholder ) {
2985		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
2986	}
2987
2988	element.animate( animate, {
2989		queue: false,
2990		duration: options.duration,
2991		easing: options.easing,
2992		complete: done
2993	} );
2994} );
2995
2996
2997/*!
2998 * jQuery UI Effects Bounce 1.14.1
2999 * https://jqueryui.com
3000 *
3001 * Copyright OpenJS Foundation and other contributors
3002 * Released under the MIT license.
3003 * https://jquery.org/license
3004 */
3005
3006//>>label: Bounce Effect
3007//>>group: Effects
3008//>>description: Bounces an element horizontally or vertically n times.
3009//>>docs: https://api.jqueryui.com/bounce-effect/
3010//>>demos: https://jqueryui.com/effect/
3011
3012
3013var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
3014	var upAnim, downAnim, refValue,
3015		element = $( this ),
3016
3017		// Defaults:
3018		mode = options.mode,
3019		hide = mode === "hide",
3020		show = mode === "show",
3021		direction = options.direction || "up",
3022		distance = options.distance,
3023		times = options.times || 5,
3024
3025		// Number of internal animations
3026		anims = times * 2 + ( show || hide ? 1 : 0 ),
3027		speed = options.duration / anims,
3028		easing = options.easing,
3029
3030		// Utility:
3031		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3032		motion = ( direction === "up" || direction === "left" ),
3033		i = 0,
3034
3035		queuelen = element.queue().length;
3036
3037	$.effects.createPlaceholder( element );
3038
3039	refValue = element.css( ref );
3040
3041	// Default distance for the BIGGEST bounce is the outer Distance / 3
3042	if ( !distance ) {
3043		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
3044	}
3045
3046	if ( show ) {
3047		downAnim = { opacity: 1 };
3048		downAnim[ ref ] = refValue;
3049
3050		// If we are showing, force opacity 0 and set the initial position
3051		// then do the "first" animation
3052		element
3053			.css( "opacity", 0 )
3054			.css( ref, motion ? -distance * 2 : distance * 2 )
3055			.animate( downAnim, speed, easing );
3056	}
3057
3058	// Start at the smallest distance if we are hiding
3059	if ( hide ) {
3060		distance = distance / Math.pow( 2, times - 1 );
3061	}
3062
3063	downAnim = {};
3064	downAnim[ ref ] = refValue;
3065
3066	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
3067	for ( ; i < times; i++ ) {
3068		upAnim = {};
3069		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3070
3071		element
3072			.animate( upAnim, speed, easing )
3073			.animate( downAnim, speed, easing );
3074
3075		distance = hide ? distance * 2 : distance / 2;
3076	}
3077
3078	// Last Bounce when Hiding
3079	if ( hide ) {
3080		upAnim = { opacity: 0 };
3081		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
3082
3083		element.animate( upAnim, speed, easing );
3084	}
3085
3086	element.queue( done );
3087
3088	$.effects.unshift( element, queuelen, anims + 1 );
3089} );
3090
3091
3092/*!
3093 * jQuery UI Effects Clip 1.14.1
3094 * https://jqueryui.com
3095 *
3096 * Copyright OpenJS Foundation and other contributors
3097 * Released under the MIT license.
3098 * https://jquery.org/license
3099 */
3100
3101//>>label: Clip Effect
3102//>>group: Effects
3103//>>description: Clips the element on and off like an old TV.
3104//>>docs: https://api.jqueryui.com/clip-effect/
3105//>>demos: https://jqueryui.com/effect/
3106
3107
3108var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
3109	var start,
3110		animate = {},
3111		element = $( this ),
3112		direction = options.direction || "vertical",
3113		both = direction === "both",
3114		horizontal = both || direction === "horizontal",
3115		vertical = both || direction === "vertical";
3116
3117	start = element.cssClip();
3118	animate.clip = {
3119		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
3120		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
3121		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
3122		left: horizontal ? ( start.right - start.left ) / 2 : start.left
3123	};
3124
3125	$.effects.createPlaceholder( element );
3126
3127	if ( options.mode === "show" ) {
3128		element.cssClip( animate.clip );
3129		animate.clip = start;
3130	}
3131
3132	element.animate( animate, {
3133		queue: false,
3134		duration: options.duration,
3135		easing: options.easing,
3136		complete: done
3137	} );
3138
3139} );
3140
3141
3142/*!
3143 * jQuery UI Effects Drop 1.14.1
3144 * https://jqueryui.com
3145 *
3146 * Copyright OpenJS Foundation and other contributors
3147 * Released under the MIT license.
3148 * https://jquery.org/license
3149 */
3150
3151//>>label: Drop Effect
3152//>>group: Effects
3153//>>description: Moves an element in one direction and hides it at the same time.
3154//>>docs: https://api.jqueryui.com/drop-effect/
3155//>>demos: https://jqueryui.com/effect/
3156
3157
3158var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
3159
3160	var distance,
3161		element = $( this ),
3162		mode = options.mode,
3163		show = mode === "show",
3164		direction = options.direction || "left",
3165		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3166		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
3167		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
3168		animation = {
3169			opacity: 0
3170		};
3171
3172	$.effects.createPlaceholder( element );
3173
3174	distance = options.distance ||
3175		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
3176
3177	animation[ ref ] = motion + distance;
3178
3179	if ( show ) {
3180		element.css( animation );
3181
3182		animation[ ref ] = oppositeMotion + distance;
3183		animation.opacity = 1;
3184	}
3185
3186	// Animate
3187	element.animate( animation, {
3188		queue: false,
3189		duration: options.duration,
3190		easing: options.easing,
3191		complete: done
3192	} );
3193} );
3194
3195
3196/*!
3197 * jQuery UI Effects Explode 1.14.1
3198 * https://jqueryui.com
3199 *
3200 * Copyright OpenJS Foundation and other contributors
3201 * Released under the MIT license.
3202 * https://jquery.org/license
3203 */
3204
3205//>>label: Explode Effect
3206//>>group: Effects
3207/* eslint-disable max-len */
3208//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
3209/* eslint-enable max-len */
3210//>>docs: https://api.jqueryui.com/explode-effect/
3211//>>demos: https://jqueryui.com/effect/
3212
3213
3214var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
3215
3216	var i, j, left, top, mx, my,
3217		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
3218		cells = rows,
3219		element = $( this ),
3220		mode = options.mode,
3221		show = mode === "show",
3222
3223		// Show and then visibility:hidden the element before calculating offset
3224		offset = element.show().css( "visibility", "hidden" ).offset(),
3225
3226		// Width and height of a piece
3227		width = Math.ceil( element.outerWidth() / cells ),
3228		height = Math.ceil( element.outerHeight() / rows ),
3229		pieces = [];
3230
3231	// Children animate complete:
3232	function childComplete() {
3233		pieces.push( this );
3234		if ( pieces.length === rows * cells ) {
3235			animComplete();
3236		}
3237	}
3238
3239	// Clone the element for each row and cell.
3240	for ( i = 0; i < rows; i++ ) { // ===>
3241		top = offset.top + i * height;
3242		my = i - ( rows - 1 ) / 2;
3243
3244		for ( j = 0; j < cells; j++ ) { // |||
3245			left = offset.left + j * width;
3246			mx = j - ( cells - 1 ) / 2;
3247
3248			// Create a clone of the now hidden main element that will be absolute positioned
3249			// within a wrapper div off the -left and -top equal to size of our pieces
3250			element
3251				.clone()
3252				.appendTo( "body" )
3253				.wrap( "<div></div>" )
3254				.css( {
3255					position: "absolute",
3256					visibility: "visible",
3257					left: -j * width,
3258					top: -i * height
3259				} )
3260
3261				// Select the wrapper - make it overflow: hidden and absolute positioned based on
3262				// where the original was located +left and +top equal to the size of pieces
3263				.parent()
3264					.addClass( "ui-effects-explode" )
3265					.css( {
3266						position: "absolute",
3267						overflow: "hidden",
3268						width: width,
3269						height: height,
3270						left: left + ( show ? mx * width : 0 ),
3271						top: top + ( show ? my * height : 0 ),
3272						opacity: show ? 0 : 1
3273					} )
3274					.animate( {
3275						left: left + ( show ? 0 : mx * width ),
3276						top: top + ( show ? 0 : my * height ),
3277						opacity: show ? 1 : 0
3278					}, options.duration || 500, options.easing, childComplete );
3279		}
3280	}
3281
3282	function animComplete() {
3283		element.css( {
3284			visibility: "visible"
3285		} );
3286		$( pieces ).remove();
3287		done();
3288	}
3289} );
3290
3291
3292/*!
3293 * jQuery UI Effects Fade 1.14.1
3294 * https://jqueryui.com
3295 *
3296 * Copyright OpenJS Foundation and other contributors
3297 * Released under the MIT license.
3298 * https://jquery.org/license
3299 */
3300
3301//>>label: Fade Effect
3302//>>group: Effects
3303//>>description: Fades the element.
3304//>>docs: https://api.jqueryui.com/fade-effect/
3305//>>demos: https://jqueryui.com/effect/
3306
3307
3308var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
3309	var show = options.mode === "show";
3310
3311	$( this )
3312		.css( "opacity", show ? 0 : 1 )
3313		.animate( {
3314			opacity: show ? 1 : 0
3315		}, {
3316			queue: false,
3317			duration: options.duration,
3318			easing: options.easing,
3319			complete: done
3320		} );
3321} );
3322
3323
3324/*!
3325 * jQuery UI Effects Fold 1.14.1
3326 * https://jqueryui.com
3327 *
3328 * Copyright OpenJS Foundation and other contributors
3329 * Released under the MIT license.
3330 * https://jquery.org/license
3331 */
3332
3333//>>label: Fold Effect
3334//>>group: Effects
3335//>>description: Folds an element first horizontally and then vertically.
3336//>>docs: https://api.jqueryui.com/fold-effect/
3337//>>demos: https://jqueryui.com/effect/
3338
3339
3340var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
3341
3342	// Create element
3343	var element = $( this ),
3344		mode = options.mode,
3345		show = mode === "show",
3346		hide = mode === "hide",
3347		size = options.size || 15,
3348		percent = /([0-9]+)%/.exec( size ),
3349		horizFirst = !!options.horizFirst,
3350		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
3351		duration = options.duration / 2,
3352
3353		placeholder = $.effects.createPlaceholder( element ),
3354
3355		start = element.cssClip(),
3356		animation1 = { clip: $.extend( {}, start ) },
3357		animation2 = { clip: $.extend( {}, start ) },
3358
3359		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
3360
3361		queuelen = element.queue().length;
3362
3363	if ( percent ) {
3364		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
3365	}
3366	animation1.clip[ ref[ 0 ] ] = size;
3367	animation2.clip[ ref[ 0 ] ] = size;
3368	animation2.clip[ ref[ 1 ] ] = 0;
3369
3370	if ( show ) {
3371		element.cssClip( animation2.clip );
3372		if ( placeholder ) {
3373			placeholder.css( $.effects.clipToBox( animation2 ) );
3374		}
3375
3376		animation2.clip = start;
3377	}
3378
3379	// Animate
3380	element
3381		.queue( function( next ) {
3382			if ( placeholder ) {
3383				placeholder
3384					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
3385					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
3386			}
3387
3388			next();
3389		} )
3390		.animate( animation1, duration, options.easing )
3391		.animate( animation2, duration, options.easing )
3392		.queue( done );
3393
3394	$.effects.unshift( element, queuelen, 4 );
3395} );
3396
3397
3398/*!
3399 * jQuery UI Effects Highlight 1.14.1
3400 * https://jqueryui.com
3401 *
3402 * Copyright OpenJS Foundation and other contributors
3403 * Released under the MIT license.
3404 * https://jquery.org/license
3405 */
3406
3407//>>label: Highlight Effect
3408//>>group: Effects
3409//>>description: Highlights the background of an element in a defined color for a custom duration.
3410//>>docs: https://api.jqueryui.com/highlight-effect/
3411//>>demos: https://jqueryui.com/effect/
3412
3413
3414var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
3415	var element = $( this ),
3416		animation = {
3417			backgroundColor: element.css( "backgroundColor" )
3418		};
3419
3420	if ( options.mode === "hide" ) {
3421		animation.opacity = 0;
3422	}
3423
3424	$.effects.saveStyle( element );
3425
3426	element
3427		.css( {
3428			backgroundImage: "none",
3429			backgroundColor: options.color || "#ffff99"
3430		} )
3431		.animate( animation, {
3432			queue: false,
3433			duration: options.duration,
3434			easing: options.easing,
3435			complete: done
3436		} );
3437} );
3438
3439
3440/*!
3441 * jQuery UI Effects Size 1.14.1
3442 * https://jqueryui.com
3443 *
3444 * Copyright OpenJS Foundation and other contributors
3445 * Released under the MIT license.
3446 * https://jquery.org/license
3447 */
3448
3449//>>label: Size Effect
3450//>>group: Effects
3451//>>description: Resize an element to a specified width and height.
3452//>>docs: https://api.jqueryui.com/size-effect/
3453//>>demos: https://jqueryui.com/effect/
3454
3455
3456var effectsEffectSize = $.effects.define( "size", function( options, done ) {
3457
3458	// Create element
3459	var baseline, factor, temp,
3460		element = $( this ),
3461
3462		// Copy for children
3463		cProps = [ "fontSize" ],
3464		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
3465		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
3466
3467		// Set options
3468		mode = options.mode,
3469		restore = mode !== "effect",
3470		scale = options.scale || "both",
3471		origin = options.origin || [ "middle", "center" ],
3472		position = element.css( "position" ),
3473		pos = element.position(),
3474		original = $.effects.scaledDimensions( element ),
3475		from = options.from || original,
3476		to = options.to || $.effects.scaledDimensions( element, 0 );
3477
3478	$.effects.createPlaceholder( element );
3479
3480	if ( mode === "show" ) {
3481		temp = from;
3482		from = to;
3483		to = temp;
3484	}
3485
3486	// Set scaling factor
3487	factor = {
3488		from: {
3489			y: from.height / original.height,
3490			x: from.width / original.width
3491		},
3492		to: {
3493			y: to.height / original.height,
3494			x: to.width / original.width
3495		}
3496	};
3497
3498	// Scale the css box
3499	if ( scale === "box" || scale === "both" ) {
3500
3501		// Vertical props scaling
3502		if ( factor.from.y !== factor.to.y ) {
3503			from = $.effects.setTransition( element, vProps, factor.from.y, from );
3504			to = $.effects.setTransition( element, vProps, factor.to.y, to );
3505		}
3506
3507		// Horizontal props scaling
3508		if ( factor.from.x !== factor.to.x ) {
3509			from = $.effects.setTransition( element, hProps, factor.from.x, from );
3510			to = $.effects.setTransition( element, hProps, factor.to.x, to );
3511		}
3512	}
3513
3514	// Scale the content
3515	if ( scale === "content" || scale === "both" ) {
3516
3517		// Vertical props scaling
3518		if ( factor.from.y !== factor.to.y ) {
3519			from = $.effects.setTransition( element, cProps, factor.from.y, from );
3520			to = $.effects.setTransition( element, cProps, factor.to.y, to );
3521		}
3522	}
3523
3524	// Adjust the position properties based on the provided origin points
3525	if ( origin ) {
3526		baseline = $.effects.getBaseline( origin, original );
3527		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
3528		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
3529		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
3530		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
3531	}
3532	delete from.outerHeight;
3533	delete from.outerWidth;
3534	element.css( from );
3535
3536	// Animate the children if desired
3537	if ( scale === "content" || scale === "both" ) {
3538
3539		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
3540		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
3541
3542		// Only animate children with width attributes specified
3543		// TODO: is this right? should we include anything with css width specified as well
3544		element.find( "*[width]" ).each( function() {
3545			var child = $( this ),
3546				childOriginal = $.effects.scaledDimensions( child ),
3547				childFrom = {
3548					height: childOriginal.height * factor.from.y,
3549					width: childOriginal.width * factor.from.x,
3550					outerHeight: childOriginal.outerHeight * factor.from.y,
3551					outerWidth: childOriginal.outerWidth * factor.from.x
3552				},
3553				childTo = {
3554					height: childOriginal.height * factor.to.y,
3555					width: childOriginal.width * factor.to.x,
3556					outerHeight: childOriginal.height * factor.to.y,
3557					outerWidth: childOriginal.width * factor.to.x
3558				};
3559
3560			// Vertical props scaling
3561			if ( factor.from.y !== factor.to.y ) {
3562				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
3563				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
3564			}
3565
3566			// Horizontal props scaling
3567			if ( factor.from.x !== factor.to.x ) {
3568				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
3569				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
3570			}
3571
3572			if ( restore ) {
3573				$.effects.saveStyle( child );
3574			}
3575
3576			// Animate children
3577			child.css( childFrom );
3578			child.animate( childTo, options.duration, options.easing, function() {
3579
3580				// Restore children
3581				if ( restore ) {
3582					$.effects.restoreStyle( child );
3583				}
3584			} );
3585		} );
3586	}
3587
3588	// Animate
3589	element.animate( to, {
3590		queue: false,
3591		duration: options.duration,
3592		easing: options.easing,
3593		complete: function() {
3594
3595			var offset = element.offset();
3596
3597			if ( to.opacity === 0 ) {
3598				element.css( "opacity", from.opacity );
3599			}
3600
3601			if ( !restore ) {
3602				element
3603					.css( "position", position === "static" ? "relative" : position )
3604					.offset( offset );
3605
3606				// Need to save style here so that automatic style restoration
3607				// doesn't restore to the original styles from before the animation.
3608				$.effects.saveStyle( element );
3609			}
3610
3611			done();
3612		}
3613	} );
3614
3615} );
3616
3617
3618/*!
3619 * jQuery UI Effects Scale 1.14.1
3620 * https://jqueryui.com
3621 *
3622 * Copyright OpenJS Foundation and other contributors
3623 * Released under the MIT license.
3624 * https://jquery.org/license
3625 */
3626
3627//>>label: Scale Effect
3628//>>group: Effects
3629//>>description: Grows or shrinks an element and its content.
3630//>>docs: https://api.jqueryui.com/scale-effect/
3631//>>demos: https://jqueryui.com/effect/
3632
3633
3634var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
3635
3636	// Create element
3637	var el = $( this ),
3638		mode = options.mode,
3639		percent = parseInt( options.percent, 10 ) ||
3640			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
3641
3642		newOptions = $.extend( true, {
3643			from: $.effects.scaledDimensions( el ),
3644			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
3645			origin: options.origin || [ "middle", "center" ]
3646		}, options );
3647
3648	// Fade option to support puff
3649	if ( options.fade ) {
3650		newOptions.from.opacity = 1;
3651		newOptions.to.opacity = 0;
3652	}
3653
3654	$.effects.effect.size.call( this, newOptions, done );
3655} );
3656
3657
3658/*!
3659 * jQuery UI Effects Puff 1.14.1
3660 * https://jqueryui.com
3661 *
3662 * Copyright OpenJS Foundation and other contributors
3663 * Released under the MIT license.
3664 * https://jquery.org/license
3665 */
3666
3667//>>label: Puff Effect
3668//>>group: Effects
3669//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
3670//>>docs: https://api.jqueryui.com/puff-effect/
3671//>>demos: https://jqueryui.com/effect/
3672
3673
3674var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
3675	var newOptions = $.extend( true, {}, options, {
3676		fade: true,
3677		percent: parseInt( options.percent, 10 ) || 150
3678	} );
3679
3680	$.effects.effect.scale.call( this, newOptions, done );
3681} );
3682
3683
3684/*!
3685 * jQuery UI Effects Pulsate 1.14.1
3686 * https://jqueryui.com
3687 *
3688 * Copyright OpenJS Foundation and other contributors
3689 * Released under the MIT license.
3690 * https://jquery.org/license
3691 */
3692
3693//>>label: Pulsate Effect
3694//>>group: Effects
3695//>>description: Pulsates an element n times by changing the opacity to zero and back.
3696//>>docs: https://api.jqueryui.com/pulsate-effect/
3697//>>demos: https://jqueryui.com/effect/
3698
3699
3700var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
3701	var element = $( this ),
3702		mode = options.mode,
3703		show = mode === "show",
3704		hide = mode === "hide",
3705		showhide = show || hide,
3706
3707		// Showing or hiding leaves off the "last" animation
3708		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
3709		duration = options.duration / anims,
3710		animateTo = 0,
3711		i = 1,
3712		queuelen = element.queue().length;
3713
3714	if ( show || !element.is( ":visible" ) ) {
3715		element.css( "opacity", 0 ).show();
3716		animateTo = 1;
3717	}
3718
3719	// Anims - 1 opacity "toggles"
3720	for ( ; i < anims; i++ ) {
3721		element.animate( { opacity: animateTo }, duration, options.easing );
3722		animateTo = 1 - animateTo;
3723	}
3724
3725	element.animate( { opacity: animateTo }, duration, options.easing );
3726
3727	element.queue( done );
3728
3729	$.effects.unshift( element, queuelen, anims + 1 );
3730} );
3731
3732
3733/*!
3734 * jQuery UI Effects Shake 1.14.1
3735 * https://jqueryui.com
3736 *
3737 * Copyright OpenJS Foundation and other contributors
3738 * Released under the MIT license.
3739 * https://jquery.org/license
3740 */
3741
3742//>>label: Shake Effect
3743//>>group: Effects
3744//>>description: Shakes an element horizontally or vertically n times.
3745//>>docs: https://api.jqueryui.com/shake-effect/
3746//>>demos: https://jqueryui.com/effect/
3747
3748
3749var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
3750
3751	var i = 1,
3752		element = $( this ),
3753		direction = options.direction || "left",
3754		distance = options.distance || 20,
3755		times = options.times || 3,
3756		anims = times * 2 + 1,
3757		speed = Math.round( options.duration / anims ),
3758		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3759		positiveMotion = ( direction === "up" || direction === "left" ),
3760		animation = {},
3761		animation1 = {},
3762		animation2 = {},
3763
3764		queuelen = element.queue().length;
3765
3766	$.effects.createPlaceholder( element );
3767
3768	// Animation
3769	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
3770	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
3771	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
3772
3773	// Animate
3774	element.animate( animation, speed, options.easing );
3775
3776	// Shakes
3777	for ( ; i < times; i++ ) {
3778		element
3779			.animate( animation1, speed, options.easing )
3780			.animate( animation2, speed, options.easing );
3781	}
3782
3783	element
3784		.animate( animation1, speed, options.easing )
3785		.animate( animation, speed / 2, options.easing )
3786		.queue( done );
3787
3788	$.effects.unshift( element, queuelen, anims + 1 );
3789} );
3790
3791
3792/*!
3793 * jQuery UI Effects Slide 1.14.1
3794 * https://jqueryui.com
3795 *
3796 * Copyright OpenJS Foundation and other contributors
3797 * Released under the MIT license.
3798 * https://jquery.org/license
3799 */
3800
3801//>>label: Slide Effect
3802//>>group: Effects
3803//>>description: Slides an element in and out of the viewport.
3804//>>docs: https://api.jqueryui.com/slide-effect/
3805//>>demos: https://jqueryui.com/effect/
3806
3807
3808var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
3809	var startClip, startRef,
3810		element = $( this ),
3811		map = {
3812			up: [ "bottom", "top" ],
3813			down: [ "top", "bottom" ],
3814			left: [ "right", "left" ],
3815			right: [ "left", "right" ]
3816		},
3817		mode = options.mode,
3818		direction = options.direction || "left",
3819		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
3820		positiveMotion = ( direction === "up" || direction === "left" ),
3821		distance = options.distance ||
3822			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
3823		animation = {};
3824
3825	$.effects.createPlaceholder( element );
3826
3827	startClip = element.cssClip();
3828	startRef = element.position()[ ref ];
3829
3830	// Define hide animation
3831	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
3832	animation.clip = element.cssClip();
3833	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
3834
3835	// Reverse the animation if we're showing
3836	if ( mode === "show" ) {
3837		element.cssClip( animation.clip );
3838		element.css( ref, animation[ ref ] );
3839		animation.clip = startClip;
3840		animation[ ref ] = startRef;
3841	}
3842
3843	// Actually animate
3844	element.animate( animation, {
3845		queue: false,
3846		duration: options.duration,
3847		easing: options.easing,
3848		complete: done
3849	} );
3850} );
3851
3852
3853/*!
3854 * jQuery UI Effects Transfer 1.14.1
3855 * https://jqueryui.com
3856 *
3857 * Copyright OpenJS Foundation and other contributors
3858 * Released under the MIT license.
3859 * https://jquery.org/license
3860 */
3861
3862//>>label: Transfer Effect
3863//>>group: Effects
3864//>>description: Displays a transfer effect from one element to another.
3865//>>docs: https://api.jqueryui.com/transfer-effect/
3866//>>demos: https://jqueryui.com/effect/
3867
3868
3869var effect;
3870if ( $.uiBackCompat === true ) {
3871	effect = $.effects.define( "transfer", function( options, done ) {
3872		$( this ).transfer( options, done );
3873	} );
3874}
3875var effectsEffectTransfer = effect;
3876
3877
3878/*!
3879 * jQuery UI Focusable 1.14.1
3880 * https://jqueryui.com
3881 *
3882 * Copyright OpenJS Foundation and other contributors
3883 * Released under the MIT license.
3884 * https://jquery.org/license
3885 */
3886
3887//>>label: :focusable Selector
3888//>>group: Core
3889//>>description: Selects elements which can be focused.
3890//>>docs: https://api.jqueryui.com/focusable-selector/
3891
3892
3893// Selectors
3894$.ui.focusable = function( element, hasTabindex ) {
3895	var map, mapName, img, focusableIfVisible, fieldset,
3896		nodeName = element.nodeName.toLowerCase();
3897
3898	if ( "area" === nodeName ) {
3899		map = element.parentNode;
3900		mapName = map.name;
3901		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
3902			return false;
3903		}
3904		img = $( "img[usemap='#" + mapName + "']" );
3905		return img.length > 0 && img.is( ":visible" );
3906	}
3907
3908	if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) {
3909		focusableIfVisible = !element.disabled;
3910
3911		if ( focusableIfVisible ) {
3912
3913			// Form controls within a disabled fieldset are disabled.
3914			// However, controls within the fieldset's legend do not get disabled.
3915			// Since controls generally aren't placed inside legends, we skip
3916			// this portion of the check.
3917			fieldset = $( element ).closest( "fieldset" )[ 0 ];
3918			if ( fieldset ) {
3919				focusableIfVisible = !fieldset.disabled;
3920			}
3921		}
3922	} else if ( "a" === nodeName ) {
3923		focusableIfVisible = element.href || hasTabindex;
3924	} else {
3925		focusableIfVisible = hasTabindex;
3926	}
3927
3928	return focusableIfVisible && $( element ).is( ":visible" ) &&
3929		$( element ).css( "visibility" ) === "visible";
3930};
3931
3932$.extend( $.expr.pseudos, {
3933	focusable: function( element ) {
3934		return $.ui.focusable( element, $.attr( element, "tabindex" ) != null );
3935	}
3936} );
3937
3938var focusable = $.ui.focusable;
3939
3940
3941/*!
3942 * jQuery UI Form Reset Mixin 1.14.1
3943 * https://jqueryui.com
3944 *
3945 * Copyright OpenJS Foundation and other contributors
3946 * Released under the MIT license.
3947 * https://jquery.org/license
3948 */
3949
3950//>>label: Form Reset Mixin
3951//>>group: Core
3952//>>description: Refresh input widgets when their form is reset
3953//>>docs: https://api.jqueryui.com/form-reset-mixin/
3954
3955
3956var formResetMixin = $.ui.formResetMixin = {
3957	_formResetHandler: function() {
3958		var form = $( this );
3959
3960		// Wait for the form reset to actually happen before refreshing
3961		setTimeout( function() {
3962			var instances = form.data( "ui-form-reset-instances" );
3963			$.each( instances, function() {
3964				this.refresh();
3965			} );
3966		} );
3967	},
3968
3969	_bindFormResetHandler: function() {
3970		this.form = $( this.element.prop( "form" ) );
3971		if ( !this.form.length ) {
3972			return;
3973		}
3974
3975		var instances = this.form.data( "ui-form-reset-instances" ) || [];
3976		if ( !instances.length ) {
3977
3978			// We don't use _on() here because we use a single event handler per form
3979			this.form.on( "reset.ui-form-reset", this._formResetHandler );
3980		}
3981		instances.push( this );
3982		this.form.data( "ui-form-reset-instances", instances );
3983	},
3984
3985	_unbindFormResetHandler: function() {
3986		if ( !this.form.length ) {
3987			return;
3988		}
3989
3990		var instances = this.form.data( "ui-form-reset-instances" );
3991		instances.splice( $.inArray( this, instances ), 1 );
3992		if ( instances.length ) {
3993			this.form.data( "ui-form-reset-instances", instances );
3994		} else {
3995			this.form
3996				.removeData( "ui-form-reset-instances" )
3997				.off( "reset.ui-form-reset" );
3998		}
3999	}
4000};
4001
4002
4003/*!
4004 * jQuery UI Legacy jQuery Core patches 1.14.1
4005 * https://jqueryui.com
4006 *
4007 * Copyright OpenJS Foundation and other contributors
4008 * Released under the MIT license.
4009 * https://jquery.org/license
4010 *
4011 */
4012
4013//>>label: Legacy jQuery Core patches
4014//>>group: Core
4015//>>description: Backport `.even()`, `.odd()` and `$.escapeSelector` to older jQuery Core versions (deprecated)
4016
4017
4018// Support: jQuery 2.2.x or older.
4019// This method has been defined in jQuery 3.0.0.
4020// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js
4021if ( !$.escapeSelector ) {
4022	$.escapeSelector = function( id ) {
4023		return CSS.escape( id + "" );
4024	};
4025}
4026
4027// Support: jQuery 3.4.x or older
4028// These methods have been defined in jQuery 3.5.0.
4029if ( !$.fn.even || !$.fn.odd ) {
4030	$.fn.extend( {
4031		even: function() {
4032			return this.filter( function( i ) {
4033				return i % 2 === 0;
4034			} );
4035		},
4036		odd: function() {
4037			return this.filter( function( i ) {
4038				return i % 2 === 1;
4039			} );
4040		}
4041	} );
4042}
4043
4044;
4045/*!
4046 * jQuery UI Keycode 1.14.1
4047 * https://jqueryui.com
4048 *
4049 * Copyright OpenJS Foundation and other contributors
4050 * Released under the MIT license.
4051 * https://jquery.org/license
4052 */
4053
4054//>>label: Keycode
4055//>>group: Core
4056//>>description: Provide keycodes as keynames
4057//>>docs: https://api.jqueryui.com/jQuery.ui.keyCode/
4058
4059
4060var keycode = $.ui.keyCode = {
4061	BACKSPACE: 8,
4062	COMMA: 188,
4063	DELETE: 46,
4064	DOWN: 40,
4065	END: 35,
4066	ENTER: 13,
4067	ESCAPE: 27,
4068	HOME: 36,
4069	LEFT: 37,
4070	PAGE_DOWN: 34,
4071	PAGE_UP: 33,
4072	PERIOD: 190,
4073	RIGHT: 39,
4074	SPACE: 32,
4075	TAB: 9,
4076	UP: 38
4077};
4078
4079
4080/*!
4081 * jQuery UI Labels 1.14.1
4082 * https://jqueryui.com
4083 *
4084 * Copyright OpenJS Foundation and other contributors
4085 * Released under the MIT license.
4086 * https://jquery.org/license
4087 */
4088
4089//>>label: labels
4090//>>group: Core
4091//>>description: Find all the labels associated with a given input
4092//>>docs: https://api.jqueryui.com/labels/
4093
4094
4095var labels = $.fn.labels = function() {
4096	var ancestor, selector, id, labels, ancestors;
4097
4098	if ( !this.length ) {
4099		return this.pushStack( [] );
4100	}
4101
4102	// Check control.labels first
4103	if ( this[ 0 ].labels && this[ 0 ].labels.length ) {
4104		return this.pushStack( this[ 0 ].labels );
4105	}
4106
4107	// If `control.labels` is empty - e.g. inside of document fragments - find
4108	// the labels manually
4109	labels = this.eq( 0 ).parents( "label" );
4110
4111	// Look for the label based on the id
4112	id = this.attr( "id" );
4113	if ( id ) {
4114
4115		// We don't search against the document in case the element
4116		// is disconnected from the DOM
4117		ancestor = this.eq( 0 ).parents().last();
4118
4119		// Get a full set of top level ancestors
4120		ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() );
4121
4122		// Create a selector for the label based on the id
4123		selector = "label[for='" + CSS.escape( id ) + "']";
4124
4125		labels = labels.add( ancestors.find( selector ).addBack( selector ) );
4126
4127	}
4128
4129	// Return whatever we have found for labels
4130	return this.pushStack( labels );
4131};
4132
4133
4134/*!
4135 * jQuery UI Scroll Parent 1.14.1
4136 * https://jqueryui.com
4137 *
4138 * Copyright OpenJS Foundation and other contributors
4139 * Released under the MIT license.
4140 * https://jquery.org/license
4141 */
4142
4143//>>label: scrollParent
4144//>>group: Core
4145//>>description: Get the closest ancestor element that is scrollable.
4146//>>docs: https://api.jqueryui.com/scrollParent/
4147
4148
4149var scrollParent = $.fn.scrollParent = function( includeHidden ) {
4150	var position = this.css( "position" ),
4151		excludeStaticParent = position === "absolute",
4152		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
4153		scrollParent = this.parents().filter( function() {
4154			var parent = $( this );
4155			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
4156				return false;
4157			}
4158			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
4159				parent.css( "overflow-x" ) );
4160		} ).eq( 0 );
4161
4162	return position === "fixed" || !scrollParent.length ?
4163		$( this[ 0 ].ownerDocument || document ) :
4164		scrollParent;
4165};
4166
4167
4168/*!
4169 * jQuery UI Tabbable 1.14.1
4170 * https://jqueryui.com
4171 *
4172 * Copyright OpenJS Foundation and other contributors
4173 * Released under the MIT license.
4174 * https://jquery.org/license
4175 */
4176
4177//>>label: :tabbable Selector
4178//>>group: Core
4179//>>description: Selects elements which can be tabbed to.
4180//>>docs: https://api.jqueryui.com/tabbable-selector/
4181
4182
4183var tabbable = $.extend( $.expr.pseudos, {
4184	tabbable: function( element ) {
4185		var tabIndex = $.attr( element, "tabindex" ),
4186			hasTabindex = tabIndex != null;
4187		return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex );
4188	}
4189} );
4190
4191
4192/*!
4193 * jQuery UI Unique ID 1.14.1
4194 * https://jqueryui.com
4195 *
4196 * Copyright OpenJS Foundation and other contributors
4197 * Released under the MIT license.
4198 * https://jquery.org/license
4199 */
4200
4201//>>label: uniqueId
4202//>>group: Core
4203//>>description: Functions to generate and remove uniqueId's
4204//>>docs: https://api.jqueryui.com/uniqueId/
4205
4206
4207var uniqueId = $.fn.extend( {
4208	uniqueId: ( function() {
4209		var uuid = 0;
4210
4211		return function() {
4212			return this.each( function() {
4213				if ( !this.id ) {
4214					this.id = "ui-id-" + ( ++uuid );
4215				}
4216			} );
4217		};
4218	} )(),
4219
4220	removeUniqueId: function() {
4221		return this.each( function() {
4222			if ( /^ui-id-\d+$/.test( this.id ) ) {
4223				$( this ).removeAttr( "id" );
4224			}
4225		} );
4226	}
4227} );
4228
4229
4230/*!
4231 * jQuery UI Accordion 1.14.1
4232 * https://jqueryui.com
4233 *
4234 * Copyright OpenJS Foundation and other contributors
4235 * Released under the MIT license.
4236 * https://jquery.org/license
4237 */
4238
4239//>>label: Accordion
4240//>>group: Widgets
4241/* eslint-disable max-len */
4242//>>description: Displays collapsible content panels for presenting information in a limited amount of space.
4243/* eslint-enable max-len */
4244//>>docs: https://api.jqueryui.com/accordion/
4245//>>demos: https://jqueryui.com/accordion/
4246//>>css.structure: ../../themes/base/core.css
4247//>>css.structure: ../../themes/base/accordion.css
4248//>>css.theme: ../../themes/base/theme.css
4249
4250
4251var widgetsAccordion = $.widget( "ui.accordion", {
4252	version: "1.14.1
vendor: 14,922 bytes, lines 4252-4833
4252",
4253	options: {
4254		active: 0,
4255		animate: {},
4256		classes: {
4257			"ui-accordion-header": "ui-corner-top",
4258			"ui-accordion-header-collapsed": "ui-corner-all",
4259			"ui-accordion-content": "ui-corner-bottom"
4260		},
4261		collapsible: false,
4262		event: "click",
4263		header: function( elem ) {
4264			return elem
4265				.find( "> li > :first-child" )
4266				.add(
4267					elem.find( "> :not(li)" )
4268
4269						// Support: jQuery <3.5 only
4270						// We could use `.even()` but that's unavailable in older jQuery.
4271						.filter( function( i ) {
4272							return i % 2 === 0;
4273						} )
4274				);
4275		},
4276		heightStyle: "auto",
4277		icons: {
4278			activeHeader: "ui-icon-triangle-1-s",
4279			header: "ui-icon-triangle-1-e"
4280		},
4281
4282		// Callbacks
4283		activate: null,
4284		beforeActivate: null
4285	},
4286
4287	hideProps: {
4288		borderTopWidth: "hide",
4289		borderBottomWidth: "hide",
4290		paddingTop: "hide",
4291		paddingBottom: "hide",
4292		height: "hide"
4293	},
4294
4295	showProps: {
4296		borderTopWidth: "show",
4297		borderBottomWidth: "show",
4298		paddingTop: "show",
4299		paddingBottom: "show",
4300		height: "show"
4301	},
4302
4303	_create: function() {
4304		var options = this.options;
4305
4306		this.prevShow = this.prevHide = $();
4307		this._addClass( "ui-accordion", "ui-widget ui-helper-reset" );
4308		this.element.attr( "role", "tablist" );
4309
4310		// Don't allow collapsible: false and active: false / null
4311		if ( !options.collapsible && ( options.active === false || options.active == null ) ) {
4312			options.active = 0;
4313		}
4314
4315		this._processPanels();
4316
4317		// handle negative values
4318		if ( options.active < 0 ) {
4319			options.active += this.headers.length;
4320		}
4321		this._refresh();
4322	},
4323
4324	_getCreateEventData: function() {
4325		return {
4326			header: this.active,
4327			panel: !this.active.length ? $() : this.active.next()
4328		};
4329	},
4330
4331	_createIcons: function() {
4332		var icon, children,
4333			icons = this.options.icons;
4334
4335		if ( icons ) {
4336			icon = $( "<span>" );
4337			this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header );
4338			icon.prependTo( this.headers );
4339			children = this.active.children( ".ui-accordion-header-icon" );
4340			this._removeClass( children, icons.header )
4341				._addClass( children, null, icons.activeHeader )
4342				._addClass( this.headers, "ui-accordion-icons" );
4343		}
4344	},
4345
4346	_destroyIcons: function() {
4347		this._removeClass( this.headers, "ui-accordion-icons" );
4348		this.headers.children( ".ui-accordion-header-icon" ).remove();
4349	},
4350
4351	_destroy: function() {
4352		var contents;
4353
4354		// Clean up main element
4355		this.element.removeAttr( "role" );
4356
4357		// Clean up headers
4358		this.headers
4359			.removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" )
4360			.removeUniqueId();
4361
4362		this._destroyIcons();
4363
4364		// Clean up content panels
4365		contents = this.headers.next()
4366			.css( "display", "" )
4367			.removeAttr( "role aria-hidden aria-labelledby" )
4368			.removeUniqueId();
4369
4370		if ( this.options.heightStyle !== "content" ) {
4371			contents.css( "height", "" );
4372		}
4373	},
4374
4375	_setOption: function( key, value ) {
4376		if ( key === "active" ) {
4377
4378			// _activate() will handle invalid values and update this.options
4379			this._activate( value );
4380			return;
4381		}
4382
4383		if ( key === "event" ) {
4384			if ( this.options.event ) {
4385				this._off( this.headers, this.options.event );
4386			}
4387			this._setupEvents( value );
4388		}
4389
4390		this._super( key, value );
4391
4392		// Setting collapsible: false while collapsed; open first panel
4393		if ( key === "collapsible" && !value && this.options.active === false ) {
4394			this._activate( 0 );
4395		}
4396
4397		if ( key === "icons" ) {
4398			this._destroyIcons();
4399			if ( value ) {
4400				this._createIcons();
4401			}
4402		}
4403	},
4404
4405	_setOptionDisabled: function( value ) {
4406		this._super( value );
4407
4408		this.element.attr( "aria-disabled", value );
4409		this._toggleClass( null, "ui-state-disabled", !!value );
4410	},
4411
4412	_keydown: function( event ) {
4413		if ( event.altKey || event.ctrlKey ) {
4414			return;
4415		}
4416
4417		var keyCode = $.ui.keyCode,
4418			length = this.headers.length,
4419			currentIndex = this.headers.index( event.target ),
4420			toFocus = false;
4421
4422		switch ( event.keyCode ) {
4423		case keyCode.RIGHT:
4424		case keyCode.DOWN:
4425			toFocus = this.headers[ ( currentIndex + 1 ) % length ];
4426			break;
4427		case keyCode.LEFT:
4428		case keyCode.UP:
4429			toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
4430			break;
4431		case keyCode.SPACE:
4432		case keyCode.ENTER:
4433			this._eventHandler( event );
4434			break;
4435		case keyCode.HOME:
4436			toFocus = this.headers[ 0 ];
4437			break;
4438		case keyCode.END:
4439			toFocus = this.headers[ length - 1 ];
4440			break;
4441		}
4442
4443		if ( toFocus ) {
4444			$( event.target ).attr( "tabIndex", -1 );
4445			$( toFocus ).attr( "tabIndex", 0 );
4446			$( toFocus ).trigger( "focus" );
4447			event.preventDefault();
4448		}
4449	},
4450
4451	_panelKeyDown: function( event ) {
4452		if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
4453			$( event.currentTarget ).prev().trigger( "focus" );
4454		}
4455	},
4456
4457	refresh: function() {
4458		var options = this.options;
4459		this._processPanels();
4460
4461		// Was collapsed or no panel
4462		if ( ( options.active === false && options.collapsible === true ) ||
4463				!this.headers.length ) {
4464			options.active = false;
4465			this.active = $();
4466
4467		// active false only when collapsible is true
4468		} else if ( options.active === false ) {
4469			this._activate( 0 );
4470
4471		// was active, but active panel is gone
4472		} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
4473
4474			// all remaining panel are disabled
4475			if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) {
4476				options.active = false;
4477				this.active = $();
4478
4479			// activate previous panel
4480			} else {
4481				this._activate( Math.max( 0, options.active - 1 ) );
4482			}
4483
4484		// was active, active panel still exists
4485		} else {
4486
4487			// make sure active index is correct
4488			options.active = this.headers.index( this.active );
4489		}
4490
4491		this._destroyIcons();
4492
4493		this._refresh();
4494	},
4495
4496	_processPanels: function() {
4497		var prevHeaders = this.headers,
4498			prevPanels = this.panels;
4499
4500		if ( typeof this.options.header === "function" ) {
4501			this.headers = this.options.header( this.element );
4502		} else {
4503			this.headers = this.element.find( this.options.header );
4504		}
4505		this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed",
4506			"ui-state-default" );
4507
4508		this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide();
4509		this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" );
4510
4511		// Avoid memory leaks (#10056)
4512		if ( prevPanels ) {
4513			this._off( prevHeaders.not( this.headers ) );
4514			this._off( prevPanels.not( this.panels ) );
4515		}
4516	},
4517
4518	_refresh: function() {
4519		var maxHeight,
4520			options = this.options,
4521			heightStyle = options.heightStyle,
4522			parent = this.element.parent();
4523
4524		this.active = this._findActive( options.active );
4525		this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" )
4526			._removeClass( this.active, "ui-accordion-header-collapsed" );
4527		this._addClass( this.active.next(), "ui-accordion-content-active" );
4528		this.active.next().show();
4529
4530		this.headers
4531			.attr( "role", "tab" )
4532			.each( function() {
4533				var header = $( this ),
4534					headerId = header.uniqueId().attr( "id" ),
4535					panel = header.next(),
4536					panelId = panel.uniqueId().attr( "id" );
4537				header.attr( "aria-controls", panelId );
4538				panel.attr( "aria-labelledby", headerId );
4539			} )
4540			.next()
4541				.attr( "role", "tabpanel" );
4542
4543		this.headers
4544			.not( this.active )
4545				.attr( {
4546					"aria-selected": "false",
4547					"aria-expanded": "false",
4548					tabIndex: -1
4549				} )
4550				.next()
4551					.attr( {
4552						"aria-hidden": "true"
4553					} )
4554					.hide();
4555
4556		// Make sure at least one header is in the tab order
4557		if ( !this.active.length ) {
4558			this.headers.eq( 0 ).attr( "tabIndex", 0 );
4559		} else {
4560			this.active.attr( {
4561				"aria-selected": "true",
4562				"aria-expanded": "true",
4563				tabIndex: 0
4564			} )
4565				.next()
4566					.attr( {
4567						"aria-hidden": "false"
4568					} );
4569		}
4570
4571		this._createIcons();
4572
4573		this._setupEvents( options.event );
4574
4575		if ( heightStyle === "fill" ) {
4576			maxHeight = parent.height();
4577			this.element.siblings( ":visible" ).each( function() {
4578				var elem = $( this ),
4579					position = elem.css( "position" );
4580
4581				if ( position === "absolute" || position === "fixed" ) {
4582					return;
4583				}
4584				maxHeight -= elem.outerHeight( true );
4585			} );
4586
4587			this.headers.each( function() {
4588				maxHeight -= $( this ).outerHeight( true );
4589			} );
4590
4591			this.headers.next()
4592				.each( function() {
4593					$( this ).height( Math.max( 0, maxHeight -
4594						$( this ).innerHeight() + $( this ).height() ) );
4595				} )
4596				.css( "overflow", "auto" );
4597		} else if ( heightStyle === "auto" ) {
4598			maxHeight = 0;
4599			this.headers.next()
4600				.each( function() {
4601					var isVisible = $( this ).is( ":visible" );
4602					if ( !isVisible ) {
4603						$( this ).show();
4604					}
4605					maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
4606					if ( !isVisible ) {
4607						$( this ).hide();
4608					}
4609				} )
4610				.height( maxHeight );
4611		}
4612	},
4613
4614	_activate: function( index ) {
4615		var active = this._findActive( index )[ 0 ];
4616
4617		// Trying to activate the already active panel
4618		if ( active === this.active[ 0 ] ) {
4619			return;
4620		}
4621
4622		// Trying to collapse, simulate a click on the currently active header
4623		active = active || this.active[ 0 ];
4624
4625		this._eventHandler( {
4626			target: active,
4627			currentTarget: active,
4628			preventDefault: $.noop
4629		} );
4630	},
4631
4632	_findActive: function( selector ) {
4633		return typeof selector === "number" ? this.headers.eq( selector ) : $();
4634	},
4635
4636	_setupEvents: function( event ) {
4637		var events = {
4638			keydown: "_keydown"
4639		};
4640		if ( event ) {
4641			$.each( event.split( " " ), function( index, eventName ) {
4642				events[ eventName ] = "_eventHandler";
4643			} );
4644		}
4645
4646		this._off( this.headers.add( this.headers.next() ) );
4647		this._on( this.headers, events );
4648		this._on( this.headers.next(), { keydown: "_panelKeyDown" } );
4649		this._hoverable( this.headers );
4650		this._focusable( this.headers );
4651	},
4652
4653	_eventHandler: function( event ) {
4654		var activeChildren, clickedChildren,
4655			options = this.options,
4656			active = this.active,
4657			clicked = $( event.currentTarget ),
4658			clickedIsActive = clicked[ 0 ] === active[ 0 ],
4659			collapsing = clickedIsActive && options.collapsible,
4660			toShow = collapsing ? $() : clicked.next(),
4661			toHide = active.next(),
4662			eventData = {
4663				oldHeader: active,
4664				oldPanel: toHide,
4665				newHeader: collapsing ? $() : clicked,
4666				newPanel: toShow
4667			};
4668
4669		event.preventDefault();
4670
4671		if (
4672
4673				// click on active header, but not collapsible
4674				( clickedIsActive && !options.collapsible ) ||
4675
4676				// allow canceling activation
4677				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
4678			return;
4679		}
4680
4681		options.active = collapsing ? false : this.headers.index( clicked );
4682
4683		// When the call to ._toggle() comes after the class changes
4684		// it causes a very odd bug in IE 8 (see #6720)
4685		this.active = clickedIsActive ? $() : clicked;
4686		this._toggle( eventData );
4687
4688		// Switch classes
4689		// corner classes on the previously active header stay after the animation
4690		this._removeClass( active, "ui-accordion-header-active", "ui-state-active" );
4691		if ( options.icons ) {
4692			activeChildren = active.children( ".ui-accordion-header-icon" );
4693			this._removeClass( activeChildren, null, options.icons.activeHeader )
4694				._addClass( activeChildren, null, options.icons.header );
4695		}
4696
4697		if ( !clickedIsActive ) {
4698			this._removeClass( clicked, "ui-accordion-header-collapsed" )
4699				._addClass( clicked, "ui-accordion-header-active", "ui-state-active" );
4700			if ( options.icons ) {
4701				clickedChildren = clicked.children( ".ui-accordion-header-icon" );
4702				this._removeClass( clickedChildren, null, options.icons.header )
4703					._addClass( clickedChildren, null, options.icons.activeHeader );
4704			}
4705
4706			this._addClass( clicked.next(), "ui-accordion-content-active" );
4707		}
4708	},
4709
4710	_toggle: function( data ) {
4711		var toShow = data.newPanel,
4712			toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
4713
4714		// Handle activating a panel during the animation for another activation
4715		this.prevShow.add( this.prevHide ).stop( true, true );
4716		this.prevShow = toShow;
4717		this.prevHide = toHide;
4718
4719		if ( this.options.animate ) {
4720			this._animate( toShow, toHide, data );
4721		} else {
4722			toHide.hide();
4723			toShow.show();
4724			this._toggleComplete( data );
4725		}
4726
4727		toHide.attr( {
4728			"aria-hidden": "true"
4729		} );
4730		toHide.prev().attr( {
4731			"aria-selected": "false",
4732			"aria-expanded": "false"
4733		} );
4734
4735		// if we're switching panels, remove the old header from the tab order
4736		// if we're opening from collapsed state, remove the previous header from the tab order
4737		// if we're collapsing, then keep the collapsing header in the tab order
4738		if ( toShow.length && toHide.length ) {
4739			toHide.prev().attr( {
4740				"tabIndex": -1,
4741				"aria-expanded": "false"
4742			} );
4743		} else if ( toShow.length ) {
4744			this.headers.filter( function() {
4745				return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0;
4746			} )
4747				.attr( "tabIndex", -1 );
4748		}
4749
4750		toShow
4751			.attr( "aria-hidden", "false" )
4752			.prev()
4753				.attr( {
4754					"aria-selected": "true",
4755					"aria-expanded": "true",
4756					tabIndex: 0
4757				} );
4758	},
4759
4760	_animate: function( toShow, toHide, data ) {
4761		var total, easing, duration,
4762			that = this,
4763			adjust = 0,
4764			boxSizing = toShow.css( "box-sizing" ),
4765			down = toShow.length &&
4766				( !toHide.length || ( toShow.index() < toHide.index() ) ),
4767			animate = this.options.animate || {},
4768			options = down && animate.down || animate,
4769			complete = function() {
4770				that._toggleComplete( data );
4771			};
4772
4773		if ( typeof options === "number" ) {
4774			duration = options;
4775		}
4776		if ( typeof options === "string" ) {
4777			easing = options;
4778		}
4779
4780		// fall back from options to animation in case of partial down settings
4781		easing = easing || options.easing || animate.easing;
4782		duration = duration || options.duration || animate.duration;
4783
4784		if ( !toHide.length ) {
4785			return toShow.animate( this.showProps, duration, easing, complete );
4786		}
4787		if ( !toShow.length ) {
4788			return toHide.animate( this.hideProps, duration, easing, complete );
4789		}
4790
4791		total = toShow.show().outerHeight();
4792		toHide.animate( this.hideProps, {
4793			duration: duration,
4794			easing: easing,
4795			step: function( now, fx ) {
4796				fx.now = Math.round( now );
4797			}
4798		} );
4799		toShow
4800			.hide()
4801			.animate( this.showProps, {
4802				duration: duration,
4803				easing: easing,
4804				complete: complete,
4805				step: function( now, fx ) {
4806					fx.now = Math.round( now );
4807					if ( fx.prop !== "height" ) {
4808						if ( boxSizing === "content-box" ) {
4809							adjust += fx.now;
4810						}
4811					} else if ( that.options.heightStyle !== "content" ) {
4812						fx.now = Math.round( total - toHide.outerHeight() - adjust );
4813						adjust = 0;
4814					}
4815				}
4816			} );
4817	},
4818
4819	_toggleComplete: function( data ) {
4820		var toHide = data.oldPanel,
4821			prev = toHide.prev();
4822
4823		this._removeClass( toHide, "ui-accordion-content-active" );
4824		this._removeClass( prev, "ui-accordion-header-active" )
4825			._addClass( prev, "ui-accordion-header-collapsed" );
4826
4827		this._trigger( "activate", null, data );
4828	}
4829} );
4830
4831
4832/*!
4833 * jQuery UI Menu 1.14.
48331
4834 * https://jqueryui.com
4835 *
4836 * Copyright OpenJS Foundation and other contributors
4837 * Released under the MIT license.
4838 * https://jquery.org/license
4839 */
4840
4841//>>label: Menu
4842//>>group: Widgets
4843//>>description: Creates nestable menus.
4844//>>docs: https://api.jqueryui.com/menu/
4845//>>demos: https://jqueryui.com/menu/
4846//>>css.structure: ../../themes/base/core.css
4847//>>css.structure: ../../themes/base/menu.css
4848//>>css.theme: ../../themes/base/theme.css
4849
4850
4851var widgetsMenu = $.widget( "ui.menu", {
4852	version: "1.14.1
vendor: 5,700 bytes, lines 4852-5071
4852",
4853	defaultElement: "<ul>",
4854	delay: 300,
4855	options: {
4856		icons: {
4857			submenu: "ui-icon-caret-1-e"
4858		},
4859		items: "> *",
4860		menus: "ul",
4861		position: {
4862			my: "left top",
4863			at: "right top"
4864		},
4865		role: "menu",
4866
4867		// Callbacks
4868		blur: null,
4869		focus: null,
4870		select: null
4871	},
4872
4873	_create: function() {
4874		this.activeMenu = this.element;
4875
4876		// Flag used to prevent firing of the click handler
4877		// as the event bubbles up through nested menus
4878		this.mouseHandled = false;
4879		this.lastMousePosition = { x: null, y: null };
4880		this.element
4881			.uniqueId()
4882			.attr( {
4883				role: this.options.role,
4884				tabIndex: 0
4885			} );
4886
4887		this._addClass( "ui-menu", "ui-widget ui-widget-content" );
4888		this._on( {
4889
4890			// Prevent focus from sticking to links inside menu after clicking
4891			// them (focus should always stay on UL during navigation).
4892			"mousedown .ui-menu-item": function( event ) {
4893				event.preventDefault();
4894
4895				this._activateItem( event );
4896			},
4897			"click .ui-menu-item": function( event ) {
4898				var target = $( event.target );
4899				var active = $( this.document[ 0 ].activeElement );
4900				if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
4901					this.select( event );
4902
4903					// Only set the mouseHandled flag if the event will bubble, see #9469.
4904					if ( !event.isPropagationStopped() ) {
4905						this.mouseHandled = true;
4906					}
4907
4908					// Open submenu on click
4909					if ( target.has( ".ui-menu" ).length ) {
4910						this.expand( event );
4911					} else if ( !this.element.is( ":focus" ) &&
4912							active.closest( ".ui-menu" ).length ) {
4913
4914						// Redirect focus to the menu
4915						this.element.trigger( "focus", [ true ] );
4916
4917						// If the active item is on the top level, let it stay active.
4918						// Otherwise, blur the active item since it is no longer visible.
4919						if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
4920							clearTimeout( this.timer );
4921						}
4922					}
4923				}
4924			},
4925			"mouseenter .ui-menu-item": "_activateItem",
4926			"mousemove .ui-menu-item": "_activateItem",
4927			mouseleave: "collapseAll",
4928			"mouseleave .ui-menu": "collapseAll",
4929			focus: function( event, keepActiveItem ) {
4930
4931				// If there's already an active item, keep it active
4932				// If not, activate the first item
4933				var item = this.active || this._menuItems().first();
4934
4935				if ( !keepActiveItem ) {
4936					this.focus( event, item );
4937				}
4938			},
4939			blur: function( event ) {
4940				this._delay( function() {
4941					var notContained = !$.contains(
4942						this.element[ 0 ],
4943						this.document[ 0 ].activeElement
4944					);
4945					if ( notContained ) {
4946						this.collapseAll( event );
4947					}
4948				} );
4949			},
4950			keydown: "_keydown"
4951		} );
4952
4953		this.refresh();
4954
4955		// Clicks outside of a menu collapse any open menus
4956		this._on( this.document, {
4957			click: function( event ) {
4958				if ( this._closeOnDocumentClick( event ) ) {
4959					this.collapseAll( event, true );
4960				}
4961
4962				// Reset the mouseHandled flag
4963				this.mouseHandled = false;
4964			}
4965		} );
4966	},
4967
4968	_activateItem: function( event ) {
4969
4970		// Ignore mouse events while typeahead is active, see #10458.
4971		// Prevents focusing the wrong item when typeahead causes a scroll while the mouse
4972		// is over an item in the menu
4973		if ( this.previousFilter ) {
4974			return;
4975		}
4976
4977		// If the mouse didn't actually move, but the page was scrolled, ignore the event (#9356)
4978		if ( event.clientX === this.lastMousePosition.x &&
4979				event.clientY === this.lastMousePosition.y ) {
4980			return;
4981		}
4982
4983		this.lastMousePosition = {
4984			x: event.clientX,
4985			y: event.clientY
4986		};
4987
4988		var actualTarget = $( event.target ).closest( ".ui-menu-item" ),
4989			target = $( event.currentTarget );
4990
4991		// Ignore bubbled events on parent items, see #11641
4992		if ( actualTarget[ 0 ] !== target[ 0 ] ) {
4993			return;
4994		}
4995
4996		// If the item is already active, there's nothing to do
4997		if ( target.is( ".ui-state-active" ) ) {
4998			return;
4999		}
5000
5001		// Remove ui-state-active class from siblings of the newly focused menu item
5002		// to avoid a jump caused by adjacent elements both having a class with a border
5003		this._removeClass( target.siblings().children( ".ui-state-active" ),
5004			null, "ui-state-active" );
5005		this.focus( event, target );
5006	},
5007
5008	_destroy: function() {
5009		var items = this.element.find( ".ui-menu-item" )
5010				.removeAttr( "role aria-disabled" ),
5011			submenus = items.children( ".ui-menu-item-wrapper" )
5012				.removeUniqueId()
5013				.removeAttr( "tabIndex role aria-haspopup" );
5014
5015		// Destroy (sub)menus
5016		this.element
5017			.removeAttr( "aria-activedescendant" )
5018			.find( ".ui-menu" ).addBack()
5019				.removeAttr( "role aria-labelledby aria-expanded aria-hidden aria-disabled " +
5020					"tabIndex" )
5021				.removeUniqueId()
5022				.show();
5023
5024		submenus.children().each( function() {
5025			var elem = $( this );
5026			if ( elem.data( "ui-menu-submenu-caret" ) ) {
5027				elem.remove();
5028			}
5029		} );
5030	},
5031
5032	_keydown: function( event ) {
5033		var match, prev, character, skip,
5034			preventDefault = true;
5035
5036		switch ( event.keyCode ) {
5037		case $.ui.keyCode.PAGE_UP:
5038			this.previousPage( event );
5039			break;
5040		case $.ui.keyCode.PAGE_DOWN:
5041			this.nextPage( event );
5042			break;
5043		case $.ui.keyCode.HOME:
5044			this._move( "first", "first", event );
5045			break;
5046		case $.ui.keyCode.END:
5047			this._move( "last", "last", event );
5048			break;
5049		case $.ui.keyCode.UP:
5050			this.previous( event );
5051			break;
5052		case $.ui.keyCode.DOWN:
5053			this.next( event );
5054			break;
5055		case $.ui.keyCode.LEFT:
5056			this.collapse( event );
5057			break;
5058		case $.ui.keyCode.RIGHT:
5059			if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5060				this.expand( event );
5061			}
5062			break;
5063		case $.ui.keyCode.ENTER:
5064		case $.ui.keyCode.SPACE:
5065			this._activate( event );
5066			break;
5067		case $.ui.keyCode.ESCAPE:
5068			this.collapse( event );
5069			break;
5070		default:
5071			preventDefault = false;
vendor: 6,930 bytes, lines 5072-5320
5072			prev = this.previousFilter || "";
5073			skip = false;
5074
5075			// Support number pad values
5076			character = event.keyCode >= 96 && event.keyCode <= 105 ?
5077				( event.keyCode - 96 ).toString() : String.fromCharCode( event.keyCode );
5078
5079			clearTimeout( this.filterTimer );
5080
5081			if ( character === prev ) {
5082				skip = true;
5083			} else {
5084				character = prev + character;
5085			}
5086
5087			match = this._filterMenuItems( character );
5088			match = skip && match.index( this.active.next() ) !== -1 ?
5089				this.active.nextAll( ".ui-menu-item" ) :
5090				match;
5091
5092			// If no matches on the current filter, reset to the last character pressed
5093			// to move down the menu to the first item that starts with that character
5094			if ( !match.length ) {
5095				character = String.fromCharCode( event.keyCode );
5096				match = this._filterMenuItems( character );
5097			}
5098
5099			if ( match.length ) {
5100				this.focus( event, match );
5101				this.previousFilter = character;
5102				this.filterTimer = this._delay( function() {
5103					delete this.previousFilter;
5104				}, 1000 );
5105			} else {
5106				delete this.previousFilter;
5107			}
5108		}
5109
5110		if ( preventDefault ) {
5111			event.preventDefault();
5112		}
5113	},
5114
5115	_activate: function( event ) {
5116		if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
5117			if ( this.active.children( "[aria-haspopup='true']" ).length ) {
5118				this.expand( event );
5119			} else {
5120				this.select( event );
5121			}
5122		}
5123	},
5124
5125	refresh: function() {
5126		var menus, items, newSubmenus, newItems, newWrappers,
5127			that = this,
5128			icon = this.options.icons.submenu,
5129			submenus = this.element.find( this.options.menus );
5130
5131		this._toggleClass( "ui-menu-icons", null, !!this.element.find( ".ui-icon" ).length );
5132
5133		// Initialize nested menus
5134		newSubmenus = submenus.filter( ":not(.ui-menu)" )
5135			.hide()
5136			.attr( {
5137				role: this.options.role,
5138				"aria-hidden": "true",
5139				"aria-expanded": "false"
5140			} )
5141			.each( function() {
5142				var menu = $( this ),
5143					item = menu.prev(),
5144					submenuCaret = $( "<span>" ).data( "ui-menu-submenu-caret", true );
5145
5146				that._addClass( submenuCaret, "ui-menu-icon", "ui-icon " + icon );
5147				item
5148					.attr( "aria-haspopup", "true" )
5149					.prepend( submenuCaret );
5150				menu.attr( "aria-labelledby", item.attr( "id" ) );
5151			} );
5152
5153		this._addClass( newSubmenus, "ui-menu", "ui-widget ui-widget-content ui-front" );
5154
5155		menus = submenus.add( this.element );
5156		items = menus.find( this.options.items );
5157
5158		// Initialize menu-items containing spaces and/or dashes only as dividers
5159		items.not( ".ui-menu-item" ).each( function() {
5160			var item = $( this );
5161			if ( that._isDivider( item ) ) {
5162				that._addClass( item, "ui-menu-divider", "ui-widget-content" );
5163			}
5164		} );
5165
5166		// Don't refresh list items that are already adapted
5167		newItems = items.not( ".ui-menu-item, .ui-menu-divider" );
5168		newWrappers = newItems.children()
5169			.not( ".ui-menu" )
5170				.uniqueId()
5171				.attr( {
5172					tabIndex: -1,
5173					role: this._itemRole()
5174				} );
5175		this._addClass( newItems, "ui-menu-item" )
5176			._addClass( newWrappers, "ui-menu-item-wrapper" );
5177
5178		// Add aria-disabled attribute to any disabled menu item
5179		items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
5180
5181		// If the active item has been removed, blur the menu
5182		if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
5183			this.blur();
5184		}
5185	},
5186
5187	_itemRole: function() {
5188		return {
5189			menu: "menuitem",
5190			listbox: "option"
5191		}[ this.options.role ];
5192	},
5193
5194	_setOption: function( key, value ) {
5195		if ( key === "icons" ) {
5196			var icons = this.element.find( ".ui-menu-icon" );
5197			this._removeClass( icons, null, this.options.icons.submenu )
5198				._addClass( icons, null, value.submenu );
5199		}
5200		this._super( key, value );
5201	},
5202
5203	_setOptionDisabled: function( value ) {
5204		this._super( value );
5205
5206		this.element.attr( "aria-disabled", String( value ) );
5207		this._toggleClass( null, "ui-state-disabled", !!value );
5208	},
5209
5210	focus: function( event, item ) {
5211		var nested, focused, activeParent;
5212		this.blur( event, event && event.type === "focus" );
5213
5214		this._scrollIntoView( item );
5215
5216		this.active = item.first();
5217
5218		focused = this.active.children( ".ui-menu-item-wrapper" );
5219		this._addClass( focused, null, "ui-state-active" );
5220
5221		// Only update aria-activedescendant if there's a role
5222		// otherwise we assume focus is managed elsewhere
5223		if ( this.options.role ) {
5224			this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
5225		}
5226
5227		// Highlight active parent menu item, if any
5228		activeParent = this.active
5229			.parent()
5230				.closest( ".ui-menu-item" )
5231					.children( ".ui-menu-item-wrapper" );
5232		this._addClass( activeParent, null, "ui-state-active" );
5233
5234		if ( event && event.type === "keydown" ) {
5235			this._close();
5236		} else {
5237			this.timer = this._delay( function() {
5238				this._close();
5239			}, this.delay );
5240		}
5241
5242		nested = item.children( ".ui-menu" );
5243		if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
5244			this._startOpening( nested );
5245		}
5246		this.activeMenu = item.parent();
5247
5248		this._trigger( "focus", event, { item: item } );
5249	},
5250
5251	_scrollIntoView: function( item ) {
5252		var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
5253		if ( this._hasScroll() ) {
5254			borderTop = parseFloat( $.css( this.activeMenu[ 0 ], "borderTopWidth" ) ) || 0;
5255			paddingTop = parseFloat( $.css( this.activeMenu[ 0 ], "paddingTop" ) ) || 0;
5256			offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
5257			scroll = this.activeMenu.scrollTop();
5258			elementHeight = this.activeMenu.height();
5259			itemHeight = item.outerHeight();
5260
5261			if ( offset < 0 ) {
5262				this.activeMenu.scrollTop( scroll + offset );
5263			} else if ( offset + itemHeight > elementHeight ) {
5264				this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
5265			}
5266		}
5267	},
5268
5269	blur: function( event, fromFocus ) {
5270		if ( !fromFocus ) {
5271			clearTimeout( this.timer );
5272		}
5273
5274		if ( !this.active ) {
5275			return;
5276		}
5277
5278		this._removeClass( this.active.children( ".ui-menu-item-wrapper" ),
5279			null, "ui-state-active" );
5280
5281		this._trigger( "blur", event, { item: this.active } );
5282		this.active = null;
5283	},
5284
5285	_startOpening: function( submenu ) {
5286		clearTimeout( this.timer );
5287
5288		// Don't open if already open fixes a Firefox bug that caused a .5 pixel
5289		// shift in the submenu position when mousing over the caret icon
5290		if ( submenu.attr( "aria-hidden" ) !== "true" ) {
5291			return;
5292		}
5293
5294		this.timer = this._delay( function() {
5295			this._close();
5296			this._open( submenu );
5297		}, this.delay );
5298	},
5299
5300	_open: function( submenu ) {
5301		var position = $.extend( {
5302			of: this.active
5303		}, this.options.position );
5304
5305		clearTimeout( this.timer );
5306		this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
5307			.hide()
5308			.attr( "aria-hidden", "true" );
5309
5310		submenu
5311			.show()
5312			.removeAttr( "aria-hidden" )
5313			.attr( "aria-expanded", "true" )
5314			.position( position );
5315	},
5316
5317	collapseAll: function( event, all ) {
5318		clearTimeout( this.timer );
5319		this.timer = this._delay( function() {
5320
vendor: 5,434 bytes, lines 5321-5524
5321			// If we were passed an event, look for the submenu that contains the event
5322			var currentMenu = all ? this.element :
5323				$( event && event.target ).closest( this.element.find( ".ui-menu" ) );
5324
5325			// If we found no valid submenu ancestor, use the main menu to close all
5326			// sub menus anyway
5327			if ( !currentMenu.length ) {
5328				currentMenu = this.element;
5329			}
5330
5331			this._close( currentMenu );
5332
5333			this.blur( event );
5334
5335			// Work around active item staying active after menu is blurred
5336			this._removeClass( currentMenu.find( ".ui-state-active" ), null, "ui-state-active" );
5337
5338			this.activeMenu = currentMenu;
5339		}, all ? 0 : this.delay );
5340	},
5341
5342	// With no arguments, closes the currently active menu - if nothing is active
5343	// it closes all menus.  If passed an argument, it will search for menus BELOW
5344	_close: function( startMenu ) {
5345		if ( !startMenu ) {
5346			startMenu = this.active ? this.active.parent() : this.element;
5347		}
5348
5349		startMenu.find( ".ui-menu" )
5350			.hide()
5351			.attr( "aria-hidden", "true" )
5352			.attr( "aria-expanded", "false" );
5353	},
5354
5355	_closeOnDocumentClick: function( event ) {
5356		return !$( event.target ).closest( ".ui-menu" ).length;
5357	},
5358
5359	_isDivider: function( item ) {
5360
5361		// Match hyphen, em dash, en dash
5362		return !/[^\-\u2014\u2013\s]/.test( item.text() );
5363	},
5364
5365	collapse: function( event ) {
5366		var newItem = this.active &&
5367			this.active.parent().closest( ".ui-menu-item", this.element );
5368		if ( newItem && newItem.length ) {
5369			this._close();
5370			this.focus( event, newItem );
5371		}
5372	},
5373
5374	expand: function( event ) {
5375		var newItem = this.active && this._menuItems( this.active.children( ".ui-menu" ) ).first();
5376
5377		if ( newItem && newItem.length ) {
5378			this._open( newItem.parent() );
5379
5380			// Delay so Firefox will not hide activedescendant change in expanding submenu from AT
5381			this._delay( function() {
5382				this.focus( event, newItem );
5383			} );
5384		}
5385	},
5386
5387	next: function( event ) {
5388		this._move( "next", "first", event );
5389	},
5390
5391	previous: function( event ) {
5392		this._move( "prev", "last", event );
5393	},
5394
5395	isFirstItem: function() {
5396		return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
5397	},
5398
5399	isLastItem: function() {
5400		return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
5401	},
5402
5403	_menuItems: function( menu ) {
5404		return ( menu || this.element )
5405			.find( this.options.items )
5406			.filter( ".ui-menu-item" );
5407	},
5408
5409	_move: function( direction, filter, event ) {
5410		var next;
5411		if ( this.active ) {
5412			if ( direction === "first" || direction === "last" ) {
5413				next = this.active
5414					[ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
5415					.last();
5416			} else {
5417				next = this.active
5418					[ direction + "All" ]( ".ui-menu-item" )
5419					.first();
5420			}
5421		}
5422		if ( !next || !next.length || !this.active ) {
5423			next = this._menuItems( this.activeMenu )[ filter ]();
5424		}
5425
5426		this.focus( event, next );
5427	},
5428
5429	nextPage: function( event ) {
5430		var item, base, height;
5431
5432		if ( !this.active ) {
5433			this.next( event );
5434			return;
5435		}
5436		if ( this.isLastItem() ) {
5437			return;
5438		}
5439		if ( this._hasScroll() ) {
5440			base = this.active.offset().top;
5441			height = this.element.innerHeight();
5442
5443			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5444			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5445				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5446			}
5447
5448			this.active.nextAll( ".ui-menu-item" ).each( function() {
5449				item = $( this );
5450				return item.offset().top - base - height < 0;
5451			} );
5452
5453			this.focus( event, item );
5454		} else {
5455			this.focus( event, this._menuItems( this.activeMenu )
5456				[ !this.active ? "first" : "last" ]() );
5457		}
5458	},
5459
5460	previousPage: function( event ) {
5461		var item, base, height;
5462		if ( !this.active ) {
5463			this.next( event );
5464			return;
5465		}
5466		if ( this.isFirstItem() ) {
5467			return;
5468		}
5469		if ( this._hasScroll() ) {
5470			base = this.active.offset().top;
5471			height = this.element.innerHeight();
5472
5473			// jQuery 3.2 doesn't include scrollbars in innerHeight, add it back.
5474			if ( $.fn.jquery.indexOf( "3.2." ) === 0 ) {
5475				height += this.element[ 0 ].offsetHeight - this.element.outerHeight();
5476			}
5477
5478			this.active.prevAll( ".ui-menu-item" ).each( function() {
5479				item = $( this );
5480				return item.offset().top - base + height > 0;
5481			} );
5482
5483			this.focus( event, item );
5484		} else {
5485			this.focus( event, this._menuItems( this.activeMenu ).first() );
5486		}
5487	},
5488
5489	_hasScroll: function() {
5490		return this.element.outerHeight() < this.element.prop( "scrollHeight" );
5491	},
5492
5493	select: function( event ) {
5494
5495		// TODO: It should never be possible to not have an active item at this
5496		// point, but the tests don't trigger mouseenter before click.
5497		this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
5498		var ui = { item: this.active };
5499		if ( !this.active.has( ".ui-menu" ).length ) {
5500			this.collapseAll( event, true );
5501		}
5502		this._trigger( "select", event, ui );
5503	},
5504
5505	_filterMenuItems: function( character ) {
5506		var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
5507			regex = new RegExp( "^" + escapedCharacter, "i" );
5508
5509		return this.activeMenu
5510			.find( this.options.items )
5511
5512				// Only match on items, not dividers or other content (#10571)
5513				.filter( ".ui-menu-item" )
5514					.filter( function() {
5515						return regex.test(
5516							String.prototype.trim.call(
5517								$( this ).children( ".ui-menu-item-wrapper" ).text() ) );
5518					} );
5519	}
5520} );
5521
5522
5523/*!
5524 * jQuery UI Autocomplete 1.14.
55241
5525 * https://jqueryui.com
5526 *
5527 * Copyright OpenJS Foundation and other contributors
5528 * Released under the MIT license.
5529 * https://jquery.org/license
5530 */
5531
5532//>>label: Autocomplete
5533//>>group: Widgets
5534//>>description: Lists suggested words as the user is typing.
5535//>>docs: https://api.jqueryui.com/autocomplete/
5536//>>demos: https://jqueryui.com/autocomplete/
5537//>>css.structure: ../../themes/base/core.css
5538//>>css.structure: ../../themes/base/autocomplete.css
5539//>>css.theme: ../../themes/base/theme.css
5540
5541
5542$.widget( "ui.autocomplete", {
5543	version: "1.14.1
vendor: 15,301 bytes, lines 5543-6143
5543",
5544	defaultElement: "<input>",
5545	options: {
5546		appendTo: null,
5547		autoFocus: false,
5548		delay: 300,
5549		minLength: 1,
5550		position: {
5551			my: "left top",
5552			at: "left bottom",
5553			collision: "none"
5554		},
5555		source: null,
5556
5557		// Callbacks
5558		change: null,
5559		close: null,
5560		focus: null,
5561		open: null,
5562		response: null,
5563		search: null,
5564		select: null
5565	},
5566
5567	requestIndex: 0,
5568	pending: 0,
5569	liveRegionTimer: null,
5570
5571	_create: function() {
5572
5573		// Some browsers only repeat keydown events, not keypress events,
5574		// so we use the suppressKeyPress flag to determine if we've already
5575		// handled the keydown event. #7269
5576		// Unfortunately the code for & in keypress is the same as the up arrow,
5577		// so we use the suppressKeyPressRepeat flag to avoid handling keypress
5578		// events when we know the keydown event was used to modify the
5579		// search term. #7799
5580		var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
5581			nodeName = this.element[ 0 ].nodeName.toLowerCase(),
5582			isTextarea = nodeName === "textarea",
5583			isInput = nodeName === "input";
5584
5585		// Textareas are always multi-line
5586		// Inputs are always single-line, even if inside a contentEditable element
5587		// All other element types are determined by whether they're contentEditable
5588		this.isMultiLine = isTextarea ||
5589			!isInput && this.element.prop( "contentEditable" ) === "true";
5590
5591		this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
5592		this.isNewMenu = true;
5593
5594		this._addClass( "ui-autocomplete-input" );
5595		this.element.attr( "autocomplete", "off" );
5596
5597		this._on( this.element, {
5598			keydown: function( event ) {
5599				if ( this.element.prop( "readOnly" ) ) {
5600					suppressKeyPress = true;
5601					suppressInput = true;
5602					suppressKeyPressRepeat = true;
5603					return;
5604				}
5605
5606				suppressKeyPress = false;
5607				suppressInput = false;
5608				suppressKeyPressRepeat = false;
5609				var keyCode = $.ui.keyCode;
5610				switch ( event.keyCode ) {
5611				case keyCode.PAGE_UP:
5612					suppressKeyPress = true;
5613					this._move( "previousPage", event );
5614					break;
5615				case keyCode.PAGE_DOWN:
5616					suppressKeyPress = true;
5617					this._move( "nextPage", event );
5618					break;
5619				case keyCode.UP:
5620					suppressKeyPress = true;
5621					this._keyEvent( "previous", event );
5622					break;
5623				case keyCode.DOWN:
5624					suppressKeyPress = true;
5625					this._keyEvent( "next", event );
5626					break;
5627				case keyCode.ENTER:
5628
5629					// when menu is open and has focus
5630					if ( this.menu.active ) {
5631
5632						// #6055 - Opera still allows the keypress to occur
5633						// which causes forms to submit
5634						suppressKeyPress = true;
5635						event.preventDefault();
5636						this.menu.select( event );
5637					}
5638					break;
5639				case keyCode.TAB:
5640					if ( this.menu.active ) {
5641						this.menu.select( event );
5642					}
5643					break;
5644				case keyCode.ESCAPE:
5645					if ( this.menu.element.is( ":visible" ) ) {
5646						if ( !this.isMultiLine ) {
5647							this._value( this.term );
5648						}
5649						this.close( event );
5650
5651						// Different browsers have different default behavior for escape
5652						// Single press can mean undo or clear
5653						event.preventDefault();
5654					}
5655					break;
5656				default:
5657					suppressKeyPressRepeat = true;
5658
5659					// search timeout should be triggered before the input value is changed
5660					this._searchTimeout( event );
5661					break;
5662				}
5663			},
5664			keypress: function( event ) {
5665				if ( suppressKeyPress ) {
5666					suppressKeyPress = false;
5667					if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
5668						event.preventDefault();
5669					}
5670					return;
5671				}
5672				if ( suppressKeyPressRepeat ) {
5673					return;
5674				}
5675
5676				// Replicate some key handlers to allow them to repeat in Firefox and Opera
5677				var keyCode = $.ui.keyCode;
5678				switch ( event.keyCode ) {
5679				case keyCode.PAGE_UP:
5680					this._move( "previousPage", event );
5681					break;
5682				case keyCode.PAGE_DOWN:
5683					this._move( "nextPage", event );
5684					break;
5685				case keyCode.UP:
5686					this._keyEvent( "previous", event );
5687					break;
5688				case keyCode.DOWN:
5689					this._keyEvent( "next", event );
5690					break;
5691				}
5692			},
5693			input: function( event ) {
5694				if ( suppressInput ) {
5695					suppressInput = false;
5696					event.preventDefault();
5697					return;
5698				}
5699				this._searchTimeout( event );
5700			},
5701			focus: function() {
5702				this.selectedItem = null;
5703				this.previous = this._value();
5704			},
5705			blur: function( event ) {
5706				clearTimeout( this.searching );
5707				this.close( event );
5708				this._change( event );
5709			}
5710		} );
5711
5712		this._initSource();
5713		this.menu = $( "<ul>" )
5714			.appendTo( this._appendTo() )
5715			.menu( {
5716
5717				// disable ARIA support, the live region takes care of that
5718				role: null
5719			} )
5720			.hide()
5721			.menu( "instance" );
5722
5723		this._addClass( this.menu.element, "ui-autocomplete", "ui-front" );
5724		this._on( this.menu.element, {
5725			mousedown: function( event ) {
5726
5727				// Prevent moving focus out of the text field
5728				event.preventDefault();
5729			},
5730			menufocus: function( event, ui ) {
5731				var label, item;
5732
5733				// Support: Firefox
5734				// Prevent accidental activation of menu items in Firefox (#7024 #9118)
5735				if ( this.isNewMenu ) {
5736					this.isNewMenu = false;
5737					if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
5738						this.menu.blur();
5739
5740						this.document.one( "mousemove", function() {
5741							$( event.target ).trigger( event.originalEvent );
5742						} );
5743
5744						return;
5745					}
5746				}
5747
5748				item = ui.item.data( "ui-autocomplete-item" );
5749				if ( false !== this._trigger( "focus", event, { item: item } ) ) {
5750
5751					// use value to match what will end up in the input, if it was a key event
5752					if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
5753						this._value( item.value );
5754					}
5755				}
5756
5757				// Announce the value in the liveRegion
5758				label = ui.item.attr( "aria-label" ) || item.value;
5759				if ( label && String.prototype.trim.call( label ).length ) {
5760					clearTimeout( this.liveRegionTimer );
5761					this.liveRegionTimer = this._delay( function() {
5762						this.liveRegion.html( $( "<div>" ).text( label ) );
5763					}, 100 );
5764				}
5765			},
5766			menuselect: function( event, ui ) {
5767				var item = ui.item.data( "ui-autocomplete-item" ),
5768					previous = this.previous;
5769
5770				// Only trigger when focus was lost (click on menu)
5771				if ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {
5772					this.element.trigger( "focus" );
5773					this.previous = previous;
5774				}
5775
5776				if ( false !== this._trigger( "select", event, { item: item } ) ) {
5777					this._value( item.value );
5778				}
5779
5780				// reset the term after the select event
5781				// this allows custom select handling to work properly
5782				this.term = this._value();
5783
5784				this.close( event );
5785				this.selectedItem = item;
5786			}
5787		} );
5788
5789		this.liveRegion = $( "<div>", {
5790			role: "status",
5791			"aria-live": "assertive",
5792			"aria-relevant": "additions"
5793		} )
5794			.appendTo( this.document[ 0 ].body );
5795
5796		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
5797
5798		// Turning off autocomplete prevents the browser from remembering the
5799		// value when navigating through history, so we re-enable autocomplete
5800		// if the page is unloaded before the widget is destroyed. #7790
5801		this._on( this.window, {
5802			beforeunload: function() {
5803				this.element.removeAttr( "autocomplete" );
5804			}
5805		} );
5806	},
5807
5808	_destroy: function() {
5809		clearTimeout( this.searching );
5810		this.element.removeAttr( "autocomplete" );
5811		this.menu.element.remove();
5812		this.liveRegion.remove();
5813	},
5814
5815	_setOption: function( key, value ) {
5816		this._super( key, value );
5817		if ( key === "source" ) {
5818			this._initSource();
5819		}
5820		if ( key === "appendTo" ) {
5821			this.menu.element.appendTo( this._appendTo() );
5822		}
5823		if ( key === "disabled" && value && this.xhr ) {
5824			this.xhr.abort();
5825		}
5826	},
5827
5828	_isEventTargetInWidget: function( event ) {
5829		var menuElement = this.menu.element[ 0 ];
5830
5831		return event.target === this.element[ 0 ] ||
5832			event.target === menuElement ||
5833			$.contains( menuElement, event.target );
5834	},
5835
5836	_closeOnClickOutside: function( event ) {
5837		if ( !this._isEventTargetInWidget( event ) ) {
5838			this.close();
5839		}
5840	},
5841
5842	_appendTo: function() {
5843		var element = this.options.appendTo;
5844
5845		if ( element ) {
5846			element = element.jquery || element.nodeType ?
5847				$( element ) :
5848				this.document.find( element ).eq( 0 );
5849		}
5850
5851		if ( !element || !element[ 0 ] ) {
5852			element = this.element.closest( ".ui-front, dialog" );
5853		}
5854
5855		if ( !element.length ) {
5856			element = this.document[ 0 ].body;
5857		}
5858
5859		return element;
5860	},
5861
5862	_initSource: function() {
5863		var array, url,
5864			that = this;
5865		if ( Array.isArray( this.options.source ) ) {
5866			array = this.options.source;
5867			this.source = function( request, response ) {
5868				response( $.ui.autocomplete.filter( array, request.term ) );
5869			};
5870		} else if ( typeof this.options.source === "string" ) {
5871			url = this.options.source;
5872			this.source = function( request, response ) {
5873				if ( that.xhr ) {
5874					that.xhr.abort();
5875				}
5876				that.xhr = $.ajax( {
5877					url: url,
5878					data: request,
5879					dataType: "json",
5880					success: function( data ) {
5881						response( data );
5882					},
5883					error: function() {
5884						response( [] );
5885					}
5886				} );
5887			};
5888		} else {
5889			this.source = this.options.source;
5890		}
5891	},
5892
5893	_searchTimeout: function( event ) {
5894		clearTimeout( this.searching );
5895		this.searching = this._delay( function() {
5896
5897			// Search if the value has changed, or if the user retypes the same value (see #7434)
5898			var equalValues = this.term === this._value(),
5899				menuVisible = this.menu.element.is( ":visible" ),
5900				modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
5901
5902			if ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {
5903				this.selectedItem = null;
5904				this.search( null, event );
5905			}
5906		}, this.options.delay );
5907	},
5908
5909	search: function( value, event ) {
5910		value = value != null ? value : this._value();
5911
5912		// Always save the actual value, not the one passed as an argument
5913		this.term = this._value();
5914
5915		if ( value.length < this.options.minLength ) {
5916			return this.close( event );
5917		}
5918
5919		if ( this._trigger( "search", event ) === false ) {
5920			return;
5921		}
5922
5923		return this._search( value );
5924	},
5925
5926	_search: function( value ) {
5927		this.pending++;
5928		this._addClass( "ui-autocomplete-loading" );
5929		this.cancelSearch = false;
5930
5931		this.source( { term: value }, this._response() );
5932	},
5933
5934	_response: function() {
5935		var index = ++this.requestIndex;
5936
5937		return function( content ) {
5938			if ( index === this.requestIndex ) {
5939				this.__response( content );
5940			}
5941
5942			this.pending--;
5943			if ( !this.pending ) {
5944				this._removeClass( "ui-autocomplete-loading" );
5945			}
5946		}.bind( this );
5947	},
5948
5949	__response: function( content ) {
5950		if ( content ) {
5951			content = this._normalize( content );
5952		}
5953		this._trigger( "response", null, { content: content } );
5954		if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
5955			this._suggest( content );
5956			this._trigger( "open" );
5957		} else {
5958
5959			// use ._close() instead of .close() so we don't cancel future searches
5960			this._close();
5961		}
5962	},
5963
5964	close: function( event ) {
5965		this.cancelSearch = true;
5966		this._close( event );
5967	},
5968
5969	_close: function( event ) {
5970
5971		// Remove the handler that closes the menu on outside clicks
5972		this._off( this.document, "mousedown" );
5973
5974		if ( this.menu.element.is( ":visible" ) ) {
5975			this.menu.element.hide();
5976			this.menu.blur();
5977			this.isNewMenu = true;
5978			this._trigger( "close", event );
5979		}
5980	},
5981
5982	_change: function( event ) {
5983		if ( this.previous !== this._value() ) {
5984			this._trigger( "change", event, { item: this.selectedItem } );
5985		}
5986	},
5987
5988	_normalize: function( items ) {
5989
5990		// assume all items have the right format when the first item is complete
5991		if ( items.length && items[ 0 ].label && items[ 0 ].value ) {
5992			return items;
5993		}
5994		return $.map( items, function( item ) {
5995			if ( typeof item === "string" ) {
5996				return {
5997					label: item,
5998					value: item
5999				};
6000			}
6001			return $.extend( {}, item, {
6002				label: item.label || item.value,
6003				value: item.value || item.label
6004			} );
6005		} );
6006	},
6007
6008	_suggest: function( items ) {
6009		var ul = this.menu.element.empty();
6010		this._renderMenu( ul, items );
6011		this.isNewMenu = true;
6012		this.menu.refresh();
6013
6014		// Size and position menu
6015		ul.show();
6016		this._resizeMenu();
6017		ul.position( $.extend( {
6018			of: this.element
6019		}, this.options.position ) );
6020
6021		if ( this.options.autoFocus ) {
6022			this.menu.next();
6023		}
6024
6025		// Listen for interactions outside of the widget (#6642)
6026		this._on( this.document, {
6027			mousedown: "_closeOnClickOutside"
6028		} );
6029	},
6030
6031	_resizeMenu: function() {
6032		var ul = this.menu.element;
6033		ul.outerWidth( Math.max(
6034
6035			// Firefox wraps long text (possibly a rounding bug)
6036			// so we add 1px to avoid the wrapping (#7513)
6037			ul.width( "" ).outerWidth() + 1,
6038			this.element.outerWidth()
6039		) );
6040	},
6041
6042	_renderMenu: function( ul, items ) {
6043		var that = this;
6044		$.each( items, function( index, item ) {
6045			that._renderItemData( ul, item );
6046		} );
6047	},
6048
6049	_renderItemData: function( ul, item ) {
6050		return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
6051	},
6052
6053	_renderItem: function( ul, item ) {
6054		return $( "<li>" )
6055			.append( $( "<div>" ).text( item.label ) )
6056			.appendTo( ul );
6057	},
6058
6059	_move: function( direction, event ) {
6060		if ( !this.menu.element.is( ":visible" ) ) {
6061			this.search( null, event );
6062			return;
6063		}
6064		if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
6065				this.menu.isLastItem() && /^next/.test( direction ) ) {
6066
6067			if ( !this.isMultiLine ) {
6068				this._value( this.term );
6069			}
6070
6071			this.menu.blur();
6072			return;
6073		}
6074		this.menu[ direction ]( event );
6075	},
6076
6077	widget: function() {
6078		return this.menu.element;
6079	},
6080
6081	_value: function() {
6082		return this.valueMethod.apply( this.element, arguments );
6083	},
6084
6085	_keyEvent: function( keyEvent, event ) {
6086		if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6087			this._move( keyEvent, event );
6088
6089			// Prevents moving cursor to beginning/end of the text field in some browsers
6090			event.preventDefault();
6091		}
6092	}
6093} );
6094
6095$.extend( $.ui.autocomplete, {
6096	escapeRegex: function( value ) {
6097		return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
6098	},
6099	filter: function( array, term ) {
6100		var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), "i" );
6101		return $.grep( array, function( value ) {
6102			return matcher.test( value.label || value.value || value );
6103		} );
6104	}
6105} );
6106
6107// Live region extension, adding a `messages` option
6108// NOTE: This is an experimental API. We are still investigating
6109// a full solution for string manipulation and internationalization.
6110$.widget( "ui.autocomplete", $.ui.autocomplete, {
6111	options: {
6112		messages: {
6113			noResults: "No search results.",
6114			results: function( amount ) {
6115				return amount + ( amount > 1 ? " results are" : " result is" ) +
6116					" available, use up and down arrow keys to navigate.";
6117			}
6118		}
6119	},
6120
6121	__response: function( content ) {
6122		var message;
6123		this._superApply( arguments );
6124		if ( this.options.disabled || this.cancelSearch ) {
6125			return;
6126		}
6127		if ( content && content.length ) {
6128			message = this.options.messages.results( content.length );
6129		} else {
6130			message = this.options.messages.noResults;
6131		}
6132		clearTimeout( this.liveRegionTimer );
6133		this.liveRegionTimer = this._delay( function() {
6134			this.liveRegion.html( $( "<div>" ).text( message ) );
6135		}, 100 );
6136	}
6137} );
6138
6139var widgetsAutocomplete = $.ui.autocomplete;
6140
6141
6142/*!
6143 * jQuery UI Controlgroup 1.14.
61431
6144 * https://jqueryui.com
6145 *
6146 * Copyright OpenJS Foundation and other contributors
6147 * Released under the MIT license.
6148 * https://jquery.org/license
6149 */
6150
6151//>>label: Controlgroup
6152//>>group: Widgets
6153//>>description: Visually groups form control widgets
6154//>>docs: https://api.jqueryui.com/controlgroup/
6155//>>demos: https://jqueryui.com/controlgroup/
6156//>>css.structure: ../../themes/base/core.css
6157//>>css.structure: ../../themes/base/controlgroup.css
6158//>>css.theme: ../../themes/base/theme.css
6159
6160
6161var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6162
6163var widgetsControlgroup = $.widget( "ui.controlgroup", {
6164	version: "1.14.1
vendor: 7,736 bytes, lines 6164-6428
6164",
6165	defaultElement: "<div>",
6166	options: {
6167		direction: "horizontal",
6168		disabled: null,
6169		onlyVisible: true,
6170		items: {
6171			"button": "input[type=button], input[type=submit], input[type=reset], button, a",
6172			"controlgroupLabel": ".ui-controlgroup-label",
6173			"checkboxradio": "input[type='checkbox'], input[type='radio']",
6174			"selectmenu": "select",
6175			"spinner": ".ui-spinner-input"
6176		}
6177	},
6178
6179	_create: function() {
6180		this._enhance();
6181	},
6182
6183	// To support the enhanced option in jQuery Mobile, we isolate DOM manipulation
6184	_enhance: function() {
6185		this.element.attr( "role", "toolbar" );
6186		this.refresh();
6187	},
6188
6189	_destroy: function() {
6190		this._callChildMethod( "destroy" );
6191		this.childWidgets.removeData( "ui-controlgroup-data" );
6192		this.element.removeAttr( "role" );
6193		if ( this.options.items.controlgroupLabel ) {
6194			this.element
6195				.find( this.options.items.controlgroupLabel )
6196				.find( ".ui-controlgroup-label-contents" )
6197				.contents().unwrap();
6198		}
6199	},
6200
6201	_initWidgets: function() {
6202		var that = this,
6203			childWidgets = [];
6204
6205		// First we iterate over each of the items options
6206		$.each( this.options.items, function( widget, selector ) {
6207			var labels;
6208			var options = {};
6209
6210			// Make sure the widget has a selector set
6211			if ( !selector ) {
6212				return;
6213			}
6214
6215			if ( widget === "controlgroupLabel" ) {
6216				labels = that.element.find( selector );
6217				labels.each( function() {
6218					var element = $( this );
6219
6220					if ( element.children( ".ui-controlgroup-label-contents" ).length ) {
6221						return;
6222					}
6223					element.contents()
6224						.wrapAll( "<span class='ui-controlgroup-label-contents'></span>" );
6225				} );
6226				that._addClass( labels, null, "ui-widget ui-widget-content ui-state-default" );
6227				childWidgets = childWidgets.concat( labels.get() );
6228				return;
6229			}
6230
6231			// Make sure the widget actually exists
6232			if ( !$.fn[ widget ] ) {
6233				return;
6234			}
6235
6236			// We assume everything is in the middle to start because we can't determine
6237			// first / last elements until all enhancments are done.
6238			if ( that[ "_" + widget + "Options" ] ) {
6239				options = that[ "_" + widget + "Options" ]( "middle" );
6240			} else {
6241				options = { classes: {} };
6242			}
6243
6244			// Find instances of this widget inside controlgroup and init them
6245			that.element
6246				.find( selector )
6247				.each( function() {
6248					var element = $( this );
6249					var instance = element[ widget ]( "instance" );
6250
6251					// We need to clone the default options for this type of widget to avoid
6252					// polluting the variable options which has a wider scope than a single widget.
6253					var instanceOptions = $.widget.extend( {}, options );
6254
6255					// If the button is the child of a spinner ignore it
6256					// TODO: Find a more generic solution
6257					if ( widget === "button" && element.parent( ".ui-spinner" ).length ) {
6258						return;
6259					}
6260
6261					// Create the widget if it doesn't exist
6262					if ( !instance ) {
6263						instance = element[ widget ]()[ widget ]( "instance" );
6264					}
6265					if ( instance ) {
6266						instanceOptions.classes =
6267							that._resolveClassesValues( instanceOptions.classes, instance );
6268					}
6269					element[ widget ]( instanceOptions );
6270
6271					// Store an instance of the controlgroup to be able to reference
6272					// from the outermost element for changing options and refresh
6273					var widgetElement = element[ widget ]( "widget" );
6274					$.data( widgetElement[ 0 ], "ui-controlgroup-data",
6275						instance ? instance : element[ widget ]( "instance" ) );
6276
6277					childWidgets.push( widgetElement[ 0 ] );
6278				} );
6279		} );
6280
6281		this.childWidgets = $( $.uniqueSort( childWidgets ) );
6282		this._addClass( this.childWidgets, "ui-controlgroup-item" );
6283	},
6284
6285	_callChildMethod: function( method ) {
6286		this.childWidgets.each( function() {
6287			var element = $( this ),
6288				data = element.data( "ui-controlgroup-data" );
6289			if ( data && data[ method ] ) {
6290				data[ method ]();
6291			}
6292		} );
6293	},
6294
6295	_updateCornerClass: function( element, position ) {
6296		var remove = "ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all";
6297		var add = this._buildSimpleOptions( position, "label" ).classes.label;
6298
6299		this._removeClass( element, null, remove );
6300		this._addClass( element, null, add );
6301	},
6302
6303	_buildSimpleOptions: function( position, key ) {
6304		var direction = this.options.direction === "vertical";
6305		var result = {
6306			classes: {}
6307		};
6308		result.classes[ key ] = {
6309			"middle": "",
6310			"first": "ui-corner-" + ( direction ? "top" : "left" ),
6311			"last": "ui-corner-" + ( direction ? "bottom" : "right" ),
6312			"only": "ui-corner-all"
6313		}[ position ];
6314
6315		return result;
6316	},
6317
6318	_spinnerOptions: function( position ) {
6319		var options = this._buildSimpleOptions( position, "ui-spinner" );
6320
6321		options.classes[ "ui-spinner-up" ] = "";
6322		options.classes[ "ui-spinner-down" ] = "";
6323
6324		return options;
6325	},
6326
6327	_buttonOptions: function( position ) {
6328		return this._buildSimpleOptions( position, "ui-button" );
6329	},
6330
6331	_checkboxradioOptions: function( position ) {
6332		return this._buildSimpleOptions( position, "ui-checkboxradio-label" );
6333	},
6334
6335	_selectmenuOptions: function( position ) {
6336		var direction = this.options.direction === "vertical";
6337		return {
6338			width: direction ? "auto" : false,
6339			classes: {
6340				middle: {
6341					"ui-selectmenu-button-open": "",
6342					"ui-selectmenu-button-closed": ""
6343				},
6344				first: {
6345					"ui-selectmenu-button-open": "ui-corner-" + ( direction ? "top" : "tl" ),
6346					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "top" : "left" )
6347				},
6348				last: {
6349					"ui-selectmenu-button-open": direction ? "" : "ui-corner-tr",
6350					"ui-selectmenu-button-closed": "ui-corner-" + ( direction ? "bottom" : "right" )
6351				},
6352				only: {
6353					"ui-selectmenu-button-open": "ui-corner-top",
6354					"ui-selectmenu-button-closed": "ui-corner-all"
6355				}
6356
6357			}[ position ]
6358		};
6359	},
6360
6361	_resolveClassesValues: function( classes, instance ) {
6362		var result = {};
6363		$.each( classes, function( key ) {
6364			var current = instance.options.classes[ key ] || "";
6365			current = String.prototype.trim.call( current.replace( controlgroupCornerRegex, "" ) );
6366			result[ key ] = ( current + " " + classes[ key ] ).replace( /\s+/g, " " );
6367		} );
6368		return result;
6369	},
6370
6371	_setOption: function( key, value ) {
6372		if ( key === "direction" ) {
6373			this._removeClass( "ui-controlgroup-" + this.options.direction );
6374		}
6375
6376		this._super( key, value );
6377		if ( key === "disabled" ) {
6378			this._callChildMethod( value ? "disable" : "enable" );
6379			return;
6380		}
6381
6382		this.refresh();
6383	},
6384
6385	refresh: function() {
6386		var children,
6387			that = this;
6388
6389		this._addClass( "ui-controlgroup ui-controlgroup-" + this.options.direction );
6390
6391		if ( this.options.direction === "horizontal" ) {
6392			this._addClass( null, "ui-helper-clearfix" );
6393		}
6394		this._initWidgets();
6395
6396		children = this.childWidgets;
6397
6398		// We filter here because we need to track all childWidgets not just the visible ones
6399		if ( this.options.onlyVisible ) {
6400			children = children.filter( ":visible" );
6401		}
6402
6403		if ( children.length ) {
6404
6405			// We do this last because we need to make sure all enhancment is done
6406			// before determining first and last
6407			$.each( [ "first", "last" ], function( index, value ) {
6408				var instance = children[ value ]().data( "ui-controlgroup-data" );
6409
6410				if ( instance && that[ "_" + instance.widgetName + "Options" ] ) {
6411					var options = that[ "_" + instance.widgetName + "Options" ](
6412						children.length === 1 ? "only" : value
6413					);
6414					options.classes = that._resolveClassesValues( options.classes, instance );
6415					instance.element[ instance.widgetName ]( options );
6416				} else {
6417					that._updateCornerClass( children[ value ](), value );
6418				}
6419			} );
6420
6421			// Finally call the refresh method on each of the child widgets.
6422			this._callChildMethod( "refresh" );
6423		}
6424	}
6425} );
6426
6427/*!
6428 * jQuery UI Checkboxradio 1.14.
vendor: 7,789 bytes, lines 6428-6718
64281
6429 * https://jqueryui.com
6430 *
6431 * Copyright OpenJS Foundation and other contributors
6432 * Released under the MIT license.
6433 * https://jquery.org/license
6434 */
6435
6436//>>label: Checkboxradio
6437//>>group: Widgets
6438//>>description: Enhances a form with multiple themeable checkboxes or radio buttons.
6439//>>docs: https://api.jqueryui.com/checkboxradio/
6440//>>demos: https://jqueryui.com/checkboxradio/
6441//>>css.structure: ../../themes/base/core.css
6442//>>css.structure: ../../themes/base/button.css
6443//>>css.structure: ../../themes/base/checkboxradio.css
6444//>>css.theme: ../../themes/base/theme.css
6445
6446
6447$.widget( "ui.checkboxradio", [ $.ui.formResetMixin, {
6448	version: "1.14.1",
6449	options: {
6450		disabled: null,
6451		label: null,
6452		icon: true,
6453		classes: {
6454			"ui-checkboxradio-label": "ui-corner-all",
6455			"ui-checkboxradio-icon": "ui-corner-all"
6456		}
6457	},
6458
6459	_getCreateOptions: function() {
6460		var disabled, labels, labelContents;
6461		var options = this._super() || {};
6462
6463		// We read the type here, because it makes more sense to throw a element type error first,
6464		// rather then the error for lack of a label. Often if its the wrong type, it
6465		// won't have a label (e.g. calling on a div, btn, etc)
6466		this._readType();
6467
6468		labels = this.element.labels();
6469
6470		// If there are multiple labels, use the last one
6471		this.label = $( labels[ labels.length - 1 ] );
6472		if ( !this.label.length ) {
6473			$.error( "No label found for checkboxradio widget" );
6474		}
6475
6476		this.originalLabel = "";
6477
6478		// We need to get the label text but this may also need to make sure it does not contain the
6479		// input itself.
6480		// The label contents could be text, html, or a mix. We wrap all elements
6481		// and read the wrapper's `innerHTML` to get a string representation of
6482		// the label, without the input as part of it.
6483		labelContents = this.label.contents().not( this.element[ 0 ] );
6484
6485		if ( labelContents.length ) {
6486			this.originalLabel += labelContents
6487				.clone()
6488				.wrapAll( "<div></div>" )
6489				.parent()
6490				.html();
6491		}
6492
6493		// Set the label option if we found label text
6494		if ( this.originalLabel ) {
6495			options.label = this.originalLabel;
6496		}
6497
6498		disabled = this.element[ 0 ].disabled;
6499		if ( disabled != null ) {
6500			options.disabled = disabled;
6501		}
6502		return options;
6503	},
6504
6505	_create: function() {
6506		var checked = this.element[ 0 ].checked;
6507
6508		this._bindFormResetHandler();
6509
6510		if ( this.options.disabled == null ) {
6511			this.options.disabled = this.element[ 0 ].disabled;
6512		}
6513
6514		this._setOption( "disabled", this.options.disabled );
6515		this._addClass( "ui-checkboxradio", "ui-helper-hidden-accessible" );
6516		this._addClass( this.label, "ui-checkboxradio-label", "ui-button ui-widget" );
6517
6518		if ( this.type === "radio" ) {
6519			this._addClass( this.label, "ui-checkboxradio-radio-label" );
6520		}
6521
6522		if ( this.options.label && this.options.label !== this.originalLabel ) {
6523			this._updateLabel();
6524		} else if ( this.originalLabel ) {
6525			this.options.label = this.originalLabel;
6526		}
6527
6528		this._enhance();
6529
6530		if ( checked ) {
6531			this._addClass( this.label, "ui-checkboxradio-checked", "ui-state-active" );
6532		}
6533
6534		this._on( {
6535			change: "_toggleClasses",
6536			focus: function() {
6537				this._addClass( this.label, null, "ui-state-focus ui-visual-focus" );
6538			},
6539			blur: function() {
6540				this._removeClass( this.label, null, "ui-state-focus ui-visual-focus" );
6541			}
6542		} );
6543	},
6544
6545	_readType: function() {
6546		var nodeName = this.element[ 0 ].nodeName.toLowerCase();
6547		this.type = this.element[ 0 ].type;
6548		if ( nodeName !== "input" || !/radio|checkbox/.test( this.type ) ) {
6549			$.error( "Can't create checkboxradio on element.nodeName=" + nodeName +
6550				" and element.type=" + this.type );
6551		}
6552	},
6553
6554	// Support jQuery Mobile enhanced option
6555	_enhance: function() {
6556		this._updateIcon( this.element[ 0 ].checked );
6557	},
6558
6559	widget: function() {
6560		return this.label;
6561	},
6562
6563	_getRadioGroup: function() {
6564		var group;
6565		var name = this.element[ 0 ].name;
6566		var nameSelector = "input[name='" + CSS.escape( name ) + "']";
6567
6568		if ( !name ) {
6569			return $( [] );
6570		}
6571
6572		if ( this.form.length ) {
6573			group = $( this.form[ 0 ].elements ).filter( nameSelector );
6574		} else {
6575
6576			// Not inside a form, check all inputs that also are not inside a form
6577			group = $( nameSelector ).filter( function() {
6578				return $( $( this ).prop( "form" ) ).length === 0;
6579			} );
6580		}
6581
6582		return group.not( this.element );
6583	},
6584
6585	_toggleClasses: function() {
6586		var checked = this.element[ 0 ].checked;
6587		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6588
6589		if ( this.options.icon && this.type === "checkbox" ) {
6590			this._toggleClass( this.icon, null, "ui-icon-check ui-state-checked", checked )
6591				._toggleClass( this.icon, null, "ui-icon-blank", !checked );
6592		}
6593
6594		if ( this.type === "radio" ) {
6595			this._getRadioGroup()
6596				.each( function() {
6597					var instance = $( this ).checkboxradio( "instance" );
6598
6599					if ( instance ) {
6600						instance._removeClass( instance.label,
6601							"ui-checkboxradio-checked", "ui-state-active" );
6602					}
6603				} );
6604		}
6605	},
6606
6607	_destroy: function() {
6608		this._unbindFormResetHandler();
6609
6610		if ( this.icon ) {
6611			this.icon.remove();
6612			this.iconSpace.remove();
6613		}
6614	},
6615
6616	_setOption: function( key, value ) {
6617
6618		// We don't allow the value to be set to nothing
6619		if ( key === "label" && !value ) {
6620			return;
6621		}
6622
6623		this._super( key, value );
6624
6625		if ( key === "disabled" ) {
6626			this._toggleClass( this.label, null, "ui-state-disabled", value );
6627			this.element[ 0 ].disabled = value;
6628
6629			// Don't refresh when setting disabled
6630			return;
6631		}
6632		this.refresh();
6633	},
6634
6635	_updateIcon: function( checked ) {
6636		var toAdd = "ui-icon ui-icon-background ";
6637
6638		if ( this.options.icon ) {
6639			if ( !this.icon ) {
6640				this.icon = $( "<span>" );
6641				this.iconSpace = $( "<span> </span>" );
6642				this._addClass( this.iconSpace, "ui-checkboxradio-icon-space" );
6643			}
6644
6645			if ( this.type === "checkbox" ) {
6646				toAdd += checked ? "ui-icon-check ui-state-checked" : "ui-icon-blank";
6647				this._removeClass( this.icon, null, checked ? "ui-icon-blank" : "ui-icon-check" );
6648			} else {
6649				toAdd += "ui-icon-blank";
6650			}
6651			this._addClass( this.icon, "ui-checkboxradio-icon", toAdd );
6652			if ( !checked ) {
6653				this._removeClass( this.icon, null, "ui-icon-check ui-state-checked" );
6654			}
6655			this.icon.prependTo( this.label ).after( this.iconSpace );
6656		} else if ( this.icon !== undefined ) {
6657			this.icon.remove();
6658			this.iconSpace.remove();
6659			delete this.icon;
6660		}
6661	},
6662
6663	_updateLabel: function() {
6664
6665		// Remove the contents of the label ( minus the icon, icon space, and input )
6666		var contents = this.label.contents().not( this.element[ 0 ] );
6667		if ( this.icon ) {
6668			contents = contents.not( this.icon[ 0 ] );
6669		}
6670		if ( this.iconSpace ) {
6671			contents = contents.not( this.iconSpace[ 0 ] );
6672		}
6673		contents.remove();
6674
6675		this.label.append( this.options.label );
6676	},
6677
6678	refresh: function() {
6679		var checked = this.element[ 0 ].checked,
6680			isDisabled = this.element[ 0 ].disabled;
6681
6682		this._updateIcon( checked );
6683		this._toggleClass( this.label, "ui-checkboxradio-checked", "ui-state-active", checked );
6684		if ( this.options.label !== null ) {
6685			this._updateLabel();
6686		}
6687
6688		if ( isDisabled !== this.options.disabled ) {
6689			this._setOptions( { "disabled": isDisabled } );
6690		}
6691	}
6692
6693} ] );
6694
6695var widgetsCheckboxradio = $.ui.checkboxradio;
6696
6697
6698/*!
6699 * jQuery UI Button 1.14.1
6700 * https://jqueryui.com
6701 *
6702 * Copyright OpenJS Foundation and other contributors
6703 * Released under the MIT license.
6704 * https://jquery.org/license
6705 */
6706
6707//>>label: Button
6708//>>group: Widgets
6709//>>description: Enhances a form with themeable buttons.
6710//>>docs: https://api.jqueryui.com/button/
6711//>>demos: https://jqueryui.com/button/
6712//>>css.structure: ../../themes/base/core.css
6713//>>css.structure: ../../themes/base/button.css
6714//>>css.theme: ../../themes/base/theme.css
6715
6716
6717$.widget( "ui.button", {
6718	version: "1.14.1
vendor: 10,754 bytes, lines 6718-7123
6718",
6719	defaultElement: "<button>",
6720	options: {
6721		classes: {
6722			"ui-button": "ui-corner-all"
6723		},
6724		disabled: null,
6725		icon: null,
6726		iconPosition: "beginning",
6727		label: null,
6728		showLabel: true
6729	},
6730
6731	_getCreateOptions: function() {
6732		var disabled,
6733
6734			// This is to support cases like in jQuery Mobile where the base widget does have
6735			// an implementation of _getCreateOptions
6736			options = this._super() || {};
6737
6738		this.isInput = this.element.is( "input" );
6739
6740		disabled = this.element[ 0 ].disabled;
6741		if ( disabled != null ) {
6742			options.disabled = disabled;
6743		}
6744
6745		this.originalLabel = this.isInput ? this.element.val() : this.element.html();
6746		if ( this.originalLabel ) {
6747			options.label = this.originalLabel;
6748		}
6749
6750		return options;
6751	},
6752
6753	_create: function() {
6754		if ( !this.option.showLabel & !this.options.icon ) {
6755			this.options.showLabel = true;
6756		}
6757
6758		// We have to check the option again here even though we did in _getCreateOptions,
6759		// because null may have been passed on init which would override what was set in
6760		// _getCreateOptions
6761		if ( this.options.disabled == null ) {
6762			this.options.disabled = this.element[ 0 ].disabled || false;
6763		}
6764
6765		this.hasTitle = !!this.element.attr( "title" );
6766
6767		// Check to see if the label needs to be set or if its already correct
6768		if ( this.options.label && this.options.label !== this.originalLabel ) {
6769			if ( this.isInput ) {
6770				this.element.val( this.options.label );
6771			} else {
6772				this.element.html( this.options.label );
6773			}
6774		}
6775		this._addClass( "ui-button", "ui-widget" );
6776		this._setOption( "disabled", this.options.disabled );
6777		this._enhance();
6778
6779		if ( this.element.is( "a" ) ) {
6780			this._on( {
6781				"keyup": function( event ) {
6782					if ( event.keyCode === $.ui.keyCode.SPACE ) {
6783						event.preventDefault();
6784
6785						// If a native click is available use it, so we
6786						// actually cause navigation. Otherwise, just trigger
6787						// a click event.
6788						if ( this.element[ 0 ].click ) {
6789							this.element[ 0 ].click();
6790						} else {
6791							this.element.trigger( "click" );
6792						}
6793					}
6794				}
6795			} );
6796		}
6797	},
6798
6799	_enhance: function() {
6800		if ( !this.element.is( "button" ) ) {
6801			this.element.attr( "role", "button" );
6802		}
6803
6804		if ( this.options.icon ) {
6805			this._updateIcon( "icon", this.options.icon );
6806			this._updateTooltip();
6807		}
6808	},
6809
6810	_updateTooltip: function() {
6811		this.title = this.element.attr( "title" );
6812
6813		if ( !this.options.showLabel && !this.title ) {
6814			this.element.attr( "title", this.options.label );
6815		}
6816	},
6817
6818	_updateIcon: function( option, value ) {
6819		var icon = option !== "iconPosition",
6820			position = icon ? this.options.iconPosition : value,
6821			displayBlock = position === "top" || position === "bottom";
6822
6823		// Create icon
6824		if ( !this.icon ) {
6825			this.icon = $( "<span>" );
6826
6827			this._addClass( this.icon, "ui-button-icon", "ui-icon" );
6828
6829			if ( !this.options.showLabel ) {
6830				this._addClass( "ui-button-icon-only" );
6831			}
6832		} else if ( icon ) {
6833
6834			// If we are updating the icon remove the old icon class
6835			this._removeClass( this.icon, null, this.options.icon );
6836		}
6837
6838		// If we are updating the icon add the new icon class
6839		if ( icon ) {
6840			this._addClass( this.icon, null, value );
6841		}
6842
6843		this._attachIcon( position );
6844
6845		// If the icon is on top or bottom we need to add the ui-widget-icon-block class and remove
6846		// the iconSpace if there is one.
6847		if ( displayBlock ) {
6848			this._addClass( this.icon, null, "ui-widget-icon-block" );
6849			if ( this.iconSpace ) {
6850				this.iconSpace.remove();
6851			}
6852		} else {
6853
6854			// Position is beginning or end so remove the ui-widget-icon-block class and add the
6855			// space if it does not exist
6856			if ( !this.iconSpace ) {
6857				this.iconSpace = $( "<span> </span>" );
6858				this._addClass( this.iconSpace, "ui-button-icon-space" );
6859			}
6860			this._removeClass( this.icon, null, "ui-wiget-icon-block" );
6861			this._attachIconSpace( position );
6862		}
6863	},
6864
6865	_destroy: function() {
6866		this.element.removeAttr( "role" );
6867
6868		if ( this.icon ) {
6869			this.icon.remove();
6870		}
6871		if ( this.iconSpace ) {
6872			this.iconSpace.remove();
6873		}
6874		if ( !this.hasTitle ) {
6875			this.element.removeAttr( "title" );
6876		}
6877	},
6878
6879	_attachIconSpace: function( iconPosition ) {
6880		this.icon[ /^(?:end|bottom)/.test( iconPosition ) ? "before" : "after" ]( this.iconSpace );
6881	},
6882
6883	_attachIcon: function( iconPosition ) {
6884		this.element[ /^(?:end|bottom)/.test( iconPosition ) ? "append" : "prepend" ]( this.icon );
6885	},
6886
6887	_setOptions: function( options ) {
6888		var newShowLabel = options.showLabel === undefined ?
6889				this.options.showLabel :
6890				options.showLabel,
6891			newIcon = options.icon === undefined ? this.options.icon : options.icon;
6892
6893		if ( !newShowLabel && !newIcon ) {
6894			options.showLabel = true;
6895		}
6896		this._super( options );
6897	},
6898
6899	_setOption: function( key, value ) {
6900		if ( key === "icon" ) {
6901			if ( value ) {
6902				this._updateIcon( key, value );
6903			} else if ( this.icon ) {
6904				this.icon.remove();
6905				if ( this.iconSpace ) {
6906					this.iconSpace.remove();
6907				}
6908			}
6909		}
6910
6911		if ( key === "iconPosition" ) {
6912			this._updateIcon( key, value );
6913		}
6914
6915		// Make sure we can't end up with a button that has neither text nor icon
6916		if ( key === "showLabel" ) {
6917				this._toggleClass( "ui-button-icon-only", null, !value );
6918				this._updateTooltip();
6919		}
6920
6921		if ( key === "label" ) {
6922			if ( this.isInput ) {
6923				this.element.val( value );
6924			} else {
6925
6926				// If there is an icon, append it, else nothing then append the value
6927				// this avoids removal of the icon when setting label text
6928				this.element.html( value );
6929				if ( this.icon ) {
6930					this._attachIcon( this.options.iconPosition );
6931					this._attachIconSpace( this.options.iconPosition );
6932				}
6933			}
6934		}
6935
6936		this._super( key, value );
6937
6938		if ( key === "disabled" ) {
6939			this._toggleClass( null, "ui-state-disabled", value );
6940			this.element[ 0 ].disabled = value;
6941			if ( value ) {
6942				this.element.trigger( "blur" );
6943			}
6944		}
6945	},
6946
6947	refresh: function() {
6948
6949		// Make sure to only check disabled if its an element that supports this otherwise
6950		// check for the disabled class to determine state
6951		var isDisabled = this.element.is( "input, button" ) ?
6952			this.element[ 0 ].disabled : this.element.hasClass( "ui-button-disabled" );
6953
6954		if ( isDisabled !== this.options.disabled ) {
6955			this._setOptions( { disabled: isDisabled } );
6956		}
6957
6958		this._updateTooltip();
6959	}
6960} );
6961
6962// DEPRECATED
6963if ( $.uiBackCompat === true ) {
6964
6965	// Text and Icons options
6966	$.widget( "ui.button", $.ui.button, {
6967		options: {
6968			text: true,
6969			icons: {
6970				primary: null,
6971				secondary: null
6972			}
6973		},
6974
6975		_create: function() {
6976			if ( this.options.showLabel && !this.options.text ) {
6977				this.options.showLabel = this.options.text;
6978			}
6979			if ( !this.options.showLabel && this.options.text ) {
6980				this.options.text = this.options.showLabel;
6981			}
6982			if ( !this.options.icon && ( this.options.icons.primary ||
6983					this.options.icons.secondary ) ) {
6984				if ( this.options.icons.primary ) {
6985					this.options.icon = this.options.icons.primary;
6986				} else {
6987					this.options.icon = this.options.icons.secondary;
6988					this.options.iconPosition = "end";
6989				}
6990			} else if ( this.options.icon ) {
6991				this.options.icons.primary = this.options.icon;
6992			}
6993			this._super();
6994		},
6995
6996		_setOption: function( key, value ) {
6997			if ( key === "text" ) {
6998				this._super( "showLabel", value );
6999				return;
7000			}
7001			if ( key === "showLabel" ) {
7002				this.options.text = value;
7003			}
7004			if ( key === "icon" ) {
7005				this.options.icons.primary = value;
7006			}
7007			if ( key === "icons" ) {
7008				if ( value.primary ) {
7009					this._super( "icon", value.primary );
7010					this._super( "iconPosition", "beginning" );
7011				} else if ( value.secondary ) {
7012					this._super( "icon", value.secondary );
7013					this._super( "iconPosition", "end" );
7014				}
7015			}
7016			this._superApply( arguments );
7017		}
7018	} );
7019
7020	$.fn.button = ( function( orig ) {
7021		return function( options ) {
7022			var isMethodCall = typeof options === "string";
7023			var args = Array.prototype.slice.call( arguments, 1 );
7024			var returnValue = this;
7025
7026			if ( isMethodCall ) {
7027
7028				// If this is an empty collection, we need to have the instance method
7029				// return undefined instead of the jQuery instance
7030				if ( !this.length && options === "instance" ) {
7031					returnValue = undefined;
7032				} else {
7033					this.each( function() {
7034						var methodValue;
7035						var type = $( this ).attr( "type" );
7036						var name = type !== "checkbox" && type !== "radio" ?
7037							"button" :
7038							"checkboxradio";
7039						var instance = $.data( this, "ui-" + name );
7040
7041						if ( options === "instance" ) {
7042							returnValue = instance;
7043							return false;
7044						}
7045
7046						if ( !instance ) {
7047							return $.error( "cannot call methods on button" +
7048								" prior to initialization; " +
7049								"attempted to call method '" + options + "'" );
7050						}
7051
7052						if ( typeof instance[ options ] !== "function" ||
7053							options.charAt( 0 ) === "_" ) {
7054							return $.error( "no such method '" + options + "' for button" +
7055								" widget instance" );
7056						}
7057
7058						methodValue = instance[ options ].apply( instance, args );
7059
7060						if ( methodValue !== instance && methodValue !== undefined ) {
7061							returnValue = methodValue && methodValue.jquery ?
7062								returnValue.pushStack( methodValue.get() ) :
7063								methodValue;
7064							return false;
7065						}
7066					} );
7067				}
7068			} else {
7069
7070				// Allow multiple hashes to be passed on init
7071				if ( args.length ) {
7072					options = $.widget.extend.apply( null, [ options ].concat( args ) );
7073				}
7074
7075				this.each( function() {
7076					var type = $( this ).attr( "type" );
7077					var name = type !== "checkbox" && type !== "radio" ? "button" : "checkboxradio";
7078					var instance = $.data( this, "ui-" + name );
7079
7080					if ( instance ) {
7081						instance.option( options || {} );
7082						if ( instance._init ) {
7083							instance._init();
7084						}
7085					} else {
7086						if ( name === "button" ) {
7087							orig.call( $( this ), options );
7088							return;
7089						}
7090
7091						$( this ).checkboxradio( $.extend( { icon: false }, options ) );
7092					}
7093				} );
7094			}
7095
7096			return returnValue;
7097		};
7098	} )( $.fn.button );
7099
7100	$.fn.buttonset = function() {
7101		if ( !$.ui.controlgroup ) {
7102			$.error( "Controlgroup widget missing" );
7103		}
7104		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" && arguments[ 2 ] ) {
7105			return this.controlgroup.apply( this,
7106				[ arguments[ 0 ], "items.button", arguments[ 2 ] ] );
7107		}
7108		if ( arguments[ 0 ] === "option" && arguments[ 1 ] === "items" ) {
7109			return this.controlgroup.apply( this, [ arguments[ 0 ], "items.button" ] );
7110		}
7111		if ( typeof arguments[ 0 ] === "object" && arguments[ 0 ].items ) {
7112			arguments[ 0 ].items = {
7113				button: arguments[ 0 ].items
7114			};
7115		}
7116		return this.controlgroup.apply( this, arguments );
7117	};
7118}
7119
7120var widgetsButton = $.ui.button;
7121
7122
7123/* eslint-disable max-len
7123, camelcase */
7124/*!
7125 * jQuery UI Datepicker 1.14.1
7126 * https://jqueryui.com
7127 *
7128 * Copyright OpenJS Foundation and other contributors
7129 * Released under the MIT license.
7130 * https://jquery.org/license
7131 */
7132
7133//>>label: Datepicker
7134//>>group: Widgets
7135//>>description: Displays a calendar from an input or inline for selecting dates.
7136//>>docs: https://api.jqueryui.com/datepicker/
7137//>>demos: https://jqueryui.com/datepicker/
7138//>>css.structure: ../../themes/base/core.css
7139//>>css.structure: ../../themes/base/datepicker.css
7140//>>css.theme: ../../themes/base/theme.css
7141
7142
7143$.extend( $.ui, { datepicker: { version: "1.14.1
vendor: 20,464 bytes, lines 7143-7642
7143" } } );
7144
7145var datepicker_instActive;
7146
7147function datepicker_getZindex( elem ) {
7148	var position, value;
7149	while ( elem.length && elem[ 0 ] !== document ) {
7150
7151		// Ignore z-index if position is set to a value where z-index is ignored by the browser
7152		// This makes behavior of this function consistent across browsers
7153		// WebKit always returns auto if the element is positioned
7154		position = elem.css( "position" );
7155		if ( position === "absolute" || position === "relative" || position === "fixed" ) {
7156
7157			// IE returns 0 when zIndex is not specified
7158			// other browsers return a string
7159			// we ignore the case of nested elements with an explicit value of 0
7160			// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
7161			value = parseInt( elem.css( "zIndex" ), 10 );
7162			if ( !isNaN( value ) && value !== 0 ) {
7163				return value;
7164			}
7165		}
7166		elem = elem.parent();
7167	}
7168
7169	return 0;
7170}
7171
7172/* Date picker manager.
7173   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7174   Settings for (groups of) date pickers are maintained in an instance object,
7175   allowing multiple different settings on the same page. */
7176
7177function Datepicker() {
7178	this._curInst = null; // The current instance in use
7179	this._keyEvent = false; // If the last event was a key event
7180	this._disabledInputs = []; // List of date picker inputs that have been disabled
7181	this._datepickerShowing = false; // True if the popup picker is showing , false if not
7182	this._inDialog = false; // True if showing within a "dialog", false if not
7183	this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7184	this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7185	this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7186	this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7187	this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7188	this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7189	this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7190	this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7191	this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7192	this.regional = []; // Available regional settings, indexed by language code
7193	this.regional[ "" ] = { // Default regional settings
7194		closeText: "Done", // Display text for close link
7195		prevText: "Prev", // Display text for previous month link
7196		nextText: "Next", // Display text for next month link
7197		currentText: "Today", // Display text for current month link
7198		monthNames: [ "January", "February", "March", "April", "May", "June",
7199			"July", "August", "September", "October", "November", "December" ], // Names of months for drop-down and formatting
7200		monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], // For formatting
7201		dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], // For formatting
7202		dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], // For formatting
7203		dayNamesMin: [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ], // Column headings for days starting at Sunday
7204		weekHeader: "Wk", // Column header for week of the year
7205		dateFormat: "mm/dd/yy", // See format options on parseDate
7206		firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7207		isRTL: false, // True if right-to-left language, false if left-to-right
7208		showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7209		yearSuffix: "", // Additional text to append to the year in the month headers,
7210		selectMonthLabel: "Select month", // Invisible label for month selector
7211		selectYearLabel: "Select year" // Invisible label for year selector
7212	};
7213	this._defaults = { // Global defaults for all the date picker instances
7214		showOn: "focus", // "focus" for popup on focus,
7215			// "button" for trigger button, or "both" for either
7216		showAnim: "fadeIn", // Name of jQuery animation for popup
7217		showOptions: {}, // Options for enhanced animations
7218		defaultDate: null, // Used when field is blank: actual date,
7219			// +/-number for offset from today, null for today
7220		appendText: "", // Display text following the input box, e.g. showing the format
7221		buttonText: "...", // Text for trigger button
7222		buttonImage: "", // URL for trigger button image
7223		buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7224		hideIfNoPrevNext: false, // True to hide next/previous month links
7225			// if not applicable, false to just disable them
7226		navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7227		gotoCurrent: false, // True if today link goes back to current selection instead
7228		changeMonth: false, // True if month can be selected directly, false if only prev/next
7229		changeYear: false, // True if year can be selected directly, false if only prev/next
7230		yearRange: "c-10:c+10", // Range of years to display in drop-down,
7231			// either relative to today's year (-nn:+nn), relative to currently displayed year
7232			// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7233		showOtherMonths: false, // True to show dates in other months, false to leave blank
7234		selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7235		showWeek: false, // True to show week of the year, false to not show it
7236		calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7237			// takes a Date and returns the number of the week for it
7238		shortYearCutoff: "+10", // Short year values < this are in the current century,
7239			// > this are in the previous century,
7240			// string value starting with "+" for current year + value
7241		minDate: null, // The earliest selectable date, or null for no limit
7242		maxDate: null, // The latest selectable date, or null for no limit
7243		duration: "fast", // Duration of display/closure
7244		beforeShowDay: null, // Function that takes a date and returns an array with
7245			// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7246			// [2] = cell title (optional), e.g. $.datepicker.noWeekends
7247		beforeShow: null, // Function that takes an input field and
7248			// returns a set of custom settings for the date picker
7249		onSelect: null, // Define a callback function when a date is selected
7250		onChangeMonthYear: null, // Define a callback function when the month or year is changed
7251		onClose: null, // Define a callback function when the datepicker is closed
7252		onUpdateDatepicker: null, // Define a callback function when the datepicker is updated
7253		numberOfMonths: 1, // Number of months to show at a time
7254		showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7255		stepMonths: 1, // Number of months to step back/forward
7256		stepBigMonths: 12, // Number of months to step back/forward for the big links
7257		altField: "", // Selector for an alternate field to store selected dates into
7258		altFormat: "", // The date format to use for the alternate field
7259		constrainInput: true, // The input is constrained by the current date format
7260		showButtonPanel: false, // True to show button panel, false to not show it
7261		autoSize: false, // True to size the input for the date format, false to leave as is
7262		disabled: false // The initial disabled state
7263	};
7264	$.extend( this._defaults, this.regional[ "" ] );
7265	this.regional.en = $.extend( true, {}, this.regional[ "" ] );
7266	this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
7267	this.dpDiv = datepicker_bindHover( $( "<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) );
7268}
7269
7270$.extend( Datepicker.prototype, {
7271
7272	/* Class name added to elements to indicate already configured with a date picker. */
7273	markerClassName: "hasDatepicker",
7274
7275	//Keep track of the maximum number of rows displayed (see #7043)
7276	maxRows: 4,
7277
7278	// TODO rename to "widget" when switching to widget factory
7279	_widgetDatepicker: function() {
7280		return this.dpDiv;
7281	},
7282
7283	/* Override the default settings for all instances of the date picker.
7284	 * @param  settings  object - the new settings to use as defaults (anonymous object)
7285	 * @return the manager object
7286	 */
7287	setDefaults: function( settings ) {
7288		datepicker_extendRemove( this._defaults, settings || {} );
7289		return this;
7290	},
7291
7292	/* Attach the date picker to a jQuery selection.
7293	 * @param  target	element - the target input field or division or span
7294	 * @param  settings  object - the new settings to use for this date picker instance (anonymous)
7295	 */
7296	_attachDatepicker: function( target, settings ) {
7297		var nodeName, inline, inst;
7298		nodeName = target.nodeName.toLowerCase();
7299		inline = ( nodeName === "div" || nodeName === "span" );
7300		if ( !target.id ) {
7301			this.uuid += 1;
7302			target.id = "dp" + this.uuid;
7303		}
7304		inst = this._newInst( $( target ), inline );
7305		inst.settings = $.extend( {}, settings || {} );
7306		if ( nodeName === "input" ) {
7307			this._connectDatepicker( target, inst );
7308		} else if ( inline ) {
7309			this._inlineDatepicker( target, inst );
7310		}
7311	},
7312
7313	/* Create a new instance object. */
7314	_newInst: function( target, inline ) {
7315		var id = target[ 0 ].id.replace( /([^A-Za-z0-9_\-])/g, "\\\\$1" ); // escape jQuery meta chars
7316		return { id: id, input: target, // associated target
7317			selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7318			drawMonth: 0, drawYear: 0, // month being drawn
7319			inline: inline, // is datepicker inline or not
7320			dpDiv: ( !inline ? this.dpDiv : // presentation div
7321			datepicker_bindHover( $( "<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>" ) ) ) };
7322	},
7323
7324	/* Attach the date picker to an input field. */
7325	_connectDatepicker: function( target, inst ) {
7326		var input = $( target );
7327		inst.append = $( [] );
7328		inst.trigger = $( [] );
7329		if ( input.hasClass( this.markerClassName ) ) {
7330			return;
7331		}
7332		this._attachments( input, inst );
7333		input.addClass( this.markerClassName ).on( "keydown", this._doKeyDown ).
7334			on( "keypress", this._doKeyPress ).on( "keyup", this._doKeyUp );
7335		this._autoSize( inst );
7336		$.data( target, "datepicker", inst );
7337
7338		//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7339		if ( inst.settings.disabled ) {
7340			this._disableDatepicker( target );
7341		}
7342	},
7343
7344	/* Make attachments based on settings. */
7345	_attachments: function( input, inst ) {
7346		var showOn, buttonText, buttonImage,
7347			appendText = this._get( inst, "appendText" ),
7348			isRTL = this._get( inst, "isRTL" );
7349
7350		if ( inst.append ) {
7351			inst.append.remove();
7352		}
7353		if ( appendText ) {
7354			inst.append = $( "<span>" )
7355				.addClass( this._appendClass )
7356				.text( appendText );
7357			input[ isRTL ? "before" : "after" ]( inst.append );
7358		}
7359
7360		input.off( "focus", this._showDatepicker );
7361
7362		if ( inst.trigger ) {
7363			inst.trigger.remove();
7364		}
7365
7366		showOn = this._get( inst, "showOn" );
7367		if ( showOn === "focus" || showOn === "both" ) { // pop-up date picker when in the marked field
7368			input.on( "focus", this._showDatepicker );
7369		}
7370		if ( showOn === "button" || showOn === "both" ) { // pop-up date picker when button clicked
7371			buttonText = this._get( inst, "buttonText" );
7372			buttonImage = this._get( inst, "buttonImage" );
7373
7374			if ( this._get( inst, "buttonImageOnly" ) ) {
7375				inst.trigger = $( "<img>" )
7376					.addClass( this._triggerClass )
7377					.attr( {
7378						src: buttonImage,
7379						alt: buttonText,
7380						title: buttonText
7381					} );
7382			} else {
7383				inst.trigger = $( "<button type='button'>" )
7384					.addClass( this._triggerClass );
7385				if ( buttonImage ) {
7386					inst.trigger.html(
7387						$( "<img>" )
7388							.attr( {
7389								src: buttonImage,
7390								alt: buttonText,
7391								title: buttonText
7392							} )
7393					);
7394				} else {
7395					inst.trigger.text( buttonText );
7396				}
7397			}
7398
7399			input[ isRTL ? "before" : "after" ]( inst.trigger );
7400			inst.trigger.on( "click", function() {
7401				if ( $.datepicker._datepickerShowing && $.datepicker._lastInput === input[ 0 ] ) {
7402					$.datepicker._hideDatepicker();
7403				} else if ( $.datepicker._datepickerShowing && $.datepicker._lastInput !== input[ 0 ] ) {
7404					$.datepicker._hideDatepicker();
7405					$.datepicker._showDatepicker( input[ 0 ] );
7406				} else {
7407					$.datepicker._showDatepicker( input[ 0 ] );
7408				}
7409				return false;
7410			} );
7411		}
7412	},
7413
7414	/* Apply the maximum length for the date format. */
7415	_autoSize: function( inst ) {
7416		if ( this._get( inst, "autoSize" ) && !inst.inline ) {
7417			var findMax, max, maxI, i,
7418				date = new Date( 2009, 12 - 1, 20 ), // Ensure double digits
7419				dateFormat = this._get( inst, "dateFormat" );
7420
7421			if ( dateFormat.match( /[DM]/ ) ) {
7422				findMax = function( names ) {
7423					max = 0;
7424					maxI = 0;
7425					for ( i = 0; i < names.length; i++ ) {
7426						if ( names[ i ].length > max ) {
7427							max = names[ i ].length;
7428							maxI = i;
7429						}
7430					}
7431					return maxI;
7432				};
7433				date.setMonth( findMax( this._get( inst, ( dateFormat.match( /MM/ ) ?
7434					"monthNames" : "monthNamesShort" ) ) ) );
7435				date.setDate( findMax( this._get( inst, ( dateFormat.match( /DD/ ) ?
7436					"dayNames" : "dayNamesShort" ) ) ) + 20 - date.getDay() );
7437			}
7438			inst.input.attr( "size", this._formatDate( inst, date ).length );
7439		}
7440	},
7441
7442	/* Attach an inline date picker to a div. */
7443	_inlineDatepicker: function( target, inst ) {
7444		var divSpan = $( target );
7445		if ( divSpan.hasClass( this.markerClassName ) ) {
7446			return;
7447		}
7448		divSpan.addClass( this.markerClassName ).append( inst.dpDiv );
7449		$.data( target, "datepicker", inst );
7450		this._setDate( inst, this._getDefaultDate( inst ), true );
7451		this._updateDatepicker( inst );
7452		this._updateAlternate( inst );
7453
7454		//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7455		if ( inst.settings.disabled ) {
7456			this._disableDatepicker( target );
7457		}
7458
7459		// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7460		// https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7461		inst.dpDiv.css( "display", "block" );
7462	},
7463
7464	/* Pop-up the date picker in a "dialog" box.
7465	 * @param  input element - ignored
7466	 * @param  date	string or Date - the initial date to display
7467	 * @param  onSelect  function - the function to call when a date is selected
7468	 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7469	 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7470	 *					event - with x/y coordinates or
7471	 *					leave empty for default (screen centre)
7472	 * @return the manager object
7473	 */
7474	_dialogDatepicker: function( input, date, onSelect, settings, pos ) {
7475		var id, browserWidth, browserHeight, scrollX, scrollY,
7476			inst = this._dialogInst; // internal instance
7477
7478		if ( !inst ) {
7479			this.uuid += 1;
7480			id = "dp" + this.uuid;
7481			this._dialogInput = $( "<input type='text' id='" + id +
7482				"' style='position: absolute; top: -100px; width: 0px;'/>" );
7483			this._dialogInput.on( "keydown", this._doKeyDown );
7484			$( "body" ).append( this._dialogInput );
7485			inst = this._dialogInst = this._newInst( this._dialogInput, false );
7486			inst.settings = {};
7487			$.data( this._dialogInput[ 0 ], "datepicker", inst );
7488		}
7489		datepicker_extendRemove( inst.settings, settings || {} );
7490		date = ( date && date.constructor === Date ? this._formatDate( inst, date ) : date );
7491		this._dialogInput.val( date );
7492
7493		this._pos = ( pos ? ( pos.length ? pos : [ pos.pageX, pos.pageY ] ) : null );
7494		if ( !this._pos ) {
7495			browserWidth = document.documentElement.clientWidth;
7496			browserHeight = document.documentElement.clientHeight;
7497			scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7498			scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7499			this._pos = // should use actual width/height below
7500				[ ( browserWidth / 2 ) - 100 + scrollX, ( browserHeight / 2 ) - 150 + scrollY ];
7501		}
7502
7503		// Move input on screen for focus, but hidden behind dialog
7504		this._dialogInput.css( "left", ( this._pos[ 0 ] + 20 ) + "px" ).css( "top", this._pos[ 1 ] + "px" );
7505		inst.settings.onSelect = onSelect;
7506		this._inDialog = true;
7507		this.dpDiv.addClass( this._dialogClass );
7508		this._showDatepicker( this._dialogInput[ 0 ] );
7509		if ( $.blockUI ) {
7510			$.blockUI( this.dpDiv );
7511		}
7512		$.data( this._dialogInput[ 0 ], "datepicker", inst );
7513		return this;
7514	},
7515
7516	/* Detach a datepicker from its control.
7517	 * @param  target	element - the target input field or division or span
7518	 */
7519	_destroyDatepicker: function( target ) {
7520		var nodeName,
7521			$target = $( target ),
7522			inst = $.data( target, "datepicker" );
7523
7524		if ( !$target.hasClass( this.markerClassName ) ) {
7525			return;
7526		}
7527
7528		nodeName = target.nodeName.toLowerCase();
7529		$.removeData( target, "datepicker" );
7530		if ( nodeName === "input" ) {
7531			inst.append.remove();
7532			inst.trigger.remove();
7533			$target.removeClass( this.markerClassName ).
7534				off( "focus", this._showDatepicker ).
7535				off( "keydown", this._doKeyDown ).
7536				off( "keypress", this._doKeyPress ).
7537				off( "keyup", this._doKeyUp );
7538		} else if ( nodeName === "div" || nodeName === "span" ) {
7539			$target.removeClass( this.markerClassName ).empty();
7540		}
7541
7542		$.datepicker._hideDatepicker();
7543		if ( datepicker_instActive === inst ) {
7544			datepicker_instActive = null;
7545			this._curInst = null;
7546		}
7547	},
7548
7549	/* Enable the date picker to a jQuery selection.
7550	 * @param  target	element - the target input field or division or span
7551	 */
7552	_enableDatepicker: function( target ) {
7553		var nodeName, inline,
7554			$target = $( target ),
7555			inst = $.data( target, "datepicker" );
7556
7557		if ( !$target.hasClass( this.markerClassName ) ) {
7558			return;
7559		}
7560
7561		nodeName = target.nodeName.toLowerCase();
7562		if ( nodeName === "input" ) {
7563			target.disabled = false;
7564			inst.trigger.filter( "button" ).
7565				each( function() {
7566					this.disabled = false;
7567				} ).end().
7568				filter( "img" ).css( { opacity: "1.0", cursor: "" } );
7569		} else if ( nodeName === "div" || nodeName === "span" ) {
7570			inline = $target.children( "." + this._inlineClass );
7571			inline.children().removeClass( "ui-state-disabled" );
7572			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7573				prop( "disabled", false );
7574		}
7575		this._disabledInputs = $.map( this._disabledInputs,
7576
7577			// Delete entry
7578			function( value ) {
7579				return ( value === target ? null : value );
7580			} );
7581	},
7582
7583	/* Disable the date picker to a jQuery selection.
7584	 * @param  target	element - the target input field or division or span
7585	 */
7586	_disableDatepicker: function( target ) {
7587		var nodeName, inline,
7588			$target = $( target ),
7589			inst = $.data( target, "datepicker" );
7590
7591		if ( !$target.hasClass( this.markerClassName ) ) {
7592			return;
7593		}
7594
7595		nodeName = target.nodeName.toLowerCase();
7596		if ( nodeName === "input" ) {
7597			target.disabled = true;
7598			inst.trigger.filter( "button" ).
7599				each( function() {
7600					this.disabled = true;
7601				} ).end().
7602				filter( "img" ).css( { opacity: "0.5", cursor: "default" } );
7603		} else if ( nodeName === "div" || nodeName === "span" ) {
7604			inline = $target.children( "." + this._inlineClass );
7605			inline.children().addClass( "ui-state-disabled" );
7606			inline.find( "select.ui-datepicker-month, select.ui-datepicker-year" ).
7607				prop( "disabled", true );
7608		}
7609		this._disabledInputs = $.map( this._disabledInputs,
7610
7611			// Delete entry
7612			function( value ) {
7613				return ( value === target ? null : value );
7614			} );
7615		this._disabledInputs[ this._disabledInputs.length ] = target;
7616	},
7617
7618	/* Is the first field in a jQuery collection disabled as a datepicker?
7619	 * @param  target	element - the target input field or division or span
7620	 * @return boolean - true if disabled, false if enabled
7621	 */
7622	_isDisabledDatepicker: function( target ) {
7623		if ( !target ) {
7624			return false;
7625		}
7626		for ( var i = 0; i < this._disabledInputs.length; i++ ) {
7627			if ( this._disabledInputs[ i ] === target ) {
7628				return true;
7629			}
7630		}
7631		return false;
7632	},
7633
7634	/* Retrieve the instance data for the target control.
7635	 * @param  target  element - the target input field or division or span
7636	 * @return  object - the associated instance data
7637	 * @throws  error if a jQuery problem getting data
7638	 */
7639	_getInst: function( target ) {
7640		try {
7641			return $.data( target, "datepicker" );
7642		} catch ( 
vendor: 8,426 bytes, lines 7642-7883
7642err ) {
7643			throw "Missing instance data for this datepicker";
7644		}
7645	},
7646
7647	/* Update or retrieve the settings for a date picker attached to an input field or division.
7648	 * @param  target  element - the target input field or division or span
7649	 * @param  name	object - the new settings to update or
7650	 *				string - the name of the setting to change or retrieve,
7651	 *				when retrieving also "all" for all instance settings or
7652	 *				"defaults" for all global defaults
7653	 * @param  value   any - the new value for the setting
7654	 *				(omit if above is an object or to retrieve a value)
7655	 */
7656	_optionDatepicker: function( target, name, value ) {
7657		var settings, date, minDate, maxDate,
7658			inst = this._getInst( target );
7659
7660		if ( arguments.length === 2 && typeof name === "string" ) {
7661			return ( name === "defaults" ? $.extend( {}, $.datepicker._defaults ) :
7662				( inst ? ( name === "all" ? $.extend( {}, inst.settings ) :
7663				this._get( inst, name ) ) : null ) );
7664		}
7665
7666		settings = name || {};
7667		if ( typeof name === "string" ) {
7668			settings = {};
7669			settings[ name ] = value;
7670		}
7671
7672		if ( inst ) {
7673			if ( this._curInst === inst ) {
7674				this._hideDatepicker();
7675			}
7676
7677			date = this._getDateDatepicker( target, true );
7678			minDate = this._getMinMaxDate( inst, "min" );
7679			maxDate = this._getMinMaxDate( inst, "max" );
7680			datepicker_extendRemove( inst.settings, settings );
7681
7682			// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7683			if ( minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined ) {
7684				inst.settings.minDate = this._formatDate( inst, minDate );
7685			}
7686			if ( maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined ) {
7687				inst.settings.maxDate = this._formatDate( inst, maxDate );
7688			}
7689			if ( "disabled" in settings ) {
7690				if ( settings.disabled ) {
7691					this._disableDatepicker( target );
7692				} else {
7693					this._enableDatepicker( target );
7694				}
7695			}
7696			this._attachments( $( target ), inst );
7697			this._autoSize( inst );
7698			this._setDate( inst, date );
7699			this._updateAlternate( inst );
7700			this._updateDatepicker( inst );
7701		}
7702	},
7703
7704	// Change method deprecated
7705	_changeDatepicker: function( target, name, value ) {
7706		this._optionDatepicker( target, name, value );
7707	},
7708
7709	/* Redraw the date picker attached to an input field or division.
7710	 * @param  target  element - the target input field or division or span
7711	 */
7712	_refreshDatepicker: function( target ) {
7713		var inst = this._getInst( target );
7714		if ( inst ) {
7715			this._updateDatepicker( inst );
7716		}
7717	},
7718
7719	/* Set the dates for a jQuery selection.
7720	 * @param  target element - the target input field or division or span
7721	 * @param  date	Date - the new date
7722	 */
7723	_setDateDatepicker: function( target, date ) {
7724		var inst = this._getInst( target );
7725		if ( inst ) {
7726			this._setDate( inst, date );
7727			this._updateDatepicker( inst );
7728			this._updateAlternate( inst );
7729		}
7730	},
7731
7732	/* Get the date(s) for the first entry in a jQuery selection.
7733	 * @param  target element - the target input field or division or span
7734	 * @param  noDefault boolean - true if no default date is to be used
7735	 * @return Date - the current date
7736	 */
7737	_getDateDatepicker: function( target, noDefault ) {
7738		var inst = this._getInst( target );
7739		if ( inst && !inst.inline ) {
7740			this._setDateFromField( inst, noDefault );
7741		}
7742		return ( inst ? this._getDate( inst ) : null );
7743	},
7744
7745	/* Handle keystrokes. */
7746	_doKeyDown: function( event ) {
7747		var onSelect, dateStr, sel,
7748			inst = $.datepicker._getInst( event.target ),
7749			handled = true,
7750			isRTL = inst.dpDiv.is( ".ui-datepicker-rtl" );
7751
7752		inst._keyEvent = true;
7753		if ( $.datepicker._datepickerShowing ) {
7754			switch ( event.keyCode ) {
7755				case 9: $.datepicker._hideDatepicker();
7756						handled = false;
7757						break; // hide on tab out
7758				case 13: sel = $( "td." + $.datepicker._dayOverClass + ":not(." +
7759									$.datepicker._currentClass + ")", inst.dpDiv );
7760						if ( sel[ 0 ] ) {
7761							$.datepicker._selectDay( event.target, inst.selectedMonth, inst.selectedYear, sel[ 0 ] );
7762						}
7763
7764						onSelect = $.datepicker._get( inst, "onSelect" );
7765						if ( onSelect ) {
7766							dateStr = $.datepicker._formatDate( inst );
7767
7768							// Trigger custom callback
7769							onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );
7770						} else {
7771							$.datepicker._hideDatepicker();
7772						}
7773
7774						return false; // don't submit the form
7775				case 27: $.datepicker._hideDatepicker();
7776						break; // hide on escape
7777				case 33: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7778							-$.datepicker._get( inst, "stepBigMonths" ) :
7779							-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7780						break; // previous month/year on page up/+ ctrl
7781				case 34: $.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7782							+$.datepicker._get( inst, "stepBigMonths" ) :
7783							+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7784						break; // next month/year on page down/+ ctrl
7785				case 35: if ( event.ctrlKey || event.metaKey ) {
7786							$.datepicker._clearDate( event.target );
7787						}
7788						handled = event.ctrlKey || event.metaKey;
7789						break; // clear on ctrl or command +end
7790				case 36: if ( event.ctrlKey || event.metaKey ) {
7791							$.datepicker._gotoToday( event.target );
7792						}
7793						handled = event.ctrlKey || event.metaKey;
7794						break; // current on ctrl or command +home
7795				case 37: if ( event.ctrlKey || event.metaKey ) {
7796							$.datepicker._adjustDate( event.target, ( isRTL ? +1 : -1 ), "D" );
7797						}
7798						handled = event.ctrlKey || event.metaKey;
7799
7800						// -1 day on ctrl or command +left
7801						if ( event.originalEvent.altKey ) {
7802							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7803								-$.datepicker._get( inst, "stepBigMonths" ) :
7804								-$.datepicker._get( inst, "stepMonths" ) ), "M" );
7805						}
7806
7807						// next month/year on alt +left on Mac
7808						break;
7809				case 38: if ( event.ctrlKey || event.metaKey ) {
7810							$.datepicker._adjustDate( event.target, -7, "D" );
7811						}
7812						handled = event.ctrlKey || event.metaKey;
7813						break; // -1 week on ctrl or command +up
7814				case 39: if ( event.ctrlKey || event.metaKey ) {
7815							$.datepicker._adjustDate( event.target, ( isRTL ? -1 : +1 ), "D" );
7816						}
7817						handled = event.ctrlKey || event.metaKey;
7818
7819						// +1 day on ctrl or command +right
7820						if ( event.originalEvent.altKey ) {
7821							$.datepicker._adjustDate( event.target, ( event.ctrlKey ?
7822								+$.datepicker._get( inst, "stepBigMonths" ) :
7823								+$.datepicker._get( inst, "stepMonths" ) ), "M" );
7824						}
7825
7826						// next month/year on alt +right
7827						break;
7828				case 40: if ( event.ctrlKey || event.metaKey ) {
7829							$.datepicker._adjustDate( event.target, +7, "D" );
7830						}
7831						handled = event.ctrlKey || event.metaKey;
7832						break; // +1 week on ctrl or command +down
7833				default: handled = false;
7834			}
7835		} else if ( event.keyCode === 36 && event.ctrlKey ) { // display the date picker on ctrl+home
7836			$.datepicker._showDatepicker( this );
7837		} else {
7838			handled = false;
7839		}
7840
7841		if ( handled ) {
7842			event.preventDefault();
7843			event.stopPropagation();
7844		}
7845	},
7846
7847	/* Filter entered characters - based on date format. */
7848	_doKeyPress: function( event ) {
7849		var chars, chr,
7850			inst = $.datepicker._getInst( event.target );
7851
7852		if ( $.datepicker._get( inst, "constrainInput" ) ) {
7853			chars = $.datepicker._possibleChars( $.datepicker._get( inst, "dateFormat" ) );
7854			chr = String.fromCharCode( event.charCode == null ? event.keyCode : event.charCode );
7855			return event.ctrlKey || event.metaKey || ( chr < " " || !chars || chars.indexOf( chr ) > -1 );
7856		}
7857	},
7858
7859	/* Synchronise manual entry and field/alternate field. */
7860	_doKeyUp: function( event ) {
7861		var date,
7862			inst = $.datepicker._getInst( event.target );
7863
7864		if ( inst.input.val() !== inst.lastVal ) {
7865			try {
7866				date = $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
7867					( inst.input ? inst.input.val() : null ),
7868					$.datepicker._getFormatConfig( inst ) );
7869
7870				if ( date ) { // only if valid
7871					$.datepicker._setDateFromField( inst );
7872					$.datepicker._updateAlternate( inst );
7873					$.datepicker._updateDatepicker( inst );
7874				}
7875			} catch ( err ) {
7876			}
7877		}
7878		return true;
7879	},
7880
7881	/* Pop-up the date picker for a given input field.
7882	 * If false returned from beforeShow event handler do not show.
7883	 * @param  input  element - the input field attached to the date picker or
vendor: 14,198 bytes, lines 7884-8293
7884	 *					event - if triggered by focus
7885	 */
7886	_showDatepicker: function( input ) {
7887		input = input.target || input;
7888		if ( input.nodeName.toLowerCase() !== "input" ) { // find from button/image trigger
7889			input = $( "input", input.parentNode )[ 0 ];
7890		}
7891
7892		if ( $.datepicker._isDisabledDatepicker( input ) || $.datepicker._lastInput === input ) { // already here
7893			return;
7894		}
7895
7896		var inst, beforeShow, beforeShowSettings, isFixed,
7897			offset, showAnim, duration;
7898
7899		inst = $.datepicker._getInst( input );
7900		if ( $.datepicker._curInst && $.datepicker._curInst !== inst ) {
7901			$.datepicker._curInst.dpDiv.stop( true, true );
7902			if ( inst && $.datepicker._datepickerShowing ) {
7903				$.datepicker._hideDatepicker( $.datepicker._curInst.input[ 0 ] );
7904			}
7905		}
7906
7907		beforeShow = $.datepicker._get( inst, "beforeShow" );
7908		beforeShowSettings = beforeShow ? beforeShow.apply( input, [ input, inst ] ) : {};
7909		if ( beforeShowSettings === false ) {
7910			return;
7911		}
7912		datepicker_extendRemove( inst.settings, beforeShowSettings );
7913
7914		inst.lastVal = null;
7915		$.datepicker._lastInput = input;
7916		$.datepicker._setDateFromField( inst );
7917
7918		if ( $.datepicker._inDialog ) { // hide cursor
7919			input.value = "";
7920		}
7921		if ( !$.datepicker._pos ) { // position below input
7922			$.datepicker._pos = $.datepicker._findPos( input );
7923			$.datepicker._pos[ 1 ] += input.offsetHeight; // add the height
7924		}
7925
7926		isFixed = false;
7927		$( input ).parents().each( function() {
7928			isFixed |= $( this ).css( "position" ) === "fixed";
7929			return !isFixed;
7930		} );
7931
7932		offset = { left: $.datepicker._pos[ 0 ], top: $.datepicker._pos[ 1 ] };
7933		$.datepicker._pos = null;
7934
7935		//to avoid flashes on Firefox
7936		inst.dpDiv.empty();
7937
7938		// determine sizing offscreen
7939		inst.dpDiv.css( { position: "absolute", display: "block", top: "-1000px" } );
7940		$.datepicker._updateDatepicker( inst );
7941
7942		// fix width for dynamic number of date pickers
7943		// and adjust position before showing
7944		offset = $.datepicker._checkOffset( inst, offset, isFixed );
7945		inst.dpDiv.css( { position: ( $.datepicker._inDialog && $.blockUI ?
7946			"static" : ( isFixed ? "fixed" : "absolute" ) ), display: "none",
7947			left: offset.left + "px", top: offset.top + "px" } );
7948
7949		if ( !inst.inline ) {
7950			showAnim = $.datepicker._get( inst, "showAnim" );
7951			duration = $.datepicker._get( inst, "duration" );
7952			inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
7953			$.datepicker._datepickerShowing = true;
7954
7955			if ( $.effects && $.effects.effect[ showAnim ] ) {
7956				inst.dpDiv.show( showAnim, $.datepicker._get( inst, "showOptions" ), duration );
7957			} else {
7958				inst.dpDiv[ showAnim || "show" ]( showAnim ? duration : null );
7959			}
7960
7961			if ( $.datepicker._shouldFocusInput( inst ) ) {
7962				inst.input.trigger( "focus" );
7963			}
7964
7965			$.datepicker._curInst = inst;
7966		}
7967	},
7968
7969	/* Generate the date picker content. */
7970	_updateDatepicker: function( inst ) {
7971		this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7972		datepicker_instActive = inst; // for delegate hover events
7973		inst.dpDiv.empty().append( this._generateHTML( inst ) );
7974		this._attachHandlers( inst );
7975
7976		var origyearshtml,
7977			numMonths = this._getNumberOfMonths( inst ),
7978			cols = numMonths[ 1 ],
7979			width = 17,
7980			activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" ),
7981			onUpdateDatepicker = $.datepicker._get( inst, "onUpdateDatepicker" );
7982
7983		if ( activeCell.length > 0 ) {
7984			datepicker_handleMouseover.apply( activeCell.get( 0 ) );
7985		}
7986
7987		inst.dpDiv.removeClass( "ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4" ).width( "" );
7988		if ( cols > 1 ) {
7989			inst.dpDiv.addClass( "ui-datepicker-multi-" + cols ).css( "width", ( width * cols ) + "em" );
7990		}
7991		inst.dpDiv[ ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ? "add" : "remove" ) +
7992			"Class" ]( "ui-datepicker-multi" );
7993		inst.dpDiv[ ( this._get( inst, "isRTL" ) ? "add" : "remove" ) +
7994			"Class" ]( "ui-datepicker-rtl" );
7995
7996		if ( inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
7997			inst.input.trigger( "focus" );
7998		}
7999
8000		// Deffered render of the years select (to avoid flashes on Firefox)
8001		if ( inst.yearshtml ) {
8002			origyearshtml = inst.yearshtml;
8003			setTimeout( function() {
8004
8005				//assure that inst.yearshtml didn't change.
8006				if ( origyearshtml === inst.yearshtml && inst.yearshtml ) {
8007					inst.dpDiv.find( "select.ui-datepicker-year" ).first().replaceWith( inst.yearshtml );
8008				}
8009				origyearshtml = inst.yearshtml = null;
8010			}, 0 );
8011		}
8012
8013		if ( onUpdateDatepicker ) {
8014			onUpdateDatepicker.apply( ( inst.input ? inst.input[ 0 ] : null ), [ inst ] );
8015		}
8016	},
8017
8018	_shouldFocusInput: function( inst ) {
8019		return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" );
8020	},
8021
8022	/* Check positioning to remain on screen. */
8023	_checkOffset: function( inst, offset, isFixed ) {
8024		var dpWidth = inst.dpDiv.outerWidth(),
8025			dpHeight = inst.dpDiv.outerHeight(),
8026			inputWidth = inst.input ? inst.input.outerWidth() : 0,
8027			inputHeight = inst.input ? inst.input.outerHeight() : 0,
8028			viewWidth = document.documentElement.clientWidth + ( isFixed ? 0 : $( document ).scrollLeft() ),
8029			viewHeight = document.documentElement.clientHeight + ( isFixed ? 0 : $( document ).scrollTop() );
8030
8031		offset.left -= ( this._get( inst, "isRTL" ) ? ( dpWidth - inputWidth ) : 0 );
8032		offset.left -= ( isFixed && offset.left === inst.input.offset().left ) ? $( document ).scrollLeft() : 0;
8033		offset.top -= ( isFixed && offset.top === ( inst.input.offset().top + inputHeight ) ) ? $( document ).scrollTop() : 0;
8034
8035		// Now check if datepicker is showing outside window viewport - move to a better place if so.
8036		offset.left -= Math.min( offset.left, ( offset.left + dpWidth > viewWidth && viewWidth > dpWidth ) ?
8037			Math.abs( offset.left + dpWidth - viewWidth ) : 0 );
8038		offset.top -= Math.min( offset.top, ( offset.top + dpHeight > viewHeight && viewHeight > dpHeight ) ?
8039			Math.abs( dpHeight + inputHeight ) : 0 );
8040
8041		return offset;
8042	},
8043
8044	/* Find an object's position on the screen. */
8045	_findPos: function( obj ) {
8046		var position,
8047			inst = this._getInst( obj ),
8048			isRTL = this._get( inst, "isRTL" );
8049
8050		while ( obj && ( obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden( obj ) ) ) {
8051			obj = obj[ isRTL ? "previousSibling" : "nextSibling" ];
8052		}
8053
8054		position = $( obj ).offset();
8055		return [ position.left, position.top ];
8056	},
8057
8058	/* Hide the date picker from view.
8059	 * @param  input  element - the input field attached to the date picker
8060	 */
8061	_hideDatepicker: function( input ) {
8062		var showAnim, duration, postProcess, onClose,
8063			inst = this._curInst;
8064
8065		if ( !inst || ( input && inst !== $.data( input, "datepicker" ) ) ) {
8066			return;
8067		}
8068
8069		if ( this._datepickerShowing ) {
8070			showAnim = this._get( inst, "showAnim" );
8071			duration = this._get( inst, "duration" );
8072			postProcess = function() {
8073				$.datepicker._tidyDialog( inst );
8074			};
8075
8076			if ( $.effects && ( $.effects.effect[ showAnim ] ) ) {
8077				inst.dpDiv.hide( showAnim, $.datepicker._get( inst, "showOptions" ), duration, postProcess );
8078			} else {
8079				inst.dpDiv[ ( showAnim === "slideDown" ? "slideUp" :
8080					( showAnim === "fadeIn" ? "fadeOut" : "hide" ) ) ]( ( showAnim ? duration : null ), postProcess );
8081			}
8082
8083			if ( !showAnim ) {
8084				postProcess();
8085			}
8086			this._datepickerShowing = false;
8087
8088			onClose = this._get( inst, "onClose" );
8089			if ( onClose ) {
8090				onClose.apply( ( inst.input ? inst.input[ 0 ] : null ), [ ( inst.input ? inst.input.val() : "" ), inst ] );
8091			}
8092
8093			this._lastInput = null;
8094			if ( this._inDialog ) {
8095				this._dialogInput.css( { position: "absolute", left: "0", top: "-100px" } );
8096				if ( $.blockUI ) {
8097					$.unblockUI();
8098					$( "body" ).append( this.dpDiv );
8099				}
8100			}
8101			this._inDialog = false;
8102		}
8103	},
8104
8105	/* Tidy up after a dialog display. */
8106	_tidyDialog: function( inst ) {
8107		inst.dpDiv.removeClass( this._dialogClass ).off( ".ui-datepicker-calendar" );
8108	},
8109
8110	/* Close date picker if clicked elsewhere. */
8111	_checkExternalClick: function( event ) {
8112		if ( !$.datepicker._curInst ) {
8113			return;
8114		}
8115
8116		var $target = $( event.target ),
8117			inst = $.datepicker._getInst( $target[ 0 ] );
8118
8119		if ( ( ( $target[ 0 ].id !== $.datepicker._mainDivId &&
8120				$target.parents( "#" + $.datepicker._mainDivId ).length === 0 &&
8121				!$target.hasClass( $.datepicker.markerClassName ) &&
8122				!$target.closest( "." + $.datepicker._triggerClass ).length &&
8123				$.datepicker._datepickerShowing && !( $.datepicker._inDialog && $.blockUI ) ) ) ||
8124			( $target.hasClass( $.datepicker.markerClassName ) && $.datepicker._curInst !== inst ) ) {
8125				$.datepicker._hideDatepicker();
8126		}
8127	},
8128
8129	/* Adjust one of the date sub-fields. */
8130	_adjustDate: function( id, offset, period ) {
8131		var target = $( id ),
8132			inst = this._getInst( target[ 0 ] );
8133
8134		if ( this._isDisabledDatepicker( target[ 0 ] ) ) {
8135			return;
8136		}
8137		this._adjustInstDate( inst, offset, period );
8138		this._updateDatepicker( inst );
8139	},
8140
8141	/* Action for current link. */
8142	_gotoToday: function( id ) {
8143		var date,
8144			target = $( id ),
8145			inst = this._getInst( target[ 0 ] );
8146
8147		if ( this._get( inst, "gotoCurrent" ) && inst.currentDay ) {
8148			inst.selectedDay = inst.currentDay;
8149			inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8150			inst.drawYear = inst.selectedYear = inst.currentYear;
8151		} else {
8152			date = new Date();
8153			inst.selectedDay = date.getDate();
8154			inst.drawMonth = inst.selectedMonth = date.getMonth();
8155			inst.drawYear = inst.selectedYear = date.getFullYear();
8156		}
8157		this._notifyChange( inst );
8158		this._adjustDate( target );
8159	},
8160
8161	/* Action for selecting a new month/year. */
8162	_selectMonthYear: function( id, select, period ) {
8163		var target = $( id ),
8164			inst = this._getInst( target[ 0 ] );
8165
8166		inst[ "selected" + ( period === "M" ? "Month" : "Year" ) ] =
8167		inst[ "draw" + ( period === "M" ? "Month" : "Year" ) ] =
8168			parseInt( select.options[ select.selectedIndex ].value, 10 );
8169
8170		this._notifyChange( inst );
8171		this._adjustDate( target );
8172	},
8173
8174	/* Action for selecting a day. */
8175	_selectDay: function( id, month, year, td ) {
8176		var inst,
8177			target = $( id );
8178
8179		if ( $( td ).hasClass( this._unselectableClass ) || this._isDisabledDatepicker( target[ 0 ] ) ) {
8180			return;
8181		}
8182
8183		inst = this._getInst( target[ 0 ] );
8184		inst.selectedDay = inst.currentDay = parseInt( $( "a", td ).attr( "data-date" ) );
8185		inst.selectedMonth = inst.currentMonth = month;
8186		inst.selectedYear = inst.currentYear = year;
8187		this._selectDate( id, this._formatDate( inst,
8188			inst.currentDay, inst.currentMonth, inst.currentYear ) );
8189	},
8190
8191	/* Erase the input field and hide the date picker. */
8192	_clearDate: function( id ) {
8193		var target = $( id );
8194		this._selectDate( target, "" );
8195	},
8196
8197	/* Update the input field with the selected date. */
8198	_selectDate: function( id, dateStr ) {
8199		var onSelect,
8200			target = $( id ),
8201			inst = this._getInst( target[ 0 ] );
8202
8203		dateStr = ( dateStr != null ? dateStr : this._formatDate( inst ) );
8204		if ( inst.input ) {
8205			inst.input.val( dateStr );
8206		}
8207		this._updateAlternate( inst );
8208
8209		onSelect = this._get( inst, "onSelect" );
8210		if ( onSelect ) {
8211			onSelect.apply( ( inst.input ? inst.input[ 0 ] : null ), [ dateStr, inst ] );  // trigger custom callback
8212		} else if ( inst.input ) {
8213			inst.input.trigger( "change" ); // fire the change event
8214		}
8215
8216		if ( inst.inline ) {
8217			this._updateDatepicker( inst );
8218		} else {
8219			this._hideDatepicker();
8220			this._lastInput = inst.input[ 0 ];
8221			if ( typeof( inst.input[ 0 ] ) !== "object" ) {
8222				inst.input.trigger( "focus" ); // restore focus
8223			}
8224			this._lastInput = null;
8225		}
8226	},
8227
8228	/* Update any alternate field to synchronise with the main field. */
8229	_updateAlternate: function( inst ) {
8230		var altFormat, date, dateStr,
8231			altField = this._get( inst, "altField" );
8232
8233		if ( altField ) { // update alternate field too
8234			altFormat = this._get( inst, "altFormat" ) || this._get( inst, "dateFormat" );
8235			date = this._getDate( inst );
8236			dateStr = this.formatDate( altFormat, date, this._getFormatConfig( inst ) );
8237			$( document ).find( altField ).val( dateStr );
8238		}
8239	},
8240
8241	/* Set as beforeShowDay function to prevent selection of weekends.
8242	 * @param  date  Date - the date to customise
8243	 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8244	 */
8245	noWeekends: function( date ) {
8246		var day = date.getDay();
8247		return [ ( day > 0 && day < 6 ), "" ];
8248	},
8249
8250	/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8251	 * @param  date  Date - the date to get the week for
8252	 * @return  number - the number of the week within the year that contains this date
8253	 */
8254	iso8601Week: function( date ) {
8255		var time,
8256			checkDate = new Date( date.getTime() );
8257
8258		// Find Thursday of this week starting on Monday
8259		checkDate.setDate( checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ) );
8260
8261		time = checkDate.getTime();
8262		checkDate.setMonth( 0 ); // Compare with Jan 1
8263		checkDate.setDate( 1 );
8264		return Math.floor( Math.round( ( time - checkDate ) / 86400000 ) / 7 ) + 1;
8265	},
8266
8267	/* Parse a string value into a date object.
8268	 * See formatDate below for the possible formats.
8269	 *
8270	 * @param  format string - the expected format of the date
8271	 * @param  value string - the date in the above format
8272	 * @param  settings Object - attributes include:
8273	 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8274	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8275	 *					dayNames		string[7] - names of the days from Sunday (optional)
8276	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8277	 *					monthNames		string[12] - names of the months (optional)
8278	 * @return  Date - the extracted date value or null if value is blank
8279	 */
8280	parseDate: function( format, value, settings ) {
8281		if ( format == null || value == null ) {
8282			throw "Invalid arguments";
8283		}
8284
8285		value = ( typeof value === "object" ? value.toString() : value + "" );
8286		if ( value === "" ) {
8287			return null;
8288		}
8289
8290		var iFormat, dim, extra,
8291			iValue = 0,
8292			shortYearCutoffTemp = ( settings ? settings.shortYearCutoff : null ) || this._defaults.shortYearCutoff,
8293			shortYearCutoff = ( typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp 
vendor: 5,431 bytes, lines 8293-8483
8293:
8294				new Date().getFullYear() % 100 + parseInt( shortYearCutoffTemp, 10 ) ),
8295			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8296			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8297			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8298			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8299			year = -1,
8300			month = -1,
8301			day = -1,
8302			doy = -1,
8303			literal = false,
8304			date,
8305
8306			// Check whether a format character is doubled
8307			lookAhead = function( match ) {
8308				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8309				if ( matches ) {
8310					iFormat++;
8311				}
8312				return matches;
8313			},
8314
8315			// Extract a number from the string value
8316			getNumber = function( match ) {
8317				var isDoubled = lookAhead( match ),
8318					size = ( match === "@" ? 14 : ( match === "!" ? 20 :
8319					( match === "y" && isDoubled ? 4 : ( match === "o" ? 3 : 2 ) ) ) ),
8320					minSize = ( match === "y" ? size : 1 ),
8321					digits = new RegExp( "^\\d{" + minSize + "," + size + "}" ),
8322					num = value.substring( iValue ).match( digits );
8323				if ( !num ) {
8324					throw "Missing number at position " + iValue;
8325				}
8326				iValue += num[ 0 ].length;
8327				return parseInt( num[ 0 ], 10 );
8328			},
8329
8330			// Extract a name from the string value and convert to an index
8331			getName = function( match, shortNames, longNames ) {
8332				var index = -1,
8333					names = $.map( lookAhead( match ) ? longNames : shortNames, function( v, k ) {
8334						return [ [ k, v ] ];
8335					} ).sort( function( a, b ) {
8336						return -( a[ 1 ].length - b[ 1 ].length );
8337					} );
8338
8339				$.each( names, function( i, pair ) {
8340					var name = pair[ 1 ];
8341					if ( value.substr( iValue, name.length ).toLowerCase() === name.toLowerCase() ) {
8342						index = pair[ 0 ];
8343						iValue += name.length;
8344						return false;
8345					}
8346				} );
8347				if ( index !== -1 ) {
8348					return index + 1;
8349				} else {
8350					throw "Unknown name at position " + iValue;
8351				}
8352			},
8353
8354			// Confirm that a literal character matches the string value
8355			checkLiteral = function() {
8356				if ( value.charAt( iValue ) !== format.charAt( iFormat ) ) {
8357					throw "Unexpected literal at position " + iValue;
8358				}
8359				iValue++;
8360			};
8361
8362		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8363			if ( literal ) {
8364				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8365					literal = false;
8366				} else {
8367					checkLiteral();
8368				}
8369			} else {
8370				switch ( format.charAt( iFormat ) ) {
8371					case "d":
8372						day = getNumber( "d" );
8373						break;
8374					case "D":
8375						getName( "D", dayNamesShort, dayNames );
8376						break;
8377					case "o":
8378						doy = getNumber( "o" );
8379						break;
8380					case "m":
8381						month = getNumber( "m" );
8382						break;
8383					case "M":
8384						month = getName( "M", monthNamesShort, monthNames );
8385						break;
8386					case "y":
8387						year = getNumber( "y" );
8388						break;
8389					case "@":
8390						date = new Date( getNumber( "@" ) );
8391						year = date.getFullYear();
8392						month = date.getMonth() + 1;
8393						day = date.getDate();
8394						break;
8395					case "!":
8396						date = new Date( ( getNumber( "!" ) - this._ticksTo1970 ) / 10000 );
8397						year = date.getFullYear();
8398						month = date.getMonth() + 1;
8399						day = date.getDate();
8400						break;
8401					case "'":
8402						if ( lookAhead( "'" ) ) {
8403							checkLiteral();
8404						} else {
8405							literal = true;
8406						}
8407						break;
8408					default:
8409						checkLiteral();
8410				}
8411			}
8412		}
8413
8414		if ( iValue < value.length ) {
8415			extra = value.substr( iValue );
8416			if ( !/^\s+/.test( extra ) ) {
8417				throw "Extra/unparsed characters found in date: " + extra;
8418			}
8419		}
8420
8421		if ( year === -1 ) {
8422			year = new Date().getFullYear();
8423		} else if ( year < 100 ) {
8424			year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8425				( year <= shortYearCutoff ? 0 : -100 );
8426		}
8427
8428		if ( doy > -1 ) {
8429			month = 1;
8430			day = doy;
8431			do {
8432				dim = this._getDaysInMonth( year, month - 1 );
8433				if ( day <= dim ) {
8434					break;
8435				}
8436				month++;
8437				day -= dim;
8438			} while ( true );
8439		}
8440
8441		date = this._daylightSavingAdjust( new Date( year, month - 1, day ) );
8442		if ( date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day ) {
8443			throw "Invalid date"; // E.g. 31/02/00
8444		}
8445		return date;
8446	},
8447
8448	/* Standard date formats. */
8449	ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8450	COOKIE: "D, dd M yy",
8451	ISO_8601: "yy-mm-dd",
8452	RFC_822: "D, d M y",
8453	RFC_850: "DD, dd-M-y",
8454	RFC_1036: "D, d M y",
8455	RFC_1123: "D, d M yy",
8456	RFC_2822: "D, d M yy",
8457	RSS: "D, d M y", // RFC 822
8458	TICKS: "!",
8459	TIMESTAMP: "@",
8460	W3C: "yy-mm-dd", // ISO 8601
8461
8462	_ticksTo1970: ( ( ( 1970 - 1 ) * 365 + Math.floor( 1970 / 4 ) - Math.floor( 1970 / 100 ) +
8463		Math.floor( 1970 / 400 ) ) * 24 * 60 * 60 * 10000000 ),
8464
8465	/* Format a date object into a string value.
8466	 * The format can be combinations of the following:
8467	 * d  - day of month (no leading zero)
8468	 * dd - day of month (two digit)
8469	 * o  - day of year (no leading zeros)
8470	 * oo - day of year (three digit)
8471	 * D  - day name short
8472	 * DD - day name long
8473	 * m  - month of year (no leading zero)
8474	 * mm - month of year (two digit)
8475	 * M  - month name short
8476	 * MM - month name long
8477	 * y  - year (two digit)
8478	 * yy - year (four digit)
8479	 * @ - Unix timestamp (ms since 01/01/1970)
8480	 * ! - Windows ticks (100ns since 01/01/0001)
8481	 * "..." - literal text
8482	 * '' - single quote
8483	 *
vendor: 6,198 bytes, lines 8484-8683
8484	 * @param  format string - the desired format of the date
8485	 * @param  date Date - the date value to format
8486	 * @param  settings Object - attributes include:
8487	 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8488	 *					dayNames		string[7] - names of the days from Sunday (optional)
8489	 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8490	 *					monthNames		string[12] - names of the months (optional)
8491	 * @return  string - the date in the above format
8492	 */
8493	formatDate: function( format, date, settings ) {
8494		if ( !date ) {
8495			return "";
8496		}
8497
8498		var iFormat,
8499			dayNamesShort = ( settings ? settings.dayNamesShort : null ) || this._defaults.dayNamesShort,
8500			dayNames = ( settings ? settings.dayNames : null ) || this._defaults.dayNames,
8501			monthNamesShort = ( settings ? settings.monthNamesShort : null ) || this._defaults.monthNamesShort,
8502			monthNames = ( settings ? settings.monthNames : null ) || this._defaults.monthNames,
8503
8504			// Check whether a format character is doubled
8505			lookAhead = function( match ) {
8506				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8507				if ( matches ) {
8508					iFormat++;
8509				}
8510				return matches;
8511			},
8512
8513			// Format a number, with leading zero if necessary
8514			formatNumber = function( match, value, len ) {
8515				var num = "" + value;
8516				if ( lookAhead( match ) ) {
8517					while ( num.length < len ) {
8518						num = "0" + num;
8519					}
8520				}
8521				return num;
8522			},
8523
8524			// Format a name, short or long as requested
8525			formatName = function( match, value, shortNames, longNames ) {
8526				return ( lookAhead( match ) ? longNames[ value ] : shortNames[ value ] );
8527			},
8528			output = "",
8529			literal = false;
8530
8531		if ( date ) {
8532			for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8533				if ( literal ) {
8534					if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8535						literal = false;
8536					} else {
8537						output += format.charAt( iFormat );
8538					}
8539				} else {
8540					switch ( format.charAt( iFormat ) ) {
8541						case "d":
8542							output += formatNumber( "d", date.getDate(), 2 );
8543							break;
8544						case "D":
8545							output += formatName( "D", date.getDay(), dayNamesShort, dayNames );
8546							break;
8547						case "o":
8548							output += formatNumber( "o",
8549								Math.round( ( new Date( date.getFullYear(), date.getMonth(), date.getDate() ).getTime() - new Date( date.getFullYear(), 0, 0 ).getTime() ) / 86400000 ), 3 );
8550							break;
8551						case "m":
8552							output += formatNumber( "m", date.getMonth() + 1, 2 );
8553							break;
8554						case "M":
8555							output += formatName( "M", date.getMonth(), monthNamesShort, monthNames );
8556							break;
8557						case "y":
8558							output += ( lookAhead( "y" ) ? date.getFullYear() :
8559								( date.getFullYear() % 100 < 10 ? "0" : "" ) + date.getFullYear() % 100 );
8560							break;
8561						case "@":
8562							output += date.getTime();
8563							break;
8564						case "!":
8565							output += date.getTime() * 10000 + this._ticksTo1970;
8566							break;
8567						case "'":
8568							if ( lookAhead( "'" ) ) {
8569								output += "'";
8570							} else {
8571								literal = true;
8572							}
8573							break;
8574						default:
8575							output += format.charAt( iFormat );
8576					}
8577				}
8578			}
8579		}
8580		return output;
8581	},
8582
8583	/* Extract all possible characters from the date format. */
8584	_possibleChars: function( format ) {
8585		var iFormat,
8586			chars = "",
8587			literal = false,
8588
8589			// Check whether a format character is doubled
8590			lookAhead = function( match ) {
8591				var matches = ( iFormat + 1 < format.length && format.charAt( iFormat + 1 ) === match );
8592				if ( matches ) {
8593					iFormat++;
8594				}
8595				return matches;
8596			};
8597
8598		for ( iFormat = 0; iFormat < format.length; iFormat++ ) {
8599			if ( literal ) {
8600				if ( format.charAt( iFormat ) === "'" && !lookAhead( "'" ) ) {
8601					literal = false;
8602				} else {
8603					chars += format.charAt( iFormat );
8604				}
8605			} else {
8606				switch ( format.charAt( iFormat ) ) {
8607					case "d": case "m": case "y": case "@":
8608						chars += "0123456789";
8609						break;
8610					case "D": case "M":
8611						return null; // Accept anything
8612					case "'":
8613						if ( lookAhead( "'" ) ) {
8614							chars += "'";
8615						} else {
8616							literal = true;
8617						}
8618						break;
8619					default:
8620						chars += format.charAt( iFormat );
8621				}
8622			}
8623		}
8624		return chars;
8625	},
8626
8627	/* Get a setting value, defaulting if necessary. */
8628	_get: function( inst, name ) {
8629		return inst.settings[ name ] !== undefined ?
8630			inst.settings[ name ] : this._defaults[ name ];
8631	},
8632
8633	/* Parse existing date and initialise date picker. */
8634	_setDateFromField: function( inst, noDefault ) {
8635		if ( inst.input.val() === inst.lastVal ) {
8636			return;
8637		}
8638
8639		var dateFormat = this._get( inst, "dateFormat" ),
8640			dates = inst.lastVal = inst.input ? inst.input.val() : null,
8641			defaultDate = this._getDefaultDate( inst ),
8642			date = defaultDate,
8643			settings = this._getFormatConfig( inst );
8644
8645		try {
8646			date = this.parseDate( dateFormat, dates, settings ) || defaultDate;
8647		} catch ( event ) {
8648			dates = ( noDefault ? "" : dates );
8649		}
8650		inst.selectedDay = date.getDate();
8651		inst.drawMonth = inst.selectedMonth = date.getMonth();
8652		inst.drawYear = inst.selectedYear = date.getFullYear();
8653		inst.currentDay = ( dates ? date.getDate() : 0 );
8654		inst.currentMonth = ( dates ? date.getMonth() : 0 );
8655		inst.currentYear = ( dates ? date.getFullYear() : 0 );
8656		this._adjustInstDate( inst );
8657	},
8658
8659	/* Retrieve the default date shown on opening. */
8660	_getDefaultDate: function( inst ) {
8661		return this._restrictMinMax( inst,
8662			this._determineDate( inst, this._get( inst, "defaultDate" ), new Date() ) );
8663	},
8664
8665	/* A date may be specified as an exact value or a relative one. */
8666	_determineDate: function( inst, date, defaultDate ) {
8667		var offsetNumeric = function( offset ) {
8668				var date = new Date();
8669				date.setDate( date.getDate() + offset );
8670				return date;
8671			},
8672			offsetString = function( offset ) {
8673				try {
8674					return $.datepicker.parseDate( $.datepicker._get( inst, "dateFormat" ),
8675						offset, $.datepicker._getFormatConfig( inst ) );
8676				} catch ( e ) {
8677
8678					// Ignore
8679				}
8680
8681				var date = ( offset.toLowerCase().match( /^c/ ) ?
8682					$.datepicker._getDate( inst ) : null ) || new Date(),
8683					year = date.getFullYear(),
vendor: 5,359 bytes, lines 8684-8822
8684					month = date.getMonth(),
8685					day = date.getDate(),
8686					pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8687					matches = pattern.exec( offset );
8688
8689				while ( matches ) {
8690					switch ( matches[ 2 ] || "d" ) {
8691						case "d" : case "D" :
8692							day += parseInt( matches[ 1 ], 10 ); break;
8693						case "w" : case "W" :
8694							day += parseInt( matches[ 1 ], 10 ) * 7; break;
8695						case "m" : case "M" :
8696							month += parseInt( matches[ 1 ], 10 );
8697							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8698							break;
8699						case "y": case "Y" :
8700							year += parseInt( matches[ 1 ], 10 );
8701							day = Math.min( day, $.datepicker._getDaysInMonth( year, month ) );
8702							break;
8703					}
8704					matches = pattern.exec( offset );
8705				}
8706				return new Date( year, month, day );
8707			},
8708			newDate = ( date == null || date === "" ? defaultDate : ( typeof date === "string" ? offsetString( date ) :
8709				( typeof date === "number" ? ( isNaN( date ) ? defaultDate : offsetNumeric( date ) ) : new Date( date.getTime() ) ) ) );
8710
8711		newDate = ( newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate );
8712		if ( newDate ) {
8713			newDate.setHours( 0 );
8714			newDate.setMinutes( 0 );
8715			newDate.setSeconds( 0 );
8716			newDate.setMilliseconds( 0 );
8717		}
8718		return this._daylightSavingAdjust( newDate );
8719	},
8720
8721	/* Handle switch to/from daylight saving.
8722	 * Hours may be non-zero on daylight saving cut-over:
8723	 * > 12 when midnight changeover, but then cannot generate
8724	 * midnight datetime, so jump to 1AM, otherwise reset.
8725	 * @param  date  (Date) the date to check
8726	 * @return  (Date) the corrected date
8727	 */
8728	_daylightSavingAdjust: function( date ) {
8729		if ( !date ) {
8730			return null;
8731		}
8732		date.setHours( date.getHours() > 12 ? date.getHours() + 2 : 0 );
8733		return date;
8734	},
8735
8736	/* Set the date(s) directly. */
8737	_setDate: function( inst, date, noChange ) {
8738		var clear = !date,
8739			origMonth = inst.selectedMonth,
8740			origYear = inst.selectedYear,
8741			newDate = this._restrictMinMax( inst, this._determineDate( inst, date, new Date() ) );
8742
8743		inst.selectedDay = inst.currentDay = newDate.getDate();
8744		inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8745		inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8746		if ( ( origMonth !== inst.selectedMonth || origYear !== inst.selectedYear ) && !noChange ) {
8747			this._notifyChange( inst );
8748		}
8749		this._adjustInstDate( inst );
8750		if ( inst.input ) {
8751			inst.input.val( clear ? "" : this._formatDate( inst ) );
8752		}
8753	},
8754
8755	/* Retrieve the date(s) directly. */
8756	_getDate: function( inst ) {
8757		var startDate = ( !inst.currentYear || ( inst.input && inst.input.val() === "" ) ? null :
8758			this._daylightSavingAdjust( new Date(
8759			inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
8760			return startDate;
8761	},
8762
8763	/* Attach the onxxx handlers.  These are declared statically so
8764	 * they work with static code transformers like Caja.
8765	 */
8766	_attachHandlers: function( inst ) {
8767		var stepMonths = this._get( inst, "stepMonths" ),
8768			id = "#" + inst.id.replace( /\\\\/g, "\\" );
8769		inst.dpDiv.find( "[data-handler]" ).map( function() {
8770			var handler = {
8771				prev: function() {
8772					$.datepicker._adjustDate( id, -stepMonths, "M" );
8773				},
8774				next: function() {
8775					$.datepicker._adjustDate( id, +stepMonths, "M" );
8776				},
8777				hide: function() {
8778					$.datepicker._hideDatepicker();
8779				},
8780				today: function() {
8781					$.datepicker._gotoToday( id );
8782				},
8783				selectDay: function() {
8784					$.datepicker._selectDay( id, +this.getAttribute( "data-month" ), +this.getAttribute( "data-year" ), this );
8785					return false;
8786				},
8787				selectMonth: function() {
8788					$.datepicker._selectMonthYear( id, this, "M" );
8789					return false;
8790				},
8791				selectYear: function() {
8792					$.datepicker._selectMonthYear( id, this, "Y" );
8793					return false;
8794				}
8795			};
8796			$( this ).on( this.getAttribute( "data-event" ), handler[ this.getAttribute( "data-handler" ) ] );
8797		} );
8798	},
8799
8800	/* Generate the HTML for the current state of the date picker. */
8801	_generateHTML: function( inst ) {
8802		var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8803			controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8804			monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8805			selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8806			cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8807			printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8808			tempDate = new Date(),
8809			today = this._daylightSavingAdjust(
8810				new Date( tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate() ) ), // clear time
8811			isRTL = this._get( inst, "isRTL" ),
8812			showButtonPanel = this._get( inst, "showButtonPanel" ),
8813			hideIfNoPrevNext = this._get( inst, "hideIfNoPrevNext" ),
8814			navigationAsDateFormat = this._get( inst, "navigationAsDateFormat" ),
8815			numMonths = this._getNumberOfMonths( inst ),
8816			showCurrentAtPos = this._get( inst, "showCurrentAtPos" ),
8817			stepMonths = this._get( inst, "stepMonths" ),
8818			isMultiMonth = ( numMonths[ 0 ] !== 1 || numMonths[ 1 ] !== 1 ),
8819			currentDate = this._daylightSavingAdjust( ( !inst.currentDay ? new Date( 9999, 9, 9 ) :
8820				new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) ),
8821			minDate = this._getMinMaxDate( inst, "min" ),
8822			maxDate = this._getMinMaxDate( inst, "max" ),
vendor: 21,259 bytes, lines 8823-9337
8823			drawMonth = inst.drawMonth - showCurrentAtPos,
8824			drawYear = inst.drawYear;
8825
8826		if ( drawMonth < 0 ) {
8827			drawMonth += 12;
8828			drawYear--;
8829		}
8830		if ( maxDate ) {
8831			maxDraw = this._daylightSavingAdjust( new Date( maxDate.getFullYear(),
8832				maxDate.getMonth() - ( numMonths[ 0 ] * numMonths[ 1 ] ) + 1, maxDate.getDate() ) );
8833			maxDraw = ( minDate && maxDraw < minDate ? minDate : maxDraw );
8834			while ( this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 ) ) > maxDraw ) {
8835				drawMonth--;
8836				if ( drawMonth < 0 ) {
8837					drawMonth = 11;
8838					drawYear--;
8839				}
8840			}
8841		}
8842		inst.drawMonth = drawMonth;
8843		inst.drawYear = drawYear;
8844
8845		prevText = this._get( inst, "prevText" );
8846		prevText = ( !navigationAsDateFormat ? prevText : this.formatDate( prevText,
8847			this._daylightSavingAdjust( new Date( drawYear, drawMonth - stepMonths, 1 ) ),
8848			this._getFormatConfig( inst ) ) );
8849
8850		if ( this._canAdjustMonth( inst, -1, drawYear, drawMonth ) ) {
8851			prev = $( "<a>" )
8852				.attr( {
8853					"class": "ui-datepicker-prev ui-corner-all",
8854					"data-handler": "prev",
8855					"data-event": "click",
8856					title: prevText
8857				} )
8858				.append(
8859					$( "<span>" )
8860						.addClass( "ui-icon ui-icon-circle-triangle-" +
8861							( isRTL ? "e" : "w" ) )
8862						.text( prevText )
8863				)[ 0 ].outerHTML;
8864		} else if ( hideIfNoPrevNext ) {
8865			prev = "";
8866		} else {
8867			prev = $( "<a>" )
8868				.attr( {
8869					"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
8870					title: prevText
8871				} )
8872				.append(
8873					$( "<span>" )
8874						.addClass( "ui-icon ui-icon-circle-triangle-" +
8875							( isRTL ? "e" : "w" ) )
8876						.text( prevText )
8877				)[ 0 ].outerHTML;
8878		}
8879
8880		nextText = this._get( inst, "nextText" );
8881		nextText = ( !navigationAsDateFormat ? nextText : this.formatDate( nextText,
8882			this._daylightSavingAdjust( new Date( drawYear, drawMonth + stepMonths, 1 ) ),
8883			this._getFormatConfig( inst ) ) );
8884
8885		if ( this._canAdjustMonth( inst, +1, drawYear, drawMonth ) ) {
8886			next = $( "<a>" )
8887				.attr( {
8888					"class": "ui-datepicker-next ui-corner-all",
8889					"data-handler": "next",
8890					"data-event": "click",
8891					title: nextText
8892				} )
8893				.append(
8894					$( "<span>" )
8895						.addClass( "ui-icon ui-icon-circle-triangle-" +
8896							( isRTL ? "w" : "e" ) )
8897						.text( nextText )
8898				)[ 0 ].outerHTML;
8899		} else if ( hideIfNoPrevNext ) {
8900			next = "";
8901		} else {
8902			next = $( "<a>" )
8903				.attr( {
8904					"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
8905					title: nextText
8906				} )
8907				.append(
8908					$( "<span>" )
8909						.attr( "class", "ui-icon ui-icon-circle-triangle-" +
8910							( isRTL ? "w" : "e" ) )
8911						.text( nextText )
8912				)[ 0 ].outerHTML;
8913		}
8914
8915		currentText = this._get( inst, "currentText" );
8916		gotoDate = ( this._get( inst, "gotoCurrent" ) && inst.currentDay ? currentDate : today );
8917		currentText = ( !navigationAsDateFormat ? currentText :
8918			this.formatDate( currentText, gotoDate, this._getFormatConfig( inst ) ) );
8919
8920		controls = "";
8921		if ( !inst.inline ) {
8922			controls = $( "<button>" )
8923				.attr( {
8924					type: "button",
8925					"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
8926					"data-handler": "hide",
8927					"data-event": "click"
8928				} )
8929				.text( this._get( inst, "closeText" ) )[ 0 ].outerHTML;
8930		}
8931
8932		buttonPanel = "";
8933		if ( showButtonPanel ) {
8934			buttonPanel = $( "<div class='ui-datepicker-buttonpane ui-widget-content'>" )
8935				.append( isRTL ? controls : "" )
8936				.append( this._isInRange( inst, gotoDate ) ?
8937					$( "<button>" )
8938						.attr( {
8939							type: "button",
8940							"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
8941							"data-handler": "today",
8942							"data-event": "click"
8943						} )
8944						.text( currentText ) :
8945					"" )
8946				.append( isRTL ? "" : controls )[ 0 ].outerHTML;
8947		}
8948
8949		firstDay = parseInt( this._get( inst, "firstDay" ), 10 );
8950		firstDay = ( isNaN( firstDay ) ? 0 : firstDay );
8951
8952		showWeek = this._get( inst, "showWeek" );
8953		dayNames = this._get( inst, "dayNames" );
8954		dayNamesMin = this._get( inst, "dayNamesMin" );
8955		monthNames = this._get( inst, "monthNames" );
8956		monthNamesShort = this._get( inst, "monthNamesShort" );
8957		beforeShowDay = this._get( inst, "beforeShowDay" );
8958		showOtherMonths = this._get( inst, "showOtherMonths" );
8959		selectOtherMonths = this._get( inst, "selectOtherMonths" );
8960		defaultDate = this._getDefaultDate( inst );
8961		html = "";
8962
8963		for ( row = 0; row < numMonths[ 0 ]; row++ ) {
8964			group = "";
8965			this.maxRows = 4;
8966			for ( col = 0; col < numMonths[ 1 ]; col++ ) {
8967				selectedDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, inst.selectedDay ) );
8968				cornerClass = " ui-corner-all";
8969				calender = "";
8970				if ( isMultiMonth ) {
8971					calender += "<div class='ui-datepicker-group";
8972					if ( numMonths[ 1 ] > 1 ) {
8973						switch ( col ) {
8974							case 0: calender += " ui-datepicker-group-first";
8975								cornerClass = " ui-corner-" + ( isRTL ? "right" : "left" ); break;
8976							case numMonths[ 1 ] - 1: calender += " ui-datepicker-group-last";
8977								cornerClass = " ui-corner-" + ( isRTL ? "left" : "right" ); break;
8978							default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8979						}
8980					}
8981					calender += "'>";
8982				}
8983				calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8984					( /all|left/.test( cornerClass ) && row === 0 ? ( isRTL ? next : prev ) : "" ) +
8985					( /all|right/.test( cornerClass ) && row === 0 ? ( isRTL ? prev : next ) : "" ) +
8986					this._generateMonthYearHeader( inst, drawMonth, drawYear, minDate, maxDate,
8987					row > 0 || col > 0, monthNames, monthNamesShort ) + // draw month headers
8988					"</div><table class='ui-datepicker-calendar'><thead>" +
8989					"<tr>";
8990				thead = ( showWeek ? "<th class='ui-datepicker-week-col'>" + this._get( inst, "weekHeader" ) + "</th>" : "" );
8991				for ( dow = 0; dow < 7; dow++ ) { // days of the week
8992					day = ( dow + firstDay ) % 7;
8993					thead += "<th scope='col'" + ( ( dow + firstDay + 6 ) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "" ) + ">" +
8994						"<span title='" + dayNames[ day ] + "'>" + dayNamesMin[ day ] + "</span></th>";
8995				}
8996				calender += thead + "</tr></thead><tbody>";
8997				daysInMonth = this._getDaysInMonth( drawYear, drawMonth );
8998				if ( drawYear === inst.selectedYear && drawMonth === inst.selectedMonth ) {
8999					inst.selectedDay = Math.min( inst.selectedDay, daysInMonth );
9000				}
9001				leadDays = ( this._getFirstDayOfMonth( drawYear, drawMonth ) - firstDay + 7 ) % 7;
9002				curRows = Math.ceil( ( leadDays + daysInMonth ) / 7 ); // calculate the number of rows to generate
9003				numRows = ( isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows ); //If multiple months, use the higher number of rows (see #7043)
9004				this.maxRows = numRows;
9005				printDate = this._daylightSavingAdjust( new Date( drawYear, drawMonth, 1 - leadDays ) );
9006				for ( dRow = 0; dRow < numRows; dRow++ ) { // create date picker rows
9007					calender += "<tr>";
9008					tbody = ( !showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9009						this._get( inst, "calculateWeek" )( printDate ) + "</td>" );
9010					for ( dow = 0; dow < 7; dow++ ) { // create date picker days
9011						daySettings = ( beforeShowDay ?
9012							beforeShowDay.apply( ( inst.input ? inst.input[ 0 ] : null ), [ printDate ] ) : [ true, "" ] );
9013						otherMonth = ( printDate.getMonth() !== drawMonth );
9014						unselectable = ( otherMonth && !selectOtherMonths ) || !daySettings[ 0 ] ||
9015							( minDate && printDate < minDate ) || ( maxDate && printDate > maxDate );
9016						tbody += "<td class='" +
9017							( ( dow + firstDay + 6 ) % 7 >= 5 ? " ui-datepicker-week-end" : "" ) + // highlight weekends
9018							( otherMonth ? " ui-datepicker-other-month" : "" ) + // highlight days from other months
9019							( ( printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent ) || // user pressed key
9020							( defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime() ) ?
9021
9022							// or defaultDate is current printedDate and defaultDate is selectedDate
9023							" " + this._dayOverClass : "" ) + // highlight selected day
9024							( unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "" ) +  // highlight unselectable days
9025							( otherMonth && !showOtherMonths ? "" : " " + daySettings[ 1 ] + // highlight custom dates
9026							( printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "" ) + // highlight selected day
9027							( printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "" ) ) + "'" + // highlight today (if different)
9028							( ( !otherMonth || showOtherMonths ) && daySettings[ 2 ] ? " title='" + daySettings[ 2 ].replace( /'/g, "&#39;" ) + "'" : "" ) + // cell title
9029							( unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'" ) + ">" + // actions
9030							( otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9031							( unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9032							( printDate.getTime() === today.getTime() ? " ui-state-highlight" : "" ) +
9033							( printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "" ) + // highlight selected day
9034							( otherMonth ? " ui-priority-secondary" : "" ) + // distinguish dates from other months
9035							"' href='#' aria-current='" + ( printDate.getTime() === currentDate.getTime() ? "true" : "false" ) + // mark date as selected for screen reader
9036							"' data-date='" + printDate.getDate() + // store date as data
9037							"'>" + printDate.getDate() + "</a>" ) ) + "</td>"; // display selectable date
9038						printDate.setDate( printDate.getDate() + 1 );
9039						printDate = this._daylightSavingAdjust( printDate );
9040					}
9041					calender += tbody + "</tr>";
9042				}
9043				drawMonth++;
9044				if ( drawMonth > 11 ) {
9045					drawMonth = 0;
9046					drawYear++;
9047				}
9048				calender += "</tbody></table>" + ( isMultiMonth ? "</div>" +
9049							( ( numMonths[ 0 ] > 0 && col === numMonths[ 1 ] - 1 ) ? "<div class='ui-datepicker-row-break'></div>" : "" ) : "" );
9050				group += calender;
9051			}
9052			html += group;
9053		}
9054		html += buttonPanel;
9055		inst._keyEvent = false;
9056		return html;
9057	},
9058
9059	/* Generate the month and year header. */
9060	_generateMonthYearHeader: function( inst, drawMonth, drawYear, minDate, maxDate,
9061			secondary, monthNames, monthNamesShort ) {
9062
9063		var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9064			changeMonth = this._get( inst, "changeMonth" ),
9065			changeYear = this._get( inst, "changeYear" ),
9066			showMonthAfterYear = this._get( inst, "showMonthAfterYear" ),
9067			selectMonthLabel = this._get( inst, "selectMonthLabel" ),
9068			selectYearLabel = this._get( inst, "selectYearLabel" ),
9069			html = "<div class='ui-datepicker-title'>",
9070			monthHtml = "";
9071
9072		// Month selection
9073		if ( secondary || !changeMonth ) {
9074			monthHtml += "<span class='ui-datepicker-month'>" + monthNames[ drawMonth ] + "</span>";
9075		} else {
9076			inMinYear = ( minDate && minDate.getFullYear() === drawYear );
9077			inMaxYear = ( maxDate && maxDate.getFullYear() === drawYear );
9078			monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
9079			for ( month = 0; month < 12; month++ ) {
9080				if ( ( !inMinYear || month >= minDate.getMonth() ) && ( !inMaxYear || month <= maxDate.getMonth() ) ) {
9081					monthHtml += "<option value='" + month + "'" +
9082						( month === drawMonth ? " selected='selected'" : "" ) +
9083						">" + monthNamesShort[ month ] + "</option>";
9084				}
9085			}
9086			monthHtml += "</select>";
9087		}
9088
9089		if ( !showMonthAfterYear ) {
9090			html += monthHtml + ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" );
9091		}
9092
9093		// Year selection
9094		if ( !inst.yearshtml ) {
9095			inst.yearshtml = "";
9096			if ( secondary || !changeYear ) {
9097				html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9098			} else {
9099
9100				// determine range of years to display
9101				years = this._get( inst, "yearRange" ).split( ":" );
9102				thisYear = new Date().getFullYear();
9103				determineYear = function( value ) {
9104					var year = ( value.match( /c[+\-].*/ ) ? drawYear + parseInt( value.substring( 1 ), 10 ) :
9105						( value.match( /[+\-].*/ ) ? thisYear + parseInt( value, 10 ) :
9106						parseInt( value, 10 ) ) );
9107					return ( isNaN( year ) ? thisYear : year );
9108				};
9109				year = determineYear( years[ 0 ] );
9110				endYear = Math.max( year, determineYear( years[ 1 ] || "" ) );
9111				year = ( minDate ? Math.max( year, minDate.getFullYear() ) : year );
9112				endYear = ( maxDate ? Math.min( endYear, maxDate.getFullYear() ) : endYear );
9113				inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
9114				for ( ; year <= endYear; year++ ) {
9115					inst.yearshtml += "<option value='" + year + "'" +
9116						( year === drawYear ? " selected='selected'" : "" ) +
9117						">" + year + "</option>";
9118				}
9119				inst.yearshtml += "</select>";
9120
9121				html += inst.yearshtml;
9122				inst.yearshtml = null;
9123			}
9124		}
9125
9126		html += this._get( inst, "yearSuffix" );
9127		if ( showMonthAfterYear ) {
9128			html += ( secondary || !( changeMonth && changeYear ) ? "&#xa0;" : "" ) + monthHtml;
9129		}
9130		html += "</div>"; // Close datepicker_header
9131		return html;
9132	},
9133
9134	/* Adjust one of the date sub-fields. */
9135	_adjustInstDate: function( inst, offset, period ) {
9136		var year = inst.selectedYear + ( period === "Y" ? offset : 0 ),
9137			month = inst.selectedMonth + ( period === "M" ? offset : 0 ),
9138			day = Math.min( inst.selectedDay, this._getDaysInMonth( year, month ) ) + ( period === "D" ? offset : 0 ),
9139			date = this._restrictMinMax( inst, this._daylightSavingAdjust( new Date( year, month, day ) ) );
9140
9141		inst.selectedDay = date.getDate();
9142		inst.drawMonth = inst.selectedMonth = date.getMonth();
9143		inst.drawYear = inst.selectedYear = date.getFullYear();
9144		if ( period === "M" || period === "Y" ) {
9145			this._notifyChange( inst );
9146		}
9147	},
9148
9149	/* Ensure a date is within any min/max bounds. */
9150	_restrictMinMax: function( inst, date ) {
9151		var minDate = this._getMinMaxDate( inst, "min" ),
9152			maxDate = this._getMinMaxDate( inst, "max" ),
9153			newDate = ( minDate && date < minDate ? minDate : date );
9154		return ( maxDate && newDate > maxDate ? maxDate : newDate );
9155	},
9156
9157	/* Notify change of month/year. */
9158	_notifyChange: function( inst ) {
9159		var onChange = this._get( inst, "onChangeMonthYear" );
9160		if ( onChange ) {
9161			onChange.apply( ( inst.input ? inst.input[ 0 ] : null ),
9162				[ inst.selectedYear, inst.selectedMonth + 1, inst ] );
9163		}
9164	},
9165
9166	/* Determine the number of months to show. */
9167	_getNumberOfMonths: function( inst ) {
9168		var numMonths = this._get( inst, "numberOfMonths" );
9169		return ( numMonths == null ? [ 1, 1 ] : ( typeof numMonths === "number" ? [ 1, numMonths ] : numMonths ) );
9170	},
9171
9172	/* Determine the current maximum date - ensure no time components are set. */
9173	_getMinMaxDate: function( inst, minMax ) {
9174		return this._determineDate( inst, this._get( inst, minMax + "Date" ), null );
9175	},
9176
9177	/* Find the number of days in a given month. */
9178	_getDaysInMonth: function( year, month ) {
9179		return 32 - this._daylightSavingAdjust( new Date( year, month, 32 ) ).getDate();
9180	},
9181
9182	/* Find the day of the week of the first of a month. */
9183	_getFirstDayOfMonth: function( year, month ) {
9184		return new Date( year, month, 1 ).getDay();
9185	},
9186
9187	/* Determines if we should allow a "next/prev" month display change. */
9188	_canAdjustMonth: function( inst, offset, curYear, curMonth ) {
9189		var numMonths = this._getNumberOfMonths( inst ),
9190			date = this._daylightSavingAdjust( new Date( curYear,
9191			curMonth + ( offset < 0 ? offset : numMonths[ 0 ] * numMonths[ 1 ] ), 1 ) );
9192
9193		if ( offset < 0 ) {
9194			date.setDate( this._getDaysInMonth( date.getFullYear(), date.getMonth() ) );
9195		}
9196		return this._isInRange( inst, date );
9197	},
9198
9199	/* Is the given date in the accepted range? */
9200	_isInRange: function( inst, date ) {
9201		var yearSplit, currentYear,
9202			minDate = this._getMinMaxDate( inst, "min" ),
9203			maxDate = this._getMinMaxDate( inst, "max" ),
9204			minYear = null,
9205			maxYear = null,
9206			years = this._get( inst, "yearRange" );
9207			if ( years ) {
9208				yearSplit = years.split( ":" );
9209				currentYear = new Date().getFullYear();
9210				minYear = parseInt( yearSplit[ 0 ], 10 );
9211				maxYear = parseInt( yearSplit[ 1 ], 10 );
9212				if ( yearSplit[ 0 ].match( /[+\-].*/ ) ) {
9213					minYear += currentYear;
9214				}
9215				if ( yearSplit[ 1 ].match( /[+\-].*/ ) ) {
9216					maxYear += currentYear;
9217				}
9218			}
9219
9220		return ( ( !minDate || date.getTime() >= minDate.getTime() ) &&
9221			( !maxDate || date.getTime() <= maxDate.getTime() ) &&
9222			( !minYear || date.getFullYear() >= minYear ) &&
9223			( !maxYear || date.getFullYear() <= maxYear ) );
9224	},
9225
9226	/* Provide the configuration settings for formatting/parsing. */
9227	_getFormatConfig: function( inst ) {
9228		var shortYearCutoff = this._get( inst, "shortYearCutoff" );
9229		shortYearCutoff = ( typeof shortYearCutoff !== "string" ? shortYearCutoff :
9230			new Date().getFullYear() % 100 + parseInt( shortYearCutoff, 10 ) );
9231		return { shortYearCutoff: shortYearCutoff,
9232			dayNamesShort: this._get( inst, "dayNamesShort" ), dayNames: this._get( inst, "dayNames" ),
9233			monthNamesShort: this._get( inst, "monthNamesShort" ), monthNames: this._get( inst, "monthNames" ) };
9234	},
9235
9236	/* Format the given date for display. */
9237	_formatDate: function( inst, day, month, year ) {
9238		if ( !day ) {
9239			inst.currentDay = inst.selectedDay;
9240			inst.currentMonth = inst.selectedMonth;
9241			inst.currentYear = inst.selectedYear;
9242		}
9243		var date = ( day ? ( typeof day === "object" ? day :
9244			this._daylightSavingAdjust( new Date( year, month, day ) ) ) :
9245			this._daylightSavingAdjust( new Date( inst.currentYear, inst.currentMonth, inst.currentDay ) ) );
9246		return this.formatDate( this._get( inst, "dateFormat" ), date, this._getFormatConfig( inst ) );
9247	}
9248} );
9249
9250/*
9251 * Bind hover events for datepicker elements.
9252 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9253 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9254 */
9255function datepicker_bindHover( dpDiv ) {
9256	var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9257	return dpDiv.on( "mouseout", selector, function() {
9258			$( this ).removeClass( "ui-state-hover" );
9259			if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9260				$( this ).removeClass( "ui-datepicker-prev-hover" );
9261			}
9262			if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9263				$( this ).removeClass( "ui-datepicker-next-hover" );
9264			}
9265		} )
9266		.on( "mouseover", selector, datepicker_handleMouseover );
9267}
9268
9269function datepicker_handleMouseover() {
9270	if ( !$.datepicker._isDisabledDatepicker( datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[ 0 ] : datepicker_instActive.input[ 0 ] ) ) {
9271		$( this ).parents( ".ui-datepicker-calendar" ).find( "a" ).removeClass( "ui-state-hover" );
9272		$( this ).addClass( "ui-state-hover" );
9273		if ( this.className.indexOf( "ui-datepicker-prev" ) !== -1 ) {
9274			$( this ).addClass( "ui-datepicker-prev-hover" );
9275		}
9276		if ( this.className.indexOf( "ui-datepicker-next" ) !== -1 ) {
9277			$( this ).addClass( "ui-datepicker-next-hover" );
9278		}
9279	}
9280}
9281
9282/* jQuery extend now ignores nulls! */
9283function datepicker_extendRemove( target, props ) {
9284	$.extend( target, props );
9285	for ( var name in props ) {
9286		if ( props[ name ] == null ) {
9287			target[ name ] = props[ name ];
9288		}
9289	}
9290	return target;
9291}
9292
9293/* Invoke the datepicker functionality.
9294   @param  options  string - a command, optionally followed by additional parameters or
9295					Object - settings for attaching new datepicker functionality
9296   @return  jQuery object */
9297$.fn.datepicker = function( options ) {
9298
9299	/* Verify an empty collection wasn't passed - Fixes #6976 */
9300	if ( !this.length ) {
9301		return this;
9302	}
9303
9304	/* Initialise the date picker. */
9305	if ( !$.datepicker.initialized ) {
9306		$( document ).on( "mousedown", $.datepicker._checkExternalClick );
9307		$.datepicker.initialized = true;
9308	}
9309
9310	/* Append datepicker main container to body if not exist. */
9311	if ( $( "#" + $.datepicker._mainDivId ).length === 0 ) {
9312		$( "body" ).append( $.datepicker.dpDiv );
9313	}
9314
9315	var otherArgs = Array.prototype.slice.call( arguments, 1 );
9316	if ( typeof options === "string" && ( options === "isDisabled" || options === "getDate" || options === "widget" ) ) {
9317		return $.datepicker[ "_" + options + "Datepicker" ].
9318			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9319	}
9320	if ( options === "option" && arguments.length === 2 && typeof arguments[ 1 ] === "string" ) {
9321		return $.datepicker[ "_" + options + "Datepicker" ].
9322			apply( $.datepicker, [ this[ 0 ] ].concat( otherArgs ) );
9323	}
9324	return this.each( function() {
9325		if ( typeof options === "string" ) {
9326			$.datepicker[ "_" + options + "Datepicker" ]
9327				.apply( $.datepicker, [ this ].concat( otherArgs ) );
9328		} else {
9329			$.datepicker._attachDatepicker( this, options );
9330		}
9331	} );
9332};
9333
9334$.datepicker = new Datepicker(); // singleton instance
9335$.datepicker.initialized = false;
9336$.datepicker.uuid = new Date().getTime();
9337$.datepicker.version = "1.14.
vendor: 6,617 bytes, lines 9337-9598
93371";
9338
9339var widgetsDatepicker = $.datepicker;
9340
9341
9342/*!
9343 * jQuery UI Mouse 1.14.1
9344 * https://jqueryui.com
9345 *
9346 * Copyright OpenJS Foundation and other contributors
9347 * Released under the MIT license.
9348 * https://jquery.org/license
9349 */
9350
9351//>>label: Mouse
9352//>>group: Widgets
9353//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9354//>>docs: https://api.jqueryui.com/mouse/
9355
9356
9357var mouseHandled = false;
9358$( document ).on( "mouseup", function() {
9359	mouseHandled = false;
9360} );
9361
9362var widgetsMouse = $.widget( "ui.mouse", {
9363	version: "1.14.1",
9364	options: {
9365		cancel: "input, textarea, button, select, option",
9366		distance: 1,
9367		delay: 0
9368	},
9369	_mouseInit: function() {
9370		var that = this;
9371
9372		this.element
9373			.on( "mousedown." + this.widgetName, function( event ) {
9374				return that._mouseDown( event );
9375			} )
9376			.on( "click." + this.widgetName, function( event ) {
9377				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
9378					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
9379					event.stopImmediatePropagation();
9380					return false;
9381				}
9382			} );
9383
9384		this.started = false;
9385	},
9386
9387	// TODO: make sure destroying one instance of mouse doesn't mess with
9388	// other instances of mouse
9389	_mouseDestroy: function() {
9390		this.element.off( "." + this.widgetName );
9391		if ( this._mouseMoveDelegate ) {
9392			this.document
9393				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9394				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9395		}
9396	},
9397
9398	_mouseDown: function( event ) {
9399
9400		// don't let more than one widget handle mouseStart
9401		if ( mouseHandled ) {
9402			return;
9403		}
9404
9405		this._mouseMoved = false;
9406
9407		// We may have missed mouseup (out of window)
9408		if ( this._mouseStarted ) {
9409			this._mouseUp( event );
9410		}
9411
9412		this._mouseDownEvent = event;
9413
9414		var that = this,
9415			btnIsLeft = event.which === 1,
9416			elIsCancel = typeof this.options.cancel === "string" ?
9417				$( event.target ).closest( this.options.cancel ).length :
9418				false;
9419		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
9420			return true;
9421		}
9422
9423		this.mouseDelayMet = !this.options.delay;
9424		if ( !this.mouseDelayMet ) {
9425			this._mouseDelayTimer = setTimeout( function() {
9426				that.mouseDelayMet = true;
9427			}, this.options.delay );
9428		}
9429
9430		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9431			this._mouseStarted = ( this._mouseStart( event ) !== false );
9432			if ( !this._mouseStarted ) {
9433				event.preventDefault();
9434				return true;
9435			}
9436		}
9437
9438		// Click event may never have fired (Gecko & Opera)
9439		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
9440			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
9441		}
9442
9443		// These delegates are required to keep context
9444		this._mouseMoveDelegate = function( event ) {
9445			return that._mouseMove( event );
9446		};
9447		this._mouseUpDelegate = function( event ) {
9448			return that._mouseUp( event );
9449		};
9450
9451		this.document
9452			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9453			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
9454
9455		event.preventDefault();
9456
9457		mouseHandled = true;
9458		return true;
9459	},
9460
9461	_mouseMove: function( event ) {
9462
9463		// Only check for mouseups outside the document if you've moved inside the document
9464		// at least once.
9465		if ( this._mouseMoved && !event.which ) {
9466
9467			// Support: Safari <=8 - 9
9468			// Safari sets which to 0 if you press any of the following keys
9469			// during a drag (#14461)
9470			if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9471					event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
9472				this.ignoreMissingWhich = true;
9473			} else if ( !this.ignoreMissingWhich ) {
9474				return this._mouseUp( event );
9475			}
9476		}
9477
9478		if ( event.which || event.button ) {
9479			this._mouseMoved = true;
9480		}
9481
9482		if ( this._mouseStarted ) {
9483			this._mouseDrag( event );
9484			return event.preventDefault();
9485		}
9486
9487		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
9488			this._mouseStarted =
9489				( this._mouseStart( this._mouseDownEvent, event ) !== false );
9490			if ( this._mouseStarted ) {
9491				this._mouseDrag( event );
9492			} else {
9493				this._mouseUp( event );
9494			}
9495		}
9496
9497		return !this._mouseStarted;
9498	},
9499
9500	_mouseUp: function( event ) {
9501		this.document
9502			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
9503			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
9504
9505		if ( this._mouseStarted ) {
9506			this._mouseStarted = false;
9507
9508			if ( event.target === this._mouseDownEvent.target ) {
9509				$.data( event.target, this.widgetName + ".preventClickEvent", true );
9510			}
9511
9512			this._mouseStop( event );
9513		}
9514
9515		if ( this._mouseDelayTimer ) {
9516			clearTimeout( this._mouseDelayTimer );
9517			delete this._mouseDelayTimer;
9518		}
9519
9520		this.ignoreMissingWhich = false;
9521		mouseHandled = false;
9522		event.preventDefault();
9523	},
9524
9525	_mouseDistanceMet: function( event ) {
9526		return ( Math.max(
9527				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
9528				Math.abs( this._mouseDownEvent.pageY - event.pageY )
9529			) >= this.options.distance
9530		);
9531	},
9532
9533	_mouseDelayMet: function( /* event */ ) {
9534		return this.mouseDelayMet;
9535	},
9536
9537	// These are placeholder methods, to be overriden by extending plugin
9538	_mouseStart: function( /* event */ ) {},
9539	_mouseDrag: function( /* event */ ) {},
9540	_mouseStop: function( /* event */ ) {},
9541	_mouseCapture: function( /* event */ ) {
9542		return true;
9543	}
9544} );
9545
9546
9547
9548// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9549var plugin = $.ui.plugin = {
9550	add: function( module, option, set ) {
9551		var i,
9552			proto = $.ui[ module ].prototype;
9553		for ( i in set ) {
9554			proto.plugins[ i ] = proto.plugins[ i ] || [];
9555			proto.plugins[ i ].push( [ option, set[ i ] ] );
9556		}
9557	},
9558	call: function( instance, name, args, allowDisconnected ) {
9559		var i,
9560			set = instance.plugins[ name ];
9561
9562		if ( !set ) {
9563			return;
9564		}
9565
9566		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
9567				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
9568			return;
9569		}
9570
9571		for ( i = 0; i < set.length; i++ ) {
9572			if ( instance.options[ set[ i ][ 0 ] ] ) {
9573				set[ i ][ 1 ].apply( instance.element, args );
9574			}
9575		}
9576	}
9577};
9578
9579
9580/*!
9581 * jQuery UI Draggable 1.14.1
9582 * https://jqueryui.com
9583 *
9584 * Copyright OpenJS Foundation and other contributors
9585 * Released under the MIT license.
9586 * https://jquery.org/license
9587 */
9588
9589//>>label: Draggable
9590//>>group: Interactions
9591//>>description: Enables dragging functionality for any element.
9592//>>docs: https://api.jqueryui.com/draggable/
9593//>>demos: https://jqueryui.com/draggable/
9594//>>css.structure: ../../themes/base/draggable.css
9595
9596
9597$.widget( "ui.draggable", $.ui.mouse, {
9598	version: "1.14.1
vendor: 34,674 bytes, lines 9598-10816
9598",
9599	widgetEventPrefix: "drag",
9600	options: {
9601		addClasses: true,
9602		appendTo: "parent",
9603		axis: false,
9604		connectToSortable: false,
9605		containment: false,
9606		cursor: "auto",
9607		cursorAt: false,
9608		grid: false,
9609		handle: false,
9610		helper: "original",
9611		iframeFix: false,
9612		opacity: false,
9613		refreshPositions: false,
9614		revert: false,
9615		revertDuration: 500,
9616		scope: "default",
9617		scroll: true,
9618		scrollSensitivity: 20,
9619		scrollSpeed: 20,
9620		snap: false,
9621		snapMode: "both",
9622		snapTolerance: 20,
9623		stack: false,
9624		zIndex: false,
9625
9626		// Callbacks
9627		drag: null,
9628		start: null,
9629		stop: null
9630	},
9631	_create: function() {
9632
9633		if ( this.options.helper === "original" ) {
9634			this._setPositionRelative();
9635		}
9636		if ( this.options.addClasses ) {
9637			this._addClass( "ui-draggable" );
9638		}
9639		this._setHandleClassName();
9640
9641		this._mouseInit();
9642	},
9643
9644	_setOption: function( key, value ) {
9645		this._super( key, value );
9646		if ( key === "handle" ) {
9647			this._removeHandleClassName();
9648			this._setHandleClassName();
9649		}
9650	},
9651
9652	_destroy: function() {
9653		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
9654			this.destroyOnClear = true;
9655			return;
9656		}
9657		this._removeHandleClassName();
9658		this._mouseDestroy();
9659	},
9660
9661	_mouseCapture: function( event ) {
9662		var o = this.options;
9663
9664		// Among others, prevent a drag on a resizable-handle
9665		if ( this.helper || o.disabled ||
9666				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
9667			return false;
9668		}
9669
9670		//Quit if we're not on a valid handle
9671		this.handle = this._getHandle( event );
9672		if ( !this.handle ) {
9673			return false;
9674		}
9675
9676		this._blurActiveElement( event );
9677
9678		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
9679
9680		return true;
9681
9682	},
9683
9684	_blockFrames: function( selector ) {
9685		this.iframeBlocks = this.document.find( selector ).map( function() {
9686			var iframe = $( this );
9687
9688			return $( "<div>" )
9689				.css( "position", "absolute" )
9690				.appendTo( iframe.parent() )
9691				.outerWidth( iframe.outerWidth() )
9692				.outerHeight( iframe.outerHeight() )
9693				.offset( iframe.offset() )[ 0 ];
9694		} );
9695	},
9696
9697	_unblockFrames: function() {
9698		if ( this.iframeBlocks ) {
9699			this.iframeBlocks.remove();
9700			delete this.iframeBlocks;
9701		}
9702	},
9703
9704	_blurActiveElement: function( event ) {
9705		var activeElement = this.document[ 0 ].activeElement,
9706			target = $( event.target );
9707
9708		// Don't blur if the event occurred on an element that is within
9709		// the currently focused element
9710		// See #10527, #12472
9711		if ( target.closest( activeElement ).length ) {
9712			return;
9713		}
9714
9715		// Blur any element that currently has focus, see #4261
9716		$( activeElement ).trigger( "blur" );
9717	},
9718
9719	_mouseStart: function( event ) {
9720
9721		var o = this.options;
9722
9723		//Create and append the visible helper
9724		this.helper = this._createHelper( event );
9725
9726		this._addClass( this.helper, "ui-draggable-dragging" );
9727
9728		//Cache the helper size
9729		this._cacheHelperProportions();
9730
9731		//If ddmanager is used for droppables, set the global draggable
9732		if ( $.ui.ddmanager ) {
9733			$.ui.ddmanager.current = this;
9734		}
9735
9736		/*
9737		 * - Position generation -
9738		 * This block generates everything position related - it's the core of draggables.
9739		 */
9740
9741		//Cache the margins of the original element
9742		this._cacheMargins();
9743
9744		//Store the helper's css position
9745		this.cssPosition = this.helper.css( "position" );
9746		this.scrollParent = this.helper.scrollParent( true );
9747		this.offsetParent = this.helper.offsetParent();
9748		this.hasFixedAncestor = this.helper.parents().filter( function() {
9749				return $( this ).css( "position" ) === "fixed";
9750			} ).length > 0;
9751
9752		//The element's absolute position on the page minus margins
9753		this.positionAbs = this.element.offset();
9754		this._refreshOffsets( event );
9755
9756		//Generate the original position
9757		this.originalPosition = this.position = this._generatePosition( event, false );
9758		this.originalPageX = event.pageX;
9759		this.originalPageY = event.pageY;
9760
9761		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9762		if ( o.cursorAt ) {
9763			this._adjustOffsetFromHelper( o.cursorAt );
9764		}
9765
9766		//Set a containment if given in the options
9767		this._setContainment();
9768
9769		//Trigger event + callbacks
9770		if ( this._trigger( "start", event ) === false ) {
9771			this._clear();
9772			return false;
9773		}
9774
9775		//Recache the helper size
9776		this._cacheHelperProportions();
9777
9778		//Prepare the droppable offsets
9779		if ( $.ui.ddmanager && !o.dropBehaviour ) {
9780			$.ui.ddmanager.prepareOffsets( this, event );
9781		}
9782
9783		// Execute the drag once - this causes the helper not to be visible before getting its
9784		// correct position
9785		this._mouseDrag( event, true );
9786
9787		// If the ddmanager is used for droppables, inform the manager that dragging has started
9788		// (see #5003)
9789		if ( $.ui.ddmanager ) {
9790			$.ui.ddmanager.dragStart( this, event );
9791		}
9792
9793		return true;
9794	},
9795
9796	_refreshOffsets: function( event ) {
9797		this.offset = {
9798			top: this.positionAbs.top - this.margins.top,
9799			left: this.positionAbs.left - this.margins.left,
9800			scroll: false,
9801			parent: this._getParentOffset(),
9802			relative: this._getRelativeOffset()
9803		};
9804
9805		this.offset.click = {
9806			left: event.pageX - this.offset.left,
9807			top: event.pageY - this.offset.top
9808		};
9809	},
9810
9811	_mouseDrag: function( event, noPropagation ) {
9812
9813		// reset any necessary cached properties (see #5009)
9814		if ( this.hasFixedAncestor ) {
9815			this.offset.parent = this._getParentOffset();
9816		}
9817
9818		//Compute the helpers position
9819		this.position = this._generatePosition( event, true );
9820		this.positionAbs = this._convertPositionTo( "absolute" );
9821
9822		//Call plugins and callbacks and use the resulting position if something is returned
9823		if ( !noPropagation ) {
9824			var ui = this._uiHash();
9825			if ( this._trigger( "drag", event, ui ) === false ) {
9826				this._mouseUp( new $.Event( "mouseup", event ) );
9827				return false;
9828			}
9829			this.position = ui.position;
9830		}
9831
9832		this.helper[ 0 ].style.left = this.position.left + "px";
9833		this.helper[ 0 ].style.top = this.position.top + "px";
9834
9835		if ( $.ui.ddmanager ) {
9836			$.ui.ddmanager.drag( this, event );
9837		}
9838
9839		return false;
9840	},
9841
9842	_mouseStop: function( event ) {
9843
9844		//If we are using droppables, inform the manager about the drop
9845		var that = this,
9846			dropped = false;
9847		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
9848			dropped = $.ui.ddmanager.drop( this, event );
9849		}
9850
9851		//if a drop comes from outside (a sortable)
9852		if ( this.dropped ) {
9853			dropped = this.dropped;
9854			this.dropped = false;
9855		}
9856
9857		if ( ( this.options.revert === "invalid" && !dropped ) ||
9858				( this.options.revert === "valid" && dropped ) ||
9859				this.options.revert === true || ( typeof this.options.revert === "function" &&
9860				this.options.revert.call( this.element, dropped ) )
9861		) {
9862			$( this.helper ).animate(
9863				this.originalPosition,
9864				parseInt( this.options.revertDuration, 10 ),
9865				function() {
9866					if ( that._trigger( "stop", event ) !== false ) {
9867						that._clear();
9868					}
9869				}
9870			);
9871		} else {
9872			if ( this._trigger( "stop", event ) !== false ) {
9873				this._clear();
9874			}
9875		}
9876
9877		return false;
9878	},
9879
9880	_mouseUp: function( event ) {
9881		this._unblockFrames();
9882
9883		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9884		// (see #5003)
9885		if ( $.ui.ddmanager ) {
9886			$.ui.ddmanager.dragStop( this, event );
9887		}
9888
9889		// Only need to focus if the event occurred on the draggable itself, see #10527
9890		if ( this.handleElement.is( event.target ) ) {
9891
9892			// The interaction is over; whether or not the click resulted in a drag,
9893			// focus the element
9894			this.element.trigger( "focus" );
9895		}
9896
9897		return $.ui.mouse.prototype._mouseUp.call( this, event );
9898	},
9899
9900	cancel: function() {
9901
9902		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
9903			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
9904		} else {
9905			this._clear();
9906		}
9907
9908		return this;
9909
9910	},
9911
9912	_getHandle: function( event ) {
9913		return this.options.handle ?
9914			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
9915			true;
9916	},
9917
9918	_setHandleClassName: function() {
9919		this.handleElement = this.options.handle ?
9920			this.element.find( this.options.handle ) : this.element;
9921		this._addClass( this.handleElement, "ui-draggable-handle" );
9922	},
9923
9924	_removeHandleClassName: function() {
9925		this._removeClass( this.handleElement, "ui-draggable-handle" );
9926	},
9927
9928	_createHelper: function( event ) {
9929
9930		var o = this.options,
9931			helperIsFunction = typeof o.helper === "function",
9932			helper = helperIsFunction ?
9933				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
9934				( o.helper === "clone" ?
9935					this.element.clone().removeAttr( "id" ) :
9936					this.element );
9937
9938		if ( !helper.parents( "body" ).length ) {
9939			helper.appendTo( ( o.appendTo === "parent" ?
9940				this.element[ 0 ].parentNode :
9941				o.appendTo ) );
9942		}
9943
9944		// https://bugs.jqueryui.com/ticket/9446
9945		// a helper function can return the original element
9946		// which wouldn't have been set to relative in _create
9947		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
9948			this._setPositionRelative();
9949		}
9950
9951		if ( helper[ 0 ] !== this.element[ 0 ] &&
9952				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
9953			helper.css( "position", "absolute" );
9954		}
9955
9956		return helper;
9957
9958	},
9959
9960	_setPositionRelative: function() {
9961		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
9962			this.element[ 0 ].style.position = "relative";
9963		}
9964	},
9965
9966	_adjustOffsetFromHelper: function( obj ) {
9967		if ( typeof obj === "string" ) {
9968			obj = obj.split( " " );
9969		}
9970		if ( Array.isArray( obj ) ) {
9971			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
9972		}
9973		if ( "left" in obj ) {
9974			this.offset.click.left = obj.left + this.margins.left;
9975		}
9976		if ( "right" in obj ) {
9977			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9978		}
9979		if ( "top" in obj ) {
9980			this.offset.click.top = obj.top + this.margins.top;
9981		}
9982		if ( "bottom" in obj ) {
9983			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9984		}
9985	},
9986
9987	_isRootNode: function( element ) {
9988		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
9989	},
9990
9991	_getParentOffset: function() {
9992
9993		//Get the offsetParent and cache its position
9994		var po = this.offsetParent.offset(),
9995			document = this.document[ 0 ];
9996
9997		// This is a special case where we need to modify a offset calculated on start, since the
9998		// following happened:
9999		// 1. The position of the helper is absolute, so it's position is calculated based on the
10000		// next positioned parent
10001		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
10002		// the document, which means that the scroll is included in the initial calculation of the
10003		// offset of the parent, and never recalculated upon drag
10004		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
10005				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
10006			po.left += this.scrollParent.scrollLeft();
10007			po.top += this.scrollParent.scrollTop();
10008		}
10009
10010		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
10011			po = { top: 0, left: 0 };
10012		}
10013
10014		return {
10015			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
10016			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
10017		};
10018
10019	},
10020
10021	_getRelativeOffset: function() {
10022		if ( this.cssPosition !== "relative" ) {
10023			return { top: 0, left: 0 };
10024		}
10025
10026		var p = this.element.position(),
10027			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10028
10029		return {
10030			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
10031				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
10032			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
10033				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
10034		};
10035
10036	},
10037
10038	_cacheMargins: function() {
10039		this.margins = {
10040			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
10041			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
10042			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
10043			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
10044		};
10045	},
10046
10047	_cacheHelperProportions: function() {
10048		this.helperProportions = {
10049			width: this.helper.outerWidth(),
10050			height: this.helper.outerHeight()
10051		};
10052	},
10053
10054	_setContainment: function() {
10055
10056		var isUserScrollable, c, ce,
10057			o = this.options,
10058			document = this.document[ 0 ];
10059
10060		this.relativeContainer = null;
10061
10062		if ( !o.containment ) {
10063			this.containment = null;
10064			return;
10065		}
10066
10067		if ( o.containment === "window" ) {
10068			this.containment = [
10069				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10070				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10071				$( window ).scrollLeft() + $( window ).width() -
10072					this.helperProportions.width - this.margins.left,
10073				$( window ).scrollTop() +
10074					( $( window ).height() || document.body.parentNode.scrollHeight ) -
10075					this.helperProportions.height - this.margins.top
10076			];
10077			return;
10078		}
10079
10080		if ( o.containment === "document" ) {
10081			this.containment = [
10082				0,
10083				0,
10084				$( document ).width() - this.helperProportions.width - this.margins.left,
10085				( $( document ).height() || document.body.parentNode.scrollHeight ) -
10086					this.helperProportions.height - this.margins.top
10087			];
10088			return;
10089		}
10090
10091		if ( o.containment.constructor === Array ) {
10092			this.containment = o.containment;
10093			return;
10094		}
10095
10096		if ( o.containment === "parent" ) {
10097			o.containment = this.helper[ 0 ].parentNode;
10098		}
10099
10100		c = $( o.containment );
10101		ce = c[ 0 ];
10102
10103		if ( !ce ) {
10104			return;
10105		}
10106
10107		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
10108
10109		this.containment = [
10110			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
10111				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
10112			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
10113				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
10114			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
10115				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
10116				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
10117				this.helperProportions.width -
10118				this.margins.left -
10119				this.margins.right,
10120			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
10121				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
10122				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
10123				this.helperProportions.height -
10124				this.margins.top -
10125				this.margins.bottom
10126		];
10127		this.relativeContainer = c;
10128	},
10129
10130	_convertPositionTo: function( d, pos ) {
10131
10132		if ( !pos ) {
10133			pos = this.position;
10134		}
10135
10136		var mod = d === "absolute" ? 1 : -1,
10137			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
10138
10139		return {
10140			top: (
10141
10142				// The absolute mouse position
10143				pos.top	+
10144
10145				// Only for relative positioned nodes: Relative offset from element to offset parent
10146				this.offset.relative.top * mod +
10147
10148				// The offsetParent's offset without borders (offset + border)
10149				this.offset.parent.top * mod -
10150				( ( this.cssPosition === "fixed" ?
10151					-this.offset.scroll.top :
10152					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
10153			),
10154			left: (
10155
10156				// The absolute mouse position
10157				pos.left +
10158
10159				// Only for relative positioned nodes: Relative offset from element to offset parent
10160				this.offset.relative.left * mod +
10161
10162				// The offsetParent's offset without borders (offset + border)
10163				this.offset.parent.left * mod	-
10164				( ( this.cssPosition === "fixed" ?
10165					-this.offset.scroll.left :
10166					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
10167			)
10168		};
10169
10170	},
10171
10172	_generatePosition: function( event, constrainPosition ) {
10173
10174		var containment, co, top, left,
10175			o = this.options,
10176			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
10177			pageX = event.pageX,
10178			pageY = event.pageY;
10179
10180		// Cache the scroll
10181		if ( !scrollIsRootNode || !this.offset.scroll ) {
10182			this.offset.scroll = {
10183				top: this.scrollParent.scrollTop(),
10184				left: this.scrollParent.scrollLeft()
10185			};
10186		}
10187
10188		/*
10189		 * - Position constraining -
10190		 * Constrain the position to a mix of grid, containment.
10191		 */
10192
10193		// If we are not dragging yet, we won't check for options
10194		if ( constrainPosition ) {
10195			if ( this.containment ) {
10196				if ( this.relativeContainer ) {
10197					co = this.relativeContainer.offset();
10198					containment = [
10199						this.containment[ 0 ] + co.left,
10200						this.containment[ 1 ] + co.top,
10201						this.containment[ 2 ] + co.left,
10202						this.containment[ 3 ] + co.top
10203					];
10204				} else {
10205					containment = this.containment;
10206				}
10207
10208				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
10209					pageX = containment[ 0 ] + this.offset.click.left;
10210				}
10211				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
10212					pageY = containment[ 1 ] + this.offset.click.top;
10213				}
10214				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
10215					pageX = containment[ 2 ] + this.offset.click.left;
10216				}
10217				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
10218					pageY = containment[ 3 ] + this.offset.click.top;
10219				}
10220			}
10221
10222			if ( o.grid ) {
10223
10224				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10225				// argument errors in IE (see ticket #6950)
10226				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
10227					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
10228				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
10229					top - this.offset.click.top > containment[ 3 ] ) ?
10230						top :
10231						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
10232							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
10233
10234				left = o.grid[ 0 ] ? this.originalPageX +
10235					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
10236					this.originalPageX;
10237				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
10238					left - this.offset.click.left > containment[ 2 ] ) ?
10239						left :
10240						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
10241							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
10242			}
10243
10244			if ( o.axis === "y" ) {
10245				pageX = this.originalPageX;
10246			}
10247
10248			if ( o.axis === "x" ) {
10249				pageY = this.originalPageY;
10250			}
10251		}
10252
10253		return {
10254			top: (
10255
10256				// The absolute mouse position
10257				pageY -
10258
10259				// Click offset (relative to the element)
10260				this.offset.click.top -
10261
10262				// Only for relative positioned nodes: Relative offset from element to offset parent
10263				this.offset.relative.top -
10264
10265				// The offsetParent's offset without borders (offset + border)
10266				this.offset.parent.top +
10267				( this.cssPosition === "fixed" ?
10268					-this.offset.scroll.top :
10269					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
10270			),
10271			left: (
10272
10273				// The absolute mouse position
10274				pageX -
10275
10276				// Click offset (relative to the element)
10277				this.offset.click.left -
10278
10279				// Only for relative positioned nodes: Relative offset from element to offset parent
10280				this.offset.relative.left -
10281
10282				// The offsetParent's offset without borders (offset + border)
10283				this.offset.parent.left +
10284				( this.cssPosition === "fixed" ?
10285					-this.offset.scroll.left :
10286					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
10287			)
10288		};
10289
10290	},
10291
10292	_clear: function() {
10293		this._removeClass( this.helper, "ui-draggable-dragging" );
10294		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
10295			this.helper.remove();
10296		}
10297		this.helper = null;
10298		this.cancelHelperRemoval = false;
10299		if ( this.destroyOnClear ) {
10300			this.destroy();
10301		}
10302	},
10303
10304	// From now on bulk stuff - mainly helpers
10305
10306	_trigger: function( type, event, ui ) {
10307		ui = ui || this._uiHash();
10308		$.ui.plugin.call( this, type, [ event, ui, this ], true );
10309
10310		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10311		if ( /^(drag|start|stop)/.test( type ) ) {
10312			this.positionAbs = this._convertPositionTo( "absolute" );
10313			ui.offset = this.positionAbs;
10314		}
10315		return $.Widget.prototype._trigger.call( this, type, event, ui );
10316	},
10317
10318	plugins: {},
10319
10320	_uiHash: function() {
10321		return {
10322			helper: this.helper,
10323			position: this.position,
10324			originalPosition: this.originalPosition,
10325			offset: this.positionAbs
10326		};
10327	}
10328
10329} );
10330
10331$.ui.plugin.add( "draggable", "connectToSortable", {
10332	start: function( event, ui, draggable ) {
10333		var uiSortable = $.extend( {}, ui, {
10334			item: draggable.element
10335		} );
10336
10337		draggable.sortables = [];
10338		$( draggable.options.connectToSortable ).each( function() {
10339			var sortable = $( this ).sortable( "instance" );
10340
10341			if ( sortable && !sortable.options.disabled ) {
10342				draggable.sortables.push( sortable );
10343
10344				// RefreshPositions is called at drag start to refresh the containerCache
10345				// which is used in drag. This ensures it's initialized and synchronized
10346				// with any changes that might have happened on the page since initialization.
10347				sortable.refreshPositions();
10348				sortable._trigger( "activate", event, uiSortable );
10349			}
10350		} );
10351	},
10352	stop: function( event, ui, draggable ) {
10353		var uiSortable = $.extend( {}, ui, {
10354			item: draggable.element
10355		} );
10356
10357		draggable.cancelHelperRemoval = false;
10358
10359		$.each( draggable.sortables, function() {
10360			var sortable = this;
10361
10362			if ( sortable.isOver ) {
10363				sortable.isOver = 0;
10364
10365				// Allow this sortable to handle removing the helper
10366				draggable.cancelHelperRemoval = true;
10367				sortable.cancelHelperRemoval = false;
10368
10369				// Use _storedCSS To restore properties in the sortable,
10370				// as this also handles revert (#9675) since the draggable
10371				// may have modified them in unexpected ways (#8809)
10372				sortable._storedCSS = {
10373					position: sortable.placeholder.css( "position" ),
10374					top: sortable.placeholder.css( "top" ),
10375					left: sortable.placeholder.css( "left" )
10376				};
10377
10378				sortable._mouseStop( event );
10379
10380				// Once drag has ended, the sortable should return to using
10381				// its original helper, not the shared helper from draggable
10382				sortable.options.helper = sortable.options._helper;
10383			} else {
10384
10385				// Prevent this Sortable from removing the helper.
10386				// However, don't set the draggable to remove the helper
10387				// either as another connected Sortable may yet handle the removal.
10388				sortable.cancelHelperRemoval = true;
10389
10390				sortable._trigger( "deactivate", event, uiSortable );
10391			}
10392		} );
10393	},
10394	drag: function( event, ui, draggable ) {
10395		$.each( draggable.sortables, function() {
10396			var innermostIntersecting = false,
10397				sortable = this;
10398
10399			// Copy over variables that sortable's _intersectsWith uses
10400			sortable.positionAbs = draggable.positionAbs;
10401			sortable.helperProportions = draggable.helperProportions;
10402			sortable.offset.click = draggable.offset.click;
10403
10404			if ( sortable._intersectsWith( sortable.containerCache ) ) {
10405				innermostIntersecting = true;
10406
10407				$.each( draggable.sortables, function() {
10408
10409					// Copy over variables that sortable's _intersectsWith uses
10410					this.positionAbs = draggable.positionAbs;
10411					this.helperProportions = draggable.helperProportions;
10412					this.offset.click = draggable.offset.click;
10413
10414					if ( this !== sortable &&
10415							this._intersectsWith( this.containerCache ) &&
10416							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
10417						innermostIntersecting = false;
10418					}
10419
10420					return innermostIntersecting;
10421				} );
10422			}
10423
10424			if ( innermostIntersecting ) {
10425
10426				// If it intersects, we use a little isOver variable and set it once,
10427				// so that the move-in stuff gets fired only once.
10428				if ( !sortable.isOver ) {
10429					sortable.isOver = 1;
10430
10431					// Store draggable's parent in case we need to reappend to it later.
10432					draggable._parent = ui.helper.parent();
10433
10434					sortable.currentItem = ui.helper
10435						.appendTo( sortable.element )
10436						.data( "ui-sortable-item", true );
10437
10438					// Store helper option to later restore it
10439					sortable.options._helper = sortable.options.helper;
10440
10441					sortable.options.helper = function() {
10442						return ui.helper[ 0 ];
10443					};
10444
10445					// Fire the start events of the sortable with our passed browser event,
10446					// and our own helper (so it doesn't create a new one)
10447					event.target = sortable.currentItem[ 0 ];
10448					sortable._mouseCapture( event, true );
10449					sortable._mouseStart( event, true, true );
10450
10451					// Because the browser event is way off the new appended portlet,
10452					// modify necessary variables to reflect the changes
10453					sortable.offset.click.top = draggable.offset.click.top;
10454					sortable.offset.click.left = draggable.offset.click.left;
10455					sortable.offset.parent.left -= draggable.offset.parent.left -
10456						sortable.offset.parent.left;
10457					sortable.offset.parent.top -= draggable.offset.parent.top -
10458						sortable.offset.parent.top;
10459
10460					draggable._trigger( "toSortable", event );
10461
10462					// Inform draggable that the helper is in a valid drop zone,
10463					// used solely in the revert option to handle "valid/invalid".
10464					draggable.dropped = sortable.element;
10465
10466					// Need to refreshPositions of all sortables in the case that
10467					// adding to one sortable changes the location of the other sortables (#9675)
10468					$.each( draggable.sortables, function() {
10469						this.refreshPositions();
10470					} );
10471
10472					// Hack so receive/update callbacks work (mostly)
10473					draggable.currentItem = draggable.element;
10474					sortable.fromOutside = draggable;
10475				}
10476
10477				if ( sortable.currentItem ) {
10478					sortable._mouseDrag( event );
10479
10480					// Copy the sortable's position because the draggable's can potentially reflect
10481					// a relative position, while sortable is always absolute, which the dragged
10482					// element has now become. (#8809)
10483					ui.position = sortable.position;
10484				}
10485			} else {
10486
10487				// If it doesn't intersect with the sortable, and it intersected before,
10488				// we fake the drag stop of the sortable, but make sure it doesn't remove
10489				// the helper by using cancelHelperRemoval.
10490				if ( sortable.isOver ) {
10491
10492					sortable.isOver = 0;
10493					sortable.cancelHelperRemoval = true;
10494
10495					// Calling sortable's mouseStop would trigger a revert,
10496					// so revert must be temporarily false until after mouseStop is called.
10497					sortable.options._revert = sortable.options.revert;
10498					sortable.options.revert = false;
10499
10500					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
10501					sortable._mouseStop( event, true );
10502
10503					// Restore sortable behaviors that were modfied
10504					// when the draggable entered the sortable area (#9481)
10505					sortable.options.revert = sortable.options._revert;
10506					sortable.options.helper = sortable.options._helper;
10507
10508					if ( sortable.placeholder ) {
10509						sortable.placeholder.remove();
10510					}
10511
10512					// Restore and recalculate the draggable's offset considering the sortable
10513					// may have modified them in unexpected ways. (#8809, #10669)
10514					ui.helper.appendTo( draggable._parent );
10515					draggable._refreshOffsets( event );
10516					ui.position = draggable._generatePosition( event, true );
10517
10518					draggable._trigger( "fromSortable", event );
10519
10520					// Inform draggable that the helper is no longer in a valid drop zone
10521					draggable.dropped = false;
10522
10523					// Need to refreshPositions of all sortables just in case removing
10524					// from one sortable changes the location of other sortables (#9675)
10525					$.each( draggable.sortables, function() {
10526						this.refreshPositions();
10527					} );
10528				}
10529			}
10530		} );
10531	}
10532} );
10533
10534$.ui.plugin.add( "draggable", "cursor", {
10535	start: function( event, ui, instance ) {
10536		var t = $( "body" ),
10537			o = instance.options;
10538
10539		if ( t.css( "cursor" ) ) {
10540			o._cursor = t.css( "cursor" );
10541		}
10542		t.css( "cursor", o.cursor );
10543	},
10544	stop: function( event, ui, instance ) {
10545		var o = instance.options;
10546		if ( o._cursor ) {
10547			$( "body" ).css( "cursor", o._cursor );
10548		}
10549	}
10550} );
10551
10552$.ui.plugin.add( "draggable", "opacity", {
10553	start: function( event, ui, instance ) {
10554		var t = $( ui.helper ),
10555			o = instance.options;
10556		if ( t.css( "opacity" ) ) {
10557			o._opacity = t.css( "opacity" );
10558		}
10559		t.css( "opacity", o.opacity );
10560	},
10561	stop: function( event, ui, instance ) {
10562		var o = instance.options;
10563		if ( o._opacity ) {
10564			$( ui.helper ).css( "opacity", o._opacity );
10565		}
10566	}
10567} );
10568
10569$.ui.plugin.add( "draggable", "scroll", {
10570	start: function( event, ui, i ) {
10571		if ( !i.scrollParentNotHidden ) {
10572			i.scrollParentNotHidden = i.helper.scrollParent( false );
10573		}
10574
10575		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
10576				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
10577			i.overflowOffset = i.scrollParentNotHidden.offset();
10578		}
10579	},
10580	drag: function( event, ui, i  ) {
10581
10582		var o = i.options,
10583			scrolled = false,
10584			scrollParent = i.scrollParentNotHidden[ 0 ],
10585			document = i.document[ 0 ];
10586
10587		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
10588			if ( !o.axis || o.axis !== "x" ) {
10589				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
10590						o.scrollSensitivity ) {
10591					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10592				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
10593					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10594				}
10595			}
10596
10597			if ( !o.axis || o.axis !== "y" ) {
10598				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
10599						o.scrollSensitivity ) {
10600					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10601				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
10602					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10603				}
10604			}
10605
10606		} else {
10607
10608			if ( !o.axis || o.axis !== "x" ) {
10609				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
10610					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
10611				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
10612						o.scrollSensitivity ) {
10613					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
10614				}
10615			}
10616
10617			if ( !o.axis || o.axis !== "y" ) {
10618				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
10619					scrolled = $( document ).scrollLeft(
10620						$( document ).scrollLeft() - o.scrollSpeed
10621					);
10622				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
10623						o.scrollSensitivity ) {
10624					scrolled = $( document ).scrollLeft(
10625						$( document ).scrollLeft() + o.scrollSpeed
10626					);
10627				}
10628			}
10629
10630		}
10631
10632		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
10633			$.ui.ddmanager.prepareOffsets( i, event );
10634		}
10635
10636	}
10637} );
10638
10639$.ui.plugin.add( "draggable", "snap", {
10640	start: function( event, ui, i ) {
10641
10642		var o = i.options;
10643
10644		i.snapElements = [];
10645
10646		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
10647			.each( function() {
10648				var $t = $( this ),
10649					$o = $t.offset();
10650				if ( this !== i.element[ 0 ] ) {
10651					i.snapElements.push( {
10652						item: this,
10653						width: $t.outerWidth(), height: $t.outerHeight(),
10654						top: $o.top, left: $o.left
10655					} );
10656				}
10657			} );
10658
10659	},
10660	drag: function( event, ui, inst ) {
10661
10662		var ts, bs, ls, rs, l, r, t, b, i, first,
10663			o = inst.options,
10664			d = o.snapTolerance,
10665			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10666			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10667
10668		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
10669
10670			l = inst.snapElements[ i ].left - inst.margins.left;
10671			r = l + inst.snapElements[ i ].width;
10672			t = inst.snapElements[ i ].top - inst.margins.top;
10673			b = t + inst.snapElements[ i ].height;
10674
10675			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10676					!$.contains( inst.snapElements[ i ].item.ownerDocument,
10677					inst.snapElements[ i ].item ) ) {
10678				if ( inst.snapElements[ i ].snapping ) {
10679					if ( inst.options.snap.release ) {
10680						inst.options.snap.release.call(
10681							inst.element,
10682							event,
10683							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
10684						);
10685					}
10686				}
10687				inst.snapElements[ i ].snapping = false;
10688				continue;
10689			}
10690
10691			if ( o.snapMode !== "inner" ) {
10692				ts = Math.abs( t - y2 ) <= d;
10693				bs = Math.abs( b - y1 ) <= d;
10694				ls = Math.abs( l - x2 ) <= d;
10695				rs = Math.abs( r - x1 ) <= d;
10696				if ( ts ) {
10697					ui.position.top = inst._convertPositionTo( "relative", {
10698						top: t - inst.helperProportions.height,
10699						left: 0
10700					} ).top;
10701				}
10702				if ( bs ) {
10703					ui.position.top = inst._convertPositionTo( "relative", {
10704						top: b,
10705						left: 0
10706					} ).top;
10707				}
10708				if ( ls ) {
10709					ui.position.left = inst._convertPositionTo( "relative", {
10710						top: 0,
10711						left: l - inst.helperProportions.width
10712					} ).left;
10713				}
10714				if ( rs ) {
10715					ui.position.left = inst._convertPositionTo( "relative", {
10716						top: 0,
10717						left: r
10718					} ).left;
10719				}
10720			}
10721
10722			first = ( ts || bs || ls || rs );
10723
10724			if ( o.snapMode !== "outer" ) {
10725				ts = Math.abs( t - y1 ) <= d;
10726				bs = Math.abs( b - y2 ) <= d;
10727				ls = Math.abs( l - x1 ) <= d;
10728				rs = Math.abs( r - x2 ) <= d;
10729				if ( ts ) {
10730					ui.position.top = inst._convertPositionTo( "relative", {
10731						top: t,
10732						left: 0
10733					} ).top;
10734				}
10735				if ( bs ) {
10736					ui.position.top = inst._convertPositionTo( "relative", {
10737						top: b - inst.helperProportions.height,
10738						left: 0
10739					} ).top;
10740				}
10741				if ( ls ) {
10742					ui.position.left = inst._convertPositionTo( "relative", {
10743						top: 0,
10744						left: l
10745					} ).left;
10746				}
10747				if ( rs ) {
10748					ui.position.left = inst._convertPositionTo( "relative", {
10749						top: 0,
10750						left: r - inst.helperProportions.width
10751					} ).left;
10752				}
10753			}
10754
10755			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
10756				if ( inst.options.snap.snap ) {
10757					inst.options.snap.snap.call(
10758						inst.element,
10759						event,
10760						$.extend( inst._uiHash(), {
10761							snapItem: inst.snapElements[ i ].item
10762						} ) );
10763				}
10764			}
10765			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
10766
10767		}
10768
10769	}
10770} );
10771
10772$.ui.plugin.add( "draggable", "stack", {
10773	start: function( event, ui, instance ) {
10774		var min,
10775			o = instance.options,
10776			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
10777				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
10778					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
10779			} );
10780
10781		if ( !group.length ) {
10782			return;
10783		}
10784
10785		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
10786		$( group ).each( function( i ) {
10787			$( this ).css( "zIndex", min + i );
10788		} );
10789		this.css( "zIndex", ( min + group.length ) );
10790	}
10791} );
10792
10793$.ui.plugin.add( "draggable", "zIndex", {
10794	start: function( event, ui, instance ) {
10795		var t = $( ui.helper ),
10796			o = instance.options;
10797
10798		if ( t.css( "zIndex" ) ) {
10799			o._zIndex = t.css( "zIndex" );
10800		}
10801		t.css( "zIndex", o.zIndex );
10802	},
10803	stop: function( event, ui, instance ) {
10804		var o = instance.options;
10805
10806		if ( o._zIndex ) {
10807			$( ui.helper ).css( "zIndex", o._zIndex );
10808		}
10809	}
10810} );
10811
10812var widgetsDraggable = $.ui.draggable;
10813
10814
10815/*!
10816 * jQuery UI Resizable 1.14.
vendor: 1,363 bytes, lines 10816-10881
108161
10817 * https://jqueryui.com
10818 *
10819 * Copyright OpenJS Foundation and other contributors
10820 * Released under the MIT license.
10821 * https://jquery.org/license
10822 */
10823
10824//>>label: Resizable
10825//>>group: Interactions
10826//>>description: Enables resize functionality for any element.
10827//>>docs: https://api.jqueryui.com/resizable/
10828//>>demos: https://jqueryui.com/resizable/
10829//>>css.structure: ../../themes/base/core.css
10830//>>css.structure: ../../themes/base/resizable.css
10831//>>css.theme: ../../themes/base/theme.css
10832
10833
10834$.widget( "ui.resizable", $.ui.mouse, {
10835	version: "1.14.1",
10836	widgetEventPrefix: "resize",
10837	options: {
10838		alsoResize: false,
10839		animate: false,
10840		animateDuration: "slow",
10841		animateEasing: "swing",
10842		aspectRatio: false,
10843		autoHide: false,
10844		classes: {
10845			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10846		},
10847		containment: false,
10848		ghost: false,
10849		grid: false,
10850		handles: "e,s,se",
10851		helper: false,
10852		maxHeight: null,
10853		maxWidth: null,
10854		minHeight: 10,
10855		minWidth: 10,
10856
10857		// See #7960
10858		zIndex: 90,
10859
10860		// Callbacks
10861		resize: null,
10862		start: null,
10863		stop: null
10864	},
10865
10866	_num: function( value ) {
10867		return parseFloat( value ) || 0;
10868	},
10869
10870	_isNumber: function( value ) {
10871		return !isNaN( parseFloat( value ) );
10872	},
10873
10874	_hasScroll: function( el, a ) {
10875
10876		var scroll,
10877			has = false,
10878			overflow = $( el ).css( "overflow" );
10879
10880		if ( overflow === "hidden" ) {
10881			return false;
10882		}
10883		if ( overflow === "scroll" ) {
10884			return true;
10885		}
10886
10887		scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop";
10888
10889		if ( el[ scroll ] > 0 ) {
10890			return true;
10891		}
10892
10893		// TODO: determine which cases actually cause this to happen
10894		// if the element doesn't have the scroll set, see if it's possible to
10895		// set the scroll
10896		try {
10897			el[ scroll ] = 1;
10898			has = ( el[ scroll ] > 0 );
10899			el[ scroll ] = 0;
10900		} catch ( 
vendor: 29,932 bytes, lines 10900-12070
10900e ) {
10901
10902			// `el` might be a string, then setting `scroll` will throw
10903			// an error in strict mode; ignore it.
10904		}
10905		return has;
10906	},
10907
10908	_create: function() {
10909
10910		var margins,
10911			o = this.options,
10912			that = this;
10913		this._addClass( "ui-resizable" );
10914
10915		$.extend( this, {
10916			_aspectRatio: !!( o.aspectRatio ),
10917			aspectRatio: o.aspectRatio,
10918			originalElement: this.element,
10919			_proportionallyResizeElements: [],
10920			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10921		} );
10922
10923		// Wrap the element if it cannot hold child nodes
10924		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
10925
10926			this.element.wrap(
10927				$( "<div class='ui-wrapper'></div>" ).css( {
10928					overflow: "hidden",
10929					position: this.element.css( "position" ),
10930					width: this.element.outerWidth(),
10931					height: this.element.outerHeight(),
10932					top: this.element.css( "top" ),
10933					left: this.element.css( "left" )
10934				} )
10935			);
10936
10937			this.element = this.element.parent().data(
10938				"ui-resizable", this.element.resizable( "instance" )
10939			);
10940
10941			this.elementIsWrapper = true;
10942
10943			margins = {
10944				marginTop: this.originalElement.css( "marginTop" ),
10945				marginRight: this.originalElement.css( "marginRight" ),
10946				marginBottom: this.originalElement.css( "marginBottom" ),
10947				marginLeft: this.originalElement.css( "marginLeft" )
10948			};
10949
10950			this.element.css( margins );
10951
10952			// Support: Safari
10953			// Prevent Safari textarea resize
10954			this.originalResizeStyle = this.originalElement.css( "resize" );
10955			this.originalElement.css( "resize", "none" );
10956
10957			this._proportionallyResizeElements.push( this.originalElement.css( {
10958				position: "static",
10959				zoom: 1,
10960				display: "block"
10961			} ) );
10962
10963			this._proportionallyResize();
10964		}
10965
10966		this._setupHandles();
10967
10968		if ( o.autoHide ) {
10969			$( this.element )
10970				.on( "mouseenter", function() {
10971					if ( o.disabled ) {
10972						return;
10973					}
10974					that._removeClass( "ui-resizable-autohide" );
10975					that._handles.show();
10976				} )
10977				.on( "mouseleave", function() {
10978					if ( o.disabled ) {
10979						return;
10980					}
10981					if ( !that.resizing ) {
10982						that._addClass( "ui-resizable-autohide" );
10983						that._handles.hide();
10984					}
10985				} );
10986		}
10987
10988		this._mouseInit();
10989	},
10990
10991	_destroy: function() {
10992
10993		this._mouseDestroy();
10994		this._addedHandles.remove();
10995
10996		var wrapper,
10997			_destroy = function( exp ) {
10998				$( exp )
10999					.removeData( "resizable" )
11000					.removeData( "ui-resizable" )
11001					.off( ".resizable" );
11002			};
11003
11004		// TODO: Unwrap at same DOM position
11005		if ( this.elementIsWrapper ) {
11006			_destroy( this.element );
11007			wrapper = this.element;
11008			this.originalElement.css( {
11009				position: wrapper.css( "position" ),
11010				width: wrapper.outerWidth(),
11011				height: wrapper.outerHeight(),
11012				top: wrapper.css( "top" ),
11013				left: wrapper.css( "left" )
11014			} ).insertAfter( wrapper );
11015			wrapper.remove();
11016		}
11017
11018		this.originalElement.css( "resize", this.originalResizeStyle );
11019		_destroy( this.originalElement );
11020
11021		return this;
11022	},
11023
11024	_setOption: function( key, value ) {
11025		this._super( key, value );
11026
11027		switch ( key ) {
11028		case "handles":
11029			this._removeHandles();
11030			this._setupHandles();
11031			break;
11032		case "aspectRatio":
11033			this._aspectRatio = !!value;
11034			break;
11035		default:
11036			break;
11037		}
11038	},
11039
11040	_setupHandles: function() {
11041		var o = this.options, handle, i, n, hname, axis, that = this;
11042		this.handles = o.handles ||
11043			( !$( ".ui-resizable-handle", this.element ).length ?
11044				"e,s,se" : {
11045					n: ".ui-resizable-n",
11046					e: ".ui-resizable-e",
11047					s: ".ui-resizable-s",
11048					w: ".ui-resizable-w",
11049					se: ".ui-resizable-se",
11050					sw: ".ui-resizable-sw",
11051					ne: ".ui-resizable-ne",
11052					nw: ".ui-resizable-nw"
11053				} );
11054
11055		this._handles = $();
11056		this._addedHandles = $();
11057		if ( this.handles.constructor === String ) {
11058
11059			if ( this.handles === "all" ) {
11060				this.handles = "n,e,s,w,se,sw,ne,nw";
11061			}
11062
11063			n = this.handles.split( "," );
11064			this.handles = {};
11065
11066			for ( i = 0; i < n.length; i++ ) {
11067
11068				handle = String.prototype.trim.call( n[ i ] );
11069				hname = "ui-resizable-" + handle;
11070				axis = $( "<div>" );
11071				this._addClass( axis, "ui-resizable-handle " + hname );
11072
11073				axis.css( { zIndex: o.zIndex } );
11074
11075				this.handles[ handle ] = ".ui-resizable-" + handle;
11076				if ( !this.element.children( this.handles[ handle ] ).length ) {
11077					this.element.append( axis );
11078					this._addedHandles = this._addedHandles.add( axis );
11079				}
11080			}
11081
11082		}
11083
11084		this._renderAxis = function( target ) {
11085
11086			var i, axis, padPos, padWrapper;
11087
11088			target = target || this.element;
11089
11090			for ( i in this.handles ) {
11091
11092				if ( this.handles[ i ].constructor === String ) {
11093					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
11094				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
11095					this.handles[ i ] = $( this.handles[ i ] );
11096					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
11097				}
11098
11099				if ( this.elementIsWrapper &&
11100						this.originalElement[ 0 ]
11101							.nodeName
11102							.match( /^(textarea|input|select|button)$/i ) ) {
11103					axis = $( this.handles[ i ], this.element );
11104
11105					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
11106						axis.outerHeight() :
11107						axis.outerWidth();
11108
11109					padPos = [ "padding",
11110						/ne|nw|n/.test( i ) ? "Top" :
11111						/se|sw|s/.test( i ) ? "Bottom" :
11112						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
11113
11114					target.css( padPos, padWrapper );
11115
11116					this._proportionallyResize();
11117				}
11118
11119				this._handles = this._handles.add( this.handles[ i ] );
11120			}
11121		};
11122
11123		// TODO: make renderAxis a prototype function
11124		this._renderAxis( this.element );
11125
11126		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
11127		this._handles.disableSelection();
11128
11129		this._handles.on( "mouseover", function() {
11130			if ( !that.resizing ) {
11131				if ( this.className ) {
11132					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
11133				}
11134				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
11135			}
11136		} );
11137
11138		if ( o.autoHide ) {
11139			this._handles.hide();
11140			this._addClass( "ui-resizable-autohide" );
11141		}
11142	},
11143
11144	_removeHandles: function() {
11145		this._addedHandles.remove();
11146	},
11147
11148	_mouseCapture: function( event ) {
11149		var i, handle,
11150			capture = false;
11151
11152		for ( i in this.handles ) {
11153			handle = $( this.handles[ i ] )[ 0 ];
11154			if ( handle === event.target || $.contains( handle, event.target ) ) {
11155				capture = true;
11156			}
11157		}
11158
11159		return !this.options.disabled && capture;
11160	},
11161
11162	_mouseStart: function( event ) {
11163
11164		var curleft, curtop, cursor, calculatedSize,
11165			o = this.options,
11166			el = this.element;
11167
11168		this.resizing = true;
11169
11170		this._renderProxy();
11171
11172		curleft = this._num( this.helper.css( "left" ) );
11173		curtop = this._num( this.helper.css( "top" ) );
11174
11175		if ( o.containment ) {
11176			curleft += $( o.containment ).scrollLeft() || 0;
11177			curtop += $( o.containment ).scrollTop() || 0;
11178		}
11179
11180		this.offset = this.helper.offset();
11181		this.position = { left: curleft, top: curtop };
11182
11183		if ( !this._helper ) {
11184			calculatedSize = this._calculateAdjustedElementDimensions( el );
11185		}
11186
11187		this.size = this._helper ? {
11188				width: this.helper.width(),
11189				height: this.helper.height()
11190			} : {
11191				width: calculatedSize.width,
11192				height: calculatedSize.height
11193			};
11194
11195		this.originalSize = this._helper ? {
11196				width: el.outerWidth(),
11197				height: el.outerHeight()
11198			} : {
11199				width: calculatedSize.width,
11200				height: calculatedSize.height
11201			};
11202
11203		this.sizeDiff = {
11204			width: el.outerWidth() - el.width(),
11205			height: el.outerHeight() - el.height()
11206		};
11207
11208		this.originalPosition = { left: curleft, top: curtop };
11209		this.originalMousePosition = { left: event.pageX, top: event.pageY };
11210
11211		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
11212			o.aspectRatio :
11213			( ( this.originalSize.width / this.originalSize.height ) || 1 );
11214
11215		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
11216		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
11217
11218		this._addClass( "ui-resizable-resizing" );
11219		this._propagate( "start", event );
11220		return true;
11221	},
11222
11223	_mouseDrag: function( event ) {
11224
11225		var data, props,
11226			smp = this.originalMousePosition,
11227			a = this.axis,
11228			dx = ( event.pageX - smp.left ) || 0,
11229			dy = ( event.pageY - smp.top ) || 0,
11230			trigger = this._change[ a ];
11231
11232		this._updatePrevProperties();
11233
11234		if ( !trigger ) {
11235			return false;
11236		}
11237
11238		data = trigger.apply( this, [ event, dx, dy ] );
11239
11240		this._updateVirtualBoundaries( event.shiftKey );
11241		if ( this._aspectRatio || event.shiftKey ) {
11242			data = this._updateRatio( data, event );
11243		}
11244
11245		data = this._respectSize( data, event );
11246
11247		this._updateCache( data );
11248
11249		this._propagate( "resize", event );
11250
11251		props = this._applyChanges();
11252
11253		if ( !this._helper && this._proportionallyResizeElements.length ) {
11254			this._proportionallyResize();
11255		}
11256
11257		if ( !$.isEmptyObject( props ) ) {
11258			this._updatePrevProperties();
11259			this._trigger( "resize", event, this.ui() );
11260			this._applyChanges();
11261		}
11262
11263		return false;
11264	},
11265
11266	_mouseStop: function( event ) {
11267
11268		this.resizing = false;
11269		var pr, ista, soffseth, soffsetw, s, left, top,
11270			o = this.options, that = this;
11271
11272		if ( this._helper ) {
11273
11274			pr = this._proportionallyResizeElements;
11275			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
11276			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
11277			soffsetw = ista ? 0 : that.sizeDiff.width;
11278
11279			s = {
11280				width: ( that.helper.width()  - soffsetw ),
11281				height: ( that.helper.height() - soffseth )
11282			};
11283			left = ( parseFloat( that.element.css( "left" ) ) +
11284				( that.position.left - that.originalPosition.left ) ) || null;
11285			top = ( parseFloat( that.element.css( "top" ) ) +
11286				( that.position.top - that.originalPosition.top ) ) || null;
11287
11288			if ( !o.animate ) {
11289				this.element.css( $.extend( s, { top: top, left: left } ) );
11290			}
11291
11292			that.helper.height( that.size.height );
11293			that.helper.width( that.size.width );
11294
11295			if ( this._helper && !o.animate ) {
11296				this._proportionallyResize();
11297			}
11298		}
11299
11300		$( "body" ).css( "cursor", "auto" );
11301
11302		this._removeClass( "ui-resizable-resizing" );
11303
11304		this._propagate( "stop", event );
11305
11306		if ( this._helper ) {
11307			this.helper.remove();
11308		}
11309
11310		return false;
11311
11312	},
11313
11314	_updatePrevProperties: function() {
11315		this.prevPosition = {
11316			top: this.position.top,
11317			left: this.position.left
11318		};
11319		this.prevSize = {
11320			width: this.size.width,
11321			height: this.size.height
11322		};
11323	},
11324
11325	_applyChanges: function() {
11326		var props = {};
11327
11328		if ( this.position.top !== this.prevPosition.top ) {
11329			props.top = this.position.top + "px";
11330		}
11331		if ( this.position.left !== this.prevPosition.left ) {
11332			props.left = this.position.left + "px";
11333		}
11334
11335		this.helper.css( props );
11336
11337		if ( this.size.width !== this.prevSize.width ) {
11338			props.width = this.size.width + "px";
11339			this.helper.width( props.width );
11340		}
11341		if ( this.size.height !== this.prevSize.height ) {
11342			props.height = this.size.height + "px";
11343			this.helper.height( props.height );
11344		}
11345
11346		return props;
11347	},
11348
11349	_updateVirtualBoundaries: function( forceAspectRatio ) {
11350		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11351			o = this.options;
11352
11353		b = {
11354			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
11355			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
11356			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
11357			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
11358		};
11359
11360		if ( this._aspectRatio || forceAspectRatio ) {
11361			pMinWidth = b.minHeight * this.aspectRatio;
11362			pMinHeight = b.minWidth / this.aspectRatio;
11363			pMaxWidth = b.maxHeight * this.aspectRatio;
11364			pMaxHeight = b.maxWidth / this.aspectRatio;
11365
11366			if ( pMinWidth > b.minWidth ) {
11367				b.minWidth = pMinWidth;
11368			}
11369			if ( pMinHeight > b.minHeight ) {
11370				b.minHeight = pMinHeight;
11371			}
11372			if ( pMaxWidth < b.maxWidth ) {
11373				b.maxWidth = pMaxWidth;
11374			}
11375			if ( pMaxHeight < b.maxHeight ) {
11376				b.maxHeight = pMaxHeight;
11377			}
11378		}
11379		this._vBoundaries = b;
11380	},
11381
11382	_updateCache: function( data ) {
11383		this.offset = this.helper.offset();
11384		if ( this._isNumber( data.left ) ) {
11385			this.position.left = data.left;
11386		}
11387		if ( this._isNumber( data.top ) ) {
11388			this.position.top = data.top;
11389		}
11390		if ( this._isNumber( data.height ) ) {
11391			this.size.height = data.height;
11392		}
11393		if ( this._isNumber( data.width ) ) {
11394			this.size.width = data.width;
11395		}
11396	},
11397
11398	_updateRatio: function( data ) {
11399
11400		var cpos = this.position,
11401			csize = this.size,
11402			a = this.axis;
11403
11404		if ( this._isNumber( data.height ) ) {
11405			data.width = ( data.height * this.aspectRatio );
11406		} else if ( this._isNumber( data.width ) ) {
11407			data.height = ( data.width / this.aspectRatio );
11408		}
11409
11410		if ( a === "sw" ) {
11411			data.left = cpos.left + ( csize.width - data.width );
11412			data.top = null;
11413		}
11414		if ( a === "nw" ) {
11415			data.top = cpos.top + ( csize.height - data.height );
11416			data.left = cpos.left + ( csize.width - data.width );
11417		}
11418
11419		return data;
11420	},
11421
11422	_respectSize: function( data ) {
11423
11424		var o = this._vBoundaries,
11425			a = this.axis,
11426			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
11427			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
11428			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
11429			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
11430			dw = this.originalPosition.left + this.originalSize.width,
11431			dh = this.originalPosition.top + this.originalSize.height,
11432			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
11433		if ( isminw ) {
11434			data.width = o.minWidth;
11435		}
11436		if ( isminh ) {
11437			data.height = o.minHeight;
11438		}
11439		if ( ismaxw ) {
11440			data.width = o.maxWidth;
11441		}
11442		if ( ismaxh ) {
11443			data.height = o.maxHeight;
11444		}
11445
11446		if ( isminw && cw ) {
11447			data.left = dw - o.minWidth;
11448		}
11449		if ( ismaxw && cw ) {
11450			data.left = dw - o.maxWidth;
11451		}
11452		if ( isminh && ch ) {
11453			data.top = dh - o.minHeight;
11454		}
11455		if ( ismaxh && ch ) {
11456			data.top = dh - o.maxHeight;
11457		}
11458
11459		// Fixing jump error on top/left - bug #2330
11460		if ( !data.width && !data.height && !data.left && data.top ) {
11461			data.top = null;
11462		} else if ( !data.width && !data.height && !data.top && data.left ) {
11463			data.left = null;
11464		}
11465
11466		return data;
11467	},
11468
11469	_getPaddingPlusBorderDimensions: function( element ) {
11470		var i = 0,
11471			widths = [],
11472			borders = [
11473				element.css( "borderTopWidth" ),
11474				element.css( "borderRightWidth" ),
11475				element.css( "borderBottomWidth" ),
11476				element.css( "borderLeftWidth" )
11477			],
11478			paddings = [
11479				element.css( "paddingTop" ),
11480				element.css( "paddingRight" ),
11481				element.css( "paddingBottom" ),
11482				element.css( "paddingLeft" )
11483			];
11484
11485		for ( ; i < 4; i++ ) {
11486			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
11487			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
11488		}
11489
11490		return {
11491			height: widths[ 0 ] + widths[ 2 ],
11492			width: widths[ 1 ] + widths[ 3 ]
11493		};
11494	},
11495
11496	_calculateAdjustedElementDimensions: function( element ) {
11497		var elWidth, elHeight, paddingBorder,
11498			ce = element.get( 0 );
11499
11500		if ( element.css( "box-sizing" ) !== "content-box" ||
11501			( !this._hasScroll( ce ) && !this._hasScroll( ce, "left" ) ) ) {
11502				return {
11503					height: parseFloat( element.css( "height" ) ),
11504					width: parseFloat( element.css( "width" ) )
11505				};
11506		}
11507
11508		// Check if CSS inline styles are set and use those (usually from previous resizes)
11509		elWidth = parseFloat( ce.style.width );
11510		elHeight = parseFloat( ce.style.height );
11511
11512		paddingBorder = this._getPaddingPlusBorderDimensions( element );
11513		elWidth = isNaN( elWidth ) ?
11514			this._getElementTheoreticalSize( element, paddingBorder, "width" ) :
11515			elWidth;
11516		elHeight = isNaN( elHeight ) ?
11517			this._getElementTheoreticalSize( element, paddingBorder, "height" ) :
11518			elHeight;
11519
11520		return {
11521			height: elHeight,
11522			width: elWidth
11523		};
11524	},
11525
11526	_getElementTheoreticalSize: function( element, extraSize, dimension ) {
11527
11528		// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
11529		var size = Math.max( 0, Math.ceil(
11530			element.get( 0 )[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
11531			extraSize[ dimension ] -
11532			0.5
11533
11534		// If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
11535		// Use an explicit zero to avoid NaN.
11536		// See https://github.com/jquery/jquery/issues/3964
11537		) ) || 0;
11538
11539		return size;
11540	},
11541
11542	_proportionallyResize: function() {
11543
11544		if ( !this._proportionallyResizeElements.length ) {
11545			return;
11546		}
11547
11548		var prel,
11549			i = 0,
11550			element = this.helper || this.element;
11551
11552		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
11553
11554			prel = this._proportionallyResizeElements[ i ];
11555
11556			// TODO: Seems like a bug to cache this.outerDimensions
11557			// considering that we are in a loop.
11558			if ( !this.outerDimensions ) {
11559				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
11560			}
11561
11562			prel.css( {
11563				height: ( element.height() - this.outerDimensions.height ) || 0,
11564				width: ( element.width() - this.outerDimensions.width ) || 0
11565			} );
11566
11567		}
11568
11569	},
11570
11571	_renderProxy: function() {
11572
11573		var el = this.element, o = this.options;
11574		this.elementOffset = el.offset();
11575
11576		if ( this._helper ) {
11577
11578			this.helper = this.helper || $( "<div></div>" ).css( { overflow: "hidden" } );
11579
11580			this._addClass( this.helper, this._helper );
11581			this.helper.css( {
11582				width: this.element.outerWidth(),
11583				height: this.element.outerHeight(),
11584				position: "absolute",
11585				left: this.elementOffset.left + "px",
11586				top: this.elementOffset.top + "px",
11587				zIndex: ++o.zIndex //TODO: Don't modify option
11588			} );
11589
11590			this.helper
11591				.appendTo( "body" )
11592				.disableSelection();
11593
11594		} else {
11595			this.helper = this.element;
11596		}
11597
11598	},
11599
11600	_change: {
11601		e: function( event, dx ) {
11602			return { width: this.originalSize.width + dx };
11603		},
11604		w: function( event, dx ) {
11605			var cs = this.originalSize, sp = this.originalPosition;
11606			return { left: sp.left + dx, width: cs.width - dx };
11607		},
11608		n: function( event, dx, dy ) {
11609			var cs = this.originalSize, sp = this.originalPosition;
11610			return { top: sp.top + dy, height: cs.height - dy };
11611		},
11612		s: function( event, dx, dy ) {
11613			return { height: this.originalSize.height + dy };
11614		},
11615		se: function( event, dx, dy ) {
11616			return $.extend( this._change.s.apply( this, arguments ),
11617				this._change.e.apply( this, [ event, dx, dy ] ) );
11618		},
11619		sw: function( event, dx, dy ) {
11620			return $.extend( this._change.s.apply( this, arguments ),
11621				this._change.w.apply( this, [ event, dx, dy ] ) );
11622		},
11623		ne: function( event, dx, dy ) {
11624			return $.extend( this._change.n.apply( this, arguments ),
11625				this._change.e.apply( this, [ event, dx, dy ] ) );
11626		},
11627		nw: function( event, dx, dy ) {
11628			return $.extend( this._change.n.apply( this, arguments ),
11629				this._change.w.apply( this, [ event, dx, dy ] ) );
11630		}
11631	},
11632
11633	_propagate: function( n, event ) {
11634		$.ui.plugin.call( this, n, [ event, this.ui() ] );
11635		if ( n !== "resize" ) {
11636			this._trigger( n, event, this.ui() );
11637		}
11638	},
11639
11640	plugins: {},
11641
11642	ui: function() {
11643		return {
11644			originalElement: this.originalElement,
11645			element: this.element,
11646			helper: this.helper,
11647			position: this.position,
11648			size: this.size,
11649			originalSize: this.originalSize,
11650			originalPosition: this.originalPosition
11651		};
11652	}
11653
11654} );
11655
11656/*
11657 * Resizable Extensions
11658 */
11659
11660$.ui.plugin.add( "resizable", "animate", {
11661
11662	stop: function( event ) {
11663		var that = $( this ).resizable( "instance" ),
11664			o = that.options,
11665			pr = that._proportionallyResizeElements,
11666			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
11667			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
11668			soffsetw = ista ? 0 : that.sizeDiff.width,
11669			style = {
11670				width: ( that.size.width - soffsetw ),
11671				height: ( that.size.height - soffseth )
11672			},
11673			left = ( parseFloat( that.element.css( "left" ) ) +
11674				( that.position.left - that.originalPosition.left ) ) || null,
11675			top = ( parseFloat( that.element.css( "top" ) ) +
11676				( that.position.top - that.originalPosition.top ) ) || null;
11677
11678		that.element.animate(
11679			$.extend( style, top && left ? { top: top, left: left } : {} ), {
11680				duration: o.animateDuration,
11681				easing: o.animateEasing,
11682				step: function() {
11683
11684					var data = {
11685						width: parseFloat( that.element.css( "width" ) ),
11686						height: parseFloat( that.element.css( "height" ) ),
11687						top: parseFloat( that.element.css( "top" ) ),
11688						left: parseFloat( that.element.css( "left" ) )
11689					};
11690
11691					if ( pr && pr.length ) {
11692						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
11693					}
11694
11695					// Propagating resize, and updating values for each animation step
11696					that._updateCache( data );
11697					that._propagate( "resize", event );
11698
11699				}
11700			}
11701		);
11702	}
11703
11704} );
11705
11706$.ui.plugin.add( "resizable", "containment", {
11707
11708	start: function() {
11709		var element, p, co, ch, cw, width, height,
11710			that = $( this ).resizable( "instance" ),
11711			o = that.options,
11712			el = that.element,
11713			oc = o.containment,
11714			ce = ( oc instanceof $ ) ?
11715				oc.get( 0 ) :
11716				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
11717
11718		if ( !ce ) {
11719			return;
11720		}
11721
11722		that.containerElement = $( ce );
11723
11724		if ( /document/.test( oc ) || oc === document ) {
11725			that.containerOffset = {
11726				left: 0,
11727				top: 0
11728			};
11729			that.containerPosition = {
11730				left: 0,
11731				top: 0
11732			};
11733
11734			that.parentData = {
11735				element: $( document ),
11736				left: 0,
11737				top: 0,
11738				width: $( document ).width(),
11739				height: $( document ).height() || document.body.parentNode.scrollHeight
11740			};
11741		} else {
11742			element = $( ce );
11743			p = [];
11744			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
11745				p[ i ] = that._num( element.css( "padding" + name ) );
11746			} );
11747
11748			that.containerOffset = element.offset();
11749			that.containerPosition = element.position();
11750			that.containerSize = {
11751				height: ( element.innerHeight() - p[ 3 ] ),
11752				width: ( element.innerWidth() - p[ 1 ] )
11753			};
11754
11755			co = that.containerOffset;
11756			ch = that.containerSize.height;
11757			cw = that.containerSize.width;
11758			width = ( that._hasScroll( ce, "left" ) ? ce.scrollWidth : cw );
11759			height = ( that._hasScroll( ce ) ? ce.scrollHeight : ch );
11760
11761			that.parentData = {
11762				element: ce,
11763				left: co.left,
11764				top: co.top,
11765				width: width,
11766				height: height
11767			};
11768		}
11769	},
11770
11771	resize: function( event ) {
11772		var woset, hoset, isParent, isOffsetRelative,
11773			that = $( this ).resizable( "instance" ),
11774			o = that.options,
11775			co = that.containerOffset,
11776			cp = that.position,
11777			pRatio = that._aspectRatio || event.shiftKey,
11778			cop = {
11779				top: 0,
11780				left: 0
11781			},
11782			ce = that.containerElement,
11783			continueResize = true;
11784
11785		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
11786			cop = co;
11787		}
11788
11789		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
11790			that.size.width = that.size.width +
11791				( that._helper ?
11792					( that.position.left - co.left ) :
11793					( that.position.left - cop.left ) );
11794
11795			if ( pRatio ) {
11796				that.size.height = that.size.width / that.aspectRatio;
11797				continueResize = false;
11798			}
11799			that.position.left = o.helper ? co.left : 0;
11800		}
11801
11802		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
11803			that.size.height = that.size.height +
11804				( that._helper ?
11805					( that.position.top - co.top ) :
11806					that.position.top );
11807
11808			if ( pRatio ) {
11809				that.size.width = that.size.height * that.aspectRatio;
11810				continueResize = false;
11811			}
11812			that.position.top = that._helper ? co.top : 0;
11813		}
11814
11815		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
11816		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
11817
11818		if ( isParent && isOffsetRelative ) {
11819			that.offset.left = that.parentData.left + that.position.left;
11820			that.offset.top = that.parentData.top + that.position.top;
11821		} else {
11822			that.offset.left = that.element.offset().left;
11823			that.offset.top = that.element.offset().top;
11824		}
11825
11826		woset = Math.abs( that.sizeDiff.width +
11827			( that._helper ?
11828				that.offset.left - cop.left :
11829				( that.offset.left - co.left ) ) );
11830
11831		hoset = Math.abs( that.sizeDiff.height +
11832			( that._helper ?
11833				that.offset.top - cop.top :
11834				( that.offset.top - co.top ) ) );
11835
11836		if ( woset + that.size.width >= that.parentData.width ) {
11837			that.size.width = that.parentData.width - woset;
11838			if ( pRatio ) {
11839				that.size.height = that.size.width / that.aspectRatio;
11840				continueResize = false;
11841			}
11842		}
11843
11844		if ( hoset + that.size.height >= that.parentData.height ) {
11845			that.size.height = that.parentData.height - hoset;
11846			if ( pRatio ) {
11847				that.size.width = that.size.height * that.aspectRatio;
11848				continueResize = false;
11849			}
11850		}
11851
11852		if ( !continueResize ) {
11853			that.position.left = that.prevPosition.left;
11854			that.position.top = that.prevPosition.top;
11855			that.size.width = that.prevSize.width;
11856			that.size.height = that.prevSize.height;
11857		}
11858	},
11859
11860	stop: function() {
11861		var that = $( this ).resizable( "instance" ),
11862			o = that.options,
11863			co = that.containerOffset,
11864			cop = that.containerPosition,
11865			ce = that.containerElement,
11866			helper = $( that.helper ),
11867			ho = helper.offset(),
11868			w = helper.outerWidth() - that.sizeDiff.width,
11869			h = helper.outerHeight() - that.sizeDiff.height;
11870
11871		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
11872			$( this ).css( {
11873				left: ho.left - cop.left - co.left,
11874				width: w,
11875				height: h
11876			} );
11877		}
11878
11879		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
11880			$( this ).css( {
11881				left: ho.left - cop.left - co.left,
11882				width: w,
11883				height: h
11884			} );
11885		}
11886	}
11887} );
11888
11889$.ui.plugin.add( "resizable", "alsoResize", {
11890
11891	start: function() {
11892		var that = $( this ).resizable( "instance" ),
11893			o = that.options;
11894
11895		$( o.alsoResize ).each( function() {
11896			var el = $( this ),
11897				elSize = that._calculateAdjustedElementDimensions( el );
11898
11899			el.data( "ui-resizable-alsoresize", {
11900				width: elSize.width, height: elSize.height,
11901				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
11902			} );
11903		} );
11904	},
11905
11906	resize: function( event, ui ) {
11907		var that = $( this ).resizable( "instance" ),
11908			o = that.options,
11909			os = that.originalSize,
11910			op = that.originalPosition,
11911			delta = {
11912				height: ( that.size.height - os.height ) || 0,
11913				width: ( that.size.width - os.width ) || 0,
11914				top: ( that.position.top - op.top ) || 0,
11915				left: ( that.position.left - op.left ) || 0
11916			};
11917
11918			$( o.alsoResize ).each( function() {
11919				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
11920					css = el.parents( ui.originalElement[ 0 ] ).length ?
11921							[ "width", "height" ] :
11922							[ "width", "height", "top", "left" ];
11923
11924				$.each( css, function( i, prop ) {
11925					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
11926					if ( sum && sum >= 0 ) {
11927						style[ prop ] = sum || null;
11928					}
11929				} );
11930
11931				el.css( style );
11932			} );
11933	},
11934
11935	stop: function() {
11936		$( this ).removeData( "ui-resizable-alsoresize" );
11937	}
11938} );
11939
11940$.ui.plugin.add( "resizable", "ghost", {
11941
11942	start: function() {
11943
11944		var that = $( this ).resizable( "instance" ), cs = that.size;
11945
11946		that.ghost = that.originalElement.clone();
11947		that.ghost.css( {
11948			opacity: 0.25,
11949			display: "block",
11950			position: "relative",
11951			height: cs.height,
11952			width: cs.width,
11953			margin: 0,
11954			left: 0,
11955			top: 0
11956		} );
11957
11958		that._addClass( that.ghost, "ui-resizable-ghost" );
11959
11960		// DEPRECATED
11961		// TODO: remove after 1.12
11962		if ( $.uiBackCompat === true && typeof that.options.ghost === "string" ) {
11963
11964			// Ghost option
11965			that.ghost.addClass( this.options.ghost );
11966		}
11967
11968		that.ghost.appendTo( that.helper );
11969
11970	},
11971
11972	resize: function() {
11973		var that = $( this ).resizable( "instance" );
11974		if ( that.ghost ) {
11975			that.ghost.css( {
11976				position: "relative",
11977				height: that.size.height,
11978				width: that.size.width
11979			} );
11980		}
11981	},
11982
11983	stop: function() {
11984		var that = $( this ).resizable( "instance" );
11985		if ( that.ghost && that.helper ) {
11986			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
11987		}
11988	}
11989
11990} );
11991
11992$.ui.plugin.add( "resizable", "grid", {
11993
11994	resize: function() {
11995		var outerDimensions,
11996			that = $( this ).resizable( "instance" ),
11997			o = that.options,
11998			cs = that.size,
11999			os = that.originalSize,
12000			op = that.originalPosition,
12001			a = that.axis,
12002			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
12003			gridX = ( grid[ 0 ] || 1 ),
12004			gridY = ( grid[ 1 ] || 1 ),
12005			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
12006			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
12007			newWidth = os.width + ox,
12008			newHeight = os.height + oy,
12009			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
12010			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
12011			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
12012			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
12013
12014		o.grid = grid;
12015
12016		if ( isMinWidth ) {
12017			newWidth += gridX;
12018		}
12019		if ( isMinHeight ) {
12020			newHeight += gridY;
12021		}
12022		if ( isMaxWidth ) {
12023			newWidth -= gridX;
12024		}
12025		if ( isMaxHeight ) {
12026			newHeight -= gridY;
12027		}
12028
12029		if ( /^(se|s|e)$/.test( a ) ) {
12030			that.size.width = newWidth;
12031			that.size.height = newHeight;
12032		} else if ( /^(ne)$/.test( a ) ) {
12033			that.size.width = newWidth;
12034			that.size.height = newHeight;
12035			that.position.top = op.top - oy;
12036		} else if ( /^(sw)$/.test( a ) ) {
12037			that.size.width = newWidth;
12038			that.size.height = newHeight;
12039			that.position.left = op.left - ox;
12040		} else {
12041			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
12042				outerDimensions = that._getPaddingPlusBorderDimensions( this );
12043			}
12044
12045			if ( newHeight - gridY > 0 ) {
12046				that.size.height = newHeight;
12047				that.position.top = op.top - oy;
12048			} else {
12049				newHeight = gridY - outerDimensions.height;
12050				that.size.height = newHeight;
12051				that.position.top = op.top + os.height - newHeight;
12052			}
12053			if ( newWidth - gridX > 0 ) {
12054				that.size.width = newWidth;
12055				that.position.left = op.left - ox;
12056			} else {
12057				newWidth = gridX - outerDimensions.width;
12058				that.size.width = newWidth;
12059				that.position.left = op.left + os.width - newWidth;
12060			}
12061		}
12062	}
12063
12064} );
12065
12066var widgetsResizable = $.ui.resizable;
12067
12068
12069/*!
12070 * jQuery UI Dialog 1.14.
120701
12071 * https://jqueryui.com
12072 *
12073 * Copyright OpenJS Foundation and other contributors
12074 * Released under the MIT license.
12075 * https://jquery.org/license
12076 */
12077
12078//>>label: Dialog
12079//>>group: Widgets
12080//>>description: Displays customizable dialog windows.
12081//>>docs: https://api.jqueryui.com/dialog/
12082//>>demos: https://jqueryui.com/dialog/
12083//>>css.structure: ../../themes/base/core.css
12084//>>css.structure: ../../themes/base/dialog.css
12085//>>css.theme: ../../themes/base/theme.css
12086
12087
12088$.widget( "ui.dialog", {
12089	version: "1.14.1
vendor: 22,384 bytes, lines 12089-12988
12089",
12090	options: {
12091		appendTo: "body",
12092		autoOpen: true,
12093		buttons: [],
12094		classes: {
12095			"ui-dialog": "ui-corner-all",
12096			"ui-dialog-titlebar": "ui-corner-all"
12097		},
12098		closeOnEscape: true,
12099		closeText: "Close",
12100		draggable: true,
12101		hide: null,
12102		height: "auto",
12103		maxHeight: null,
12104		maxWidth: null,
12105		minHeight: 150,
12106		minWidth: 150,
12107		modal: false,
12108		position: {
12109			my: "center",
12110			at: "center",
12111			of: window,
12112			collision: "fit",
12113
12114			// Ensure the titlebar is always visible
12115			using: function( pos ) {
12116				var topOffset = $( this ).css( pos ).offset().top;
12117				if ( topOffset < 0 ) {
12118					$( this ).css( "top", pos.top - topOffset );
12119				}
12120			}
12121		},
12122		resizable: true,
12123		show: null,
12124		title: null,
12125		uiDialogTitleHeadingLevel: 0,
12126		width: 300,
12127
12128		// Callbacks
12129		beforeClose: null,
12130		close: null,
12131		drag: null,
12132		dragStart: null,
12133		dragStop: null,
12134		focus: null,
12135		open: null,
12136		resize: null,
12137		resizeStart: null,
12138		resizeStop: null
12139	},
12140
12141	sizeRelatedOptions: {
12142		buttons: true,
12143		height: true,
12144		maxHeight: true,
12145		maxWidth: true,
12146		minHeight: true,
12147		minWidth: true,
12148		width: true
12149	},
12150
12151	resizableRelatedOptions: {
12152		maxHeight: true,
12153		maxWidth: true,
12154		minHeight: true,
12155		minWidth: true
12156	},
12157
12158	_create: function() {
12159		this.originalCss = {
12160			display: this.element[ 0 ].style.display,
12161			width: this.element[ 0 ].style.width,
12162			minHeight: this.element[ 0 ].style.minHeight,
12163			maxHeight: this.element[ 0 ].style.maxHeight,
12164			height: this.element[ 0 ].style.height
12165		};
12166		this.originalPosition = {
12167			parent: this.element.parent(),
12168			index: this.element.parent().children().index( this.element )
12169		};
12170		this.originalTitle = this.element.attr( "title" );
12171		if ( this.options.title == null && this.originalTitle != null ) {
12172			this.options.title = this.originalTitle;
12173		}
12174
12175		// Dialogs can't be disabled
12176		if ( this.options.disabled ) {
12177			this.options.disabled = false;
12178		}
12179
12180		this._createWrapper();
12181
12182		this.element
12183			.show()
12184			.removeAttr( "title" )
12185			.appendTo( this.uiDialog );
12186
12187		this._addClass( "ui-dialog-content", "ui-widget-content" );
12188
12189		this._createTitlebar();
12190		this._createButtonPane();
12191
12192		if ( this.options.draggable && $.fn.draggable ) {
12193			this._makeDraggable();
12194		}
12195		if ( this.options.resizable && $.fn.resizable ) {
12196			this._makeResizable();
12197		}
12198
12199		this._isOpen = false;
12200
12201		this._trackFocus();
12202	},
12203
12204	_init: function() {
12205		if ( this.options.autoOpen ) {
12206			this.open();
12207		}
12208	},
12209
12210	_appendTo: function() {
12211		var element = this.options.appendTo;
12212		if ( element && ( element.jquery || element.nodeType ) ) {
12213			return $( element );
12214		}
12215		return this.document.find( element || "body" ).eq( 0 );
12216	},
12217
12218	_destroy: function() {
12219		var next,
12220			originalPosition = this.originalPosition;
12221
12222		this._untrackInstance();
12223		this._destroyOverlay();
12224
12225		this.element
12226			.removeUniqueId()
12227			.css( this.originalCss )
12228
12229			// Without detaching first, the following becomes really slow
12230			.detach();
12231
12232		this.uiDialog.remove();
12233
12234		if ( this.originalTitle ) {
12235			this.element.attr( "title", this.originalTitle );
12236		}
12237
12238		next = originalPosition.parent.children().eq( originalPosition.index );
12239
12240		// Don't try to place the dialog next to itself (#8613)
12241		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
12242			next.before( this.element );
12243		} else {
12244			originalPosition.parent.append( this.element );
12245		}
12246	},
12247
12248	widget: function() {
12249		return this.uiDialog;
12250	},
12251
12252	disable: $.noop,
12253	enable: $.noop,
12254
12255	close: function( event ) {
12256		var that = this;
12257
12258		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
12259			return;
12260		}
12261
12262		this._isOpen = false;
12263		this._focusedElement = null;
12264		this._destroyOverlay();
12265		this._untrackInstance();
12266
12267		if ( !this.opener.filter( ":focusable" ).trigger( "focus" ).length ) {
12268
12269			// Hiding a focused element doesn't trigger blur in WebKit
12270			// so in case we have nothing to focus on, explicitly blur the active element
12271			// https://bugs.webkit.org/show_bug.cgi?id=47182
12272			$( this.document[ 0 ].activeElement ).trigger( "blur" );
12273		}
12274
12275		this._hide( this.uiDialog, this.options.hide, function() {
12276			that._trigger( "close", event );
12277		} );
12278	},
12279
12280	isOpen: function() {
12281		return this._isOpen;
12282	},
12283
12284	moveToTop: function() {
12285		this._moveToTop();
12286	},
12287
12288	_moveToTop: function( event, silent ) {
12289		var moved = false,
12290			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map( function() {
12291				return +$( this ).css( "z-index" );
12292			} ).get(),
12293			zIndexMax = Math.max.apply( null, zIndices );
12294
12295		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
12296			this.uiDialog.css( "z-index", zIndexMax + 1 );
12297			moved = true;
12298		}
12299
12300		if ( moved && !silent ) {
12301			this._trigger( "focus", event );
12302		}
12303		return moved;
12304	},
12305
12306	open: function() {
12307		var that = this;
12308		if ( this._isOpen ) {
12309			if ( this._moveToTop() ) {
12310				this._focusTabbable();
12311			}
12312			return;
12313		}
12314
12315		this._isOpen = true;
12316		this.opener = $( this.document[ 0 ].activeElement );
12317
12318		this._size();
12319		this._position();
12320		this._createOverlay();
12321		this._moveToTop( null, true );
12322
12323		// Ensure the overlay is moved to the top with the dialog, but only when
12324		// opening. The overlay shouldn't move after the dialog is open so that
12325		// modeless dialogs opened after the modal dialog stack properly.
12326		if ( this.overlay ) {
12327			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
12328		}
12329
12330		this._show( this.uiDialog, this.options.show, function() {
12331			that._focusTabbable();
12332			that._trigger( "focus" );
12333		} );
12334
12335		// Track the dialog immediately upon opening in case a focus event
12336		// somehow occurs outside of the dialog before an element inside the
12337		// dialog is focused (#10152)
12338		this._makeFocusTarget();
12339
12340		this._trigger( "open" );
12341	},
12342
12343	_focusTabbable: function() {
12344
12345		// Set focus to the first match:
12346		// 1. An element that was focused previously
12347		// 2. First element inside the dialog matching [autofocus]
12348		// 3. Tabbable element inside the content element
12349		// 4. Tabbable element inside the buttonpane
12350		// 5. The close button
12351		// 6. The dialog itself
12352		var hasFocus = this._focusedElement;
12353		if ( !hasFocus ) {
12354			hasFocus = this.element.find( "[autofocus]" );
12355		}
12356		if ( !hasFocus.length ) {
12357			hasFocus = this.element.find( ":tabbable" );
12358		}
12359		if ( !hasFocus.length ) {
12360			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
12361		}
12362		if ( !hasFocus.length ) {
12363			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
12364		}
12365		if ( !hasFocus.length ) {
12366			hasFocus = this.uiDialog;
12367		}
12368		hasFocus.eq( 0 ).trigger( "focus" );
12369	},
12370
12371	_restoreTabbableFocus: function() {
12372		var activeElement = this.document[ 0 ].activeElement,
12373			isActive = this.uiDialog[ 0 ] === activeElement ||
12374				$.contains( this.uiDialog[ 0 ], activeElement );
12375		if ( !isActive ) {
12376			this._focusTabbable();
12377		}
12378	},
12379
12380	_keepFocus: function( event ) {
12381		event.preventDefault();
12382		this._restoreTabbableFocus();
12383	},
12384
12385	_createWrapper: function() {
12386		this.uiDialog = $( "<div>" )
12387			.hide()
12388			.attr( {
12389
12390				// Setting tabIndex makes the div focusable
12391				tabIndex: -1,
12392				role: "dialog",
12393				"aria-modal": this.options.modal ? "true" : null
12394			} )
12395			.appendTo( this._appendTo() );
12396
12397		this._addClass( this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front" );
12398		this._on( this.uiDialog, {
12399			keydown: function( event ) {
12400				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12401						event.keyCode === $.ui.keyCode.ESCAPE ) {
12402					event.preventDefault();
12403					this.close( event );
12404					return;
12405				}
12406
12407				// Prevent tabbing out of dialogs
12408				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
12409					return;
12410				}
12411				var tabbables = this.uiDialog.find( ":tabbable" ),
12412					first = tabbables.first(),
12413					last = tabbables.last();
12414
12415				if ( ( event.target === last[ 0 ] || event.target === this.uiDialog[ 0 ] ) &&
12416						!event.shiftKey ) {
12417					this._delay( function() {
12418						first.trigger( "focus" );
12419					} );
12420					event.preventDefault();
12421				} else if ( ( event.target === first[ 0 ] ||
12422						event.target === this.uiDialog[ 0 ] ) && event.shiftKey ) {
12423					this._delay( function() {
12424						last.trigger( "focus" );
12425					} );
12426					event.preventDefault();
12427				}
12428			},
12429			mousedown: function( event ) {
12430				if ( this._moveToTop( event ) ) {
12431					this._focusTabbable();
12432				}
12433			}
12434		} );
12435
12436		// We assume that any existing aria-describedby attribute means
12437		// that the dialog content is marked up properly
12438		// otherwise we brute force the content as the description
12439		if ( !this.element.find( "[aria-describedby]" ).length ) {
12440			this.uiDialog.attr( {
12441				"aria-describedby": this.element.uniqueId().attr( "id" )
12442			} );
12443		}
12444	},
12445
12446	_createTitlebar: function() {
12447		var uiDialogTitle;
12448
12449		this.uiDialogTitlebar = $( "<div>" );
12450		this._addClass( this.uiDialogTitlebar,
12451			"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix" );
12452		this._on( this.uiDialogTitlebar, {
12453			mousedown: function( event ) {
12454
12455				// Don't prevent click on close button (#8838)
12456				// Focusing a dialog that is partially scrolled out of view
12457				// causes the browser to scroll it into view, preventing the click event
12458				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
12459
12460					// Dialog isn't getting focus when dragging (#8063)
12461					this.uiDialog.trigger( "focus" );
12462				}
12463			}
12464		} );
12465
12466		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
12467			.button( {
12468				label: $( "<a>" ).text( this.options.closeText ).html(),
12469				icon: "ui-icon-closethick",
12470				showLabel: false
12471			} )
12472			.appendTo( this.uiDialogTitlebar );
12473
12474		this._addClass( this.uiDialogTitlebarClose, "ui-dialog-titlebar-close" );
12475		this._on( this.uiDialogTitlebarClose, {
12476			click: function( event ) {
12477				event.preventDefault();
12478				this.close( event );
12479			}
12480		} );
12481
12482		var uiDialogHeadingLevel = Number.isInteger( this.options.uiDialogTitleHeadingLevel ) &&
12483			this.options.uiDialogTitleHeadingLevel > 0 &&
12484			this.options.uiDialogTitleHeadingLevel <= 6 ?
12485			"h" + this.options.uiDialogTitleHeadingLevel : "span";
12486
12487		uiDialogTitle = $( "<" + uiDialogHeadingLevel + ">" )
12488			.uniqueId().prependTo( this.uiDialogTitlebar );
12489		this._addClass( uiDialogTitle, "ui-dialog-title" );
12490		this._title( uiDialogTitle );
12491
12492		this.uiDialogTitlebar.prependTo( this.uiDialog );
12493
12494		this.uiDialog.attr( {
12495			"aria-labelledby": uiDialogTitle.attr( "id" )
12496		} );
12497	},
12498
12499	_title: function( title ) {
12500		if ( this.options.title ) {
12501			title.text( this.options.title );
12502		} else {
12503			title.html( "&#160;" );
12504		}
12505	},
12506
12507	_createButtonPane: function() {
12508		this.uiDialogButtonPane = $( "<div>" );
12509		this._addClass( this.uiDialogButtonPane, "ui-dialog-buttonpane",
12510			"ui-widget-content ui-helper-clearfix" );
12511
12512		this.uiButtonSet = $( "<div>" )
12513			.appendTo( this.uiDialogButtonPane );
12514		this._addClass( this.uiButtonSet, "ui-dialog-buttonset" );
12515
12516		this._createButtons();
12517	},
12518
12519	_createButtons: function() {
12520		var that = this,
12521			buttons = this.options.buttons;
12522
12523		// If we already have a button pane, remove it
12524		this.uiDialogButtonPane.remove();
12525		this.uiButtonSet.empty();
12526
12527		if ( $.isEmptyObject( buttons ) || ( Array.isArray( buttons ) && !buttons.length ) ) {
12528			this._removeClass( this.uiDialog, "ui-dialog-buttons" );
12529			return;
12530		}
12531
12532		$.each( buttons, function( name, props ) {
12533			var click, buttonOptions;
12534			props = typeof props === "function" ?
12535				{ click: props, text: name } :
12536				props;
12537
12538			// Default to a non-submitting button
12539			props = $.extend( { type: "button" }, props );
12540
12541			// Change the context for the click callback to be the main element
12542			click = props.click;
12543			buttonOptions = {
12544				icon: props.icon,
12545				iconPosition: props.iconPosition,
12546				showLabel: props.showLabel,
12547
12548				// Deprecated options
12549				icons: props.icons,
12550				text: props.text
12551			};
12552
12553			delete props.click;
12554			delete props.icon;
12555			delete props.iconPosition;
12556			delete props.showLabel;
12557
12558			// Deprecated options
12559			delete props.icons;
12560			if ( typeof props.text === "boolean" ) {
12561				delete props.text;
12562			}
12563
12564			$( "<button></button>", props )
12565				.button( buttonOptions )
12566				.appendTo( that.uiButtonSet )
12567				.on( "click", function() {
12568					click.apply( that.element[ 0 ], arguments );
12569				} );
12570		} );
12571		this._addClass( this.uiDialog, "ui-dialog-buttons" );
12572		this.uiDialogButtonPane.appendTo( this.uiDialog );
12573	},
12574
12575	_makeDraggable: function() {
12576		var that = this,
12577			options = this.options;
12578
12579		function filteredUi( ui ) {
12580			return {
12581				position: ui.position,
12582				offset: ui.offset
12583			};
12584		}
12585
12586		this.uiDialog.draggable( {
12587			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12588			handle: ".ui-dialog-titlebar",
12589			containment: "document",
12590			start: function( event, ui ) {
12591				that._addClass( $( this ), "ui-dialog-dragging" );
12592				that._blockFrames();
12593				that._trigger( "dragStart", event, filteredUi( ui ) );
12594			},
12595			drag: function( event, ui ) {
12596				that._trigger( "drag", event, filteredUi( ui ) );
12597			},
12598			stop: function( event, ui ) {
12599				var left = ui.offset.left - that.document.scrollLeft(),
12600					top = ui.offset.top - that.document.scrollTop();
12601
12602				options.position = {
12603					my: "left top",
12604					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12605						"top" + ( top >= 0 ? "+" : "" ) + top,
12606					of: that.window
12607				};
12608				that._removeClass( $( this ), "ui-dialog-dragging" );
12609				that._unblockFrames();
12610				that._trigger( "dragStop", event, filteredUi( ui ) );
12611			}
12612		} );
12613	},
12614
12615	_makeResizable: function() {
12616		var that = this,
12617			options = this.options,
12618			handles = options.resizable,
12619
12620			// .ui-resizable has position: relative defined in the stylesheet
12621			// but dialogs have to use absolute or fixed positioning
12622			position = this.uiDialog.css( "position" ),
12623			resizeHandles = typeof handles === "string" ?
12624				handles :
12625				"n,e,s,w,se,sw,ne,nw";
12626
12627		function filteredUi( ui ) {
12628			return {
12629				originalPosition: ui.originalPosition,
12630				originalSize: ui.originalSize,
12631				position: ui.position,
12632				size: ui.size
12633			};
12634		}
12635
12636		this.uiDialog.resizable( {
12637			cancel: ".ui-dialog-content",
12638			containment: "document",
12639			alsoResize: this.element,
12640			maxWidth: options.maxWidth,
12641			maxHeight: options.maxHeight,
12642			minWidth: options.minWidth,
12643			minHeight: this._minHeight(),
12644			handles: resizeHandles,
12645			start: function( event, ui ) {
12646				that._addClass( $( this ), "ui-dialog-resizing" );
12647				that._blockFrames();
12648				that._trigger( "resizeStart", event, filteredUi( ui ) );
12649			},
12650			resize: function( event, ui ) {
12651				that._trigger( "resize", event, filteredUi( ui ) );
12652			},
12653			stop: function( event, ui ) {
12654				var offset = that.uiDialog.offset(),
12655					left = offset.left - that.document.scrollLeft(),
12656					top = offset.top - that.document.scrollTop();
12657
12658				options.height = that.uiDialog.height();
12659				options.width = that.uiDialog.width();
12660				options.position = {
12661					my: "left top",
12662					at: "left" + ( left >= 0 ? "+" : "" ) + left + " " +
12663						"top" + ( top >= 0 ? "+" : "" ) + top,
12664					of: that.window
12665				};
12666				that._removeClass( $( this ), "ui-dialog-resizing" );
12667				that._unblockFrames();
12668				that._trigger( "resizeStop", event, filteredUi( ui ) );
12669			}
12670		} )
12671			.css( "position", position );
12672	},
12673
12674	_trackFocus: function() {
12675		this._on( this.widget(), {
12676			focusin: function( event ) {
12677				this._makeFocusTarget();
12678				this._focusedElement = $( event.target );
12679			}
12680		} );
12681	},
12682
12683	_makeFocusTarget: function() {
12684		this._untrackInstance();
12685		this._trackingInstances().unshift( this );
12686	},
12687
12688	_untrackInstance: function() {
12689		var instances = this._trackingInstances(),
12690			exists = $.inArray( this, instances );
12691		if ( exists !== -1 ) {
12692			instances.splice( exists, 1 );
12693		}
12694	},
12695
12696	_trackingInstances: function() {
12697		var instances = this.document.data( "ui-dialog-instances" );
12698		if ( !instances ) {
12699			instances = [];
12700			this.document.data( "ui-dialog-instances", instances );
12701		}
12702		return instances;
12703	},
12704
12705	_minHeight: function() {
12706		var options = this.options;
12707
12708		return options.height === "auto" ?
12709			options.minHeight :
12710			Math.min( options.minHeight, options.height );
12711	},
12712
12713	_position: function() {
12714
12715		// Need to show the dialog to get the actual offset in the position plugin
12716		var isVisible = this.uiDialog.is( ":visible" );
12717		if ( !isVisible ) {
12718			this.uiDialog.show();
12719		}
12720		this.uiDialog.position( this.options.position );
12721		if ( !isVisible ) {
12722			this.uiDialog.hide();
12723		}
12724	},
12725
12726	_setOptions: function( options ) {
12727		var that = this,
12728			resize = false,
12729			resizableOptions = {};
12730
12731		$.each( options, function( key, value ) {
12732			that._setOption( key, value );
12733
12734			if ( key in that.sizeRelatedOptions ) {
12735				resize = true;
12736			}
12737			if ( key in that.resizableRelatedOptions ) {
12738				resizableOptions[ key ] = value;
12739			}
12740		} );
12741
12742		if ( resize ) {
12743			this._size();
12744			this._position();
12745		}
12746		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12747			this.uiDialog.resizable( "option", resizableOptions );
12748		}
12749	},
12750
12751	_setOption: function( key, value ) {
12752		var isDraggable, isResizable,
12753			uiDialog = this.uiDialog;
12754
12755		if ( key === "disabled" ) {
12756			return;
12757		}
12758
12759		this._super( key, value );
12760
12761		if ( key === "appendTo" ) {
12762			this.uiDialog.appendTo( this._appendTo() );
12763		}
12764
12765		if ( key === "buttons" ) {
12766			this._createButtons();
12767		}
12768
12769		if ( key === "closeText" ) {
12770			this.uiDialogTitlebarClose.button( {
12771
12772				// Ensure that we always pass a string
12773				label: $( "<a>" ).text( "" + this.options.closeText ).html()
12774			} );
12775		}
12776
12777		if ( key === "draggable" ) {
12778			isDraggable = uiDialog.is( ":data(ui-draggable)" );
12779			if ( isDraggable && !value ) {
12780				uiDialog.draggable( "destroy" );
12781			}
12782
12783			if ( !isDraggable && value ) {
12784				this._makeDraggable();
12785			}
12786		}
12787
12788		if ( key === "position" ) {
12789			this._position();
12790		}
12791
12792		if ( key === "resizable" ) {
12793
12794			// currently resizable, becoming non-resizable
12795			isResizable = uiDialog.is( ":data(ui-resizable)" );
12796			if ( isResizable && !value ) {
12797				uiDialog.resizable( "destroy" );
12798			}
12799
12800			// Currently resizable, changing handles
12801			if ( isResizable && typeof value === "string" ) {
12802				uiDialog.resizable( "option", "handles", value );
12803			}
12804
12805			// Currently non-resizable, becoming resizable
12806			if ( !isResizable && value !== false ) {
12807				this._makeResizable();
12808			}
12809		}
12810
12811		if ( key === "title" ) {
12812			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
12813		}
12814
12815		if ( key === "modal" ) {
12816			uiDialog.attr( "aria-modal", value ? "true" : null );
12817		}
12818	},
12819
12820	_size: function() {
12821
12822		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12823		// divs will both have width and height set, so we need to reset them
12824		var nonContentHeight, minContentHeight, maxContentHeight,
12825			options = this.options;
12826
12827		// Reset content sizing
12828		this.element.show().css( {
12829			width: "auto",
12830			minHeight: 0,
12831			maxHeight: "none",
12832			height: 0
12833		} );
12834
12835		if ( options.minWidth > options.width ) {
12836			options.width = options.minWidth;
12837		}
12838
12839		// Reset wrapper sizing
12840		// determine the height of all the non-content elements
12841		nonContentHeight = this.uiDialog.css( {
12842			height: "auto",
12843			width: options.width
12844		} )
12845			.outerHeight();
12846		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
12847		maxContentHeight = typeof options.maxHeight === "number" ?
12848			Math.max( 0, options.maxHeight - nonContentHeight ) :
12849			"none";
12850
12851		if ( options.height === "auto" ) {
12852			this.element.css( {
12853				minHeight: minContentHeight,
12854				maxHeight: maxContentHeight,
12855				height: "auto"
12856			} );
12857		} else {
12858			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
12859		}
12860
12861		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
12862			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
12863		}
12864	},
12865
12866	_blockFrames: function() {
12867		this.iframeBlocks = this.document.find( "iframe" ).map( function() {
12868			var iframe = $( this );
12869
12870			return $( "<div>" )
12871				.css( {
12872					position: "absolute",
12873					width: iframe.outerWidth(),
12874					height: iframe.outerHeight()
12875				} )
12876				.appendTo( iframe.parent() )
12877				.offset( iframe.offset() )[ 0 ];
12878		} );
12879	},
12880
12881	_unblockFrames: function() {
12882		if ( this.iframeBlocks ) {
12883			this.iframeBlocks.remove();
12884			delete this.iframeBlocks;
12885		}
12886	},
12887
12888	_allowInteraction: function( event ) {
12889		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
12890			return true;
12891		}
12892
12893		// TODO: Remove hack when datepicker implements
12894		// the .ui-front logic (#8989)
12895		return !!$( event.target ).closest( ".ui-datepicker" ).length;
12896	},
12897
12898	_createOverlay: function() {
12899		if ( !this.options.modal ) {
12900			return;
12901		}
12902
12903		// We use a delay in case the overlay is created from an
12904		// event that we're going to be cancelling (#2804)
12905		var isOpening = true;
12906		this._delay( function() {
12907			isOpening = false;
12908		} );
12909
12910		if ( !this.document.data( "ui-dialog-overlays" ) ) {
12911
12912			// Prevent use of anchors and inputs
12913			// This doesn't use `_on()` because it is a shared event handler
12914			// across all open modal dialogs.
12915			this.document.on( "focusin.ui-dialog", function( event ) {
12916				if ( isOpening ) {
12917					return;
12918				}
12919
12920				var instance = this._trackingInstances()[ 0 ];
12921				if ( !instance._allowInteraction( event ) ) {
12922					event.preventDefault();
12923					instance._focusTabbable();
12924				}
12925			}.bind( this ) );
12926		}
12927
12928		this.overlay = $( "<div>" )
12929			.appendTo( this._appendTo() );
12930
12931		this._addClass( this.overlay, null, "ui-widget-overlay ui-front" );
12932		this._on( this.overlay, {
12933			mousedown: "_keepFocus"
12934		} );
12935		this.document.data( "ui-dialog-overlays",
12936			( this.document.data( "ui-dialog-overlays" ) || 0 ) + 1 );
12937	},
12938
12939	_destroyOverlay: function() {
12940		if ( !this.options.modal ) {
12941			return;
12942		}
12943
12944		if ( this.overlay ) {
12945			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;
12946
12947			if ( !overlays ) {
12948				this.document.off( "focusin.ui-dialog" );
12949				this.document.removeData( "ui-dialog-overlays" );
12950			} else {
12951				this.document.data( "ui-dialog-overlays", overlays );
12952			}
12953
12954			this.overlay.remove();
12955			this.overlay = null;
12956		}
12957	}
12958} );
12959
12960// DEPRECATED
12961// TODO: switch return back to widget declaration at top of file when this is removed
12962if ( $.uiBackCompat === true ) {
12963
12964	// Backcompat for dialogClass option
12965	$.widget( "ui.dialog", $.ui.dialog, {
12966		options: {
12967			dialogClass: ""
12968		},
12969		_createWrapper: function() {
12970			this._super();
12971			this.uiDialog.addClass( this.options.dialogClass );
12972		},
12973		_setOption: function( key, value ) {
12974			if ( key === "dialogClass" ) {
12975				this.uiDialog
12976					.removeClass( this.options.dialogClass )
12977					.addClass( value );
12978			}
12979			this._superApply( arguments );
12980		}
12981	} );
12982}
12983
12984var widgetsDialog = $.ui.dialog;
12985
12986
12987/*!
12988 * jQuery UI Droppable 1.14.
129881
12989 * https://jqueryui.com
12990 *
12991 * Copyright OpenJS Foundation and other contributors
12992 * Released under the MIT license.
12993 * https://jquery.org/license
12994 */
12995
12996//>>label: Droppable
12997//>>group: Interactions
12998//>>description: Enables drop targets for draggable elements.
12999//>>docs: https://api.jqueryui.com/droppable/
13000//>>demos: https://jqueryui.com/droppable/
13001
13002
13003$.widget( "ui.droppable", {
13004	version: "1.14.1
vendor: 12,183 bytes, lines 13004-13471
13004",
13005	widgetEventPrefix: "drop",
13006	options: {
13007		accept: "*",
13008		addClasses: true,
13009		greedy: false,
13010		scope: "default",
13011		tolerance: "intersect",
13012
13013		// Callbacks
13014		activate: null,
13015		deactivate: null,
13016		drop: null,
13017		out: null,
13018		over: null
13019	},
13020	_create: function() {
13021
13022		var proportions,
13023			o = this.options,
13024			accept = o.accept;
13025
13026		this.isover = false;
13027		this.isout = true;
13028
13029		this.accept = typeof accept === "function" ? accept : function( d ) {
13030			return d.is( accept );
13031		};
13032
13033		this.proportions = function( /* valueToWrite */ ) {
13034			if ( arguments.length ) {
13035
13036				// Store the droppable's proportions
13037				proportions = arguments[ 0 ];
13038			} else {
13039
13040				// Retrieve or derive the droppable's proportions
13041				return proportions ?
13042					proportions :
13043					proportions = {
13044						width: this.element[ 0 ].offsetWidth,
13045						height: this.element[ 0 ].offsetHeight
13046					};
13047			}
13048		};
13049
13050		this._addToManager( o.scope );
13051
13052		if ( o.addClasses ) {
13053			this._addClass( "ui-droppable" );
13054		}
13055
13056	},
13057
13058	_addToManager: function( scope ) {
13059
13060		// Add the reference and positions to the manager
13061		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
13062		$.ui.ddmanager.droppables[ scope ].push( this );
13063	},
13064
13065	_splice: function( drop ) {
13066		var i = 0;
13067		for ( ; i < drop.length; i++ ) {
13068			if ( drop[ i ] === this ) {
13069				drop.splice( i, 1 );
13070			}
13071		}
13072	},
13073
13074	_destroy: function() {
13075		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13076
13077		this._splice( drop );
13078	},
13079
13080	_setOption: function( key, value ) {
13081
13082		if ( key === "accept" ) {
13083			this.accept = typeof value === "function" ? value : function( d ) {
13084				return d.is( value );
13085			};
13086		} else if ( key === "scope" ) {
13087			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
13088
13089			this._splice( drop );
13090			this._addToManager( value );
13091		}
13092
13093		this._super( key, value );
13094	},
13095
13096	_activate: function( event ) {
13097		var draggable = $.ui.ddmanager.current;
13098
13099		this._addActiveClass();
13100		if ( draggable ) {
13101			this._trigger( "activate", event, this.ui( draggable ) );
13102		}
13103	},
13104
13105	_deactivate: function( event ) {
13106		var draggable = $.ui.ddmanager.current;
13107
13108		this._removeActiveClass();
13109		if ( draggable ) {
13110			this._trigger( "deactivate", event, this.ui( draggable ) );
13111		}
13112	},
13113
13114	_over: function( event ) {
13115
13116		var draggable = $.ui.ddmanager.current;
13117
13118		// Bail if draggable and droppable are same element
13119		if ( !draggable || ( draggable.currentItem ||
13120				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13121			return;
13122		}
13123
13124		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13125				draggable.element ) ) ) {
13126			this._addHoverClass();
13127			this._trigger( "over", event, this.ui( draggable ) );
13128		}
13129
13130	},
13131
13132	_out: function( event ) {
13133
13134		var draggable = $.ui.ddmanager.current;
13135
13136		// Bail if draggable and droppable are same element
13137		if ( !draggable || ( draggable.currentItem ||
13138				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13139			return;
13140		}
13141
13142		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
13143				draggable.element ) ) ) {
13144			this._removeHoverClass();
13145			this._trigger( "out", event, this.ui( draggable ) );
13146		}
13147
13148	},
13149
13150	_drop: function( event, custom ) {
13151
13152		var draggable = custom || $.ui.ddmanager.current,
13153			childrenIntersection = false;
13154
13155		// Bail if draggable and droppable are same element
13156		if ( !draggable || ( draggable.currentItem ||
13157				draggable.element )[ 0 ] === this.element[ 0 ] ) {
13158			return false;
13159		}
13160
13161		this.element
13162			.find( ":data(ui-droppable)" )
13163			.not( ".ui-draggable-dragging" )
13164			.each( function() {
13165				var inst = $( this ).droppable( "instance" );
13166				if (
13167					inst.options.greedy &&
13168					!inst.options.disabled &&
13169					inst.options.scope === draggable.options.scope &&
13170					inst.accept.call(
13171						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
13172					) &&
13173					$.ui.intersect(
13174						draggable,
13175						$.extend( inst, { offset: inst.element.offset() } ),
13176						inst.options.tolerance, event
13177					)
13178				) {
13179					childrenIntersection = true;
13180					return false;
13181				}
13182			} );
13183		if ( childrenIntersection ) {
13184			return false;
13185		}
13186
13187		if ( this.accept.call( this.element[ 0 ],
13188				( draggable.currentItem || draggable.element ) ) ) {
13189			this._removeActiveClass();
13190			this._removeHoverClass();
13191
13192			this._trigger( "drop", event, this.ui( draggable ) );
13193			return this.element;
13194		}
13195
13196		return false;
13197
13198	},
13199
13200	ui: function( c ) {
13201		return {
13202			draggable: ( c.currentItem || c.element ),
13203			helper: c.helper,
13204			position: c.position,
13205			offset: c.positionAbs
13206		};
13207	},
13208
13209	// Extension points just to make backcompat sane and avoid duplicating logic
13210	// TODO: Remove in 1.14 along with call to it below
13211	_addHoverClass: function() {
13212		this._addClass( "ui-droppable-hover" );
13213	},
13214
13215	_removeHoverClass: function() {
13216		this._removeClass( "ui-droppable-hover" );
13217	},
13218
13219	_addActiveClass: function() {
13220		this._addClass( "ui-droppable-active" );
13221	},
13222
13223	_removeActiveClass: function() {
13224		this._removeClass( "ui-droppable-active" );
13225	}
13226} );
13227
13228$.ui.intersect = ( function() {
13229	function isOverAxis( x, reference, size ) {
13230		return ( x >= reference ) && ( x < ( reference + size ) );
13231	}
13232
13233	return function( draggable, droppable, toleranceMode, event ) {
13234
13235		if ( !droppable.offset ) {
13236			return false;
13237		}
13238
13239		var x1 = ( draggable.positionAbs ||
13240				draggable.position.absolute ).left + draggable.margins.left,
13241			y1 = ( draggable.positionAbs ||
13242				draggable.position.absolute ).top + draggable.margins.top,
13243			x2 = x1 + draggable.helperProportions.width,
13244			y2 = y1 + draggable.helperProportions.height,
13245			l = droppable.offset.left,
13246			t = droppable.offset.top,
13247			r = l + droppable.proportions().width,
13248			b = t + droppable.proportions().height;
13249
13250		switch ( toleranceMode ) {
13251		case "fit":
13252			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
13253		case "intersect":
13254			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
13255				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
13256				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
13257				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
13258		case "pointer":
13259			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
13260				isOverAxis( event.pageX, l, droppable.proportions().width );
13261		case "touch":
13262			return (
13263				( y1 >= t && y1 <= b ) || // Top edge touching
13264				( y2 >= t && y2 <= b ) || // Bottom edge touching
13265				( y1 < t && y2 > b ) // Surrounded vertically
13266			) && (
13267				( x1 >= l && x1 <= r ) || // Left edge touching
13268				( x2 >= l && x2 <= r ) || // Right edge touching
13269				( x1 < l && x2 > r ) // Surrounded horizontally
13270			);
13271		default:
13272			return false;
13273		}
13274	};
13275} )();
13276
13277/*
13278	This manager tracks offsets of draggables and droppables
13279*/
13280$.ui.ddmanager = {
13281	current: null,
13282	droppables: { "default": [] },
13283	prepareOffsets: function( t, event ) {
13284
13285		var i, j,
13286			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
13287			type = event ? event.type : null, // workaround for #2317
13288			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
13289
13290		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
13291
13292			// No disabled and non-accepted
13293			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
13294					( t.currentItem || t.element ) ) ) ) {
13295				continue;
13296			}
13297
13298			// Filter out elements in the current dragged item
13299			for ( j = 0; j < list.length; j++ ) {
13300				if ( list[ j ] === m[ i ].element[ 0 ] ) {
13301					m[ i ].proportions().height = 0;
13302					continue droppablesLoop;
13303				}
13304			}
13305
13306			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
13307			if ( !m[ i ].visible ) {
13308				continue;
13309			}
13310
13311			// Activate the droppable if used directly from draggables
13312			if ( type === "mousedown" ) {
13313				m[ i ]._activate.call( m[ i ], event );
13314			}
13315
13316			m[ i ].offset = m[ i ].element.offset();
13317			m[ i ].proportions( {
13318				width: m[ i ].element[ 0 ].offsetWidth,
13319				height: m[ i ].element[ 0 ].offsetHeight
13320			} );
13321
13322		}
13323
13324	},
13325	drop: function( draggable, event ) {
13326
13327		var dropped = false;
13328
13329		// Create a copy of the droppables in case the list changes during the drop (#9116)
13330		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
13331
13332			if ( !this.options ) {
13333				return;
13334			}
13335			if ( !this.options.disabled && this.visible &&
13336					$.ui.intersect( draggable, this, this.options.tolerance, event ) ) {
13337				dropped = this._drop.call( this, event ) || dropped;
13338			}
13339
13340			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
13341					( draggable.currentItem || draggable.element ) ) ) {
13342				this.isout = true;
13343				this.isover = false;
13344				this._deactivate.call( this, event );
13345			}
13346
13347		} );
13348		return dropped;
13349
13350	},
13351	dragStart: function( draggable, event ) {
13352
13353		// Listen for scrolling so that if the dragging causes scrolling the position of the
13354		// droppables can be recalculated (see #5003)
13355		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
13356			if ( !draggable.options.refreshPositions ) {
13357				$.ui.ddmanager.prepareOffsets( draggable, event );
13358			}
13359		} );
13360	},
13361	drag: function( draggable, event ) {
13362
13363		// If you have a highly dynamic page, you might try this option. It renders positions
13364		// every time you move the mouse.
13365		if ( draggable.options.refreshPositions ) {
13366			$.ui.ddmanager.prepareOffsets( draggable, event );
13367		}
13368
13369		// Run through all droppables and check their positions based on specific tolerance options
13370		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
13371
13372			if ( this.options.disabled || this.greedyChild || !this.visible ) {
13373				return;
13374			}
13375
13376			var parentInstance, scope, parent,
13377				intersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),
13378				c = !intersects && this.isover ?
13379					"isout" :
13380					( intersects && !this.isover ? "isover" : null );
13381			if ( !c ) {
13382				return;
13383			}
13384
13385			if ( this.options.greedy ) {
13386
13387				// find droppable parents with same scope
13388				scope = this.options.scope;
13389				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
13390					return $( this ).droppable( "instance" ).options.scope === scope;
13391				} );
13392
13393				if ( parent.length ) {
13394					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
13395					parentInstance.greedyChild = ( c === "isover" );
13396				}
13397			}
13398
13399			// We just moved into a greedy child
13400			if ( parentInstance && c === "isover" ) {
13401				parentInstance.isover = false;
13402				parentInstance.isout = true;
13403				parentInstance._out.call( parentInstance, event );
13404			}
13405
13406			this[ c ] = true;
13407			this[ c === "isout" ? "isover" : "isout" ] = false;
13408			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
13409
13410			// We just moved out of a greedy child
13411			if ( parentInstance && c === "isout" ) {
13412				parentInstance.isout = false;
13413				parentInstance.isover = true;
13414				parentInstance._over.call( parentInstance, event );
13415			}
13416		} );
13417
13418	},
13419	dragStop: function( draggable, event ) {
13420		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
13421
13422		// Call prepareOffsets one final time since IE does not fire return scroll events when
13423		// overflow was caused by drag (see #5003)
13424		if ( !draggable.options.refreshPositions ) {
13425			$.ui.ddmanager.prepareOffsets( draggable, event );
13426		}
13427	}
13428};
13429
13430// DEPRECATED
13431// TODO: switch return back to widget declaration at top of file when this is removed
13432if ( $.uiBackCompat === true ) {
13433
13434	// Backcompat for activeClass and hoverClass options
13435	$.widget( "ui.droppable", $.ui.droppable, {
13436		options: {
13437			hoverClass: false,
13438			activeClass: false
13439		},
13440		_addActiveClass: function() {
13441			this._super();
13442			if ( this.options.activeClass ) {
13443				this.element.addClass( this.options.activeClass );
13444			}
13445		},
13446		_removeActiveClass: function() {
13447			this._super();
13448			if ( this.options.activeClass ) {
13449				this.element.removeClass( this.options.activeClass );
13450			}
13451		},
13452		_addHoverClass: function() {
13453			this._super();
13454			if ( this.options.hoverClass ) {
13455				this.element.addClass( this.options.hoverClass );
13456			}
13457		},
13458		_removeHoverClass: function() {
13459			this._super();
13460			if ( this.options.hoverClass ) {
13461				this.element.removeClass( this.options.hoverClass );
13462			}
13463		}
13464	} );
13465}
13466
13467var widgetsDroppable = $.ui.droppable;
13468
13469
13470/*!
13471 * jQuery UI Progressbar 1.14.
134711
13472 * https://jqueryui.com
13473 *
13474 * Copyright OpenJS Foundation and other contributors
13475 * Released under the MIT license.
13476 * https://jquery.org/license
13477 */
13478
13479//>>label: Progressbar
13480//>>group: Widgets
13481/* eslint-disable max-len */
13482//>>
vendor: 4,223 bytes, lines 13482-13651
13482description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13483/* eslint-enable max-len */
13484//>>docs: https://api.jqueryui.com/progressbar/
13485//>>demos: https://jqueryui.com/progressbar/
13486//>>css.structure: ../../themes/base/core.css
13487//>>css.structure: ../../themes/base/progressbar.css
13488//>>css.theme: ../../themes/base/theme.css
13489
13490
13491var widgetsProgressbar = $.widget( "ui.progressbar", {
13492	version: "1.14.1",
13493	options: {
13494		classes: {
13495			"ui-progressbar": "ui-corner-all",
13496			"ui-progressbar-value": "ui-corner-left",
13497			"ui-progressbar-complete": "ui-corner-right"
13498		},
13499		max: 100,
13500		value: 0,
13501
13502		change: null,
13503		complete: null
13504	},
13505
13506	min: 0,
13507
13508	_create: function() {
13509
13510		// Constrain initial value
13511		this.oldValue = this.options.value = this._constrainedValue();
13512
13513		this.element.attr( {
13514
13515			// Only set static values; aria-valuenow and aria-valuemax are
13516			// set inside _refreshValue()
13517			role: "progressbar",
13518			"aria-valuemin": this.min
13519		} );
13520		this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
13521
13522		this.valueDiv = $( "<div>" ).appendTo( this.element );
13523		this._addClass( this.valueDiv, "ui-progressbar-value", "ui-widget-header" );
13524		this._refreshValue();
13525	},
13526
13527	_destroy: function() {
13528		this.element.removeAttr( "role aria-valuemin aria-valuemax aria-valuenow" );
13529
13530		this.valueDiv.remove();
13531	},
13532
13533	value: function( newValue ) {
13534		if ( newValue === undefined ) {
13535			return this.options.value;
13536		}
13537
13538		this.options.value = this._constrainedValue( newValue );
13539		this._refreshValue();
13540	},
13541
13542	_constrainedValue: function( newValue ) {
13543		if ( newValue === undefined ) {
13544			newValue = this.options.value;
13545		}
13546
13547		this.indeterminate = newValue === false;
13548
13549		// Sanitize value
13550		if ( typeof newValue !== "number" ) {
13551			newValue = 0;
13552		}
13553
13554		return this.indeterminate ? false :
13555			Math.min( this.options.max, Math.max( this.min, newValue ) );
13556	},
13557
13558	_setOptions: function( options ) {
13559
13560		// Ensure "value" option is set after other values (like max)
13561		var value = options.value;
13562		delete options.value;
13563
13564		this._super( options );
13565
13566		this.options.value = this._constrainedValue( value );
13567		this._refreshValue();
13568	},
13569
13570	_setOption: function( key, value ) {
13571		if ( key === "max" ) {
13572
13573			// Don't allow a max less than min
13574			value = Math.max( this.min, value );
13575		}
13576		this._super( key, value );
13577	},
13578
13579	_setOptionDisabled: function( value ) {
13580		this._super( value );
13581
13582		this.element.attr( "aria-disabled", value );
13583		this._toggleClass( null, "ui-state-disabled", !!value );
13584	},
13585
13586	_percentage: function() {
13587		return this.indeterminate ?
13588			100 :
13589			100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
13590	},
13591
13592	_refreshValue: function() {
13593		var value = this.options.value,
13594			percentage = this._percentage();
13595
13596		this.valueDiv
13597			.toggle( this.indeterminate || value > this.min )
13598			.width( percentage.toFixed( 0 ) + "%" );
13599
13600		this
13601			._toggleClass( this.valueDiv, "ui-progressbar-complete", null,
13602				value === this.options.max )
13603			._toggleClass( "ui-progressbar-indeterminate", null, this.indeterminate );
13604
13605		if ( this.indeterminate ) {
13606			this.element.removeAttr( "aria-valuenow" );
13607			if ( !this.overlayDiv ) {
13608				this.overlayDiv = $( "<div>" ).appendTo( this.valueDiv );
13609				this._addClass( this.overlayDiv, "ui-progressbar-overlay" );
13610			}
13611		} else {
13612			this.element.attr( {
13613				"aria-valuemax": this.options.max,
13614				"aria-valuenow": value
13615			} );
13616			if ( this.overlayDiv ) {
13617				this.overlayDiv.remove();
13618				this.overlayDiv = null;
13619			}
13620		}
13621
13622		if ( this.oldValue !== value ) {
13623			this.oldValue = value;
13624			this._trigger( "change" );
13625		}
13626		if ( value === this.options.max ) {
13627			this._trigger( "complete" );
13628		}
13629	}
13630} );
13631
13632
13633/*!
13634 * jQuery UI Selectable 1.14.1
13635 * https://jqueryui.com
13636 *
13637 * Copyright OpenJS Foundation and other contributors
13638 * Released under the MIT license.
13639 * https://jquery.org/license
13640 */
13641
13642//>>label: Selectable
13643//>>group: Interactions
13644//>>description: Allows groups of elements to be selected with the mouse.
13645//>>docs: https://api.jqueryui.com/selectable/
13646//>>demos: https://jqueryui.com/selectable/
13647//>>css.structure: ../../themes/base/selectable.css
13648
13649
13650var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
13651	version: "1.14.1
vendor: 7,327 bytes, lines 13651-13932
13651",
13652	options: {
13653		appendTo: "body",
13654		autoRefresh: true,
13655		distance: 0,
13656		filter: "*",
13657		tolerance: "touch",
13658
13659		// Callbacks
13660		selected: null,
13661		selecting: null,
13662		start: null,
13663		stop: null,
13664		unselected: null,
13665		unselecting: null
13666	},
13667	_create: function() {
13668		var that = this;
13669
13670		this._addClass( "ui-selectable" );
13671
13672		this.dragged = false;
13673
13674		// Cache selectee children based on filter
13675		this.refresh = function() {
13676			that.elementPos = $( that.element[ 0 ] ).offset();
13677			that.selectees = $( that.options.filter, that.element[ 0 ] );
13678			that._addClass( that.selectees, "ui-selectee" );
13679			that.selectees.each( function() {
13680				var $this = $( this ),
13681					selecteeOffset = $this.offset(),
13682					pos = {
13683						left: selecteeOffset.left - that.elementPos.left,
13684						top: selecteeOffset.top - that.elementPos.top
13685					};
13686				$.data( this, "selectable-item", {
13687					element: this,
13688					$element: $this,
13689					left: pos.left,
13690					top: pos.top,
13691					right: pos.left + $this.outerWidth(),
13692					bottom: pos.top + $this.outerHeight(),
13693					startselected: false,
13694					selected: $this.hasClass( "ui-selected" ),
13695					selecting: $this.hasClass( "ui-selecting" ),
13696					unselecting: $this.hasClass( "ui-unselecting" )
13697				} );
13698			} );
13699		};
13700		this.refresh();
13701
13702		this._mouseInit();
13703
13704		this.helper = $( "<div>" );
13705		this._addClass( this.helper, "ui-selectable-helper" );
13706	},
13707
13708	_destroy: function() {
13709		this.selectees.removeData( "selectable-item" );
13710		this._mouseDestroy();
13711	},
13712
13713	_mouseStart: function( event ) {
13714		var that = this,
13715			options = this.options;
13716
13717		this.opos = [ event.pageX, event.pageY ];
13718		this.elementPos = $( this.element[ 0 ] ).offset();
13719
13720		if ( this.options.disabled ) {
13721			return;
13722		}
13723
13724		this.selectees = $( options.filter, this.element[ 0 ] );
13725
13726		this._trigger( "start", event );
13727
13728		$( options.appendTo ).append( this.helper );
13729
13730		// position helper (lasso)
13731		this.helper.css( {
13732			"left": event.pageX,
13733			"top": event.pageY,
13734			"width": 0,
13735			"height": 0
13736		} );
13737
13738		if ( options.autoRefresh ) {
13739			this.refresh();
13740		}
13741
13742		this.selectees.filter( ".ui-selected" ).each( function() {
13743			var selectee = $.data( this, "selectable-item" );
13744			selectee.startselected = true;
13745			if ( !event.metaKey && !event.ctrlKey ) {
13746				that._removeClass( selectee.$element, "ui-selected" );
13747				selectee.selected = false;
13748				that._addClass( selectee.$element, "ui-unselecting" );
13749				selectee.unselecting = true;
13750
13751				// selectable UNSELECTING callback
13752				that._trigger( "unselecting", event, {
13753					unselecting: selectee.element
13754				} );
13755			}
13756		} );
13757
13758		$( event.target ).parents().addBack().each( function() {
13759			var doSelect,
13760				selectee = $.data( this, "selectable-item" );
13761			if ( selectee ) {
13762				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
13763					!selectee.$element.hasClass( "ui-selected" );
13764				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
13765					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
13766				selectee.unselecting = !doSelect;
13767				selectee.selecting = doSelect;
13768				selectee.selected = doSelect;
13769
13770				// selectable (UN)SELECTING callback
13771				if ( doSelect ) {
13772					that._trigger( "selecting", event, {
13773						selecting: selectee.element
13774					} );
13775				} else {
13776					that._trigger( "unselecting", event, {
13777						unselecting: selectee.element
13778					} );
13779				}
13780				return false;
13781			}
13782		} );
13783
13784	},
13785
13786	_mouseDrag: function( event ) {
13787
13788		this.dragged = true;
13789
13790		if ( this.options.disabled ) {
13791			return;
13792		}
13793
13794		var tmp,
13795			that = this,
13796			options = this.options,
13797			x1 = this.opos[ 0 ],
13798			y1 = this.opos[ 1 ],
13799			x2 = event.pageX,
13800			y2 = event.pageY;
13801
13802		if ( x1 > x2 ) {
13803			tmp = x2; x2 = x1; x1 = tmp;
13804		}
13805		if ( y1 > y2 ) {
13806			tmp = y2; y2 = y1; y1 = tmp;
13807		}
13808		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
13809
13810		this.selectees.each( function() {
13811			var selectee = $.data( this, "selectable-item" ),
13812				hit = false,
13813				offset = {};
13814
13815			//prevent helper from being selected if appendTo: selectable
13816			if ( !selectee || selectee.element === that.element[ 0 ] ) {
13817				return;
13818			}
13819
13820			offset.left   = selectee.left   + that.elementPos.left;
13821			offset.right  = selectee.right  + that.elementPos.left;
13822			offset.top    = selectee.top    + that.elementPos.top;
13823			offset.bottom = selectee.bottom + that.elementPos.top;
13824
13825			if ( options.tolerance === "touch" ) {
13826				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13827                    offset.bottom < y1 ) );
13828			} else if ( options.tolerance === "fit" ) {
13829				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13830                    offset.bottom < y2 );
13831			}
13832
13833			if ( hit ) {
13834
13835				// SELECT
13836				if ( selectee.selected ) {
13837					that._removeClass( selectee.$element, "ui-selected" );
13838					selectee.selected = false;
13839				}
13840				if ( selectee.unselecting ) {
13841					that._removeClass( selectee.$element, "ui-unselecting" );
13842					selectee.unselecting = false;
13843				}
13844				if ( !selectee.selecting ) {
13845					that._addClass( selectee.$element, "ui-selecting" );
13846					selectee.selecting = true;
13847
13848					// selectable SELECTING callback
13849					that._trigger( "selecting", event, {
13850						selecting: selectee.element
13851					} );
13852				}
13853			} else {
13854
13855				// UNSELECT
13856				if ( selectee.selecting ) {
13857					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
13858						that._removeClass( selectee.$element, "ui-selecting" );
13859						selectee.selecting = false;
13860						that._addClass( selectee.$element, "ui-selected" );
13861						selectee.selected = true;
13862					} else {
13863						that._removeClass( selectee.$element, "ui-selecting" );
13864						selectee.selecting = false;
13865						if ( selectee.startselected ) {
13866							that._addClass( selectee.$element, "ui-unselecting" );
13867							selectee.unselecting = true;
13868						}
13869
13870						// selectable UNSELECTING callback
13871						that._trigger( "unselecting", event, {
13872							unselecting: selectee.element
13873						} );
13874					}
13875				}
13876				if ( selectee.selected ) {
13877					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
13878						that._removeClass( selectee.$element, "ui-selected" );
13879						selectee.selected = false;
13880
13881						that._addClass( selectee.$element, "ui-unselecting" );
13882						selectee.unselecting = true;
13883
13884						// selectable UNSELECTING callback
13885						that._trigger( "unselecting", event, {
13886							unselecting: selectee.element
13887						} );
13888					}
13889				}
13890			}
13891		} );
13892
13893		return false;
13894	},
13895
13896	_mouseStop: function( event ) {
13897		var that = this;
13898
13899		this.dragged = false;
13900
13901		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
13902			var selectee = $.data( this, "selectable-item" );
13903			that._removeClass( selectee.$element, "ui-unselecting" );
13904			selectee.unselecting = false;
13905			selectee.startselected = false;
13906			that._trigger( "unselected", event, {
13907				unselected: selectee.element
13908			} );
13909		} );
13910		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
13911			var selectee = $.data( this, "selectable-item" );
13912			that._removeClass( selectee.$element, "ui-selecting" )
13913				._addClass( selectee.$element, "ui-selected" );
13914			selectee.selecting = false;
13915			selectee.selected = true;
13916			selectee.startselected = true;
13917			that._trigger( "selected", event, {
13918				selected: selectee.element
13919			} );
13920		} );
13921		this._trigger( "stop", event );
13922
13923		this.helper.remove();
13924
13925		return false;
13926	}
13927
13928} );
13929
13930
13931/*!
13932 * jQuery UI Selectmenu 1.14.
139321
13933 * https://jqueryui.com
13934 *
13935 * Copyright OpenJS Foundation and other contributors
13936 * Released under the MIT license.
13937 * https://jquery.org/license
13938 */
13939
13940//>>label: Selectmenu
13941//>>group: Widgets
13942/* eslint-disable max-len */
13943//>>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.
13944/* eslint-enable max-len */
13945//>>docs: https://api.jqueryui.com/selectmenu/
13946//>>demos: https://jqueryui.com/selectmenu/
13947//>>css.structure: ../../themes/base/core.css
13948//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13949//>>css.theme: ../../themes/base/theme.css
13950
13951
13952var widgetsSelectmenu = $.widget( "ui.selectmenu", [ $.ui.formResetMixin, {
13953	version: "1.14.1
vendor: 14,466 bytes, lines 13953-14574
13953",
13954	defaultElement: "<select>",
13955	options: {
13956		appendTo: null,
13957		classes: {
13958			"ui-selectmenu-button-open": "ui-corner-top",
13959			"ui-selectmenu-button-closed": "ui-corner-all"
13960		},
13961		disabled: null,
13962		icons: {
13963			button: "ui-icon-triangle-1-s"
13964		},
13965		position: {
13966			my: "left top",
13967			at: "left bottom",
13968			collision: "none"
13969		},
13970		width: false,
13971
13972		// Callbacks
13973		change: null,
13974		close: null,
13975		focus: null,
13976		open: null,
13977		select: null
13978	},
13979
13980	_create: function() {
13981		var selectmenuId = this.element.uniqueId().attr( "id" );
13982		this.ids = {
13983			element: selectmenuId,
13984			button: selectmenuId + "-button",
13985			menu: selectmenuId + "-menu"
13986		};
13987
13988		this._drawButton();
13989		this._drawMenu();
13990		this._bindFormResetHandler();
13991
13992		this._rendered = false;
13993		this.menuItems = $();
13994	},
13995
13996	_drawButton: function() {
13997		var icon,
13998			that = this,
13999			item = this._parseOption(
14000				this.element.find( "option:selected" ),
14001				this.element[ 0 ].selectedIndex
14002			);
14003
14004		// Associate existing label with the new button
14005		this.labels = this.element.labels().attr( "for", this.ids.button );
14006		this._on( this.labels, {
14007			click: function( event ) {
14008				this.button.trigger( "focus" );
14009				event.preventDefault();
14010			}
14011		} );
14012
14013		// Hide original select element
14014		this.element.hide();
14015
14016		// Create button
14017		this.button = $( "<span>", {
14018			tabindex: this.options.disabled ? -1 : 0,
14019			id: this.ids.button,
14020			role: "combobox",
14021			"aria-expanded": "false",
14022			"aria-autocomplete": "list",
14023			"aria-owns": this.ids.menu,
14024			"aria-haspopup": "true",
14025			title: this.element.attr( "title" )
14026		} )
14027			.insertAfter( this.element );
14028
14029		this._addClass( this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
14030			"ui-button ui-widget" );
14031
14032		icon = $( "<span>" ).appendTo( this.button );
14033		this._addClass( icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button );
14034		this.buttonItem = this._renderButtonItem( item )
14035			.appendTo( this.button );
14036
14037		if ( this.options.width !== false ) {
14038			this._resizeButton();
14039		}
14040
14041		this._on( this.button, this._buttonEvents );
14042		this.button.one( "focusin", function() {
14043
14044			// Delay rendering the menu items until the button receives focus.
14045			// The menu may have already been rendered via a programmatic open.
14046			if ( !that._rendered ) {
14047				that._refreshMenu();
14048			}
14049		} );
14050	},
14051
14052	_drawMenu: function() {
14053		var that = this;
14054
14055		// Create menu
14056		this.menu = $( "<ul>", {
14057			"aria-hidden": "true",
14058			"aria-labelledby": this.ids.button,
14059			id: this.ids.menu
14060		} );
14061
14062		// Wrap menu
14063		this.menuWrap = $( "<div>" ).append( this.menu );
14064		this._addClass( this.menuWrap, "ui-selectmenu-menu", "ui-front" );
14065		this.menuWrap.appendTo( this._appendTo() );
14066
14067		// Initialize menu widget
14068		this.menuInstance = this.menu
14069			.menu( {
14070				classes: {
14071					"ui-menu": "ui-corner-bottom"
14072				},
14073				role: "listbox",
14074				select: function( event, ui ) {
14075					event.preventDefault();
14076					that._select( ui.item.data( "ui-selectmenu-item" ), event );
14077				},
14078				focus: function( event, ui ) {
14079					var item = ui.item.data( "ui-selectmenu-item" );
14080
14081					// Prevent inital focus from firing and check if its a newly focused item
14082					if ( that.focusIndex != null && item.index !== that.focusIndex ) {
14083						that._trigger( "focus", event, { item: item } );
14084						if ( !that.isOpen ) {
14085							that._select( item, event );
14086						}
14087					}
14088					that.focusIndex = item.index;
14089
14090					that.button.attr( "aria-activedescendant",
14091						that.menuItems.eq( item.index ).attr( "id" ) );
14092				}
14093			} )
14094			.menu( "instance" );
14095
14096		// Don't close the menu on mouseleave
14097		this.menuInstance._off( this.menu, "mouseleave" );
14098
14099		// Cancel the menu's collapseAll on document click
14100		this.menuInstance._closeOnDocumentClick = function() {
14101			return false;
14102		};
14103
14104		// Selects often contain empty items, but never contain dividers
14105		this.menuInstance._isDivider = function() {
14106			return false;
14107		};
14108	},
14109
14110	refresh: function() {
14111		this._refreshMenu();
14112		this.buttonItem.replaceWith(
14113			this.buttonItem = this._renderButtonItem(
14114
14115				// Fall back to an empty object in case there are no options
14116				this._getSelectedItem().data( "ui-selectmenu-item" ) || {}
14117			)
14118		);
14119		if ( this.options.width === null ) {
14120			this._resizeButton();
14121		}
14122	},
14123
14124	_refreshMenu: function() {
14125		var item,
14126			options = this.element.find( "option" );
14127
14128		this.menu.empty();
14129
14130		this._parseOptions( options );
14131		this._renderMenu( this.menu, this.items );
14132
14133		this.menuInstance.refresh();
14134		this.menuItems = this.menu.find( "li" )
14135			.not( ".ui-selectmenu-optgroup" )
14136				.find( ".ui-menu-item-wrapper" );
14137
14138		this._rendered = true;
14139
14140		if ( !options.length ) {
14141			return;
14142		}
14143
14144		item = this._getSelectedItem();
14145
14146		// Update the menu to have the correct item focused
14147		this.menuInstance.focus( null, item );
14148		this._setAria( item.data( "ui-selectmenu-item" ) );
14149
14150		// Set disabled state
14151		this._setOption( "disabled", this.element.prop( "disabled" ) );
14152	},
14153
14154	open: function( event ) {
14155		if ( this.options.disabled ) {
14156			return;
14157		}
14158
14159		// If this is the first time the menu is being opened, render the items
14160		if ( !this._rendered ) {
14161			this._refreshMenu();
14162		} else {
14163
14164			// Menu clears focus on close, reset focus to selected item
14165			this._removeClass( this.menu.find( ".ui-state-active" ), null, "ui-state-active" );
14166			this.menuInstance.focus( null, this._getSelectedItem() );
14167		}
14168
14169		// If there are no options, don't open the menu
14170		if ( !this.menuItems.length ) {
14171			return;
14172		}
14173
14174		this.isOpen = true;
14175		this._toggleAttr();
14176		this._resizeMenu();
14177		this._position();
14178
14179		this._on( this.document, this._documentClick );
14180
14181		this._trigger( "open", event );
14182	},
14183
14184	_position: function() {
14185		this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
14186	},
14187
14188	close: function( event ) {
14189		if ( !this.isOpen ) {
14190			return;
14191		}
14192
14193		this.isOpen = false;
14194		this._toggleAttr();
14195
14196		this.range = null;
14197		this._off( this.document );
14198
14199		this._trigger( "close", event );
14200	},
14201
14202	widget: function() {
14203		return this.button;
14204	},
14205
14206	menuWidget: function() {
14207		return this.menu;
14208	},
14209
14210	_renderButtonItem: function( item ) {
14211		var buttonItem = $( "<span>" );
14212
14213		this._setText( buttonItem, item.label );
14214		this._addClass( buttonItem, "ui-selectmenu-text" );
14215
14216		return buttonItem;
14217	},
14218
14219	_renderMenu: function( ul, items ) {
14220		var that = this,
14221			currentOptgroup = "";
14222
14223		$.each( items, function( index, item ) {
14224			var li;
14225
14226			if ( item.optgroup !== currentOptgroup ) {
14227				li = $( "<li>", {
14228					text: item.optgroup
14229				} );
14230				that._addClass( li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14231					( item.element.parent( "optgroup" ).prop( "disabled" ) ?
14232						" ui-state-disabled" :
14233						"" ) );
14234
14235				li.appendTo( ul );
14236
14237				currentOptgroup = item.optgroup;
14238			}
14239
14240			that._renderItemData( ul, item );
14241		} );
14242	},
14243
14244	_renderItemData: function( ul, item ) {
14245		return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
14246	},
14247
14248	_renderItem: function( ul, item ) {
14249		var li = $( "<li>" ),
14250			wrapper = $( "<div>", {
14251				title: item.element.attr( "title" )
14252			} );
14253
14254		if ( item.disabled ) {
14255			this._addClass( li, null, "ui-state-disabled" );
14256		}
14257
14258		if ( item.hidden ) {
14259			li.prop( "hidden", true );
14260		} else {
14261			this._setText( wrapper, item.label );
14262		}
14263
14264		return li.append( wrapper ).appendTo( ul );
14265	},
14266
14267	_setText: function( element, value ) {
14268		if ( value ) {
14269			element.text( value );
14270		} else {
14271			element.html( "&#160;" );
14272		}
14273	},
14274
14275	_move: function( direction, event ) {
14276		var item, next,
14277			filter = ".ui-menu-item";
14278
14279		if ( this.isOpen ) {
14280			item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14281		} else {
14282			item = this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14283			filter += ":not(.ui-state-disabled)";
14284		}
14285
14286		if ( direction === "first" || direction === "last" ) {
14287			next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
14288		} else {
14289			next = item[ direction + "All" ]( filter ).eq( 0 );
14290		}
14291
14292		if ( next.length ) {
14293			this.menuInstance.focus( event, next );
14294		}
14295	},
14296
14297	_getSelectedItem: function() {
14298		return this.menuItems.eq( this.element[ 0 ].selectedIndex ).parent( "li" );
14299	},
14300
14301	_toggle: function( event ) {
14302		this[ this.isOpen ? "close" : "open" ]( event );
14303	},
14304
14305	_setSelection: function() {
14306		var selection;
14307
14308		if ( !this.range ) {
14309			return;
14310		}
14311
14312		selection = window.getSelection();
14313		selection.removeAllRanges();
14314		selection.addRange( this.range );
14315	},
14316
14317	_documentClick: {
14318		mousedown: function( event ) {
14319			if ( !this.isOpen ) {
14320				return;
14321			}
14322
14323			if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" +
14324				CSS.escape( this.ids.button ) ).length ) {
14325				this.close( event );
14326			}
14327		}
14328	},
14329
14330	_buttonEvents: {
14331
14332		// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14333		mousedown: function() {
14334			var selection = window.getSelection();
14335			if ( selection.rangeCount ) {
14336				this.range = selection.getRangeAt( 0 );
14337			}
14338		},
14339
14340		click: function( event ) {
14341			this._setSelection();
14342			this._toggle( event );
14343		},
14344
14345		keydown: function( event ) {
14346			var preventDefault = true;
14347			switch ( event.keyCode ) {
14348			case $.ui.keyCode.TAB:
14349			case $.ui.keyCode.ESCAPE:
14350				this.close( event );
14351				preventDefault = false;
14352				break;
14353			case $.ui.keyCode.ENTER:
14354				if ( this.isOpen ) {
14355					this._selectFocusedItem( event );
14356				}
14357				break;
14358			case $.ui.keyCode.UP:
14359				if ( event.altKey ) {
14360					this._toggle( event );
14361				} else {
14362					this._move( "prev", event );
14363				}
14364				break;
14365			case $.ui.keyCode.DOWN:
14366				if ( event.altKey ) {
14367					this._toggle( event );
14368				} else {
14369					this._move( "next", event );
14370				}
14371				break;
14372			case $.ui.keyCode.SPACE:
14373				if ( this.isOpen ) {
14374					this._selectFocusedItem( event );
14375				} else {
14376					this._toggle( event );
14377				}
14378				break;
14379			case $.ui.keyCode.LEFT:
14380				this._move( "prev", event );
14381				break;
14382			case $.ui.keyCode.RIGHT:
14383				this._move( "next", event );
14384				break;
14385			case $.ui.keyCode.HOME:
14386			case $.ui.keyCode.PAGE_UP:
14387				this._move( "first", event );
14388				break;
14389			case $.ui.keyCode.END:
14390			case $.ui.keyCode.PAGE_DOWN:
14391				this._move( "last", event );
14392				break;
14393			default:
14394				this.menu.trigger( event );
14395				preventDefault = false;
14396			}
14397
14398			if ( preventDefault ) {
14399				event.preventDefault();
14400			}
14401		}
14402	},
14403
14404	_selectFocusedItem: function( event ) {
14405		var item = this.menuItems.eq( this.focusIndex ).parent( "li" );
14406		if ( !item.hasClass( "ui-state-disabled" ) ) {
14407			this._select( item.data( "ui-selectmenu-item" ), event );
14408		}
14409	},
14410
14411	_select: function( item, event ) {
14412		var oldIndex = this.element[ 0 ].selectedIndex;
14413
14414		// Change native select element
14415		this.element[ 0 ].selectedIndex = item.index;
14416		this.buttonItem.replaceWith( this.buttonItem = this._renderButtonItem( item ) );
14417		this._setAria( item );
14418		this._trigger( "select", event, { item: item } );
14419
14420		if ( item.index !== oldIndex ) {
14421			this._trigger( "change", event, { item: item } );
14422		}
14423
14424		this.close( event );
14425	},
14426
14427	_setAria: function( item ) {
14428		var id = this.menuItems.eq( item.index ).attr( "id" );
14429
14430		this.button.attr( {
14431			"aria-labelledby": id,
14432			"aria-activedescendant": id
14433		} );
14434		this.menu.attr( "aria-activedescendant", id );
14435	},
14436
14437	_setOption: function( key, value ) {
14438		if ( key === "icons" ) {
14439			var icon = this.button.find( "span.ui-icon" );
14440			this._removeClass( icon, null, this.options.icons.button )
14441				._addClass( icon, null, value.button );
14442		}
14443
14444		this._super( key, value );
14445
14446		if ( key === "appendTo" ) {
14447			this.menuWrap.appendTo( this._appendTo() );
14448		}
14449
14450		if ( key === "width" ) {
14451			this._resizeButton();
14452		}
14453	},
14454
14455	_setOptionDisabled: function( value ) {
14456		this._super( value );
14457
14458		this.menuInstance.option( "disabled", value );
14459		this.button.attr( "aria-disabled", value );
14460		this._toggleClass( this.button, null, "ui-state-disabled", value );
14461
14462		this.element.prop( "disabled", value );
14463		if ( value ) {
14464			this.button.attr( "tabindex", -1 );
14465			this.close();
14466		} else {
14467			this.button.attr( "tabindex", 0 );
14468		}
14469	},
14470
14471	_appendTo: function() {
14472		var element = this.options.appendTo;
14473
14474		if ( element ) {
14475			element = element.jquery || element.nodeType ?
14476				$( element ) :
14477				this.document.find( element ).eq( 0 );
14478		}
14479
14480		if ( !element || !element[ 0 ] ) {
14481			element = this.element.closest( ".ui-front, dialog" );
14482		}
14483
14484		if ( !element.length ) {
14485			element = this.document[ 0 ].body;
14486		}
14487
14488		return element;
14489	},
14490
14491	_toggleAttr: function() {
14492		this.button.attr( "aria-expanded", this.isOpen );
14493
14494		// We can't use two _toggleClass() calls here, because we need to make sure
14495		// we always remove classes first and add them second, otherwise if both classes have the
14496		// same theme class, it will be removed after we add it.
14497		this._removeClass( this.button, "ui-selectmenu-button-" +
14498			( this.isOpen ? "closed" : "open" ) )
14499			._addClass( this.button, "ui-selectmenu-button-" +
14500				( this.isOpen ? "open" : "closed" ) )
14501			._toggleClass( this.menuWrap, "ui-selectmenu-open", null, this.isOpen );
14502
14503		this.menu.attr( "aria-hidden", !this.isOpen );
14504	},
14505
14506	_resizeButton: function() {
14507		var width = this.options.width;
14508
14509		// For `width: false`, just remove inline style and stop
14510		if ( width === false ) {
14511			this.button.css( "width", "" );
14512			return;
14513		}
14514
14515		// For `width: null`, match the width of the original element
14516		if ( width === null ) {
14517			width = this.element.show().outerWidth();
14518			this.element.hide();
14519		}
14520
14521		this.button.outerWidth( width );
14522	},
14523
14524	_resizeMenu: function() {
14525		this.menu.outerWidth( Math.max(
14526			this.button.outerWidth(),
14527			this.menu.width( "" ).outerWidth()
14528		) );
14529	},
14530
14531	_getCreateOptions: function() {
14532		var options = this._super();
14533
14534		options.disabled = this.element.prop( "disabled" );
14535
14536		return options;
14537	},
14538
14539	_parseOptions: function( options ) {
14540		var that = this,
14541			data = [];
14542		options.each( function( index, item ) {
14543			data.push( that._parseOption( $( item ), index ) );
14544		} );
14545		this.items = data;
14546	},
14547
14548	_parseOption: function( option, index ) {
14549		var optgroup = option.parent( "optgroup" );
14550
14551		return {
14552			element: option,
14553			index: index,
14554			value: option.val(),
14555			label: option.text(),
14556			hidden: optgroup.prop( "hidden" ) || option.prop( "hidden" ),
14557			optgroup: optgroup.attr( "label" ) || "",
14558			disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
14559		};
14560	},
14561
14562	_destroy: function() {
14563		this._unbindFormResetHandler();
14564		this.menuWrap.remove();
14565		this.button.remove();
14566		this.element.show();
14567		this.element.removeUniqueId();
14568		this.labels.attr( "for", this.ids.element );
14569	}
14570} ] );
14571
14572
14573/*!
14574 * jQuery UI Slider 1.14.
vendor: 2,981 bytes, lines 14574-14690
145741
14575 * https://jqueryui.com
14576 *
14577 * Copyright OpenJS Foundation and other contributors
14578 * Released under the MIT license.
14579 * https://jquery.org/license
14580 */
14581
14582//>>label: Slider
14583//>>group: Widgets
14584//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14585//>>docs: https://api.jqueryui.com/slider/
14586//>>demos: https://jqueryui.com/slider/
14587//>>css.structure: ../../themes/base/core.css
14588//>>css.structure: ../../themes/base/slider.css
14589//>>css.theme: ../../themes/base/theme.css
14590
14591
14592var widgetsSlider = $.widget( "ui.slider", $.ui.mouse, {
14593	version: "1.14.1",
14594	widgetEventPrefix: "slide",
14595
14596	options: {
14597		animate: false,
14598		classes: {
14599			"ui-slider": "ui-corner-all",
14600			"ui-slider-handle": "ui-corner-all",
14601
14602			// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14603			// element, but worked best visually with a variety of themes
14604			"ui-slider-range": "ui-corner-all ui-widget-header"
14605		},
14606		distance: 0,
14607		max: 100,
14608		min: 0,
14609		orientation: "horizontal",
14610		range: false,
14611		step: 1,
14612		value: 0,
14613		values: null,
14614
14615		// Callbacks
14616		change: null,
14617		slide: null,
14618		start: null,
14619		stop: null
14620	},
14621
14622	// Number of pages in a slider
14623	// (how many times can you page up/down to go through the whole range)
14624	numPages: 5,
14625
14626	_create: function() {
14627		this._keySliding = false;
14628		this._mouseSliding = false;
14629		this._animateOff = true;
14630		this._handleIndex = null;
14631		this._detectOrientation();
14632		this._mouseInit();
14633		this._calculateNewMax();
14634
14635		this._addClass( "ui-slider ui-slider-" + this.orientation,
14636			"ui-widget ui-widget-content" );
14637
14638		this._refresh();
14639
14640		this._animateOff = false;
14641	},
14642
14643	_refresh: function() {
14644		this._createRange();
14645		this._createHandles();
14646		this._setupEvents();
14647		this._refreshValue();
14648	},
14649
14650	_createHandles: function() {
14651		var i, handleCount,
14652			options = this.options,
14653			existingHandles = this.element.find( ".ui-slider-handle" ),
14654			handle = "<span tabindex='0'></span>",
14655			handles = [];
14656
14657		handleCount = ( options.values && options.values.length ) || 1;
14658
14659		if ( existingHandles.length > handleCount ) {
14660			existingHandles.slice( handleCount ).remove();
14661			existingHandles = existingHandles.slice( 0, handleCount );
14662		}
14663
14664		for ( i = existingHandles.length; i < handleCount; i++ ) {
14665			handles.push( handle );
14666		}
14667
14668		this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
14669
14670		this._addClass( this.handles, "ui-slider-handle", "ui-state-default" );
14671
14672		this.handle = this.handles.eq( 0 );
14673
14674		this.handles.each( function( i ) {
14675			$( this )
14676				.data( "ui-slider-handle-index", i )
14677				.attr( "tabIndex", 0 );
14678		} );
14679	},
14680
14681	_createRange: function() {
14682		var options = this.options;
14683
14684		if ( options.range ) {
14685			if ( options.range === true ) {
14686				if ( !options.values ) {
14687					options.values = [ this._valueMin(), this._valueMin() ];
14688				} else if ( options.values.length && options.values.length !== 2 ) {
14689					options.values = [ options.values[ 0 ], options.values[ 0 ] ];
14690				} else if ( Array
vendor: 6,343 bytes, lines 14690-14936
14690.isArray( options.values ) ) {
14691					options.values = options.values.slice( 0 );
14692				}
14693			}
14694
14695			if ( !this.range || !this.range.length ) {
14696				this.range = $( "<div>" )
14697					.appendTo( this.element );
14698
14699				this._addClass( this.range, "ui-slider-range" );
14700			} else {
14701				this._removeClass( this.range, "ui-slider-range-min ui-slider-range-max" );
14702
14703				// Handle range switching from true to min/max
14704				this.range.css( {
14705					"left": "",
14706					"bottom": ""
14707				} );
14708			}
14709			if ( options.range === "min" || options.range === "max" ) {
14710				this._addClass( this.range, "ui-slider-range-" + options.range );
14711			}
14712		} else {
14713			if ( this.range ) {
14714				this.range.remove();
14715			}
14716			this.range = null;
14717		}
14718	},
14719
14720	_setupEvents: function() {
14721		this._off( this.handles );
14722		this._on( this.handles, this._handleEvents );
14723		this._hoverable( this.handles );
14724		this._focusable( this.handles );
14725	},
14726
14727	_destroy: function() {
14728		this.handles.remove();
14729		if ( this.range ) {
14730			this.range.remove();
14731		}
14732
14733		this._mouseDestroy();
14734	},
14735
14736	_mouseCapture: function( event ) {
14737		var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14738			that = this,
14739			o = this.options;
14740
14741		if ( o.disabled ) {
14742			return false;
14743		}
14744
14745		this.elementSize = {
14746			width: this.element.outerWidth(),
14747			height: this.element.outerHeight()
14748		};
14749		this.elementOffset = this.element.offset();
14750
14751		position = { x: event.pageX, y: event.pageY };
14752		normValue = this._normValueFromMouse( position );
14753		distance = this._valueMax() - this._valueMin() + 1;
14754		this.handles.each( function( i ) {
14755			var thisDistance = Math.abs( normValue - that.values( i ) );
14756			if ( ( distance > thisDistance ) ||
14757				( distance === thisDistance &&
14758					( i === that._lastChangedValue || that.values( i ) === o.min ) ) ) {
14759				distance = thisDistance;
14760				closestHandle = $( this );
14761				index = i;
14762			}
14763		} );
14764
14765		allowed = this._start( event, index );
14766		if ( allowed === false ) {
14767			return false;
14768		}
14769		this._mouseSliding = true;
14770
14771		this._handleIndex = index;
14772
14773		this._addClass( closestHandle, null, "ui-state-active" );
14774		closestHandle.trigger( "focus" );
14775
14776		offset = closestHandle.offset();
14777		mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
14778		this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14779			left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
14780			top: event.pageY - offset.top -
14781				( closestHandle.height() / 2 ) -
14782				( parseInt( closestHandle.css( "borderTopWidth" ), 10 ) || 0 ) -
14783				( parseInt( closestHandle.css( "borderBottomWidth" ), 10 ) || 0 ) +
14784				( parseInt( closestHandle.css( "marginTop" ), 10 ) || 0 )
14785		};
14786
14787		if ( !this.handles.hasClass( "ui-state-hover" ) ) {
14788			this._slide( event, index, normValue );
14789		}
14790		this._animateOff = true;
14791		return true;
14792	},
14793
14794	_mouseStart: function() {
14795		return true;
14796	},
14797
14798	_mouseDrag: function( event ) {
14799		var position = { x: event.pageX, y: event.pageY },
14800			normValue = this._normValueFromMouse( position );
14801
14802		this._slide( event, this._handleIndex, normValue );
14803
14804		return false;
14805	},
14806
14807	_mouseStop: function( event ) {
14808		this._removeClass( this.handles, null, "ui-state-active" );
14809		this._mouseSliding = false;
14810
14811		this._stop( event, this._handleIndex );
14812		this._change( event, this._handleIndex );
14813
14814		this._handleIndex = null;
14815		this._clickOffset = null;
14816		this._animateOff = false;
14817
14818		return false;
14819	},
14820
14821	_detectOrientation: function() {
14822		this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
14823	},
14824
14825	_normValueFromMouse: function( position ) {
14826		var pixelTotal,
14827			pixelMouse,
14828			percentMouse,
14829			valueTotal,
14830			valueMouse;
14831
14832		if ( this.orientation === "horizontal" ) {
14833			pixelTotal = this.elementSize.width;
14834			pixelMouse = position.x - this.elementOffset.left -
14835				( this._clickOffset ? this._clickOffset.left : 0 );
14836		} else {
14837			pixelTotal = this.elementSize.height;
14838			pixelMouse = position.y - this.elementOffset.top -
14839				( this._clickOffset ? this._clickOffset.top : 0 );
14840		}
14841
14842		percentMouse = ( pixelMouse / pixelTotal );
14843		if ( percentMouse > 1 ) {
14844			percentMouse = 1;
14845		}
14846		if ( percentMouse < 0 ) {
14847			percentMouse = 0;
14848		}
14849		if ( this.orientation === "vertical" ) {
14850			percentMouse = 1 - percentMouse;
14851		}
14852
14853		valueTotal = this._valueMax() - this._valueMin();
14854		valueMouse = this._valueMin() + percentMouse * valueTotal;
14855
14856		return this._trimAlignValue( valueMouse );
14857	},
14858
14859	_uiHash: function( index, value, values ) {
14860		var uiHash = {
14861			handle: this.handles[ index ],
14862			handleIndex: index,
14863			value: value !== undefined ? value : this.value()
14864		};
14865
14866		if ( this._hasMultipleValues() ) {
14867			uiHash.value = value !== undefined ? value : this.values( index );
14868			uiHash.values = values || this.values();
14869		}
14870
14871		return uiHash;
14872	},
14873
14874	_hasMultipleValues: function() {
14875		return this.options.values && this.options.values.length;
14876	},
14877
14878	_start: function( event, index ) {
14879		return this._trigger( "start", event, this._uiHash( index ) );
14880	},
14881
14882	_slide: function( event, index, newVal ) {
14883		var allowed, otherVal,
14884			currentValue = this.value(),
14885			newValues = this.values();
14886
14887		if ( this._hasMultipleValues() ) {
14888			otherVal = this.values( index ? 0 : 1 );
14889			currentValue = this.values( index );
14890
14891			if ( this.options.values.length === 2 && this.options.range === true ) {
14892				newVal =  index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal );
14893			}
14894
14895			newValues[ index ] = newVal;
14896		}
14897
14898		if ( newVal === currentValue ) {
14899			return;
14900		}
14901
14902		allowed = this._trigger( "slide", event, this._uiHash( index, newVal, newValues ) );
14903
14904		// A slide can be canceled by returning false from the slide callback
14905		if ( allowed === false ) {
14906			return;
14907		}
14908
14909		if ( this._hasMultipleValues() ) {
14910			this.values( index, newVal );
14911		} else {
14912			this.value( newVal );
14913		}
14914	},
14915
14916	_stop: function( event, index ) {
14917		this._trigger( "stop", event, this._uiHash( index ) );
14918	},
14919
14920	_change: function( event, index ) {
14921		if ( !this._keySliding && !this._mouseSliding ) {
14922
14923			//store the last changed value index for reference when handles overlap
14924			this._lastChangedValue = index;
14925			this._trigger( "change", event, this._uiHash( index ) );
14926		}
14927	},
14928
14929	value: function( newValue ) {
14930		if ( arguments.length ) {
14931			this.options.value = this._trimAlignValue( newValue );
14932			this._refreshValue();
14933			this._change( null, 0 );
14934			return;
14935		}
14936
vendor: 4,358 bytes, lines 14937-15109
14937		return this._value();
14938	},
14939
14940	values: function( index, newValue ) {
14941		var vals,
14942			newValues,
14943			i;
14944
14945		if ( arguments.length > 1 ) {
14946			this.options.values[ index ] = this._trimAlignValue( newValue );
14947			this._refreshValue();
14948			this._change( null, index );
14949			return;
14950		}
14951
14952		if ( arguments.length ) {
14953			if ( Array.isArray( arguments[ 0 ] ) ) {
14954				vals = this.options.values;
14955				newValues = arguments[ 0 ];
14956				for ( i = 0; i < vals.length; i += 1 ) {
14957					vals[ i ] = this._trimAlignValue( newValues[ i ] );
14958					this._change( null, i );
14959				}
14960				this._refreshValue();
14961			} else {
14962				if ( this._hasMultipleValues() ) {
14963					return this._values( index );
14964				} else {
14965					return this.value();
14966				}
14967			}
14968		} else {
14969			return this._values();
14970		}
14971	},
14972
14973	_setOption: function( key, value ) {
14974		var i,
14975			valsLength = 0;
14976
14977		if ( key === "range" && this.options.range === true ) {
14978			if ( value === "min" ) {
14979				this.options.value = this._values( 0 );
14980				this.options.values = null;
14981			} else if ( value === "max" ) {
14982				this.options.value = this._values( this.options.values.length - 1 );
14983				this.options.values = null;
14984			}
14985		}
14986
14987		if ( Array.isArray( this.options.values ) ) {
14988			valsLength = this.options.values.length;
14989		}
14990
14991		this._super( key, value );
14992
14993		switch ( key ) {
14994			case "orientation":
14995				this._detectOrientation();
14996				this._removeClass( "ui-slider-horizontal ui-slider-vertical" )
14997					._addClass( "ui-slider-" + this.orientation );
14998				this._refreshValue();
14999				if ( this.options.range ) {
15000					this._refreshRange( value );
15001				}
15002
15003				// Reset positioning from previous orientation
15004				this.handles.css( value === "horizontal" ? "bottom" : "left", "" );
15005				break;
15006			case "value":
15007				this._animateOff = true;
15008				this._refreshValue();
15009				this._change( null, 0 );
15010				this._animateOff = false;
15011				break;
15012			case "values":
15013				this._animateOff = true;
15014				this._refreshValue();
15015
15016				// Start from the last handle to prevent unreachable handles (#9046)
15017				for ( i = valsLength - 1; i >= 0; i-- ) {
15018					this._change( null, i );
15019				}
15020				this._animateOff = false;
15021				break;
15022			case "step":
15023			case "min":
15024			case "max":
15025				this._animateOff = true;
15026				this._calculateNewMax();
15027				this._refreshValue();
15028				this._animateOff = false;
15029				break;
15030			case "range":
15031				this._animateOff = true;
15032				this._refresh();
15033				this._animateOff = false;
15034				break;
15035		}
15036	},
15037
15038	_setOptionDisabled: function( value ) {
15039		this._super( value );
15040
15041		this._toggleClass( null, "ui-state-disabled", !!value );
15042	},
15043
15044	//internal value getter
15045	// _value() returns value trimmed by min and max, aligned by step
15046	_value: function() {
15047		var val = this.options.value;
15048		val = this._trimAlignValue( val );
15049
15050		return val;
15051	},
15052
15053	//internal values getter
15054	// _values() returns array of values trimmed by min and max, aligned by step
15055	// _values( index ) returns single value trimmed by min and max, aligned by step
15056	_values: function( index ) {
15057		var val,
15058			vals,
15059			i;
15060
15061		if ( arguments.length ) {
15062			val = this.options.values[ index ];
15063			val = this._trimAlignValue( val );
15064
15065			return val;
15066		} else if ( this._hasMultipleValues() ) {
15067
15068			// .slice() creates a copy of the array
15069			// this copy gets trimmed by min and max and then returned
15070			vals = this.options.values.slice();
15071			for ( i = 0; i < vals.length; i += 1 ) {
15072				vals[ i ] = this._trimAlignValue( vals[ i ] );
15073			}
15074
15075			return vals;
15076		} else {
15077			return [];
15078		}
15079	},
15080
15081	// Returns the step-aligned value that val is closest to, between (inclusive) min and max
15082	_trimAlignValue: function( val ) {
15083		if ( val <= this._valueMin() ) {
15084			return this._valueMin();
15085		}
15086		if ( val >= this._valueMax() ) {
15087			return this._valueMax();
15088		}
15089		var step = ( this.options.step > 0 ) ? this.options.step : 1,
15090			valModStep = ( val - this._valueMin() ) % step,
15091			alignValue = val - valModStep;
15092
15093		if ( Math.abs( valModStep ) * 2 >= step ) {
15094			alignValue += ( valModStep > 0 ) ? step : ( -step );
15095		}
15096
15097		// Since JavaScript has problems with large floats, round
15098		// the final value to 5 digits after the decimal point (see #4124)
15099		return parseFloat( alignValue.toFixed( 5 ) );
15100	},
15101
15102	_calculateNewMax: function() {
15103		var max = this.options.max,
15104			min = this._valueMin(),
15105			step = this.options.step,
15106			aboveMin = Math.round( ( max - min ) / step ) * step;
15107		max = aboveMin + min;
15108		if ( max > this.options.max ) {
15109
vendor: 5,583 bytes, lines 15110-15309
15110			//If max is not divisible by step, rounding off may increase its value
15111			max -= step;
15112		}
15113		this.max = parseFloat( max.toFixed( this._precision() ) );
15114	},
15115
15116	_precision: function() {
15117		var precision = this._precisionOf( this.options.step );
15118		if ( this.options.min !== null ) {
15119			precision = Math.max( precision, this._precisionOf( this.options.min ) );
15120		}
15121		return precision;
15122	},
15123
15124	_precisionOf: function( num ) {
15125		var str = num.toString(),
15126			decimal = str.indexOf( "." );
15127		return decimal === -1 ? 0 : str.length - decimal - 1;
15128	},
15129
15130	_valueMin: function() {
15131		return this.options.min;
15132	},
15133
15134	_valueMax: function() {
15135		return this.max;
15136	},
15137
15138	_refreshRange: function( orientation ) {
15139		if ( orientation === "vertical" ) {
15140			this.range.css( { "width": "", "left": "" } );
15141		}
15142		if ( orientation === "horizontal" ) {
15143			this.range.css( { "height": "", "bottom": "" } );
15144		}
15145	},
15146
15147	_refreshValue: function() {
15148		var lastValPercent, valPercent, value, valueMin, valueMax,
15149			oRange = this.options.range,
15150			o = this.options,
15151			that = this,
15152			animate = ( !this._animateOff ) ? o.animate : false,
15153			_set = {};
15154
15155		if ( this._hasMultipleValues() ) {
15156			this.handles.each( function( i ) {
15157				valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() -
15158					that._valueMin() ) * 100;
15159				_set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15160				$( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15161				if ( that.options.range === true ) {
15162					if ( that.orientation === "horizontal" ) {
15163						if ( i === 0 ) {
15164							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15165								left: valPercent + "%"
15166							}, o.animate );
15167						}
15168						if ( i === 1 ) {
15169							that.range[ animate ? "animate" : "css" ]( {
15170								width: ( valPercent - lastValPercent ) + "%"
15171							}, {
15172								queue: false,
15173								duration: o.animate
15174							} );
15175						}
15176					} else {
15177						if ( i === 0 ) {
15178							that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15179								bottom: ( valPercent ) + "%"
15180							}, o.animate );
15181						}
15182						if ( i === 1 ) {
15183							that.range[ animate ? "animate" : "css" ]( {
15184								height: ( valPercent - lastValPercent ) + "%"
15185							}, {
15186								queue: false,
15187								duration: o.animate
15188							} );
15189						}
15190					}
15191				}
15192				lastValPercent = valPercent;
15193			} );
15194		} else {
15195			value = this.value();
15196			valueMin = this._valueMin();
15197			valueMax = this._valueMax();
15198			valPercent = ( valueMax !== valueMin ) ?
15199					( value - valueMin ) / ( valueMax - valueMin ) * 100 :
15200					0;
15201			_set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
15202			this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
15203
15204			if ( oRange === "min" && this.orientation === "horizontal" ) {
15205				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15206					width: valPercent + "%"
15207				}, o.animate );
15208			}
15209			if ( oRange === "max" && this.orientation === "horizontal" ) {
15210				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15211					width: ( 100 - valPercent ) + "%"
15212				}, o.animate );
15213			}
15214			if ( oRange === "min" && this.orientation === "vertical" ) {
15215				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15216					height: valPercent + "%"
15217				}, o.animate );
15218			}
15219			if ( oRange === "max" && this.orientation === "vertical" ) {
15220				this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( {
15221					height: ( 100 - valPercent ) + "%"
15222				}, o.animate );
15223			}
15224		}
15225	},
15226
15227	_handleEvents: {
15228		keydown: function( event ) {
15229			var allowed, curVal, newVal, step,
15230				index = $( event.target ).data( "ui-slider-handle-index" );
15231
15232			switch ( event.keyCode ) {
15233				case $.ui.keyCode.HOME:
15234				case $.ui.keyCode.END:
15235				case $.ui.keyCode.PAGE_UP:
15236				case $.ui.keyCode.PAGE_DOWN:
15237				case $.ui.keyCode.UP:
15238				case $.ui.keyCode.RIGHT:
15239				case $.ui.keyCode.DOWN:
15240				case $.ui.keyCode.LEFT:
15241					event.preventDefault();
15242					if ( !this._keySliding ) {
15243						this._keySliding = true;
15244						this._addClass( $( event.target ), null, "ui-state-active" );
15245						allowed = this._start( event, index );
15246						if ( allowed === false ) {
15247							return;
15248						}
15249					}
15250					break;
15251			}
15252
15253			step = this.options.step;
15254			if ( this._hasMultipleValues() ) {
15255				curVal = newVal = this.values( index );
15256			} else {
15257				curVal = newVal = this.value();
15258			}
15259
15260			switch ( event.keyCode ) {
15261				case $.ui.keyCode.HOME:
15262					newVal = this._valueMin();
15263					break;
15264				case $.ui.keyCode.END:
15265					newVal = this._valueMax();
15266					break;
15267				case $.ui.keyCode.PAGE_UP:
15268					newVal = this._trimAlignValue(
15269						curVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )
15270					);
15271					break;
15272				case $.ui.keyCode.PAGE_DOWN:
15273					newVal = this._trimAlignValue(
15274						curVal - ( ( this._valueMax() - this._valueMin() ) / this.numPages ) );
15275					break;
15276				case $.ui.keyCode.UP:
15277				case $.ui.keyCode.RIGHT:
15278					if ( curVal === this._valueMax() ) {
15279						return;
15280					}
15281					newVal = this._trimAlignValue( curVal + step );
15282					break;
15283				case $.ui.keyCode.DOWN:
15284				case $.ui.keyCode.LEFT:
15285					if ( curVal === this._valueMin() ) {
15286						return;
15287					}
15288					newVal = this._trimAlignValue( curVal - step );
15289					break;
15290			}
15291
15292			this._slide( event, index, newVal );
15293		},
15294		keyup: function( event ) {
15295			var index = $( event.target ).data( "ui-slider-handle-index" );
15296
15297			if ( this._keySliding ) {
15298				this._keySliding = false;
15299				this._stop( event, index );
15300				this._change( event, index );
15301				this._removeClass( $( event.target ), null, "ui-state-active" );
15302			}
15303		}
15304	}
15305} );
15306
15307
15308/*!
15309 * jQuery UI S
vendor: 3,506 bytes, lines 15309-15465
15309ortable 1.14.1
15310 * https://jqueryui.com
15311 *
15312 * Copyright OpenJS Foundation and other contributors
15313 * Released under the MIT license.
15314 * https://jquery.org/license
15315 */
15316
15317//>>label: Sortable
15318//>>group: Interactions
15319//>>description: Enables items in a list to be sorted using the mouse.
15320//>>docs: https://api.jqueryui.com/sortable/
15321//>>demos: https://jqueryui.com/sortable/
15322//>>css.structure: ../../themes/base/sortable.css
15323
15324
15325var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
15326	version: "1.14.1",
15327	widgetEventPrefix: "sort",
15328	ready: false,
15329	options: {
15330		appendTo: "parent",
15331		axis: false,
15332		connectWith: false,
15333		containment: false,
15334		cursor: "auto",
15335		cursorAt: false,
15336		dropOnEmpty: true,
15337		forcePlaceholderSize: false,
15338		forceHelperSize: false,
15339		grid: false,
15340		handle: false,
15341		helper: "original",
15342		items: "> *",
15343		opacity: false,
15344		placeholder: false,
15345		revert: false,
15346		scroll: true,
15347		scrollSensitivity: 20,
15348		scrollSpeed: 20,
15349		scope: "default",
15350		tolerance: "intersect",
15351		zIndex: 1000,
15352
15353		// Callbacks
15354		activate: null,
15355		beforeStop: null,
15356		change: null,
15357		deactivate: null,
15358		out: null,
15359		over: null,
15360		receive: null,
15361		remove: null,
15362		sort: null,
15363		start: null,
15364		stop: null,
15365		update: null
15366	},
15367
15368	_isOverAxis: function( x, reference, size ) {
15369		return ( x >= reference ) && ( x < ( reference + size ) );
15370	},
15371
15372	_isFloating: function( item ) {
15373		return ( /left|right/ ).test( item.css( "float" ) ) ||
15374			( /inline|table-cell/ ).test( item.css( "display" ) );
15375	},
15376
15377	_create: function() {
15378		this.containerCache = {};
15379		this._addClass( "ui-sortable" );
15380
15381		//Get the items
15382		this.refresh();
15383
15384		//Let's determine the parent's offset
15385		this.offset = this.element.offset();
15386
15387		//Initialize mouse events for interaction
15388		this._mouseInit();
15389
15390		this._setHandleClassName();
15391
15392		//We're ready to go
15393		this.ready = true;
15394
15395	},
15396
15397	_setOption: function( key, value ) {
15398		this._super( key, value );
15399
15400		if ( key === "handle" ) {
15401			this._setHandleClassName();
15402		}
15403	},
15404
15405	_setHandleClassName: function() {
15406		var that = this;
15407		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
15408		$.each( this.items, function() {
15409			that._addClass(
15410				this.instance.options.handle ?
15411					this.item.find( this.instance.options.handle ) :
15412					this.item,
15413				"ui-sortable-handle"
15414			);
15415		} );
15416	},
15417
15418	_destroy: function() {
15419		this._mouseDestroy();
15420
15421		for ( var i = this.items.length - 1; i >= 0; i-- ) {
15422			this.items[ i ].item.removeData( this.widgetName + "-item" );
15423		}
15424
15425		return this;
15426	},
15427
15428	_mouseCapture: function( event, overrideHandle ) {
15429		var currentItem = null,
15430			validHandle = false,
15431			that = this;
15432
15433		if ( this.reverting ) {
15434			return false;
15435		}
15436
15437		if ( this.options.disabled || this.options.type === "static" ) {
15438			return false;
15439		}
15440
15441		//We have to refresh the items data once first
15442		this._refreshItems( event );
15443
15444		//Find out if the clicked node (or one of its parents) is a actual item in this.items
15445		$( event.target ).parents().each( function() {
15446			if ( $.data( this, that.widgetName + "-item" ) === that ) {
15447				currentItem = $( this );
15448				return false;
15449			}
15450		} );
15451		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
15452			currentItem = $( event.target );
15453		}
15454
15455		if ( !currentItem ) {
15456			return false;
15457		}
15458		if ( this.options.handle && !overrideHandle ) {
15459			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
15460				if ( this === event.target ) {
15461					validHandle = true;
15462				}
15463			} );
15464			if ( !validHandle ) {
15465				return false;
vendor: 9,308 bytes, lines 15466-15784
15466			}
15467		}
15468
15469		this.currentItem = currentItem;
15470		this._removeCurrentsFromItems();
15471		return true;
15472
15473	},
15474
15475	_mouseStart: function( event, overrideHandle, noActivation ) {
15476
15477		var i, body,
15478			o = this.options;
15479
15480		this.currentContainer = this;
15481
15482		//We only need to call refreshPositions, because the refreshItems call has been moved to
15483		// mouseCapture
15484		this.refreshPositions();
15485
15486		//Prepare the dragged items parent
15487		this.appendTo = $( o.appendTo !== "parent" ?
15488				o.appendTo :
15489				this.currentItem.parent() );
15490
15491		//Create and append the visible helper
15492		this.helper = this._createHelper( event );
15493
15494		//Cache the helper size
15495		this._cacheHelperProportions();
15496
15497		/*
15498		 * - Position generation -
15499		 * This block generates everything position related - it's the core of draggables.
15500		 */
15501
15502		//Cache the margins of the original element
15503		this._cacheMargins();
15504
15505		//The element's absolute position on the page minus margins
15506		this.offset = this.currentItem.offset();
15507		this.offset = {
15508			top: this.offset.top - this.margins.top,
15509			left: this.offset.left - this.margins.left
15510		};
15511
15512		$.extend( this.offset, {
15513			click: { //Where the click happened, relative to the element
15514				left: event.pageX - this.offset.left,
15515				top: event.pageY - this.offset.top
15516			},
15517
15518			// This is a relative to absolute position minus the actual position calculation -
15519			// only used for relative positioned helper
15520			relative: this._getRelativeOffset()
15521		} );
15522
15523		// After we get the helper offset, but before we get the parent offset we can
15524		// change the helper's position to absolute
15525		// TODO: Still need to figure out a way to make relative sorting possible
15526		this.helper.css( "position", "absolute" );
15527		this.cssPosition = this.helper.css( "position" );
15528
15529		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15530		if ( o.cursorAt ) {
15531			this._adjustOffsetFromHelper( o.cursorAt );
15532		}
15533
15534		//Cache the former DOM position
15535		this.domPosition = {
15536			prev: this.currentItem.prev()[ 0 ],
15537			parent: this.currentItem.parent()[ 0 ]
15538		};
15539
15540		// If the helper is not the original, hide the original so it's not playing any role during
15541		// the drag, won't cause anything bad this way
15542		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
15543			this.currentItem.hide();
15544		}
15545
15546		//Create the placeholder
15547		this._createPlaceholder();
15548
15549		//Get the next scrolling parent
15550		this.scrollParent = this.placeholder.scrollParent();
15551
15552		$.extend( this.offset, {
15553			parent: this._getParentOffset()
15554		} );
15555
15556		//Set a containment if given in the options
15557		if ( o.containment ) {
15558			this._setContainment();
15559		}
15560
15561		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
15562			body = this.document.find( "body" );
15563
15564			this._storedStylesheet =
15565				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
15566		}
15567
15568		// We need to make sure to grab the zIndex before setting the
15569		// opacity, because setting the opacity to anything lower than 1
15570		// causes the zIndex to change from "auto" to 0.
15571		if ( o.zIndex ) { // zIndex option
15572			if ( this.helper.css( "zIndex" ) ) {
15573				this._storedZIndex = this.helper.css( "zIndex" );
15574			}
15575			this.helper.css( "zIndex", o.zIndex );
15576		}
15577
15578		if ( o.opacity ) { // opacity option
15579			if ( this.helper.css( "opacity" ) ) {
15580				this._storedOpacity = this.helper.css( "opacity" );
15581			}
15582			this.helper.css( "opacity", o.opacity );
15583		}
15584
15585		//Prepare scrolling
15586		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15587				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15588			this.overflowOffset = this.scrollParent.offset();
15589		}
15590
15591		//Call callbacks
15592		this._trigger( "start", event, this._uiHash() );
15593
15594		//Recache the helper size
15595		if ( !this._preserveHelperProportions ) {
15596			this._cacheHelperProportions();
15597		}
15598
15599		//Post "activate" events to possible containers
15600		if ( !noActivation ) {
15601			for ( i = this.containers.length - 1; i >= 0; i-- ) {
15602				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
15603			}
15604		}
15605
15606		//Prepare possible droppables
15607		if ( $.ui.ddmanager ) {
15608			$.ui.ddmanager.current = this;
15609		}
15610
15611		if ( $.ui.ddmanager && !o.dropBehaviour ) {
15612			$.ui.ddmanager.prepareOffsets( this, event );
15613		}
15614
15615		this.dragging = true;
15616
15617		this._addClass( this.helper, "ui-sortable-helper" );
15618
15619		//Move the helper, if needed
15620		if ( !this.helper.parent().is( this.appendTo ) ) {
15621			this.helper.detach().appendTo( this.appendTo );
15622
15623			//Update position
15624			this.offset.parent = this._getParentOffset();
15625		}
15626
15627		//Generate the original position
15628		this.position = this.originalPosition = this._generatePosition( event );
15629		this.originalPageX = event.pageX;
15630		this.originalPageY = event.pageY;
15631		this.lastPositionAbs = this.positionAbs = this._convertPositionTo( "absolute" );
15632
15633		this._mouseDrag( event );
15634
15635		return true;
15636
15637	},
15638
15639	_scroll: function( event ) {
15640		var o = this.options,
15641			scrolled = false;
15642
15643		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
15644				this.scrollParent[ 0 ].tagName !== "HTML" ) {
15645
15646			if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
15647					event.pageY < o.scrollSensitivity ) {
15648				this.scrollParent[ 0 ].scrollTop =
15649					scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
15650			} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
15651				this.scrollParent[ 0 ].scrollTop =
15652					scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
15653			}
15654
15655			if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
15656					event.pageX < o.scrollSensitivity ) {
15657				this.scrollParent[ 0 ].scrollLeft = scrolled =
15658					this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
15659			} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
15660				this.scrollParent[ 0 ].scrollLeft = scrolled =
15661					this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
15662			}
15663
15664		} else {
15665
15666			if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
15667				scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
15668			} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
15669					o.scrollSensitivity ) {
15670				scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
15671			}
15672
15673			if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
15674				scrolled = this.document.scrollLeft(
15675					this.document.scrollLeft() - o.scrollSpeed
15676				);
15677			} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
15678					o.scrollSensitivity ) {
15679				scrolled = this.document.scrollLeft(
15680					this.document.scrollLeft() + o.scrollSpeed
15681				);
15682			}
15683
15684		}
15685
15686		return scrolled;
15687	},
15688
15689	_mouseDrag: function( event ) {
15690		var i, item, itemElement, intersection,
15691			o = this.options;
15692
15693		//Compute the helpers position
15694		this.position = this._generatePosition( event );
15695		this.positionAbs = this._convertPositionTo( "absolute" );
15696
15697		//Set the helper position
15698		if ( !this.options.axis || this.options.axis !== "y" ) {
15699			this.helper[ 0 ].style.left = this.position.left + "px";
15700		}
15701		if ( !this.options.axis || this.options.axis !== "x" ) {
15702			this.helper[ 0 ].style.top = this.position.top + "px";
15703		}
15704
15705		//Do scrolling
15706		if ( o.scroll ) {
15707			if ( this._scroll( event ) !== false ) {
15708
15709				//Update item positions used in position checks
15710				this._refreshItemPositions( true );
15711
15712				if ( $.ui.ddmanager && !o.dropBehaviour ) {
15713					$.ui.ddmanager.prepareOffsets( this, event );
15714				}
15715			}
15716		}
15717
15718		this.dragDirection = {
15719			vertical: this._getDragVerticalDirection(),
15720			horizontal: this._getDragHorizontalDirection()
15721		};
15722
15723		//Rearrange
15724		for ( i = this.items.length - 1; i >= 0; i-- ) {
15725
15726			//Cache variables and intersection, continue if no intersection
15727			item = this.items[ i ];
15728			itemElement = item.item[ 0 ];
15729			intersection = this._intersectsWithPointer( item );
15730			if ( !intersection ) {
15731				continue;
15732			}
15733
15734			// Only put the placeholder inside the current Container, skip all
15735			// items from other containers. This works because when moving
15736			// an item from one container to another the
15737			// currentContainer is switched before the placeholder is moved.
15738			//
15739			// Without this, moving items in "sub-sortables" can cause
15740			// the placeholder to jitter between the outer and inner container.
15741			if ( item.instance !== this.currentContainer ) {
15742				continue;
15743			}
15744
15745			// Cannot intersect with itself
15746			// no useless actions that have been done before
15747			// no action if the item moved is the parent of the item checked
15748			if ( itemElement !== this.currentItem[ 0 ] &&
15749				this.placeholder[ intersection === 1 ?
15750				"next" : "prev" ]()[ 0 ] !== itemElement &&
15751				!$.contains( this.placeholder[ 0 ], itemElement ) &&
15752				( this.options.type === "semi-dynamic" ?
15753					!$.contains( this.element[ 0 ], itemElement ) :
15754					true
15755				)
15756			) {
15757
15758				this.direction = intersection === 1 ? "down" : "up";
15759
15760				if ( this.options.tolerance === "pointer" ||
15761						this._intersectsWithSides( item ) ) {
15762					this._rearrange( event, item );
15763				} else {
15764					break;
15765				}
15766
15767				this._trigger( "change", event, this._uiHash() );
15768				break;
15769			}
15770		}
15771
15772		//Post events to containers
15773		this._contactContainers( event );
15774
15775		//Interconnect with droppables
15776		if ( $.ui.ddmanager ) {
15777			$.ui.ddmanager.drag( this, event );
15778		}
15779
15780		//Call callbacks
15781		this._trigger( "sort", event, this._uiHash() );
15782
15783		this.lastPositionAbs = this.positionAbs;
15784		return false;
vendor: 5,063 bytes, lines 15785-15974
15785
15786	},
15787
15788	_mouseStop: function( event, noPropagation ) {
15789
15790		if ( !event ) {
15791			return;
15792		}
15793
15794		//If we are using droppables, inform the manager about the drop
15795		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
15796			$.ui.ddmanager.drop( this, event );
15797		}
15798
15799		if ( this.options.revert ) {
15800			var that = this,
15801				cur = this.placeholder.offset(),
15802				axis = this.options.axis,
15803				animation = {};
15804
15805			if ( !axis || axis === "x" ) {
15806				animation.left = cur.left - this.offset.parent.left - this.margins.left +
15807					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15808						0 :
15809						this.offsetParent[ 0 ].scrollLeft
15810					);
15811			}
15812			if ( !axis || axis === "y" ) {
15813				animation.top = cur.top - this.offset.parent.top - this.margins.top +
15814					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
15815						0 :
15816						this.offsetParent[ 0 ].scrollTop
15817					);
15818			}
15819			this.reverting = true;
15820			$( this.helper ).animate(
15821				animation,
15822				parseInt( this.options.revert, 10 ) || 500,
15823				function() {
15824					that._clear( event );
15825				}
15826			);
15827		} else {
15828			this._clear( event, noPropagation );
15829		}
15830
15831		return false;
15832
15833	},
15834
15835	cancel: function() {
15836
15837		if ( this.dragging ) {
15838
15839			this._mouseUp( new $.Event( "mouseup", { target: null } ) );
15840
15841			if ( this.options.helper === "original" ) {
15842				this.currentItem.css( this._storedCSS );
15843				this._removeClass( this.currentItem, "ui-sortable-helper" );
15844			} else {
15845				this.currentItem.show();
15846			}
15847
15848			//Post deactivating events to containers
15849			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
15850				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
15851				if ( this.containers[ i ].containerCache.over ) {
15852					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
15853					this.containers[ i ].containerCache.over = 0;
15854				}
15855			}
15856
15857		}
15858
15859		if ( this.placeholder ) {
15860
15861			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15862			// it unbinds ALL events from the original node!
15863			if ( this.placeholder[ 0 ].parentNode ) {
15864				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
15865			}
15866			if ( this.options.helper !== "original" && this.helper &&
15867					this.helper[ 0 ].parentNode ) {
15868				this.helper.remove();
15869			}
15870
15871			$.extend( this, {
15872				helper: null,
15873				dragging: false,
15874				reverting: false,
15875				_noFinalSort: null
15876			} );
15877
15878			if ( this.domPosition.prev ) {
15879				$( this.domPosition.prev ).after( this.currentItem );
15880			} else {
15881				$( this.domPosition.parent ).prepend( this.currentItem );
15882			}
15883		}
15884
15885		return this;
15886
15887	},
15888
15889	serialize: function( o ) {
15890
15891		var items = this._getItemsAsjQuery( o && o.connected ),
15892			str = [];
15893		o = o || {};
15894
15895		$( items ).each( function() {
15896			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
15897				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
15898			if ( res ) {
15899				str.push(
15900					( o.key || res[ 1 ] + "[]" ) +
15901					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
15902			}
15903		} );
15904
15905		if ( !str.length && o.key ) {
15906			str.push( o.key + "=" );
15907		}
15908
15909		return str.join( "&" );
15910
15911	},
15912
15913	toArray: function( o ) {
15914
15915		var items = this._getItemsAsjQuery( o && o.connected ),
15916			ret = [];
15917
15918		o = o || {};
15919
15920		items.each( function() {
15921			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
15922		} );
15923		return ret;
15924
15925	},
15926
15927	/* Be careful with the following core functions */
15928	_intersectsWith: function( item ) {
15929
15930		var x1 = this.positionAbs.left,
15931			x2 = x1 + this.helperProportions.width,
15932			y1 = this.positionAbs.top,
15933			y2 = y1 + this.helperProportions.height,
15934			l = item.left,
15935			r = l + item.width,
15936			t = item.top,
15937			b = t + item.height,
15938			dyClick = this.offset.click.top,
15939			dxClick = this.offset.click.left,
15940			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
15941				( y1 + dyClick ) < b ),
15942			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
15943				( x1 + dxClick ) < r ),
15944			isOverElement = isOverElementHeight && isOverElementWidth;
15945
15946		if ( this.options.tolerance === "pointer" ||
15947			this.options.forcePointerForContainers ||
15948			( this.options.tolerance !== "pointer" &&
15949				this.helperProportions[ this.floating ? "width" : "height" ] >
15950				item[ this.floating ? "width" : "height" ] )
15951		) {
15952			return isOverElement;
15953		} else {
15954
15955			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
15956				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
15957				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
15958				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
15959
15960		}
15961	},
15962
15963	_intersectsWithPointer: function( item ) {
15964		var verticalDirection, horizontalDirection,
15965			isOverElementHeight = ( this.options.axis === "x" ) ||
15966				this._isOverAxis(
15967					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
15968			isOverElementWidth = ( this.options.axis === "y" ) ||
15969				this._isOverAxis(
15970					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
15971			isOverElement = isOverElementHeight && isOverElementWidth;
15972
15973		if ( !isOverElement ) {
15974			return false;
vendor: 18,528 bytes, lines 15975-16555
15975		}
15976
15977		verticalDirection = this.dragDirection.vertical;
15978		horizontalDirection = this.dragDirection.horizontal;
15979
15980		return this.floating ?
15981			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 ) :
15982			( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
15983
15984	},
15985
15986	_intersectsWithSides: function( item ) {
15987
15988		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
15989				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
15990			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
15991				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
15992			verticalDirection = this.dragDirection.vertical,
15993			horizontalDirection = this.dragDirection.horizontal;
15994
15995		if ( this.floating && horizontalDirection ) {
15996			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
15997				( horizontalDirection === "left" && !isOverRightHalf ) );
15998		} else {
15999			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
16000				( verticalDirection === "up" && !isOverBottomHalf ) );
16001		}
16002
16003	},
16004
16005	_getDragVerticalDirection: function() {
16006		var delta = this.positionAbs.top - this.lastPositionAbs.top;
16007		return delta !== 0 && ( delta > 0 ? "down" : "up" );
16008	},
16009
16010	_getDragHorizontalDirection: function() {
16011		var delta = this.positionAbs.left - this.lastPositionAbs.left;
16012		return delta !== 0 && ( delta > 0 ? "right" : "left" );
16013	},
16014
16015	refresh: function( event ) {
16016		this._refreshItems( event );
16017		this._setHandleClassName();
16018		this.refreshPositions();
16019		return this;
16020	},
16021
16022	_connectWith: function() {
16023		var options = this.options;
16024		return options.connectWith.constructor === String ?
16025			[ options.connectWith ] :
16026			options.connectWith;
16027	},
16028
16029	_getItemsAsjQuery: function( connected ) {
16030
16031		var i, j, cur, inst,
16032			items = [],
16033			queries = [],
16034			connectWith = this._connectWith();
16035
16036		if ( connectWith && connected ) {
16037			for ( i = connectWith.length - 1; i >= 0; i-- ) {
16038				cur = $( connectWith[ i ], this.document[ 0 ] );
16039				for ( j = cur.length - 1; j >= 0; j-- ) {
16040					inst = $.data( cur[ j ], this.widgetFullName );
16041					if ( inst && inst !== this && !inst.options.disabled ) {
16042						queries.push( [ typeof inst.options.items === "function" ?
16043							inst.options.items.call( inst.element ) :
16044							$( inst.options.items, inst.element )
16045								.not( ".ui-sortable-helper" )
16046								.not( ".ui-sortable-placeholder" ), inst ] );
16047					}
16048				}
16049			}
16050		}
16051
16052		queries.push( [ typeof this.options.items === "function" ?
16053			this.options.items
16054				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
16055			$( this.options.items, this.element )
16056				.not( ".ui-sortable-helper" )
16057				.not( ".ui-sortable-placeholder" ), this ] );
16058
16059		function addItems() {
16060			items.push( this );
16061		}
16062		for ( i = queries.length - 1; i >= 0; i-- ) {
16063			queries[ i ][ 0 ].each( addItems );
16064		}
16065
16066		return $( items );
16067
16068	},
16069
16070	_removeCurrentsFromItems: function() {
16071
16072		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
16073
16074		this.items = $.grep( this.items, function( item ) {
16075			for ( var j = 0; j < list.length; j++ ) {
16076				if ( list[ j ] === item.item[ 0 ] ) {
16077					return false;
16078				}
16079			}
16080			return true;
16081		} );
16082
16083	},
16084
16085	_refreshItems: function( event ) {
16086
16087		this.items = [];
16088		this.containers = [ this ];
16089
16090		var i, j, cur, inst, targetData, _queries, item, queriesLength,
16091			items = this.items,
16092			queries = [ [ typeof this.options.items === "function" ?
16093				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
16094				$( this.options.items, this.element ), this ] ],
16095			connectWith = this._connectWith();
16096
16097		//Shouldn't be run the first time through due to massive slow-down
16098		if ( connectWith && this.ready ) {
16099			for ( i = connectWith.length - 1; i >= 0; i-- ) {
16100				cur = $( connectWith[ i ], this.document[ 0 ] );
16101				for ( j = cur.length - 1; j >= 0; j-- ) {
16102					inst = $.data( cur[ j ], this.widgetFullName );
16103					if ( inst && inst !== this && !inst.options.disabled ) {
16104						queries.push( [ typeof inst.options.items === "function" ?
16105							inst.options.items
16106								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
16107							$( inst.options.items, inst.element ), inst ] );
16108						this.containers.push( inst );
16109					}
16110				}
16111			}
16112		}
16113
16114		for ( i = queries.length - 1; i >= 0; i-- ) {
16115			targetData = queries[ i ][ 1 ];
16116			_queries = queries[ i ][ 0 ];
16117
16118			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
16119				item = $( _queries[ j ] );
16120
16121				// Data for target checking (mouse manager)
16122				item.data( this.widgetName + "-item", targetData );
16123
16124				items.push( {
16125					item: item,
16126					instance: targetData,
16127					width: 0, height: 0,
16128					left: 0, top: 0
16129				} );
16130			}
16131		}
16132
16133	},
16134
16135	_refreshItemPositions: function( fast ) {
16136		var i, item, t, p;
16137
16138		for ( i = this.items.length - 1; i >= 0; i-- ) {
16139			item = this.items[ i ];
16140
16141			//We ignore calculating positions of all connected containers when we're not over them
16142			if ( this.currentContainer && item.instance !== this.currentContainer &&
16143					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
16144				continue;
16145			}
16146
16147			t = this.options.toleranceElement ?
16148				$( this.options.toleranceElement, item.item ) :
16149				item.item;
16150
16151			if ( !fast ) {
16152				item.width = t.outerWidth();
16153				item.height = t.outerHeight();
16154			}
16155
16156			p = t.offset();
16157			item.left = p.left;
16158			item.top = p.top;
16159		}
16160	},
16161
16162	refreshPositions: function( fast ) {
16163
16164		// Determine whether items are being displayed horizontally
16165		this.floating = this.items.length ?
16166			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
16167			false;
16168
16169		// This has to be redone because due to the item being moved out/into the offsetParent,
16170		// the offsetParent's position will change
16171		if ( this.offsetParent && this.helper ) {
16172			this.offset.parent = this._getParentOffset();
16173		}
16174
16175		this._refreshItemPositions( fast );
16176
16177		var i, p;
16178
16179		if ( this.options.custom && this.options.custom.refreshContainers ) {
16180			this.options.custom.refreshContainers.call( this );
16181		} else {
16182			for ( i = this.containers.length - 1; i >= 0; i-- ) {
16183				p = this.containers[ i ].element.offset();
16184				this.containers[ i ].containerCache.left = p.left;
16185				this.containers[ i ].containerCache.top = p.top;
16186				this.containers[ i ].containerCache.width =
16187					this.containers[ i ].element.outerWidth();
16188				this.containers[ i ].containerCache.height =
16189					this.containers[ i ].element.outerHeight();
16190			}
16191		}
16192
16193		return this;
16194	},
16195
16196	_createPlaceholder: function( that ) {
16197		that = that || this;
16198		var className, nodeName,
16199			o = that.options;
16200
16201		if ( !o.placeholder || o.placeholder.constructor === String ) {
16202			className = o.placeholder;
16203			nodeName = that.currentItem[ 0 ].nodeName.toLowerCase();
16204			o.placeholder = {
16205				element: function() {
16206
16207					var element = $( "<" + nodeName + ">", that.document[ 0 ] );
16208
16209					that._addClass( element, "ui-sortable-placeholder",
16210							className || that.currentItem[ 0 ].className )
16211						._removeClass( element, "ui-sortable-helper" );
16212
16213					if ( nodeName === "tbody" ) {
16214						that._createTrPlaceholder(
16215							that.currentItem.find( "tr" ).eq( 0 ),
16216							$( "<tr>", that.document[ 0 ] ).appendTo( element )
16217						);
16218					} else if ( nodeName === "tr" ) {
16219						that._createTrPlaceholder( that.currentItem, element );
16220					} else if ( nodeName === "img" ) {
16221						element.attr( "src", that.currentItem.attr( "src" ) );
16222					}
16223
16224					if ( !className ) {
16225						element.css( "visibility", "hidden" );
16226					}
16227
16228					return element;
16229				},
16230				update: function( container, p ) {
16231
16232					// 1. If a className is set as 'placeholder option, we don't force sizes -
16233					// the class is responsible for that
16234					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16235					// class name is specified
16236					if ( className && !o.forcePlaceholderSize ) {
16237						return;
16238					}
16239
16240					// If the element doesn't have a actual height or width by itself (without
16241					// styles coming from a stylesheet), it receives the inline height and width
16242					// from the dragged item. Or, if it's a tbody or tr, it's going to have a height
16243					// anyway since we're populating them with <td>s above, but they're unlikely to
16244					// be the correct height on their own if the row heights are dynamic, so we'll
16245					// always assign the height of the dragged item given forcePlaceholderSize
16246					// is true.
16247					if ( !p.height() || ( o.forcePlaceholderSize &&
16248							( nodeName === "tbody" || nodeName === "tr" ) ) ) {
16249						p.height(
16250							that.currentItem.innerHeight() -
16251							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
16252							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
16253					}
16254					if ( !p.width() ) {
16255						p.width(
16256							that.currentItem.innerWidth() -
16257							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
16258							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
16259					}
16260				}
16261			};
16262		}
16263
16264		//Create the placeholder
16265		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
16266
16267		//Append it after the actual current item
16268		that.currentItem.after( that.placeholder );
16269
16270		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16271		o.placeholder.update( that, that.placeholder );
16272
16273	},
16274
16275	_createTrPlaceholder: function( sourceTr, targetTr ) {
16276		var that = this;
16277
16278		sourceTr.children().each( function() {
16279			$( "<td>&#160;</td>", that.document[ 0 ] )
16280				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
16281				.appendTo( targetTr );
16282		} );
16283	},
16284
16285	_contactContainers: function( event ) {
16286		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16287			floating, axis,
16288			innermostContainer = null,
16289			innermostIndex = null;
16290
16291		// Get innermost container that intersects with item
16292		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16293
16294			// Never consider a container that's located within the item itself
16295			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
16296				continue;
16297			}
16298
16299			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
16300
16301				// If we've already found a container and it's more "inner" than this, then continue
16302				if ( innermostContainer &&
16303						$.contains(
16304							this.containers[ i ].element[ 0 ],
16305							innermostContainer.element[ 0 ] ) ) {
16306					continue;
16307				}
16308
16309				innermostContainer = this.containers[ i ];
16310				innermostIndex = i;
16311
16312			} else {
16313
16314				// container doesn't intersect. trigger "out" event if necessary
16315				if ( this.containers[ i ].containerCache.over ) {
16316					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
16317					this.containers[ i ].containerCache.over = 0;
16318				}
16319			}
16320
16321		}
16322
16323		// If no intersecting containers found, return
16324		if ( !innermostContainer ) {
16325			return;
16326		}
16327
16328		// Move the item into the container if it's not there already
16329		if ( this.containers.length === 1 ) {
16330			if ( !this.containers[ innermostIndex ].containerCache.over ) {
16331				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16332				this.containers[ innermostIndex ].containerCache.over = 1;
16333			}
16334		} else {
16335
16336			// When entering a new container, we will find the item with the least distance and
16337			// append our item near it
16338			dist = 10000;
16339			itemWithLeastDistance = null;
16340			floating = innermostContainer.floating || this._isFloating( this.currentItem );
16341			posProperty = floating ? "left" : "top";
16342			sizeProperty = floating ? "width" : "height";
16343			axis = floating ? "pageX" : "pageY";
16344
16345			for ( j = this.items.length - 1; j >= 0; j-- ) {
16346				if ( !$.contains(
16347						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
16348				) {
16349					continue;
16350				}
16351				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
16352					continue;
16353				}
16354
16355				cur = this.items[ j ].item.offset()[ posProperty ];
16356				nearBottom = false;
16357				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
16358					nearBottom = true;
16359				}
16360
16361				if ( Math.abs( event[ axis ] - cur ) < dist ) {
16362					dist = Math.abs( event[ axis ] - cur );
16363					itemWithLeastDistance = this.items[ j ];
16364					this.direction = nearBottom ? "up" : "down";
16365				}
16366			}
16367
16368			//Check if dropOnEmpty is enabled
16369			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
16370				return;
16371			}
16372
16373			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
16374				if ( !this.currentContainer.containerCache.over ) {
16375					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
16376					this.currentContainer.containerCache.over = 1;
16377				}
16378				return;
16379			}
16380
16381			if ( itemWithLeastDistance ) {
16382				this._rearrange( event, itemWithLeastDistance, null, true );
16383			} else {
16384				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
16385			}
16386			this._trigger( "change", event, this._uiHash() );
16387			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
16388			this.currentContainer = this.containers[ innermostIndex ];
16389
16390			//Update the placeholder
16391			this.options.placeholder.update( this.currentContainer, this.placeholder );
16392
16393			//Update scrollParent
16394			this.scrollParent = this.placeholder.scrollParent();
16395
16396			//Update overflowOffset
16397			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16398					this.scrollParent[ 0 ].tagName !== "HTML" ) {
16399				this.overflowOffset = this.scrollParent.offset();
16400			}
16401
16402			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
16403			this.containers[ innermostIndex ].containerCache.over = 1;
16404		}
16405
16406	},
16407
16408	_createHelper: function( event ) {
16409
16410		var o = this.options,
16411			helper = typeof o.helper === "function" ?
16412				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
16413				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
16414
16415		//Add the helper to the DOM if that didn't happen already
16416		if ( !helper.parents( "body" ).length ) {
16417			this.appendTo[ 0 ].appendChild( helper[ 0 ] );
16418		}
16419
16420		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
16421			this._storedCSS = {
16422				width: this.currentItem[ 0 ].style.width,
16423				height: this.currentItem[ 0 ].style.height,
16424				position: this.currentItem.css( "position" ),
16425				top: this.currentItem.css( "top" ),
16426				left: this.currentItem.css( "left" )
16427			};
16428		}
16429
16430		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
16431			helper.width( this.currentItem.width() );
16432		}
16433		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
16434			helper.height( this.currentItem.height() );
16435		}
16436
16437		return helper;
16438
16439	},
16440
16441	_adjustOffsetFromHelper: function( obj ) {
16442		if ( typeof obj === "string" ) {
16443			obj = obj.split( " " );
16444		}
16445		if ( Array.isArray( obj ) ) {
16446			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
16447		}
16448		if ( "left" in obj ) {
16449			this.offset.click.left = obj.left + this.margins.left;
16450		}
16451		if ( "right" in obj ) {
16452			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16453		}
16454		if ( "top" in obj ) {
16455			this.offset.click.top = obj.top + this.margins.top;
16456		}
16457		if ( "bottom" in obj ) {
16458			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16459		}
16460	},
16461
16462	_getParentOffset: function() {
16463
16464		//Get the offsetParent and cache its position
16465		this.offsetParent = this.helper.offsetParent();
16466		var po = this.offsetParent.offset();
16467
16468		// This is a special case where we need to modify a offset calculated on start, since the
16469		// following happened:
16470		// 1. The position of the helper is absolute, so it's position is calculated based on the
16471		// next positioned parent
16472		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16473		// the document, which means that the scroll is included in the initial calculation of the
16474		// offset of the parent, and never recalculated upon drag
16475		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16476				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
16477			po.left += this.scrollParent.scrollLeft();
16478			po.top += this.scrollParent.scrollTop();
16479		}
16480
16481		// This needs to be actually done for all browsers, since pageX/pageY includes
16482		// this information.
16483		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ) {
16484			po = { top: 0, left: 0 };
16485		}
16486
16487		return {
16488			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
16489			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
16490		};
16491
16492	},
16493
16494	_getRelativeOffset: function() {
16495
16496		if ( this.cssPosition === "relative" ) {
16497			var p = this.currentItem.position();
16498			return {
16499				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
16500					this.scrollParent.scrollTop(),
16501				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
16502					this.scrollParent.scrollLeft()
16503			};
16504		} else {
16505			return { top: 0, left: 0 };
16506		}
16507
16508	},
16509
16510	_cacheMargins: function() {
16511		this.margins = {
16512			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
16513			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
16514		};
16515	},
16516
16517	_cacheHelperProportions: function() {
16518		this.helperProportions = {
16519			width: this.helper.outerWidth(),
16520			height: this.helper.outerHeight()
16521		};
16522	},
16523
16524	_setContainment: function() {
16525
16526		var ce, co, over,
16527			o = this.options;
16528		if ( o.containment === "parent" ) {
16529			o.containment = this.helper[ 0 ].parentNode;
16530		}
16531		if ( o.containment === "document" || o.containment === "window" ) {
16532			this.containment = [
16533				0 - this.offset.relative.left - this.offset.parent.left,
16534				0 - this.offset.relative.top - this.offset.parent.top,
16535				o.containment === "document" ?
16536					this.document.width() :
16537					this.window.width() - this.helperProportions.width - this.margins.left,
16538				( o.containment === "document" ?
16539					( this.document.height() || document.body.parentNode.scrollHeight ) :
16540					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
16541				) - this.helperProportions.height - this.margins.top
16542			];
16543		}
16544
16545		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
16546			ce = $( o.containment )[ 0 ];
16547			co = $( o.containment ).offset();
16548			over = ( $( ce ).css( "overflow" ) !== "hidden" );
16549
16550			this.containment = [
16551				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
16552					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
16553				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
16554					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
16555				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) 
vendor: 1,747 bytes, lines 16555-16607
16555: ce.offsetWidth ) -
16556					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
16557					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
16558					this.helperProportions.width - this.margins.left,
16559				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
16560					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
16561					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
16562					this.helperProportions.height - this.margins.top
16563			];
16564		}
16565
16566	},
16567
16568	_convertPositionTo: function( d, pos ) {
16569
16570		if ( !pos ) {
16571			pos = this.position;
16572		}
16573		var mod = d === "absolute" ? 1 : -1,
16574			scroll = this.cssPosition === "absolute" &&
16575				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16576				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16577					this.offsetParent :
16578					this.scrollParent,
16579			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16580
16581		return {
16582			top: (
16583
16584				// The absolute mouse position
16585				pos.top	+
16586
16587				// Only for relative positioned nodes: Relative offset from element to offset parent
16588				this.offset.relative.top * mod +
16589
16590				// The offsetParent's offset without borders (offset + border)
16591				this.offset.parent.top * mod -
16592				( ( this.cssPosition === "fixed" ?
16593					-this.scrollParent.scrollTop() :
16594					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
16595			),
16596			left: (
16597
16598				// The absolute mouse position
16599				pos.left +
16600
16601				// Only for relative positioned nodes: Relative offset from element to offset parent
16602				this.offset.relative.left * mod +
16603
16604				// The offsetParent's offset without borders (offset + border)
16605				this.offset.parent.left * mod	-
16606				( ( this.cssPosition === "fixed" ?
16607					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
vendor: 8,368 bytes, lines 16608-16868
16608					scroll.scrollLeft() ) * mod )
16609			)
16610		};
16611
16612	},
16613
16614	_generatePosition: function( event ) {
16615
16616		var top, left,
16617			o = this.options,
16618			pageX = event.pageX,
16619			pageY = event.pageY,
16620			scroll = this.cssPosition === "absolute" &&
16621				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16622				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
16623					this.offsetParent :
16624					this.scrollParent,
16625				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
16626
16627		// This is another very weird special case that only happens for relative elements:
16628		// 1. If the css position is relative
16629		// 2. and the scroll parent is the document or similar to the offset parent
16630		// we have to refresh the relative offset during the scroll so there are no jumps
16631		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
16632				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
16633			this.offset.relative = this._getRelativeOffset();
16634		}
16635
16636		/*
16637		 * - Position constraining -
16638		 * Constrain the position to a mix of grid, containment.
16639		 */
16640
16641		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
16642
16643			if ( this.containment ) {
16644				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
16645					pageX = this.containment[ 0 ] + this.offset.click.left;
16646				}
16647				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
16648					pageY = this.containment[ 1 ] + this.offset.click.top;
16649				}
16650				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
16651					pageX = this.containment[ 2 ] + this.offset.click.left;
16652				}
16653				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
16654					pageY = this.containment[ 3 ] + this.offset.click.top;
16655				}
16656			}
16657
16658			if ( o.grid ) {
16659				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
16660					o.grid[ 1 ] ) * o.grid[ 1 ];
16661				pageY = this.containment ?
16662					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
16663						top - this.offset.click.top <= this.containment[ 3 ] ) ?
16664							top :
16665							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
16666								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
16667								top;
16668
16669				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
16670					o.grid[ 0 ] ) * o.grid[ 0 ];
16671				pageX = this.containment ?
16672					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
16673						left - this.offset.click.left <= this.containment[ 2 ] ) ?
16674							left :
16675							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
16676								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
16677								left;
16678			}
16679
16680		}
16681
16682		return {
16683			top: (
16684
16685				// The absolute mouse position
16686				pageY -
16687
16688				// Click offset (relative to the element)
16689				this.offset.click.top -
16690
16691				// Only for relative positioned nodes: Relative offset from element to offset parent
16692				this.offset.relative.top -
16693
16694				// The offsetParent's offset without borders (offset + border)
16695				this.offset.parent.top +
16696				( ( this.cssPosition === "fixed" ?
16697					-this.scrollParent.scrollTop() :
16698					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
16699			),
16700			left: (
16701
16702				// The absolute mouse position
16703				pageX -
16704
16705				// Click offset (relative to the element)
16706				this.offset.click.left -
16707
16708				// Only for relative positioned nodes: Relative offset from element to offset parent
16709				this.offset.relative.left -
16710
16711				// The offsetParent's offset without borders (offset + border)
16712				this.offset.parent.left +
16713				( ( this.cssPosition === "fixed" ?
16714					-this.scrollParent.scrollLeft() :
16715					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
16716			)
16717		};
16718
16719	},
16720
16721	_rearrange: function( event, i, a, hardRefresh ) {
16722
16723		if ( a ) {
16724			a[ 0 ].appendChild( this.placeholder[ 0 ] );
16725		} else {
16726			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
16727				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
16728		}
16729
16730		//Various things done here to improve the performance:
16731		// 1. we create a setTimeout, that calls refreshPositions
16732		// 2. on the instance, we have a counter variable, that get's higher after every append
16733		// 3. on the local scope, we copy the counter variable, and check in the timeout,
16734		// if it's still the same
16735		// 4. this lets only the last addition to the timeout stack through
16736		this.counter = this.counter ? ++this.counter : 1;
16737		var counter = this.counter;
16738
16739		this._delay( function() {
16740			if ( counter === this.counter ) {
16741
16742				//Precompute after each DOM insertion, NOT on mousemove
16743				this.refreshPositions( !hardRefresh );
16744			}
16745		} );
16746
16747	},
16748
16749	_clear: function( event, noPropagation ) {
16750
16751		this.reverting = false;
16752
16753		// We delay all events that have to be triggered to after the point where the placeholder
16754		// has been removed and everything else normalized again
16755		var i,
16756			delayedTriggers = [];
16757
16758		// We first have to update the dom position of the actual currentItem
16759		// Note: don't do it if the current item is already removed (by a user), or it gets
16760		// reappended (see #4088)
16761		if ( !this._noFinalSort && this.currentItem.parent().length ) {
16762			this.placeholder.before( this.currentItem );
16763		}
16764		this._noFinalSort = null;
16765
16766		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
16767			for ( i in this._storedCSS ) {
16768				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
16769					this._storedCSS[ i ] = "";
16770				}
16771			}
16772			this.currentItem.css( this._storedCSS );
16773			this._removeClass( this.currentItem, "ui-sortable-helper" );
16774		} else {
16775			this.currentItem.show();
16776		}
16777
16778		if ( this.fromOutside && !noPropagation ) {
16779			delayedTriggers.push( function( event ) {
16780				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
16781			} );
16782		}
16783		if ( ( this.fromOutside ||
16784				this.domPosition.prev !==
16785				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
16786				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
16787
16788			// Trigger update callback if the DOM position has changed
16789			delayedTriggers.push( function( event ) {
16790				this._trigger( "update", event, this._uiHash() );
16791			} );
16792		}
16793
16794		// Check if the items Container has Changed and trigger appropriate
16795		// events.
16796		if ( this !== this.currentContainer ) {
16797			if ( !noPropagation ) {
16798				delayedTriggers.push( function( event ) {
16799					this._trigger( "remove", event, this._uiHash() );
16800				} );
16801				delayedTriggers.push( ( function( c ) {
16802					return function( event ) {
16803						c._trigger( "receive", event, this._uiHash( this ) );
16804					};
16805				} ).call( this, this.currentContainer ) );
16806				delayedTriggers.push( ( function( c ) {
16807					return function( event ) {
16808						c._trigger( "update", event, this._uiHash( this ) );
16809					};
16810				} ).call( this, this.currentContainer ) );
16811			}
16812		}
16813
16814		//Post events to containers
16815		function delayEvent( type, instance, container ) {
16816			return function( event ) {
16817				container._trigger( type, event, instance._uiHash( instance ) );
16818			};
16819		}
16820		for ( i = this.containers.length - 1; i >= 0; i-- ) {
16821			if ( !noPropagation ) {
16822				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
16823			}
16824			if ( this.containers[ i ].containerCache.over ) {
16825				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
16826				this.containers[ i ].containerCache.over = 0;
16827			}
16828		}
16829
16830		//Do what was originally in plugins
16831		if ( this._storedStylesheet ) {
16832			this._storedStylesheet.remove();
16833			this._storedStylesheet = null;
16834		}
16835		if ( this._storedOpacity ) {
16836			this.helper.css( "opacity", this._storedOpacity );
16837		}
16838		if ( this._storedZIndex ) {
16839			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
16840		}
16841
16842		this.dragging = false;
16843
16844		if ( !noPropagation ) {
16845			this._trigger( "beforeStop", event, this._uiHash() );
16846		}
16847
16848		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16849		// it unbinds ALL events from the original node!
16850		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
16851
16852		if ( !this.cancelHelperRemoval ) {
16853			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
16854				this.helper.remove();
16855			}
16856			this.helper = null;
16857		}
16858
16859		if ( !noPropagation ) {
16860			for ( i = 0; i < delayedTriggers.length; i++ ) {
16861
16862				// Trigger all delayed events
16863				delayedTriggers[ i ].call( this, event );
16864			}
16865			this._trigger( "stop", event, this._uiHash() );
16866		}
16867
16868		this.fromOutside = false;
vendor: 3,820 bytes, lines 16869-17033
16869		return !this.cancelHelperRemoval;
16870
16871	},
16872
16873	_trigger: function() {
16874		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
16875			this.cancel();
16876		}
16877	},
16878
16879	_uiHash: function( _inst ) {
16880		var inst = _inst || this;
16881		return {
16882			helper: inst.helper,
16883			placeholder: inst.placeholder || $( [] ),
16884			position: inst.position,
16885			originalPosition: inst.originalPosition,
16886			offset: inst.positionAbs,
16887			item: inst.currentItem,
16888			sender: _inst ? _inst.element : null
16889		};
16890	}
16891
16892} );
16893
16894
16895/*!
16896 * jQuery UI Spinner 1.14.1
16897 * https://jqueryui.com
16898 *
16899 * Copyright OpenJS Foundation and other contributors
16900 * Released under the MIT license.
16901 * https://jquery.org/license
16902 */
16903
16904//>>label: Spinner
16905//>>group: Widgets
16906//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16907//>>docs: https://api.jqueryui.com/spinner/
16908//>>demos: https://jqueryui.com/spinner/
16909//>>css.structure: ../../themes/base/core.css
16910//>>css.structure: ../../themes/base/spinner.css
16911//>>css.theme: ../../themes/base/theme.css
16912
16913
16914function spinnerModifier( fn ) {
16915	return function() {
16916		var previous = this.element.val();
16917		fn.apply( this, arguments );
16918		this._refresh();
16919		if ( previous !== this.element.val() ) {
16920			this._trigger( "change" );
16921		}
16922	};
16923}
16924
16925$.widget( "ui.spinner", {
16926	version: "1.14.1",
16927	defaultElement: "<input>",
16928	widgetEventPrefix: "spin",
16929	options: {
16930		classes: {
16931			"ui-spinner": "ui-corner-all",
16932			"ui-spinner-down": "ui-corner-br",
16933			"ui-spinner-up": "ui-corner-tr"
16934		},
16935		culture: null,
16936		icons: {
16937			down: "ui-icon-triangle-1-s",
16938			up: "ui-icon-triangle-1-n"
16939		},
16940		incremental: true,
16941		max: null,
16942		min: null,
16943		numberFormat: null,
16944		page: 10,
16945		step: 1,
16946
16947		change: null,
16948		spin: null,
16949		start: null,
16950		stop: null
16951	},
16952
16953	_create: function() {
16954
16955		// handle string values that need to be parsed
16956		this._setOption( "max", this.options.max );
16957		this._setOption( "min", this.options.min );
16958		this._setOption( "step", this.options.step );
16959
16960		// Only format if there is a value, prevents the field from being marked
16961		// as invalid in Firefox, see #9573.
16962		if ( this.value() !== "" ) {
16963
16964			// Format the value, but don't constrain.
16965			this._value( this.element.val(), true );
16966		}
16967
16968		this._draw();
16969		this._on( this._events );
16970		this._refresh();
16971
16972		// Turning off autocomplete prevents the browser from remembering the
16973		// value when navigating through history, so we re-enable autocomplete
16974		// if the page is unloaded before the widget is destroyed. #7790
16975		this._on( this.window, {
16976			beforeunload: function() {
16977				this.element.removeAttr( "autocomplete" );
16978			}
16979		} );
16980	},
16981
16982	_getCreateOptions: function() {
16983		var options = this._super();
16984		var element = this.element;
16985
16986		$.each( [ "min", "max", "step" ], function( i, option ) {
16987			var value = element.attr( option );
16988			if ( value != null && value.length ) {
16989				options[ option ] = value;
16990			}
16991		} );
16992
16993		return options;
16994	},
16995
16996	_events: {
16997		keydown: function( event ) {
16998			if ( this._start( event ) && this._keydown( event ) ) {
16999				event.preventDefault();
17000			}
17001		},
17002		keyup: "_stop",
17003		focus: function() {
17004			this.previous = this.element.val();
17005		},
17006		blur: function( event ) {
17007			this._stop();
17008			this._refresh();
17009			if ( this.previous !== this.element.val() ) {
17010				this._trigger( "change", event );
17011			}
17012		},
17013		mousewheel: function( event, delta ) {
17014			var activeElement = this.document[ 0 ].activeElement;
17015			var isActive = this.element[ 0 ] === activeElement;
17016
17017			if ( !isActive || !delta ) {
17018				return;
17019			}
17020
17021			if ( !this.spinning && !this._start( event ) ) {
17022				return false;
17023			}
17024
17025			this._spin( ( delta > 0 ? 1 : -1 ) * this.options.step, event );
17026			clearTimeout( this.mousewheelTimer );
17027			this.mousewheelTimer = this._delay( function() {
17028				if ( this.spinning ) {
17029					this._stop( event );
17030				}
17031			}, 100 );
17032			event.preventDefault();
17033		},
vendor: 10,099 bytes, lines 17033-17435
17033
17034		"mousedown .ui-spinner-button": function( event ) {
17035			var previous;
17036
17037			// We never want the buttons to have focus; whenever the user is
17038			// interacting with the spinner, the focus should be on the input.
17039			// If the input is focused then this.previous is properly set from
17040			// when the input first received focus. If the input is not focused
17041			// then we need to set this.previous based on the value before spinning.
17042			previous = this.element[ 0 ] === this.document[ 0 ].activeElement ?
17043				this.previous : this.element.val();
17044			function checkFocus() {
17045				var isActive = this.element[ 0 ] === this.document[ 0 ].activeElement;
17046				if ( !isActive ) {
17047					this.element.trigger( "focus" );
17048					this.previous = previous;
17049				}
17050			}
17051
17052			// Ensure focus is on (or stays on) the text field
17053			event.preventDefault();
17054			checkFocus.call( this );
17055
17056			if ( this._start( event ) === false ) {
17057				return;
17058			}
17059
17060			this._repeat( null, $( event.currentTarget )
17061				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17062		},
17063		"mouseup .ui-spinner-button": "_stop",
17064		"mouseenter .ui-spinner-button": function( event ) {
17065
17066			// button will add ui-state-active if mouse was down while mouseleave and kept down
17067			if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
17068				return;
17069			}
17070
17071			if ( this._start( event ) === false ) {
17072				return false;
17073			}
17074			this._repeat( null, $( event.currentTarget )
17075				.hasClass( "ui-spinner-up" ) ? 1 : -1, event );
17076		},
17077
17078		// TODO: do we really want to consider this a stop?
17079		// shouldn't we just stop the repeater and wait until mouseup before
17080		// we trigger the stop event?
17081		"mouseleave .ui-spinner-button": "_stop"
17082	},
17083
17084	// Support mobile enhanced option and make backcompat more sane
17085	_enhance: function() {
17086		this.uiSpinner = this.element
17087			.attr( "autocomplete", "off" )
17088			.wrap( "<span>" )
17089			.parent()
17090
17091				// Add buttons
17092				.append(
17093					"<a></a><a></a>"
17094				);
17095	},
17096
17097	_draw: function() {
17098		this._enhance();
17099
17100		this._addClass( this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content" );
17101		this._addClass( "ui-spinner-input" );
17102
17103		this.element.attr( "role", "spinbutton" );
17104
17105		// Button bindings
17106		this.buttons = this.uiSpinner.children( "a" )
17107			.attr( "tabIndex", -1 )
17108			.attr( "aria-hidden", true )
17109			.button( {
17110				classes: {
17111					"ui-button": ""
17112				}
17113			} );
17114
17115		// TODO: Right now button does not support classes this is already updated in button PR
17116		this._removeClass( this.buttons, "ui-corner-all" );
17117
17118		this._addClass( this.buttons.first(), "ui-spinner-button ui-spinner-up" );
17119		this._addClass( this.buttons.last(), "ui-spinner-button ui-spinner-down" );
17120		this.buttons.first().button( {
17121			"icon": this.options.icons.up,
17122			"showLabel": false
17123		} );
17124		this.buttons.last().button( {
17125			"icon": this.options.icons.down,
17126			"showLabel": false
17127		} );
17128
17129		// IE 6 doesn't understand height: 50% for the buttons
17130		// unless the wrapper has an explicit height
17131		if ( this.buttons.height() > Math.ceil( this.uiSpinner.height() * 0.5 ) &&
17132				this.uiSpinner.height() > 0 ) {
17133			this.uiSpinner.height( this.uiSpinner.height() );
17134		}
17135	},
17136
17137	_keydown: function( event ) {
17138		var options = this.options,
17139			keyCode = $.ui.keyCode;
17140
17141		switch ( event.keyCode ) {
17142		case keyCode.UP:
17143			this._repeat( null, 1, event );
17144			return true;
17145		case keyCode.DOWN:
17146			this._repeat( null, -1, event );
17147			return true;
17148		case keyCode.PAGE_UP:
17149			this._repeat( null, options.page, event );
17150			return true;
17151		case keyCode.PAGE_DOWN:
17152			this._repeat( null, -options.page, event );
17153			return true;
17154		}
17155
17156		return false;
17157	},
17158
17159	_start: function( event ) {
17160		if ( !this.spinning && this._trigger( "start", event ) === false ) {
17161			return false;
17162		}
17163
17164		if ( !this.counter ) {
17165			this.counter = 1;
17166		}
17167		this.spinning = true;
17168		return true;
17169	},
17170
17171	_repeat: function( i, steps, event ) {
17172		i = i || 500;
17173
17174		clearTimeout( this.timer );
17175		this.timer = this._delay( function() {
17176			this._repeat( 40, steps, event );
17177		}, i );
17178
17179		this._spin( steps * this.options.step, event );
17180	},
17181
17182	_spin: function( step, event ) {
17183		var value = this.value() || 0;
17184
17185		if ( !this.counter ) {
17186			this.counter = 1;
17187		}
17188
17189		value = this._adjustValue( value + step * this._increment( this.counter ) );
17190
17191		if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false ) {
17192			this._value( value );
17193			this.counter++;
17194		}
17195	},
17196
17197	_increment: function( i ) {
17198		var incremental = this.options.incremental;
17199
17200		if ( incremental ) {
17201			return typeof incremental === "function" ?
17202				incremental( i ) :
17203				Math.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );
17204		}
17205
17206		return 1;
17207	},
17208
17209	_precision: function() {
17210		var precision = this._precisionOf( this.options.step );
17211		if ( this.options.min !== null ) {
17212			precision = Math.max( precision, this._precisionOf( this.options.min ) );
17213		}
17214		return precision;
17215	},
17216
17217	_precisionOf: function( num ) {
17218		var str = num.toString(),
17219			decimal = str.indexOf( "." );
17220		return decimal === -1 ? 0 : str.length - decimal - 1;
17221	},
17222
17223	_adjustValue: function( value ) {
17224		var base, aboveMin,
17225			options = this.options;
17226
17227		// Make sure we're at a valid step
17228		// - find out where we are relative to the base (min or 0)
17229		base = options.min !== null ? options.min : 0;
17230		aboveMin = value - base;
17231
17232		// - round to the nearest step
17233		aboveMin = Math.round( aboveMin / options.step ) * options.step;
17234
17235		// - rounding is based on 0, so adjust back to our base
17236		value = base + aboveMin;
17237
17238		// Fix precision from bad JS floating point math
17239		value = parseFloat( value.toFixed( this._precision() ) );
17240
17241		// Clamp the value
17242		if ( options.max !== null && value > options.max ) {
17243			return options.max;
17244		}
17245		if ( options.min !== null && value < options.min ) {
17246			return options.min;
17247		}
17248
17249		return value;
17250	},
17251
17252	_stop: function( event ) {
17253		if ( !this.spinning ) {
17254			return;
17255		}
17256
17257		clearTimeout( this.timer );
17258		clearTimeout( this.mousewheelTimer );
17259		this.counter = 0;
17260		this.spinning = false;
17261		this._trigger( "stop", event );
17262	},
17263
17264	_setOption: function( key, value ) {
17265		var prevValue, first, last;
17266
17267		if ( key === "culture" || key === "numberFormat" ) {
17268			prevValue = this._parse( this.element.val() );
17269			this.options[ key ] = value;
17270			this.element.val( this._format( prevValue ) );
17271			return;
17272		}
17273
17274		if ( key === "max" || key === "min" || key === "step" ) {
17275			if ( typeof value === "string" ) {
17276				value = this._parse( value );
17277			}
17278		}
17279		if ( key === "icons" ) {
17280			first = this.buttons.first().find( ".ui-icon" );
17281			this._removeClass( first, null, this.options.icons.up );
17282			this._addClass( first, null, value.up );
17283			last = this.buttons.last().find( ".ui-icon" );
17284			this._removeClass( last, null, this.options.icons.down );
17285			this._addClass( last, null, value.down );
17286		}
17287
17288		this._super( key, value );
17289	},
17290
17291	_setOptionDisabled: function( value ) {
17292		this._super( value );
17293
17294		this._toggleClass( this.uiSpinner, null, "ui-state-disabled", !!value );
17295		this.element.prop( "disabled", !!value );
17296		this.buttons.button( value ? "disable" : "enable" );
17297	},
17298
17299	_setOptions: spinnerModifier( function( options ) {
17300		this._super( options );
17301	} ),
17302
17303	_parse: function( val ) {
17304		if ( typeof val === "string" && val !== "" ) {
17305			val = window.Globalize && this.options.numberFormat ?
17306				Globalize.parseFloat( val, 10, this.options.culture ) : +val;
17307		}
17308		return val === "" || isNaN( val ) ? null : val;
17309	},
17310
17311	_format: function( value ) {
17312		if ( value === "" ) {
17313			return "";
17314		}
17315		return window.Globalize && this.options.numberFormat ?
17316			Globalize.format( value, this.options.numberFormat, this.options.culture ) :
17317			value;
17318	},
17319
17320	_refresh: function() {
17321		this.element.attr( {
17322			"aria-valuemin": this.options.min,
17323			"aria-valuemax": this.options.max,
17324
17325			// TODO: what should we do with values that can't be parsed?
17326			"aria-valuenow": this._parse( this.element.val() )
17327		} );
17328	},
17329
17330	isValid: function() {
17331		var value = this.value();
17332
17333		// Null is invalid
17334		if ( value === null ) {
17335			return false;
17336		}
17337
17338		// If value gets adjusted, it's invalid
17339		return value === this._adjustValue( value );
17340	},
17341
17342	// Update the value without triggering change
17343	_value: function( value, allowAny ) {
17344		var parsed;
17345		if ( value !== "" ) {
17346			parsed = this._parse( value );
17347			if ( parsed !== null ) {
17348				if ( !allowAny ) {
17349					parsed = this._adjustValue( parsed );
17350				}
17351				value = this._format( parsed );
17352			}
17353		}
17354		this.element.val( value );
17355		this._refresh();
17356	},
17357
17358	_destroy: function() {
17359		this.element
17360			.prop( "disabled", false )
17361			.removeAttr( "autocomplete role aria-valuemin aria-valuemax aria-valuenow" );
17362
17363		this.uiSpinner.replaceWith( this.element );
17364	},
17365
17366	stepUp: spinnerModifier( function( steps ) {
17367		this._stepUp( steps );
17368	} ),
17369	_stepUp: function( steps ) {
17370		if ( this._start() ) {
17371			this._spin( ( steps || 1 ) * this.options.step );
17372			this._stop();
17373		}
17374	},
17375
17376	stepDown: spinnerModifier( function( steps ) {
17377		this._stepDown( steps );
17378	} ),
17379	_stepDown: function( steps ) {
17380		if ( this._start() ) {
17381			this._spin( ( steps || 1 ) * -this.options.step );
17382			this._stop();
17383		}
17384	},
17385
17386	pageUp: spinnerModifier( function( pages ) {
17387		this._stepUp( ( pages || 1 ) * this.options.page );
17388	} ),
17389
17390	pageDown: spinnerModifier( function( pages ) {
17391		this._stepDown( ( pages || 1 ) * this.options.page );
17392	} ),
17393
17394	value: function( newVal ) {
17395		if ( !arguments.length ) {
17396			return this._parse( this.element.val() );
17397		}
17398		spinnerModifier( this._value ).call( this, newVal );
17399	},
17400
17401	widget: function() {
17402		return this.uiSpinner;
17403	}
17404} );
17405
17406// DEPRECATED
17407// TODO: switch return back to widget declaration at top of file when this is removed
17408if ( $.uiBackCompat === true ) {
17409
17410	// Backcompat for spinner html extension points
17411	$.widget( "ui.spinner", $.ui.spinner, {
17412		_enhance: function() {
17413			this.uiSpinner = this.element
17414				.attr( "autocomplete", "off" )
17415				.wrap( this._uiSpinnerHtml() )
17416				.parent()
17417
17418					// Add buttons
17419					.append( this._buttonHtml() );
17420		},
17421		_uiSpinnerHtml: function() {
17422			return "<span>";
17423		},
17424
17425		_buttonHtml: function() {
17426			return "<a></a><a></a>";
17427		}
17428	} );
17429}
17430
17431var widgetsSpinner = $.ui.spinner;
17432
17433
17434/*!
17435 * jQuery UI Tabs 1.14.
vendor: 1,533 bytes, lines 17435-17502
174351
17436 * https://jqueryui.com
17437 *
17438 * Copyright OpenJS Foundation and other contributors
17439 * Released under the MIT license.
17440 * https://jquery.org/license
17441 */
17442
17443//>>label: Tabs
17444//>>group: Widgets
17445//>>description: Transforms a set of container elements into a tab structure.
17446//>>docs: https://api.jqueryui.com/tabs/
17447//>>demos: https://jqueryui.com/tabs/
17448//>>css.structure: ../../themes/base/core.css
17449//>>css.structure: ../../themes/base/tabs.css
17450//>>css.theme: ../../themes/base/theme.css
17451
17452
17453$.widget( "ui.tabs", {
17454	version: "1.14.1",
17455	delay: 300,
17456	options: {
17457		active: null,
17458		classes: {
17459			"ui-tabs": "ui-corner-all",
17460			"ui-tabs-nav": "ui-corner-all",
17461			"ui-tabs-panel": "ui-corner-bottom",
17462			"ui-tabs-tab": "ui-corner-top"
17463		},
17464		collapsible: false,
17465		event: "click",
17466		heightStyle: "content",
17467		hide: null,
17468		show: null,
17469
17470		// Callbacks
17471		activate: null,
17472		beforeActivate: null,
17473		beforeLoad: null,
17474		load: null
17475	},
17476
17477	_isLocal: ( function() {
17478		var rhash = /#.*$/;
17479
17480		return function( anchor ) {
17481			var anchorUrl, locationUrl;
17482
17483			anchorUrl = anchor.href.replace( rhash, "" );
17484			locationUrl = location.href.replace( rhash, "" );
17485
17486			// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17487			try {
17488				anchorUrl = decodeURIComponent( anchorUrl );
17489			} catch ( error ) {}
17490			try {
17491				locationUrl = decodeURIComponent( locationUrl );
17492			} catch ( error ) {}
17493
17494			return anchor.hash.length > 1 && anchorUrl === locationUrl;
17495		};
17496	} )(),
17497
17498	_create: function() {
17499		var that = this,
17500			options = this.options;
17501
17502		this.running = false;
vendor: 10,605 bytes, lines 17503-17903
17503
17504		this._addClass( "ui-tabs", "ui-widget ui-widget-content" );
17505		this._toggleClass( "ui-tabs-collapsible", null, options.collapsible );
17506
17507		this._processTabs();
17508		options.active = this._initialActive();
17509
17510		// Take disabling tabs via class attribute from HTML
17511		// into account and update option properly.
17512		if ( Array.isArray( options.disabled ) ) {
17513			options.disabled = $.uniqueSort( options.disabled.concat(
17514				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
17515					return that.tabs.index( li );
17516				} )
17517			) ).sort();
17518		}
17519
17520		// Check for length avoids error when initializing empty list
17521		if ( this.options.active !== false && this.anchors.length ) {
17522			this.active = this._findActive( options.active );
17523		} else {
17524			this.active = $();
17525		}
17526
17527		this._refresh();
17528
17529		if ( this.active.length ) {
17530			this.load( options.active );
17531		}
17532	},
17533
17534	_initialActive: function() {
17535		var active = this.options.active,
17536			collapsible = this.options.collapsible,
17537			locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) );
17538
17539		if ( active === null ) {
17540
17541			// check the fragment identifier in the URL
17542			if ( locationHashDecoded ) {
17543				this.tabs.each( function( i, tab ) {
17544					if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
17545						active = i;
17546						return false;
17547					}
17548				} );
17549			}
17550
17551			// Check for a tab marked active via a class
17552			if ( active === null ) {
17553				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
17554			}
17555
17556			// No active tab, set to false
17557			if ( active === null || active === -1 ) {
17558				active = this.tabs.length ? 0 : false;
17559			}
17560		}
17561
17562		// Handle numbers: negative, out of range
17563		if ( active !== false ) {
17564			active = this.tabs.index( this.tabs.eq( active ) );
17565			if ( active === -1 ) {
17566				active = collapsible ? false : 0;
17567			}
17568		}
17569
17570		// Don't allow collapsible: false and active: false
17571		if ( !collapsible && active === false && this.anchors.length ) {
17572			active = 0;
17573		}
17574
17575		return active;
17576	},
17577
17578	_getCreateEventData: function() {
17579		return {
17580			tab: this.active,
17581			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
17582		};
17583	},
17584
17585	_tabKeydown: function( event ) {
17586		var focusedTab = $( this.document[ 0 ].activeElement ).closest( "li" ),
17587			selectedIndex = this.tabs.index( focusedTab ),
17588			goingForward = true;
17589
17590		if ( this._handlePageNav( event ) ) {
17591			return;
17592		}
17593
17594		switch ( event.keyCode ) {
17595		case $.ui.keyCode.RIGHT:
17596		case $.ui.keyCode.DOWN:
17597			selectedIndex++;
17598			break;
17599		case $.ui.keyCode.UP:
17600		case $.ui.keyCode.LEFT:
17601			goingForward = false;
17602			selectedIndex--;
17603			break;
17604		case $.ui.keyCode.END:
17605			selectedIndex = this.anchors.length - 1;
17606			break;
17607		case $.ui.keyCode.HOME:
17608			selectedIndex = 0;
17609			break;
17610		case $.ui.keyCode.SPACE:
17611
17612			// Activate only, no collapsing
17613			event.preventDefault();
17614			clearTimeout( this.activating );
17615			this._activate( selectedIndex );
17616			return;
17617		case $.ui.keyCode.ENTER:
17618
17619			// Toggle (cancel delayed activation, allow collapsing)
17620			event.preventDefault();
17621			clearTimeout( this.activating );
17622
17623			// Determine if we should collapse or activate
17624			this._activate( selectedIndex === this.options.active ? false : selectedIndex );
17625			return;
17626		default:
17627			return;
17628		}
17629
17630		// Focus the appropriate tab, based on which key was pressed
17631		event.preventDefault();
17632		clearTimeout( this.activating );
17633		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
17634
17635		// Navigating with control/command key will prevent automatic activation
17636		if ( !event.ctrlKey && !event.metaKey ) {
17637
17638			// Update aria-selected immediately so that AT think the tab is already selected.
17639			// Otherwise AT may confuse the user by stating that they need to activate the tab,
17640			// but the tab will already be activated by the time the announcement finishes.
17641			focusedTab.attr( "aria-selected", "false" );
17642			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
17643
17644			this.activating = this._delay( function() {
17645				this.option( "active", selectedIndex );
17646			}, this.delay );
17647		}
17648	},
17649
17650	_panelKeydown: function( event ) {
17651		if ( this._handlePageNav( event ) ) {
17652			return;
17653		}
17654
17655		// Ctrl+up moves focus to the current tab
17656		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
17657			event.preventDefault();
17658			this.active.trigger( "focus" );
17659		}
17660	},
17661
17662	// Alt+page up/down moves focus to the previous/next tab (and activates)
17663	_handlePageNav: function( event ) {
17664		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
17665			this._activate( this._focusNextTab( this.options.active - 1, false ) );
17666			return true;
17667		}
17668		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
17669			this._activate( this._focusNextTab( this.options.active + 1, true ) );
17670			return true;
17671		}
17672	},
17673
17674	_findNextTab: function( index, goingForward ) {
17675		var lastTabIndex = this.tabs.length - 1;
17676
17677		function constrain() {
17678			if ( index > lastTabIndex ) {
17679				index = 0;
17680			}
17681			if ( index < 0 ) {
17682				index = lastTabIndex;
17683			}
17684			return index;
17685		}
17686
17687		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
17688			index = goingForward ? index + 1 : index - 1;
17689		}
17690
17691		return index;
17692	},
17693
17694	_focusNextTab: function( index, goingForward ) {
17695		index = this._findNextTab( index, goingForward );
17696		this.tabs.eq( index ).trigger( "focus" );
17697		return index;
17698	},
17699
17700	_setOption: function( key, value ) {
17701		if ( key === "active" ) {
17702
17703			// _activate() will handle invalid values and update this.options
17704			this._activate( value );
17705			return;
17706		}
17707
17708		this._super( key, value );
17709
17710		if ( key === "collapsible" ) {
17711			this._toggleClass( "ui-tabs-collapsible", null, value );
17712
17713			// Setting collapsible: false while collapsed; open first panel
17714			if ( !value && this.options.active === false ) {
17715				this._activate( 0 );
17716			}
17717		}
17718
17719		if ( key === "event" ) {
17720			this._setupEvents( value );
17721		}
17722
17723		if ( key === "heightStyle" ) {
17724			this._setupHeightStyle( value );
17725		}
17726	},
17727
17728	refresh: function() {
17729		var options = this.options,
17730			lis = this.tablist.children( ":has(a[href])" );
17731
17732		// Get disabled tabs from class attribute from HTML
17733		// this will get converted to a boolean if needed in _refresh()
17734		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
17735			return lis.index( tab );
17736		} );
17737
17738		this._processTabs();
17739
17740		// Was collapsed or no tabs
17741		if ( options.active === false || !this.anchors.length ) {
17742			options.active = false;
17743			this.active = $();
17744
17745		// was active, but active tab is gone
17746		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
17747
17748			// all remaining tabs are disabled
17749			if ( this.tabs.length === options.disabled.length ) {
17750				options.active = false;
17751				this.active = $();
17752
17753			// activate previous tab
17754			} else {
17755				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
17756			}
17757
17758		// was active, active tab still exists
17759		} else {
17760
17761			// make sure active index is correct
17762			options.active = this.tabs.index( this.active );
17763		}
17764
17765		this._refresh();
17766	},
17767
17768	_refresh: function() {
17769		this._setOptionDisabled( this.options.disabled );
17770		this._setupEvents( this.options.event );
17771		this._setupHeightStyle( this.options.heightStyle );
17772
17773		this.tabs.not( this.active ).attr( {
17774			"aria-selected": "false",
17775			"aria-expanded": "false",
17776			tabIndex: -1
17777		} );
17778		this.panels.not( this._getPanelForTab( this.active ) )
17779			.hide()
17780			.attr( {
17781				"aria-hidden": "true"
17782			} );
17783
17784		// Make sure one tab is in the tab order
17785		if ( !this.active.length ) {
17786			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
17787		} else {
17788			this.active
17789				.attr( {
17790					"aria-selected": "true",
17791					"aria-expanded": "true",
17792					tabIndex: 0
17793				} );
17794			this._addClass( this.active, "ui-tabs-active", "ui-state-active" );
17795			this._getPanelForTab( this.active )
17796				.show()
17797				.attr( {
17798					"aria-hidden": "false"
17799				} );
17800		}
17801	},
17802
17803	_processTabs: function() {
17804		var that = this,
17805			prevTabs = this.tabs,
17806			prevAnchors = this.anchors,
17807			prevPanels = this.panels;
17808
17809		this.tablist = this._getList().attr( "role", "tablist" );
17810		this._addClass( this.tablist, "ui-tabs-nav",
17811			"ui-helper-reset ui-helper-clearfix ui-widget-header" );
17812
17813		// Prevent users from focusing disabled tabs via click
17814		this.tablist
17815			.on( "mousedown" + this.eventNamespace, "> li", function( event ) {
17816				if ( $( this ).is( ".ui-state-disabled" ) ) {
17817					event.preventDefault();
17818				}
17819			} );
17820
17821		this.tabs = this.tablist.find( "> li:has(a[href])" )
17822			.attr( {
17823				role: "tab",
17824				tabIndex: -1
17825			} );
17826		this._addClass( this.tabs, "ui-tabs-tab", "ui-state-default" );
17827
17828		this.anchors = this.tabs.map( function() {
17829			return $( "a", this )[ 0 ];
17830		} )
17831			.attr( {
17832				tabIndex: -1
17833			} );
17834		this._addClass( this.anchors, "ui-tabs-anchor" );
17835
17836		this.panels = $();
17837
17838		this.anchors.each( function( i, anchor ) {
17839			var selector, panel, panelId,
17840				anchorId = $( anchor ).uniqueId().attr( "id" ),
17841				tab = $( anchor ).closest( "li" ),
17842				originalAriaControls = tab.attr( "aria-controls" );
17843
17844			// Inline tab
17845			if ( that._isLocal( anchor ) ) {
17846				selector = decodeURIComponent( anchor.hash );
17847				panelId = selector.substring( 1 );
17848				panel = that.element.find( "#" + CSS.escape( panelId ) );
17849
17850			// remote tab
17851			} else {
17852
17853				// If the tab doesn't already have aria-controls,
17854				// generate an id by using a throw-away element
17855				panelId = tab.attr( "aria-controls" ) || $( {} ).uniqueId()[ 0 ].id;
17856				selector = "#" + panelId;
17857				panel = that.element.find( selector );
17858				if ( !panel.length ) {
17859					panel = that._createPanel( panelId );
17860					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
17861				}
17862				panel.attr( "aria-live", "polite" );
17863			}
17864
17865			if ( panel.length ) {
17866				that.panels = that.panels.add( panel );
17867			}
17868			if ( originalAriaControls ) {
17869				tab.data( "ui-tabs-aria-controls", originalAriaControls );
17870			}
17871			tab.attr( {
17872				"aria-controls": panelId,
17873				"aria-labelledby": anchorId
17874			} );
17875			panel.attr( "aria-labelledby", anchorId );
17876		} );
17877
17878		this.panels.attr( "role", "tabpanel" );
17879		this._addClass( this.panels, "ui-tabs-panel", "ui-widget-content" );
17880
17881		// Avoid memory leaks (#10056)
17882		if ( prevTabs ) {
17883			this._off( prevTabs.not( this.tabs ) );
17884			this._off( prevAnchors.not( this.anchors ) );
17885			this._off( prevPanels.not( this.panels ) );
17886		}
17887	},
17888
17889	// Allow overriding how to find the list for rare usage scenarios (#7715)
17890	_getList: function() {
17891		return this.tablist || this.element.find( "ol, ul" ).eq( 0 );
17892	},
17893
17894	_createPanel: function( id ) {
17895		return $( "<div>" )
17896			.attr( "id", id )
17897			.data( "ui-tabs-destroy", true );
17898	},
17899
17900	_setOptionDisabled: function( disabled ) {
17901		var currentItem, li, i;
17902
17903		if ( Array
vendor: 6,222 bytes, lines 17903-18134
17903.isArray( disabled ) ) {
17904			if ( !disabled.length ) {
17905				disabled = false;
17906			} else if ( disabled.length === this.anchors.length ) {
17907				disabled = true;
17908			}
17909		}
17910
17911		// Disable tabs
17912		for ( i = 0; ( li = this.tabs[ i ] ); i++ ) {
17913			currentItem = $( li );
17914			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
17915				currentItem.attr( "aria-disabled", "true" );
17916				this._addClass( currentItem, null, "ui-state-disabled" );
17917			} else {
17918				currentItem.removeAttr( "aria-disabled" );
17919				this._removeClass( currentItem, null, "ui-state-disabled" );
17920			}
17921		}
17922
17923		this.options.disabled = disabled;
17924
17925		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null,
17926			disabled === true );
17927	},
17928
17929	_setupEvents: function( event ) {
17930		var events = {};
17931		if ( event ) {
17932			$.each( event.split( " " ), function( index, eventName ) {
17933				events[ eventName ] = "_eventHandler";
17934			} );
17935		}
17936
17937		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
17938
17939		// Always prevent the default action, even when disabled
17940		this._on( true, this.anchors, {
17941			click: function( event ) {
17942				event.preventDefault();
17943			}
17944		} );
17945		this._on( this.anchors, events );
17946		this._on( this.tabs, { keydown: "_tabKeydown" } );
17947		this._on( this.panels, { keydown: "_panelKeydown" } );
17948
17949		this._focusable( this.tabs );
17950		this._hoverable( this.tabs );
17951	},
17952
17953	_setupHeightStyle: function( heightStyle ) {
17954		var maxHeight,
17955			parent = this.element.parent();
17956
17957		if ( heightStyle === "fill" ) {
17958			maxHeight = parent.height();
17959			maxHeight -= this.element.outerHeight() - this.element.height();
17960
17961			this.element.siblings( ":visible" ).each( function() {
17962				var elem = $( this ),
17963					position = elem.css( "position" );
17964
17965				if ( position === "absolute" || position === "fixed" ) {
17966					return;
17967				}
17968				maxHeight -= elem.outerHeight( true );
17969			} );
17970
17971			this.element.children().not( this.panels ).each( function() {
17972				maxHeight -= $( this ).outerHeight( true );
17973			} );
17974
17975			this.panels.each( function() {
17976				$( this ).height( Math.max( 0, maxHeight -
17977					$( this ).innerHeight() + $( this ).height() ) );
17978			} )
17979				.css( "overflow", "auto" );
17980		} else if ( heightStyle === "auto" ) {
17981			maxHeight = 0;
17982			this.panels.each( function() {
17983				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
17984			} ).height( maxHeight );
17985		}
17986	},
17987
17988	_eventHandler: function( event ) {
17989		var options = this.options,
17990			active = this.active,
17991			anchor = $( event.currentTarget ),
17992			tab = anchor.closest( "li" ),
17993			clickedIsActive = tab[ 0 ] === active[ 0 ],
17994			collapsing = clickedIsActive && options.collapsible,
17995			toShow = collapsing ? $() : this._getPanelForTab( tab ),
17996			toHide = !active.length ? $() : this._getPanelForTab( active ),
17997			eventData = {
17998				oldTab: active,
17999				oldPanel: toHide,
18000				newTab: collapsing ? $() : tab,
18001				newPanel: toShow
18002			};
18003
18004		event.preventDefault();
18005
18006		if ( tab.hasClass( "ui-state-disabled" ) ||
18007
18008				// tab is already loading
18009				tab.hasClass( "ui-tabs-loading" ) ||
18010
18011				// can't switch durning an animation
18012				this.running ||
18013
18014				// click on active header, but not collapsible
18015				( clickedIsActive && !options.collapsible ) ||
18016
18017				// allow canceling activation
18018				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
18019			return;
18020		}
18021
18022		options.active = collapsing ? false : this.tabs.index( tab );
18023
18024		this.active = clickedIsActive ? $() : tab;
18025		if ( this.xhr ) {
18026			this.xhr.abort();
18027		}
18028
18029		if ( !toHide.length && !toShow.length ) {
18030			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
18031		}
18032
18033		if ( toShow.length ) {
18034			this.load( this.tabs.index( tab ), event );
18035		}
18036		this._toggle( event, eventData );
18037	},
18038
18039	// Handles show/hide for selecting tabs
18040	_toggle: function( event, eventData ) {
18041		var that = this,
18042			toShow = eventData.newPanel,
18043			toHide = eventData.oldPanel;
18044
18045		this.running = true;
18046
18047		function complete() {
18048			that.running = false;
18049			that._trigger( "activate", event, eventData );
18050		}
18051
18052		function show() {
18053			that._addClass( eventData.newTab.closest( "li" ), "ui-tabs-active", "ui-state-active" );
18054
18055			if ( toShow.length && that.options.show ) {
18056				that._show( toShow, that.options.show, complete );
18057			} else {
18058				toShow.show();
18059				complete();
18060			}
18061		}
18062
18063		// Start out by hiding, then showing, then completing
18064		if ( toHide.length && this.options.hide ) {
18065			this._hide( toHide, this.options.hide, function() {
18066				that._removeClass( eventData.oldTab.closest( "li" ),
18067					"ui-tabs-active", "ui-state-active" );
18068				show();
18069			} );
18070		} else {
18071			this._removeClass( eventData.oldTab.closest( "li" ),
18072				"ui-tabs-active", "ui-state-active" );
18073			toHide.hide();
18074			show();
18075		}
18076
18077		toHide.attr( "aria-hidden", "true" );
18078		eventData.oldTab.attr( {
18079			"aria-selected": "false",
18080			"aria-expanded": "false"
18081		} );
18082
18083		// If we're switching tabs, remove the old tab from the tab order.
18084		// If we're opening from collapsed state, remove the previous tab from the tab order.
18085		// If we're collapsing, then keep the collapsing tab in the tab order.
18086		if ( toShow.length && toHide.length ) {
18087			eventData.oldTab.attr( "tabIndex", -1 );
18088		} else if ( toShow.length ) {
18089			this.tabs.filter( function() {
18090				return $( this ).attr( "tabIndex" ) === 0;
18091			} )
18092				.attr( "tabIndex", -1 );
18093		}
18094
18095		toShow.attr( "aria-hidden", "false" );
18096		eventData.newTab.attr( {
18097			"aria-selected": "true",
18098			"aria-expanded": "true",
18099			tabIndex: 0
18100		} );
18101	},
18102
18103	_activate: function( index ) {
18104		var anchor,
18105			active = this._findActive( index );
18106
18107		// Trying to activate the already active panel
18108		if ( active[ 0 ] === this.active[ 0 ] ) {
18109			return;
18110		}
18111
18112		// Trying to collapse, simulate a click on the current active header
18113		if ( !active.length ) {
18114			active = this.active;
18115		}
18116
18117		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
18118		this._eventHandler( {
18119			target: anchor,
18120			currentTarget: anchor,
18121			preventDefault: $.noop
18122		} );
18123	},
18124
18125	_findActive: function( index ) {
18126		return index === false ? $() : this.tabs.eq( index );
18127	},
18128
18129	_getIndex: function( index ) {
18130
18131		// meta-function to give users option to provide a href string instead of a numerical index.
18132		if ( typeof index === "string" ) {
18133			index = this.anchors.index( this.anchors.filter( "[href$='" +
18134				
vendor: 17,747 bytes, lines 18134-18809
18134CSS.escape( index ) + "']" ) );
18135		}
18136
18137		return index;
18138	},
18139
18140	_destroy: function() {
18141		if ( this.xhr ) {
18142			this.xhr.abort();
18143		}
18144
18145		this.tablist
18146			.removeAttr( "role" )
18147			.off( this.eventNamespace );
18148
18149		this.anchors
18150			.removeAttr( "role tabIndex" )
18151			.removeUniqueId();
18152
18153		this.tabs.add( this.panels ).each( function() {
18154			if ( $.data( this, "ui-tabs-destroy" ) ) {
18155				$( this ).remove();
18156			} else {
18157				$( this ).removeAttr( "role tabIndex " +
18158					"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded" );
18159			}
18160		} );
18161
18162		this.tabs.each( function() {
18163			var li = $( this ),
18164				prev = li.data( "ui-tabs-aria-controls" );
18165			if ( prev ) {
18166				li
18167					.attr( "aria-controls", prev )
18168					.removeData( "ui-tabs-aria-controls" );
18169			} else {
18170				li.removeAttr( "aria-controls" );
18171			}
18172		} );
18173
18174		this.panels.show();
18175
18176		if ( this.options.heightStyle !== "content" ) {
18177			this.panels.css( "height", "" );
18178		}
18179	},
18180
18181	enable: function( index ) {
18182		var disabled = this.options.disabled;
18183		if ( disabled === false ) {
18184			return;
18185		}
18186
18187		if ( index === undefined ) {
18188			disabled = false;
18189		} else {
18190			index = this._getIndex( index );
18191			if ( Array.isArray( disabled ) ) {
18192				disabled = $.map( disabled, function( num ) {
18193					return num !== index ? num : null;
18194				} );
18195			} else {
18196				disabled = $.map( this.tabs, function( li, num ) {
18197					return num !== index ? num : null;
18198				} );
18199			}
18200		}
18201		this._setOptionDisabled( disabled );
18202	},
18203
18204	disable: function( index ) {
18205		var disabled = this.options.disabled;
18206		if ( disabled === true ) {
18207			return;
18208		}
18209
18210		if ( index === undefined ) {
18211			disabled = true;
18212		} else {
18213			index = this._getIndex( index );
18214			if ( $.inArray( index, disabled ) !== -1 ) {
18215				return;
18216			}
18217			if ( Array.isArray( disabled ) ) {
18218				disabled = $.merge( [ index ], disabled ).sort();
18219			} else {
18220				disabled = [ index ];
18221			}
18222		}
18223		this._setOptionDisabled( disabled );
18224	},
18225
18226	load: function( index, event ) {
18227		index = this._getIndex( index );
18228		var that = this,
18229			tab = this.tabs.eq( index ),
18230			anchor = tab.find( ".ui-tabs-anchor" ),
18231			panel = this._getPanelForTab( tab ),
18232			eventData = {
18233				tab: tab,
18234				panel: panel
18235			},
18236			complete = function( jqXHR, status ) {
18237				if ( status === "abort" ) {
18238					that.panels.stop( false, true );
18239				}
18240
18241				that._removeClass( tab, "ui-tabs-loading" );
18242				panel.removeAttr( "aria-busy" );
18243
18244				if ( jqXHR === that.xhr ) {
18245					delete that.xhr;
18246				}
18247			};
18248
18249		// Not remote
18250		if ( this._isLocal( anchor[ 0 ] ) ) {
18251			return;
18252		}
18253
18254		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
18255
18256		if ( this.xhr.statusText !== "canceled" ) {
18257			this._addClass( tab, "ui-tabs-loading" );
18258			panel.attr( "aria-busy", "true" );
18259
18260			this.xhr
18261				.done( function( response, status, jqXHR ) {
18262					panel.html( response );
18263					that._trigger( "load", event, eventData );
18264
18265					complete( jqXHR, status );
18266				} )
18267				.fail( function( jqXHR, status ) {
18268					complete( jqXHR, status );
18269				} );
18270		}
18271	},
18272
18273	_ajaxSettings: function( anchor, event, eventData ) {
18274		var that = this;
18275		return {
18276			url: anchor.attr( "href" ),
18277			beforeSend: function( jqXHR, settings ) {
18278				return that._trigger( "beforeLoad", event,
18279					$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );
18280			}
18281		};
18282	},
18283
18284	_getPanelForTab: function( tab ) {
18285		var id = $( tab ).attr( "aria-controls" );
18286		return this.element.find( "#" + CSS.escape( id ) );
18287	}
18288} );
18289
18290// DEPRECATED
18291// TODO: Switch return back to widget declaration at top of file when this is removed
18292if ( $.uiBackCompat === true ) {
18293
18294	// Backcompat for ui-tab class (now ui-tabs-tab)
18295	$.widget( "ui.tabs", $.ui.tabs, {
18296		_processTabs: function() {
18297			this._superApply( arguments );
18298			this._addClass( this.tabs, "ui-tab" );
18299		}
18300	} );
18301}
18302
18303var widgetsTabs = $.ui.tabs;
18304
18305
18306/*!
18307 * jQuery UI Tooltip 1.14.1
18308 * https://jqueryui.com
18309 *
18310 * Copyright OpenJS Foundation and other contributors
18311 * Released under the MIT license.
18312 * https://jquery.org/license
18313 */
18314
18315//>>label: Tooltip
18316//>>group: Widgets
18317//>>description: Shows additional information for any element on hover or focus.
18318//>>docs: https://api.jqueryui.com/tooltip/
18319//>>demos: https://jqueryui.com/tooltip/
18320//>>css.structure: ../../themes/base/core.css
18321//>>css.structure: ../../themes/base/tooltip.css
18322//>>css.theme: ../../themes/base/theme.css
18323
18324
18325$.widget( "ui.tooltip", {
18326	version: "1.14.1",
18327	options: {
18328		classes: {
18329			"ui-tooltip": "ui-corner-all ui-widget-shadow"
18330		},
18331		content: function() {
18332			var title = $( this ).attr( "title" );
18333
18334			// Escape title, since we're going from an attribute to raw HTML
18335			return $( "<a>" ).text( title ).html();
18336		},
18337		hide: true,
18338
18339		// Disabled elements have inconsistent behavior across browsers (#8661)
18340		items: "[title]:not([disabled])",
18341		position: {
18342			my: "left top+15",
18343			at: "left bottom",
18344			collision: "flipfit flip"
18345		},
18346		show: true,
18347		track: false,
18348
18349		// Callbacks
18350		close: null,
18351		open: null
18352	},
18353
18354	_addDescribedBy: function( elem, id ) {
18355		var describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ );
18356		describedby.push( id );
18357		elem
18358			.data( "ui-tooltip-id", id )
18359			.attr( "aria-describedby", String.prototype.trim.call( describedby.join( " " ) ) );
18360	},
18361
18362	_removeDescribedBy: function( elem ) {
18363		var id = elem.data( "ui-tooltip-id" ),
18364			describedby = ( elem.attr( "aria-describedby" ) || "" ).split( /\s+/ ),
18365			index = $.inArray( id, describedby );
18366
18367		if ( index !== -1 ) {
18368			describedby.splice( index, 1 );
18369		}
18370
18371		elem.removeData( "ui-tooltip-id" );
18372		describedby = String.prototype.trim.call( describedby.join( " " ) );
18373		if ( describedby ) {
18374			elem.attr( "aria-describedby", describedby );
18375		} else {
18376			elem.removeAttr( "aria-describedby" );
18377		}
18378	},
18379
18380	_create: function() {
18381		this._on( {
18382			mouseover: "open",
18383			focusin: "open"
18384		} );
18385
18386		// IDs of generated tooltips, needed for destroy
18387		this.tooltips = {};
18388
18389		// IDs of parent tooltips where we removed the title attribute
18390		this.parents = {};
18391
18392		// Append the aria-live region so tooltips announce correctly
18393		this.liveRegion = $( "<div>" )
18394			.attr( {
18395				role: "log",
18396				"aria-live": "assertive",
18397				"aria-relevant": "additions"
18398			} )
18399			.appendTo( this.document[ 0 ].body );
18400		this._addClass( this.liveRegion, null, "ui-helper-hidden-accessible" );
18401
18402		this.disabledTitles = $( [] );
18403	},
18404
18405	_setOption: function( key, value ) {
18406		var that = this;
18407
18408		this._super( key, value );
18409
18410		if ( key === "content" ) {
18411			$.each( this.tooltips, function( id, tooltipData ) {
18412				that._updateContent( tooltipData.element );
18413			} );
18414		}
18415	},
18416
18417	_setOptionDisabled: function( value ) {
18418		this[ value ? "_disable" : "_enable" ]();
18419	},
18420
18421	_disable: function() {
18422		var that = this;
18423
18424		// Close open tooltips
18425		$.each( this.tooltips, function( id, tooltipData ) {
18426			var event = $.Event( "blur" );
18427			event.target = event.currentTarget = tooltipData.element[ 0 ];
18428			that.close( event, true );
18429		} );
18430
18431		// Remove title attributes to prevent native tooltips
18432		this.disabledTitles = this.disabledTitles.add(
18433			this.element.find( this.options.items ).addBack()
18434				.filter( function() {
18435					var element = $( this );
18436					if ( element.is( "[title]" ) ) {
18437						return element
18438							.data( "ui-tooltip-title", element.attr( "title" ) )
18439							.removeAttr( "title" );
18440					}
18441				} )
18442		);
18443	},
18444
18445	_enable: function() {
18446
18447		// restore title attributes
18448		this.disabledTitles.each( function() {
18449			var element = $( this );
18450			if ( element.data( "ui-tooltip-title" ) ) {
18451				element.attr( "title", element.data( "ui-tooltip-title" ) );
18452			}
18453		} );
18454		this.disabledTitles = $( [] );
18455	},
18456
18457	open: function( event ) {
18458		var that = this,
18459			target = $( event ? event.target : this.element )
18460
18461				// we need closest here due to mouseover bubbling,
18462				// but always pointing at the same event target
18463				.closest( this.options.items );
18464
18465		// No element to show a tooltip for or the tooltip is already open
18466		if ( !target.length || target.data( "ui-tooltip-id" ) ) {
18467			return;
18468		}
18469
18470		if ( target.attr( "title" ) ) {
18471			target.data( "ui-tooltip-title", target.attr( "title" ) );
18472		}
18473
18474		target.data( "ui-tooltip-open", true );
18475
18476		// Kill parent tooltips, custom or native, for hover
18477		if ( event && event.type === "mouseover" ) {
18478			target.parents().each( function() {
18479				var parent = $( this ),
18480					blurEvent;
18481				if ( parent.data( "ui-tooltip-open" ) ) {
18482					blurEvent = $.Event( "blur" );
18483					blurEvent.target = blurEvent.currentTarget = this;
18484					that.close( blurEvent, true );
18485				}
18486				if ( parent.attr( "title" ) ) {
18487					parent.uniqueId();
18488					that.parents[ this.id ] = {
18489						element: this,
18490						title: parent.attr( "title" )
18491					};
18492					parent.attr( "title", "" );
18493				}
18494			} );
18495		}
18496
18497		this._registerCloseHandlers( event, target );
18498		this._updateContent( target, event );
18499	},
18500
18501	_updateContent: function( target, event ) {
18502		var content,
18503			contentOption = this.options.content,
18504			that = this,
18505			eventType = event ? event.type : null;
18506
18507		if ( typeof contentOption === "string" || contentOption.nodeType ||
18508				contentOption.jquery ) {
18509			return this._open( event, target, contentOption );
18510		}
18511
18512		content = contentOption.call( target[ 0 ], function( response ) {
18513
18514			// Ignore async response if tooltip was closed already
18515			if ( !target.data( "ui-tooltip-open" ) ) {
18516				return;
18517			}
18518
18519			// JQuery creates a special event for focusin when it doesn't
18520			// exist natively. To improve performance, the native event
18521			// object is reused and the type is changed. Therefore, we can't
18522			// rely on the type being correct after the event finished
18523			// bubbling, so we set it back to the previous value. (#8740)
18524			if ( event ) {
18525				event.type = eventType;
18526			}
18527			that._open( event, target, response );
18528		} );
18529		if ( content ) {
18530			this._open( event, target, content );
18531		}
18532	},
18533
18534	_open: function( event, target, content ) {
18535		var tooltipData, tooltip, delayedShow, a11yContent,
18536			positionOption = $.extend( {}, this.options.position );
18537
18538		if ( !content ) {
18539			return;
18540		}
18541
18542		// Content can be updated multiple times. If the tooltip already
18543		// exists, then just update the content and bail.
18544		tooltipData = this._find( target );
18545		if ( tooltipData ) {
18546			tooltipData.tooltip.find( ".ui-tooltip-content" ).html( content );
18547			return;
18548		}
18549
18550		// If we have a title, clear it to prevent the native tooltip
18551		// we have to check first to avoid defining a title if none exists
18552		// (we don't want to cause an element to start matching [title])
18553		//
18554		// We use removeAttr only for key events, to allow IE to export the correct
18555		// accessible attributes. For mouse events, set to empty string to avoid
18556		// native tooltip showing up (happens only when removing inside mouseover).
18557		if ( target.is( "[title]" ) ) {
18558			if ( event && event.type === "mouseover" ) {
18559				target.attr( "title", "" );
18560			} else {
18561				target.removeAttr( "title" );
18562			}
18563		}
18564
18565		tooltipData = this._tooltip( target );
18566		tooltip = tooltipData.tooltip;
18567		this._addDescribedBy( target, tooltip.attr( "id" ) );
18568		tooltip.find( ".ui-tooltip-content" ).html( content );
18569
18570		// Support: Voiceover on OS X, JAWS on IE <= 9
18571		// JAWS announces deletions even when aria-relevant="additions"
18572		// Voiceover will sometimes re-read the entire log region's contents from the beginning
18573		this.liveRegion.children().hide();
18574		a11yContent = $( "<div>" ).html( tooltip.find( ".ui-tooltip-content" ).html() );
18575		a11yContent.removeAttr( "name" ).find( "[name]" ).removeAttr( "name" );
18576		a11yContent.removeAttr( "id" ).find( "[id]" ).removeAttr( "id" );
18577		a11yContent.appendTo( this.liveRegion );
18578
18579		function position( event ) {
18580			positionOption.of = event;
18581			if ( tooltip.is( ":hidden" ) ) {
18582				return;
18583			}
18584			tooltip.position( positionOption );
18585		}
18586		if ( this.options.track && event && /^mouse/.test( event.type ) ) {
18587			this._on( this.document, {
18588				mousemove: position
18589			} );
18590
18591			// trigger once to override element-relative positioning
18592			position( event );
18593		} else {
18594			tooltip.position( $.extend( {
18595				of: target
18596			}, this.options.position ) );
18597		}
18598
18599		tooltip.hide();
18600
18601		this._show( tooltip, this.options.show );
18602
18603		// Handle tracking tooltips that are shown with a delay (#8644). As soon
18604		// as the tooltip is visible, position the tooltip using the most recent
18605		// event.
18606		// Adds the check to add the timers only when both delay and track options are set (#14682)
18607		if ( this.options.track && this.options.show && this.options.show.delay ) {
18608			delayedShow = this.delayedShow = setInterval( function() {
18609				if ( tooltip.is( ":visible" ) ) {
18610					position( positionOption.of );
18611					clearInterval( delayedShow );
18612				}
18613			}, 13 );
18614		}
18615
18616		this._trigger( "open", event, { tooltip: tooltip } );
18617	},
18618
18619	_registerCloseHandlers: function( event, target ) {
18620		var events = {
18621			keyup: function( event ) {
18622				if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
18623					var fakeEvent = $.Event( event );
18624					fakeEvent.currentTarget = target[ 0 ];
18625					this.close( fakeEvent, true );
18626				}
18627			}
18628		};
18629
18630		// Only bind remove handler for delegated targets. Non-delegated
18631		// tooltips will handle this in destroy.
18632		if ( target[ 0 ] !== this.element[ 0 ] ) {
18633			events.remove = function() {
18634				var targetElement = this._find( target );
18635				if ( targetElement ) {
18636					this._removeTooltip( targetElement.tooltip );
18637				}
18638			};
18639		}
18640
18641		if ( !event || event.type === "mouseover" ) {
18642			events.mouseleave = "close";
18643		}
18644		if ( !event || event.type === "focusin" ) {
18645			events.focusout = "close";
18646		}
18647		this._on( true, target, events );
18648	},
18649
18650	close: function( event ) {
18651		var tooltip,
18652			that = this,
18653			target = $( event ? event.currentTarget : this.element ),
18654			tooltipData = this._find( target );
18655
18656		// The tooltip may already be closed
18657		if ( !tooltipData ) {
18658
18659			// We set ui-tooltip-open immediately upon open (in open()), but only set the
18660			// additional data once there's actually content to show (in _open()). So even if the
18661			// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18662			// the period between open() and _open().
18663			target.removeData( "ui-tooltip-open" );
18664			return;
18665		}
18666
18667		tooltip = tooltipData.tooltip;
18668
18669		// Disabling closes the tooltip, so we need to track when we're closing
18670		// to avoid an infinite loop in case the tooltip becomes disabled on close
18671		if ( tooltipData.closing ) {
18672			return;
18673		}
18674
18675		// Clear the interval for delayed tracking tooltips
18676		clearInterval( this.delayedShow );
18677
18678		// Only set title if we had one before (see comment in _open())
18679		// If the title attribute has changed since open(), don't restore
18680		if ( target.data( "ui-tooltip-title" ) && !target.attr( "title" ) ) {
18681			target.attr( "title", target.data( "ui-tooltip-title" ) );
18682		}
18683
18684		this._removeDescribedBy( target );
18685
18686		tooltipData.hiding = true;
18687		tooltip.stop( true );
18688		this._hide( tooltip, this.options.hide, function() {
18689			that._removeTooltip( $( this ) );
18690		} );
18691
18692		target.removeData( "ui-tooltip-open" );
18693		this._off( target, "mouseleave focusout keyup" );
18694
18695		// Remove 'remove' binding only on delegated targets
18696		if ( target[ 0 ] !== this.element[ 0 ] ) {
18697			this._off( target, "remove" );
18698		}
18699		this._off( this.document, "mousemove" );
18700
18701		if ( event && event.type === "mouseleave" ) {
18702			$.each( this.parents, function( id, parent ) {
18703				$( parent.element ).attr( "title", parent.title );
18704				delete that.parents[ id ];
18705			} );
18706		}
18707
18708		tooltipData.closing = true;
18709		this._trigger( "close", event, { tooltip: tooltip } );
18710		if ( !tooltipData.hiding ) {
18711			tooltipData.closing = false;
18712		}
18713	},
18714
18715	_tooltip: function( element ) {
18716		var tooltip = $( "<div>" ).attr( "role", "tooltip" ),
18717			content = $( "<div>" ).appendTo( tooltip ),
18718			id = tooltip.uniqueId().attr( "id" );
18719
18720		this._addClass( content, "ui-tooltip-content" );
18721		this._addClass( tooltip, "ui-tooltip", "ui-widget ui-widget-content" );
18722
18723		tooltip.appendTo( this._appendTo( element ) );
18724
18725		return this.tooltips[ id ] = {
18726			element: element,
18727			tooltip: tooltip
18728		};
18729	},
18730
18731	_find: function( target ) {
18732		var id = target.data( "ui-tooltip-id" );
18733		return id ? this.tooltips[ id ] : null;
18734	},
18735
18736	_removeTooltip: function( tooltip ) {
18737
18738		// Clear the interval for delayed tracking tooltips
18739		clearInterval( this.delayedShow );
18740
18741		tooltip.remove();
18742		delete this.tooltips[ tooltip.attr( "id" ) ];
18743	},
18744
18745	_appendTo: function( target ) {
18746		var element = target.closest( ".ui-front, dialog" );
18747
18748		if ( !element.length ) {
18749			element = this.document[ 0 ].body;
18750		}
18751
18752		return element;
18753	},
18754
18755	_destroy: function() {
18756		var that = this;
18757
18758		// Close open tooltips
18759		$.each( this.tooltips, function( id, tooltipData ) {
18760
18761			// Delegate to close method to handle common cleanup
18762			var event = $.Event( "blur" ),
18763				element = tooltipData.element;
18764			event.target = event.currentTarget = element[ 0 ];
18765			that.close( event, true );
18766
18767			// Remove immediately; destroying an open tooltip doesn't use the
18768			// hide animation
18769			$( "#" + id ).remove();
18770
18771			// Restore the title
18772			if ( element.data( "ui-tooltip-title" ) ) {
18773
18774				// If the title attribute has changed since open(), don't restore
18775				if ( !element.attr( "title" ) ) {
18776					element.attr( "title", element.data( "ui-tooltip-title" ) );
18777				}
18778				element.removeData( "ui-tooltip-title" );
18779			}
18780		} );
18781		this.liveRegion.remove();
18782	}
18783} );
18784
18785// DEPRECATED
18786// TODO: Switch return back to widget declaration at top of file when this is removed
18787if ( $.uiBackCompat === true ) {
18788
18789	// Backcompat for tooltipClass option
18790	$.widget( "ui.tooltip", $.ui.tooltip, {
18791		options: {
18792			tooltipClass: null
18793		},
18794		_tooltip: function() {
18795			var tooltipData = this._superApply( arguments );
18796			if ( this.options.tooltipClass ) {
18797				tooltipData.tooltip.addClass( this.options.tooltipClass );
18798			}
18799			return tooltipData;
18800		}
18801	} );
18802}
18803
18804var widgetsTooltip = $.ui.tooltip;
18805
18806
18807
18808
18809} );

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.