PageSourceSearch

https://www.ultomirispregnancystudy.com/Assets/Registries/Website/Common/Scripts/jquery-ui.js

js ultomirispregnancystudy.com collected 2026-10-04 02:28:43 UTC 541,494 bytes, 18,815 lines download raw bytes

vendor: 200,193 bytes, lines 1-7198
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
23	var version = $.ui.version = "1.14.1";
24
25
26	/*!
27	 * jQuery UI Widget 1.14.1
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
42	var widgetUuid = 0;
43	var widgetHasOwnProperty = Array.prototype.hasOwnProperty;
44	var 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
768	var widget = $.widget;
769
770
771	/*!
772	 * jQuery UI Position 1.14.1
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 () {
790		var 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
800		function 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
807		function parseCss(element, property) {
808			return parseInt($.css(element, property), 10) || 0;
809		}
810
811		function isWindow(obj) {
812			return obj != null && obj === obj.window;
813		}
814
815		function 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),
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
1265	var position = $.ui.position;
1266
1267
1268	/*!
1269	 * jQuery UI :data 1.14.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
1283	var 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
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
1307	var 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
1331	var 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
1479	each(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
1489	jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
1490		function (_i, name) {
1491			class2type["[object " + name + "]"] = name.toLowerCase();
1492		});
1493
1494	function 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
1504	function 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
1525	function 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
1565	color.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	});
1781	color.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
1786	function 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
1800	spaces.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
1837	spaces.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
1857	each(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
1940	color.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
1968	color.hook(stepHooks);
1969
1970	jQuery.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.
1984	colors = 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.1
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 */
2025	//>>docs: https://api.jqueryui.com/category/effects-core/
2026	//>>demos: https://jqueryui.com/effect/
2027
2028
2029	var 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
2042		var 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
2067		function camelCase(string) {
2068			return string.replace(/-([\da-z])/gi, function (all, letter) {
2069				return letter.toUpperCase();
2070			});
2071		}
2072
2073		function 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
2089		function 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
2238		if ($.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
2246		if ($.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 (e) {
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",
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:
2574		function _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
2626		function 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
2853		function 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
2894		var 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
2939	var effect = $.effects;
2940
2941
2942	/*!
2943	 * jQuery UI Effects Blind 1.14.1
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
2958	var 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
3013	var 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
3108	var 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
3158	var 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
3214	var 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
3308	var 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
3340	var 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
3414	var 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
3456	var 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
3634	var 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
3674	var 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
3700	var 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
3749	var 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
3808	var 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
3869	var effect;
3870	if ($.uiBackCompat === true) {
3871		effect = $.effects.define("transfer", function (options, done) {
3872			$(this).transfer(options, done);
3873		});
3874	}
3875	var 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
3938	var 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
3956	var 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
4021	if (!$.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.
4029	if (!$.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
4060	var 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
4095	var 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
4149	var 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
4183	var 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
4207	var 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
4251	var widgetsAccordion = $.widget("ui.accordion", {
4252		version: "1.14.1",
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.1
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
4851	var widgetsMenu = $.widget("ui.menu", {
4852		version: "1.14.1",
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;
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
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.1
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",
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
6139	var widgetsAutocomplete = $.ui.autocomplete;
6140
6141
6142	/*!
6143	 * jQuery UI Controlgroup 1.14.1
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
6161	var controlgroupCornerRegex = /ui-corner-([a-z]){2,6}/g;
6162
6163	var widgetsControlgroup = $.widget("ui.controlgroup", {
6164		version: "1.14.1",
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.1
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
6695	var 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",
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
6963	if ($.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
7120	var widgetsButton = $.ui.button;
7121
7122
7123	/* eslint-disable max-len, 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" } });
7144
7145	var datepicker_instActive;
7146
7147	function 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
7177	function 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
vendor: 295,800 bytes, lines 7252-17279
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 {
7317				id: id, input: target, // associated target
7318				selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7319				drawMonth: 0, drawYear: 0, // month being drawn
7320				inline: inline, // is datepicker inline or not
7321				dpDiv: (!inline ? this.dpDiv : // presentation div
7322					datepicker_bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))
7323			};
7324		},
7325
7326		/* Attach the date picker to an input field. */
7327		_connectDatepicker: function (target, inst) {
7328			var input = $(target);
7329			inst.append = $([]);
7330			inst.trigger = $([]);
7331			if (input.hasClass(this.markerClassName)) {
7332				return;
7333			}
7334			this._attachments(input, inst);
7335			input.addClass(this.markerClassName).on("keydown", this._doKeyDown).
7336				on("keypress", this._doKeyPress).on("keyup", this._doKeyUp);
7337			this._autoSize(inst);
7338			$.data(target, "datepicker", inst);
7339
7340			//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7341			if (inst.settings.disabled) {
7342				this._disableDatepicker(target);
7343			}
7344		},
7345
7346		/* Make attachments based on settings. */
7347		_attachments: function (input, inst) {
7348			var showOn, buttonText, buttonImage,
7349				appendText = this._get(inst, "appendText"),
7350				isRTL = this._get(inst, "isRTL");
7351
7352			if (inst.append) {
7353				inst.append.remove();
7354			}
7355			if (appendText) {
7356				inst.append = $("<span>")
7357					.addClass(this._appendClass)
7358					.text(appendText);
7359				input[isRTL ? "before" : "after"](inst.append);
7360			}
7361
7362			input.off("focus", this._showDatepicker);
7363
7364			if (inst.trigger) {
7365				inst.trigger.remove();
7366			}
7367
7368			showOn = this._get(inst, "showOn");
7369			if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7370				input.on("focus", this._showDatepicker);
7371			}
7372			if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7373				buttonText = this._get(inst, "buttonText");
7374				buttonImage = this._get(inst, "buttonImage");
7375
7376				if (this._get(inst, "buttonImageOnly")) {
7377					inst.trigger = $("<img>")
7378						.addClass(this._triggerClass)
7379						.attr({
7380							src: buttonImage,
7381							alt: buttonText,
7382							title: buttonText
7383						});
7384				} else {
7385					inst.trigger = $("<button type='button'>")
7386						.addClass(this._triggerClass);
7387					if (buttonImage) {
7388						inst.trigger.html(
7389							$("<img>")
7390								.attr({
7391									src: buttonImage,
7392									alt: buttonText,
7393									title: buttonText
7394								})
7395						);
7396					} else {
7397						inst.trigger.text(buttonText);
7398					}
7399				}
7400
7401				input[isRTL ? "before" : "after"](inst.trigger);
7402				inst.trigger.on("click", function () {
7403					if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7404						$.datepicker._hideDatepicker();
7405					} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7406						$.datepicker._hideDatepicker();
7407						$.datepicker._showDatepicker(input[0]);
7408					} else {
7409						$.datepicker._showDatepicker(input[0]);
7410					}
7411					return false;
7412				});
7413			}
7414		},
7415
7416		/* Apply the maximum length for the date format. */
7417		_autoSize: function (inst) {
7418			if (this._get(inst, "autoSize") && !inst.inline) {
7419				var findMax, max, maxI, i,
7420					date = new Date(2009, 12 - 1, 20), // Ensure double digits
7421					dateFormat = this._get(inst, "dateFormat");
7422
7423				if (dateFormat.match(/[DM]/)) {
7424					findMax = function (names) {
7425						max = 0;
7426						maxI = 0;
7427						for (i = 0; i < names.length; i++) {
7428							if (names[i].length > max) {
7429								max = names[i].length;
7430								maxI = i;
7431							}
7432						}
7433						return maxI;
7434					};
7435					date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7436						"monthNames" : "monthNamesShort"))));
7437					date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7438						"dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7439				}
7440				inst.input.attr("size", this._formatDate(inst, date).length);
7441			}
7442		},
7443
7444		/* Attach an inline date picker to a div. */
7445		_inlineDatepicker: function (target, inst) {
7446			var divSpan = $(target);
7447			if (divSpan.hasClass(this.markerClassName)) {
7448				return;
7449			}
7450			divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7451			$.data(target, "datepicker", inst);
7452			this._setDate(inst, this._getDefaultDate(inst), true);
7453			this._updateDatepicker(inst);
7454			this._updateAlternate(inst);
7455
7456			//If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7457			if (inst.settings.disabled) {
7458				this._disableDatepicker(target);
7459			}
7460
7461			// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7462			// https://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7463			inst.dpDiv.css("display", "block");
7464		},
7465
7466		/* Pop-up the date picker in a "dialog" box.
7467		 * @param  input element - ignored
7468		 * @param  date	string or Date - the initial date to display
7469		 * @param  onSelect  function - the function to call when a date is selected
7470		 * @param  settings  object - update the dialog date picker instance's settings (anonymous object)
7471		 * @param  pos int[2] - coordinates for the dialog's position within the screen or
7472		 *					event - with x/y coordinates or
7473		 *					leave empty for default (screen centre)
7474		 * @return the manager object
7475		 */
7476		_dialogDatepicker: function (input, date, onSelect, settings, pos) {
7477			var id, browserWidth, browserHeight, scrollX, scrollY,
7478				inst = this._dialogInst; // internal instance
7479
7480			if (!inst) {
7481				this.uuid += 1;
7482				id = "dp" + this.uuid;
7483				this._dialogInput = $("<input type='text' id='" + id +
7484					"' style='position: absolute; top: -100px; width: 0px;'/>");
7485				this._dialogInput.on("keydown", this._doKeyDown);
7486				$("body").append(this._dialogInput);
7487				inst = this._dialogInst = this._newInst(this._dialogInput, false);
7488				inst.settings = {};
7489				$.data(this._dialogInput[0], "datepicker", inst);
7490			}
7491			datepicker_extendRemove(inst.settings, settings || {});
7492			date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7493			this._dialogInput.val(date);
7494
7495			this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7496			if (!this._pos) {
7497				browserWidth = document.documentElement.clientWidth;
7498				browserHeight = document.documentElement.clientHeight;
7499				scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7500				scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7501				this._pos = // should use actual width/height below
7502					[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7503			}
7504
7505			// Move input on screen for focus, but hidden behind dialog
7506			this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7507			inst.settings.onSelect = onSelect;
7508			this._inDialog = true;
7509			this.dpDiv.addClass(this._dialogClass);
7510			this._showDatepicker(this._dialogInput[0]);
7511			if ($.blockUI) {
7512				$.blockUI(this.dpDiv);
7513			}
7514			$.data(this._dialogInput[0], "datepicker", inst);
7515			return this;
7516		},
7517
7518		/* Detach a datepicker from its control.
7519		 * @param  target	element - the target input field or division or span
7520		 */
7521		_destroyDatepicker: function (target) {
7522			var nodeName,
7523				$target = $(target),
7524				inst = $.data(target, "datepicker");
7525
7526			if (!$target.hasClass(this.markerClassName)) {
7527				return;
7528			}
7529
7530			nodeName = target.nodeName.toLowerCase();
7531			$.removeData(target, "datepicker");
7532			if (nodeName === "input") {
7533				inst.append.remove();
7534				inst.trigger.remove();
7535				$target.removeClass(this.markerClassName).
7536					off("focus", this._showDatepicker).
7537					off("keydown", this._doKeyDown).
7538					off("keypress", this._doKeyPress).
7539					off("keyup", this._doKeyUp);
7540			} else if (nodeName === "div" || nodeName === "span") {
7541				$target.removeClass(this.markerClassName).empty();
7542			}
7543
7544			$.datepicker._hideDatepicker();
7545			if (datepicker_instActive === inst) {
7546				datepicker_instActive = null;
7547				this._curInst = null;
7548			}
7549		},
7550
7551		/* Enable the date picker to a jQuery selection.
7552		 * @param  target	element - the target input field or division or span
7553		 */
7554		_enableDatepicker: function (target) {
7555			var nodeName, inline,
7556				$target = $(target),
7557				inst = $.data(target, "datepicker");
7558
7559			if (!$target.hasClass(this.markerClassName)) {
7560				return;
7561			}
7562
7563			nodeName = target.nodeName.toLowerCase();
7564			if (nodeName === "input") {
7565				target.disabled = false;
7566				inst.trigger.filter("button").
7567					each(function () {
7568						this.disabled = false;
7569					}).end().
7570					filter("img").css({ opacity: "1.0", cursor: "" });
7571			} else if (nodeName === "div" || nodeName === "span") {
7572				inline = $target.children("." + this._inlineClass);
7573				inline.children().removeClass("ui-state-disabled");
7574				inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7575					prop("disabled", false);
7576			}
7577			this._disabledInputs = $.map(this._disabledInputs,
7578
7579				// Delete entry
7580				function (value) {
7581					return (value === target ? null : value);
7582				});
7583		},
7584
7585		/* Disable the date picker to a jQuery selection.
7586		 * @param  target	element - the target input field or division or span
7587		 */
7588		_disableDatepicker: function (target) {
7589			var nodeName, inline,
7590				$target = $(target),
7591				inst = $.data(target, "datepicker");
7592
7593			if (!$target.hasClass(this.markerClassName)) {
7594				return;
7595			}
7596
7597			nodeName = target.nodeName.toLowerCase();
7598			if (nodeName === "input") {
7599				target.disabled = true;
7600				inst.trigger.filter("button").
7601					each(function () {
7602						this.disabled = true;
7603					}).end().
7604					filter("img").css({ opacity: "0.5", cursor: "default" });
7605			} else if (nodeName === "div" || nodeName === "span") {
7606				inline = $target.children("." + this._inlineClass);
7607				inline.children().addClass("ui-state-disabled");
7608				inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7609					prop("disabled", true);
7610			}
7611			this._disabledInputs = $.map(this._disabledInputs,
7612
7613				// Delete entry
7614				function (value) {
7615					return (value === target ? null : value);
7616				});
7617			this._disabledInputs[this._disabledInputs.length] = target;
7618		},
7619
7620		/* Is the first field in a jQuery collection disabled as a datepicker?
7621		 * @param  target	element - the target input field or division or span
7622		 * @return boolean - true if disabled, false if enabled
7623		 */
7624		_isDisabledDatepicker: function (target) {
7625			if (!target) {
7626				return false;
7627			}
7628			for (var i = 0; i < this._disabledInputs.length; i++) {
7629				if (this._disabledInputs[i] === target) {
7630					return true;
7631				}
7632			}
7633			return false;
7634		},
7635
7636		/* Retrieve the instance data for the target control.
7637		 * @param  target  element - the target input field or division or span
7638		 * @return  object - the associated instance data
7639		 * @throws  error if a jQuery problem getting data
7640		 */
7641		_getInst: function (target) {
7642			try {
7643				return $.data(target, "datepicker");
7644			} catch (err) {
7645				throw "Missing instance data for this datepicker";
7646			}
7647		},
7648
7649		/* Update or retrieve the settings for a date picker attached to an input field or division.
7650		 * @param  target  element - the target input field or division or span
7651		 * @param  name	object - the new settings to update or
7652		 *				string - the name of the setting to change or retrieve,
7653		 *				when retrieving also "all" for all instance settings or
7654		 *				"defaults" for all global defaults
7655		 * @param  value   any - the new value for the setting
7656		 *				(omit if above is an object or to retrieve a value)
7657		 */
7658		_optionDatepicker: function (target, name, value) {
7659			var settings, date, minDate, maxDate,
7660				inst = this._getInst(target);
7661
7662			if (arguments.length === 2 && typeof name === "string") {
7663				return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
7664					(inst ? (name === "all" ? $.extend({}, inst.settings) :
7665						this._get(inst, name)) : null));
7666			}
7667
7668			settings = name || {};
7669			if (typeof name === "string") {
7670				settings = {};
7671				settings[name] = value;
7672			}
7673
7674			if (inst) {
7675				if (this._curInst === inst) {
7676					this._hideDatepicker();
7677				}
7678
7679				date = this._getDateDatepicker(target, true);
7680				minDate = this._getMinMaxDate(inst, "min");
7681				maxDate = this._getMinMaxDate(inst, "max");
7682				datepicker_extendRemove(inst.settings, settings);
7683
7684				// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
7685				if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
7686					inst.settings.minDate = this._formatDate(inst, minDate);
7687				}
7688				if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
7689					inst.settings.maxDate = this._formatDate(inst, maxDate);
7690				}
7691				if ("disabled" in settings) {
7692					if (settings.disabled) {
7693						this._disableDatepicker(target);
7694					} else {
7695						this._enableDatepicker(target);
7696					}
7697				}
7698				this._attachments($(target), inst);
7699				this._autoSize(inst);
7700				this._setDate(inst, date);
7701				this._updateAlternate(inst);
7702				this._updateDatepicker(inst);
7703			}
7704		},
7705
7706		// Change method deprecated
7707		_changeDatepicker: function (target, name, value) {
7708			this._optionDatepicker(target, name, value);
7709		},
7710
7711		/* Redraw the date picker attached to an input field or division.
7712		 * @param  target  element - the target input field or division or span
7713		 */
7714		_refreshDatepicker: function (target) {
7715			var inst = this._getInst(target);
7716			if (inst) {
7717				this._updateDatepicker(inst);
7718			}
7719		},
7720
7721		/* Set the dates for a jQuery selection.
7722		 * @param  target element - the target input field or division or span
7723		 * @param  date	Date - the new date
7724		 */
7725		_setDateDatepicker: function (target, date) {
7726			var inst = this._getInst(target);
7727			if (inst) {
7728				this._setDate(inst, date);
7729				this._updateDatepicker(inst);
7730				this._updateAlternate(inst);
7731			}
7732		},
7733
7734		/* Get the date(s) for the first entry in a jQuery selection.
7735		 * @param  target element - the target input field or division or span
7736		 * @param  noDefault boolean - true if no default date is to be used
7737		 * @return Date - the current date
7738		 */
7739		_getDateDatepicker: function (target, noDefault) {
7740			var inst = this._getInst(target);
7741			if (inst && !inst.inline) {
7742				this._setDateFromField(inst, noDefault);
7743			}
7744			return (inst ? this._getDate(inst) : null);
7745		},
7746
7747		/* Handle keystrokes. */
7748		_doKeyDown: function (event) {
7749			var onSelect, dateStr, sel,
7750				inst = $.datepicker._getInst(event.target),
7751				handled = true,
7752				isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
7753
7754			inst._keyEvent = true;
7755			if ($.datepicker._datepickerShowing) {
7756				switch (event.keyCode) {
7757					case 9: $.datepicker._hideDatepicker();
7758						handled = false;
7759						break; // hide on tab out
7760					case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
7761						$.datepicker._currentClass + ")", inst.dpDiv);
7762						if (sel[0]) {
7763							$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
7764						}
7765
7766						onSelect = $.datepicker._get(inst, "onSelect");
7767						if (onSelect) {
7768							dateStr = $.datepicker._formatDate(inst);
7769
7770							// Trigger custom callback
7771							onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
7772						} else {
7773							$.datepicker._hideDatepicker();
7774						}
7775
7776						return false; // don't submit the form
7777					case 27: $.datepicker._hideDatepicker();
7778						break; // hide on escape
7779					case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7780						-$.datepicker._get(inst, "stepBigMonths") :
7781						-$.datepicker._get(inst, "stepMonths")), "M");
7782						break; // previous month/year on page up/+ ctrl
7783					case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
7784						+$.datepicker._get(inst, "stepBigMonths") :
7785						+$.datepicker._get(inst, "stepMonths")), "M");
7786						break; // next month/year on page down/+ ctrl
7787					case 35: if (event.ctrlKey || event.metaKey) {
7788						$.datepicker._clearDate(event.target);
7789					}
7790						handled = event.ctrlKey || event.metaKey;
7791						break; // clear on ctrl or command +end
7792					case 36: if (event.ctrlKey || event.metaKey) {
7793						$.datepicker._gotoToday(event.target);
7794					}
7795						handled = event.ctrlKey || event.metaKey;
7796						break; // current on ctrl or command +home
7797					case 37: if (event.ctrlKey || event.metaKey) {
7798						$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
7799					}
7800						handled = event.ctrlKey || event.metaKey;
7801
7802						// -1 day on ctrl or command +left
7803						if (event.originalEvent.altKey) {
7804							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
7805								-$.datepicker._get(inst, "stepBigMonths") :
7806								-$.datepicker._get(inst, "stepMonths")), "M");
7807						}
7808
7809						// next month/year on alt +left on Mac
7810						break;
7811					case 38: if (event.ctrlKey || event.metaKey) {
7812						$.datepicker._adjustDate(event.target, -7, "D");
7813					}
7814						handled = event.ctrlKey || event.metaKey;
7815						break; // -1 week on ctrl or command +up
7816					case 39: if (event.ctrlKey || event.metaKey) {
7817						$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
7818					}
7819						handled = event.ctrlKey || event.metaKey;
7820
7821						// +1 day on ctrl or command +right
7822						if (event.originalEvent.altKey) {
7823							$.datepicker._adjustDate(event.target, (event.ctrlKey ?
7824								+$.datepicker._get(inst, "stepBigMonths") :
7825								+$.datepicker._get(inst, "stepMonths")), "M");
7826						}
7827
7828						// next month/year on alt +right
7829						break;
7830					case 40: if (event.ctrlKey || event.metaKey) {
7831						$.datepicker._adjustDate(event.target, +7, "D");
7832					}
7833						handled = event.ctrlKey || event.metaKey;
7834						break; // +1 week on ctrl or command +down
7835					default: handled = false;
7836				}
7837			} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
7838				$.datepicker._showDatepicker(this);
7839			} else {
7840				handled = false;
7841			}
7842
7843			if (handled) {
7844				event.preventDefault();
7845				event.stopPropagation();
7846			}
7847		},
7848
7849		/* Filter entered characters - based on date format. */
7850		_doKeyPress: function (event) {
7851			var chars, chr,
7852				inst = $.datepicker._getInst(event.target);
7853
7854			if ($.datepicker._get(inst, "constrainInput")) {
7855				chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
7856				chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
7857				return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
7858			}
7859		},
7860
7861		/* Synchronise manual entry and field/alternate field. */
7862		_doKeyUp: function (event) {
7863			var date,
7864				inst = $.datepicker._getInst(event.target);
7865
7866			if (inst.input.val() !== inst.lastVal) {
7867				try {
7868					date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
7869						(inst.input ? inst.input.val() : null),
7870						$.datepicker._getFormatConfig(inst));
7871
7872					if (date) { // only if valid
7873						$.datepicker._setDateFromField(inst);
7874						$.datepicker._updateAlternate(inst);
7875						$.datepicker._updateDatepicker(inst);
7876					}
7877				} catch (err) {
7878				}
7879			}
7880			return true;
7881		},
7882
7883		/* Pop-up the date picker for a given input field.
7884		 * If false returned from beforeShow event handler do not show.
7885		 * @param  input  element - the input field attached to the date picker or
7886		 *					event - if triggered by focus
7887		 */
7888		_showDatepicker: function (input) {
7889			input = input.target || input;
7890			if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
7891				input = $("input", input.parentNode)[0];
7892			}
7893
7894			if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
7895				return;
7896			}
7897
7898			var inst, beforeShow, beforeShowSettings, isFixed,
7899				offset, showAnim, duration;
7900
7901			inst = $.datepicker._getInst(input);
7902			if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
7903				$.datepicker._curInst.dpDiv.stop(true, true);
7904				if (inst && $.datepicker._datepickerShowing) {
7905					$.datepicker._hideDatepicker($.datepicker._curInst.input[0]);
7906				}
7907			}
7908
7909			beforeShow = $.datepicker._get(inst, "beforeShow");
7910			beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
7911			if (beforeShowSettings === false) {
7912				return;
7913			}
7914			datepicker_extendRemove(inst.settings, beforeShowSettings);
7915
7916			inst.lastVal = null;
7917			$.datepicker._lastInput = input;
7918			$.datepicker._setDateFromField(inst);
7919
7920			if ($.datepicker._inDialog) { // hide cursor
7921				input.value = "";
7922			}
7923			if (!$.datepicker._pos) { // position below input
7924				$.datepicker._pos = $.datepicker._findPos(input);
7925				$.datepicker._pos[1] += input.offsetHeight; // add the height
7926			}
7927
7928			isFixed = false;
7929			$(input).parents().each(function () {
7930				isFixed |= $(this).css("position") === "fixed";
7931				return !isFixed;
7932			});
7933
7934			offset = { left: $.datepicker._pos[0], top: $.datepicker._pos[1] };
7935			$.datepicker._pos = null;
7936
7937			//to avoid flashes on Firefox
7938			inst.dpDiv.empty();
7939
7940			// determine sizing offscreen
7941			inst.dpDiv.css({ position: "absolute", display: "block", top: "-1000px" });
7942			$.datepicker._updateDatepicker(inst);
7943
7944			// fix width for dynamic number of date pickers
7945			// and adjust position before showing
7946			offset = $.datepicker._checkOffset(inst, offset, isFixed);
7947			inst.dpDiv.css({
7948				position: ($.datepicker._inDialog && $.blockUI ?
7949					"static" : (isFixed ? "fixed" : "absolute")), display: "none",
7950				left: offset.left + "px", top: offset.top + "px"
7951			});
7952
7953			if (!inst.inline) {
7954				showAnim = $.datepicker._get(inst, "showAnim");
7955				duration = $.datepicker._get(inst, "duration");
7956				inst.dpDiv.css("z-index", datepicker_getZindex($(input)) + 1);
7957				$.datepicker._datepickerShowing = true;
7958
7959				if ($.effects && $.effects.effect[showAnim]) {
7960					inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
7961				} else {
7962					inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
7963				}
7964
7965				if ($.datepicker._shouldFocusInput(inst)) {
7966					inst.input.trigger("focus");
7967				}
7968
7969				$.datepicker._curInst = inst;
7970			}
7971		},
7972
7973		/* Generate the date picker content. */
7974		_updateDatepicker: function (inst) {
7975			this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
7976			datepicker_instActive = inst; // for delegate hover events
7977			inst.dpDiv.empty().append(this._generateHTML(inst));
7978			this._attachHandlers(inst);
7979
7980			var origyearshtml,
7981				numMonths = this._getNumberOfMonths(inst),
7982				cols = numMonths[1],
7983				width = 17,
7984				activeCell = inst.dpDiv.find("." + this._dayOverClass + " a"),
7985				onUpdateDatepicker = $.datepicker._get(inst, "onUpdateDatepicker");
7986
7987			if (activeCell.length > 0) {
7988				datepicker_handleMouseover.apply(activeCell.get(0));
7989			}
7990
7991			inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
7992			if (cols > 1) {
7993				inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
7994			}
7995			inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
7996				"Class"]("ui-datepicker-multi");
7997			inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
7998				"Class"]("ui-datepicker-rtl");
7999
8000			if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput(inst)) {
8001				inst.input.trigger("focus");
8002			}
8003
8004			// Deffered render of the years select (to avoid flashes on Firefox)
8005			if (inst.yearshtml) {
8006				origyearshtml = inst.yearshtml;
8007				setTimeout(function () {
8008
8009					//assure that inst.yearshtml didn't change.
8010					if (origyearshtml === inst.yearshtml && inst.yearshtml) {
8011						inst.dpDiv.find("select.ui-datepicker-year").first().replaceWith(inst.yearshtml);
8012					}
8013					origyearshtml = inst.yearshtml = null;
8014				}, 0);
8015			}
8016
8017			if (onUpdateDatepicker) {
8018				onUpdateDatepicker.apply((inst.input ? inst.input[0] : null), [inst]);
8019			}
8020		},
8021
8022		_shouldFocusInput: function (inst) {
8023			return inst.input && inst.input.is(":visible") && !inst.input.is(":disabled");
8024		},
8025
8026		/* Check positioning to remain on screen. */
8027		_checkOffset: function (inst, offset, isFixed) {
8028			var dpWidth = inst.dpDiv.outerWidth(),
8029				dpHeight = inst.dpDiv.outerHeight(),
8030				inputWidth = inst.input ? inst.input.outerWidth() : 0,
8031				inputHeight = inst.input ? inst.input.outerHeight() : 0,
8032				viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8033				viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8034
8035			offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8036			offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8037			offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8038
8039			// Now check if datepicker is showing outside window viewport - move to a better place if so.
8040			offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8041				Math.abs(offset.left + dpWidth - viewWidth) : 0);
8042			offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8043				Math.abs(dpHeight + inputHeight) : 0);
8044
8045			return offset;
8046		},
8047
8048		/* Find an object's position on the screen. */
8049		_findPos: function (obj) {
8050			var position,
8051				inst = this._getInst(obj),
8052				isRTL = this._get(inst, "isRTL");
8053
8054			while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.pseudos.hidden(obj))) {
8055				obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8056			}
8057
8058			position = $(obj).offset();
8059			return [position.left, position.top];
8060		},
8061
8062		/* Hide the date picker from view.
8063		 * @param  input  element - the input field attached to the date picker
8064		 */
8065		_hideDatepicker: function (input) {
8066			var showAnim, duration, postProcess, onClose,
8067				inst = this._curInst;
8068
8069			if (!inst || (input && inst !== $.data(input, "datepicker"))) {
8070				return;
8071			}
8072
8073			if (this._datepickerShowing) {
8074				showAnim = this._get(inst, "showAnim");
8075				duration = this._get(inst, "duration");
8076				postProcess = function () {
8077					$.datepicker._tidyDialog(inst);
8078				};
8079
8080				if ($.effects && ($.effects.effect[showAnim])) {
8081					inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8082				} else {
8083					inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8084						(showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8085				}
8086
8087				if (!showAnim) {
8088					postProcess();
8089				}
8090				this._datepickerShowing = false;
8091
8092				onClose = this._get(inst, "onClose");
8093				if (onClose) {
8094					onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8095				}
8096
8097				this._lastInput = null;
8098				if (this._inDialog) {
8099					this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8100					if ($.blockUI) {
8101						$.unblockUI();
8102						$("body").append(this.dpDiv);
8103					}
8104				}
8105				this._inDialog = false;
8106			}
8107		},
8108
8109		/* Tidy up after a dialog display. */
8110		_tidyDialog: function (inst) {
8111			inst.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar");
8112		},
8113
8114		/* Close date picker if clicked elsewhere. */
8115		_checkExternalClick: function (event) {
8116			if (!$.datepicker._curInst) {
8117				return;
8118			}
8119
8120			var $target = $(event.target),
8121				inst = $.datepicker._getInst($target[0]);
8122
8123			if ((($target[0].id !== $.datepicker._mainDivId &&
8124				$target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8125				!$target.hasClass($.datepicker.markerClassName) &&
8126				!$target.closest("." + $.datepicker._triggerClass).length &&
8127				$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI))) ||
8128				($target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst)) {
8129				$.datepicker._hideDatepicker();
8130			}
8131		},
8132
8133		/* Adjust one of the date sub-fields. */
8134		_adjustDate: function (id, offset, period) {
8135			var target = $(id),
8136				inst = this._getInst(target[0]);
8137
8138			if (this._isDisabledDatepicker(target[0])) {
8139				return;
8140			}
8141			this._adjustInstDate(inst, offset, period);
8142			this._updateDatepicker(inst);
8143		},
8144
8145		/* Action for current link. */
8146		_gotoToday: function (id) {
8147			var date,
8148				target = $(id),
8149				inst = this._getInst(target[0]);
8150
8151			if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8152				inst.selectedDay = inst.currentDay;
8153				inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8154				inst.drawYear = inst.selectedYear = inst.currentYear;
8155			} else {
8156				date = new Date();
8157				inst.selectedDay = date.getDate();
8158				inst.drawMonth = inst.selectedMonth = date.getMonth();
8159				inst.drawYear = inst.selectedYear = date.getFullYear();
8160			}
8161			this._notifyChange(inst);
8162			this._adjustDate(target);
8163		},
8164
8165		/* Action for selecting a new month/year. */
8166		_selectMonthYear: function (id, select, period) {
8167			var target = $(id),
8168				inst = this._getInst(target[0]);
8169
8170			inst["selected" + (period === "M" ? "Month" : "Year")] =
8171				inst["draw" + (period === "M" ? "Month" : "Year")] =
8172				parseInt(select.options[select.selectedIndex].value, 10);
8173
8174			this._notifyChange(inst);
8175			this._adjustDate(target);
8176		},
8177
8178		/* Action for selecting a day. */
8179		_selectDay: function (id, month, year, td) {
8180			var inst,
8181				target = $(id);
8182
8183			if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8184				return;
8185			}
8186
8187			inst = this._getInst(target[0]);
8188			inst.selectedDay = inst.currentDay = parseInt($("a", td).attr("data-date"));
8189			inst.selectedMonth = inst.currentMonth = month;
8190			inst.selectedYear = inst.currentYear = year;
8191			this._selectDate(id, this._formatDate(inst,
8192				inst.currentDay, inst.currentMonth, inst.currentYear));
8193		},
8194
8195		/* Erase the input field and hide the date picker. */
8196		_clearDate: function (id) {
8197			var target = $(id);
8198			this._selectDate(target, "");
8199		},
8200
8201		/* Update the input field with the selected date. */
8202		_selectDate: function (id, dateStr) {
8203			var onSelect,
8204				target = $(id),
8205				inst = this._getInst(target[0]);
8206
8207			dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8208			if (inst.input) {
8209				inst.input.val(dateStr);
8210			}
8211			this._updateAlternate(inst);
8212
8213			onSelect = this._get(inst, "onSelect");
8214			if (onSelect) {
8215				onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
8216			} else if (inst.input) {
8217				inst.input.trigger("change"); // fire the change event
8218			}
8219
8220			if (inst.inline) {
8221				this._updateDatepicker(inst);
8222			} else {
8223				this._hideDatepicker();
8224				this._lastInput = inst.input[0];
8225				if (typeof (inst.input[0]) !== "object") {
8226					inst.input.trigger("focus"); // restore focus
8227				}
8228				this._lastInput = null;
8229			}
8230		},
8231
8232		/* Update any alternate field to synchronise with the main field. */
8233		_updateAlternate: function (inst) {
8234			var altFormat, date, dateStr,
8235				altField = this._get(inst, "altField");
8236
8237			if (altField) { // update alternate field too
8238				altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8239				date = this._getDate(inst);
8240				dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8241				$(document).find(altField).val(dateStr);
8242			}
8243		},
8244
8245		/* Set as beforeShowDay function to prevent selection of weekends.
8246		 * @param  date  Date - the date to customise
8247		 * @return [boolean, string] - is this date selectable?, what is its CSS class?
8248		 */
8249		noWeekends: function (date) {
8250			var day = date.getDay();
8251			return [(day > 0 && day < 6), ""];
8252		},
8253
8254		/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8255		 * @param  date  Date - the date to get the week for
8256		 * @return  number - the number of the week within the year that contains this date
8257		 */
8258		iso8601Week: function (date) {
8259			var time,
8260				checkDate = new Date(date.getTime());
8261
8262			// Find Thursday of this week starting on Monday
8263			checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8264
8265			time = checkDate.getTime();
8266			checkDate.setMonth(0); // Compare with Jan 1
8267			checkDate.setDate(1);
8268			return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8269		},
8270
8271		/* Parse a string value into a date object.
8272		 * See formatDate below for the possible formats.
8273		 *
8274		 * @param  format string - the expected format of the date
8275		 * @param  value string - the date in the above format
8276		 * @param  settings Object - attributes include:
8277		 *					shortYearCutoff  number - the cutoff year for determining the century (optional)
8278		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8279		 *					dayNames		string[7] - names of the days from Sunday (optional)
8280		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8281		 *					monthNames		string[12] - names of the months (optional)
8282		 * @return  Date - the extracted date value or null if value is blank
8283		 */
8284		parseDate: function (format, value, settings) {
8285			if (format == null || value == null) {
8286				throw "Invalid arguments";
8287			}
8288
8289			value = (typeof value === "object" ? value.toString() : value + "");
8290			if (value === "") {
8291				return null;
8292			}
8293
8294			var iFormat, dim, extra,
8295				iValue = 0,
8296				shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8297				shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8298					new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8299				dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8300				dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8301				monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8302				monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8303				year = -1,
8304				month = -1,
8305				day = -1,
8306				doy = -1,
8307				literal = false,
8308				date,
8309
8310				// Check whether a format character is doubled
8311				lookAhead = function (match) {
8312					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8313					if (matches) {
8314						iFormat++;
8315					}
8316					return matches;
8317				},
8318
8319				// Extract a number from the string value
8320				getNumber = function (match) {
8321					var isDoubled = lookAhead(match),
8322						size = (match === "@" ? 14 : (match === "!" ? 20 :
8323							(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8324						minSize = (match === "y" ? size : 1),
8325						digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
8326						num = value.substring(iValue).match(digits);
8327					if (!num) {
8328						throw "Missing number at position " + iValue;
8329					}
8330					iValue += num[0].length;
8331					return parseInt(num[0], 10);
8332				},
8333
8334				// Extract a name from the string value and convert to an index
8335				getName = function (match, shortNames, longNames) {
8336					var index = -1,
8337						names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8338							return [[k, v]];
8339						}).sort(function (a, b) {
8340							return -(a[1].length - b[1].length);
8341						});
8342
8343					$.each(names, function (i, pair) {
8344						var name = pair[1];
8345						if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8346							index = pair[0];
8347							iValue += name.length;
8348							return false;
8349						}
8350					});
8351					if (index !== -1) {
8352						return index + 1;
8353					} else {
8354						throw "Unknown name at position " + iValue;
8355					}
8356				},
8357
8358				// Confirm that a literal character matches the string value
8359				checkLiteral = function () {
8360					if (value.charAt(iValue) !== format.charAt(iFormat)) {
8361						throw "Unexpected literal at position " + iValue;
8362					}
8363					iValue++;
8364				};
8365
8366			for (iFormat = 0; iFormat < format.length; iFormat++) {
8367				if (literal) {
8368					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8369						literal = false;
8370					} else {
8371						checkLiteral();
8372					}
8373				} else {
8374					switch (format.charAt(iFormat)) {
8375						case "d":
8376							day = getNumber("d");
8377							break;
8378						case "D":
8379							getName("D", dayNamesShort, dayNames);
8380							break;
8381						case "o":
8382							doy = getNumber("o");
8383							break;
8384						case "m":
8385							month = getNumber("m");
8386							break;
8387						case "M":
8388							month = getName("M", monthNamesShort, monthNames);
8389							break;
8390						case "y":
8391							year = getNumber("y");
8392							break;
8393						case "@":
8394							date = new Date(getNumber("@"));
8395							year = date.getFullYear();
8396							month = date.getMonth() + 1;
8397							day = date.getDate();
8398							break;
8399						case "!":
8400							date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8401							year = date.getFullYear();
8402							month = date.getMonth() + 1;
8403							day = date.getDate();
8404							break;
8405						case "'":
8406							if (lookAhead("'")) {
8407								checkLiteral();
8408							} else {
8409								literal = true;
8410							}
8411							break;
8412						default:
8413							checkLiteral();
8414					}
8415				}
8416			}
8417
8418			if (iValue < value.length) {
8419				extra = value.substr(iValue);
8420				if (!/^\s+/.test(extra)) {
8421					throw "Extra/unparsed characters found in date: " + extra;
8422				}
8423			}
8424
8425			if (year === -1) {
8426				year = new Date().getFullYear();
8427			} else if (year < 100) {
8428				year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8429					(year <= shortYearCutoff ? 0 : -100);
8430			}
8431
8432			if (doy > -1) {
8433				month = 1;
8434				day = doy;
8435				do {
8436					dim = this._getDaysInMonth(year, month - 1);
8437					if (day <= dim) {
8438						break;
8439					}
8440					month++;
8441					day -= dim;
8442				} while (true);
8443			}
8444
8445			date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8446			if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8447				throw "Invalid date"; // E.g. 31/02/00
8448			}
8449			return date;
8450		},
8451
8452		/* Standard date formats. */
8453		ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8454		COOKIE: "D, dd M yy",
8455		ISO_8601: "yy-mm-dd",
8456		RFC_822: "D, d M y",
8457		RFC_850: "DD, dd-M-y",
8458		RFC_1036: "D, d M y",
8459		RFC_1123: "D, d M yy",
8460		RFC_2822: "D, d M yy",
8461		RSS: "D, d M y", // RFC 822
8462		TICKS: "!",
8463		TIMESTAMP: "@",
8464		W3C: "yy-mm-dd", // ISO 8601
8465
8466		_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8467			Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8468
8469		/* Format a date object into a string value.
8470		 * The format can be combinations of the following:
8471		 * d  - day of month (no leading zero)
8472		 * dd - day of month (two digit)
8473		 * o  - day of year (no leading zeros)
8474		 * oo - day of year (three digit)
8475		 * D  - day name short
8476		 * DD - day name long
8477		 * m  - month of year (no leading zero)
8478		 * mm - month of year (two digit)
8479		 * M  - month name short
8480		 * MM - month name long
8481		 * y  - year (two digit)
8482		 * yy - year (four digit)
8483		 * @ - Unix timestamp (ms since 01/01/1970)
8484		 * ! - Windows ticks (100ns since 01/01/0001)
8485		 * "..." - literal text
8486		 * '' - single quote
8487		 *
8488		 * @param  format string - the desired format of the date
8489		 * @param  date Date - the date value to format
8490		 * @param  settings Object - attributes include:
8491		 *					dayNamesShort	string[7] - abbreviated names of the days from Sunday (optional)
8492		 *					dayNames		string[7] - names of the days from Sunday (optional)
8493		 *					monthNamesShort string[12] - abbreviated names of the months (optional)
8494		 *					monthNames		string[12] - names of the months (optional)
8495		 * @return  string - the date in the above format
8496		 */
8497		formatDate: function (format, date, settings) {
8498			if (!date) {
8499				return "";
8500			}
8501
8502			var iFormat,
8503				dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8504				dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8505				monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8506				monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8507
8508				// Check whether a format character is doubled
8509				lookAhead = function (match) {
8510					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8511					if (matches) {
8512						iFormat++;
8513					}
8514					return matches;
8515				},
8516
8517				// Format a number, with leading zero if necessary
8518				formatNumber = function (match, value, len) {
8519					var num = "" + value;
8520					if (lookAhead(match)) {
8521						while (num.length < len) {
8522							num = "0" + num;
8523						}
8524					}
8525					return num;
8526				},
8527
8528				// Format a name, short or long as requested
8529				formatName = function (match, value, shortNames, longNames) {
8530					return (lookAhead(match) ? longNames[value] : shortNames[value]);
8531				},
8532				output = "",
8533				literal = false;
8534
8535			if (date) {
8536				for (iFormat = 0; iFormat < format.length; iFormat++) {
8537					if (literal) {
8538						if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8539							literal = false;
8540						} else {
8541							output += format.charAt(iFormat);
8542						}
8543					} else {
8544						switch (format.charAt(iFormat)) {
8545							case "d":
8546								output += formatNumber("d", date.getDate(), 2);
8547								break;
8548							case "D":
8549								output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8550								break;
8551							case "o":
8552								output += formatNumber("o",
8553									Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8554								break;
8555							case "m":
8556								output += formatNumber("m", date.getMonth() + 1, 2);
8557								break;
8558							case "M":
8559								output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8560								break;
8561							case "y":
8562								output += (lookAhead("y") ? date.getFullYear() :
8563									(date.getFullYear() % 100 < 10 ? "0" : "") + date.getFullYear() % 100);
8564								break;
8565							case "@":
8566								output += date.getTime();
8567								break;
8568							case "!":
8569								output += date.getTime() * 10000 + this._ticksTo1970;
8570								break;
8571							case "'":
8572								if (lookAhead("'")) {
8573									output += "'";
8574								} else {
8575									literal = true;
8576								}
8577								break;
8578							default:
8579								output += format.charAt(iFormat);
8580						}
8581					}
8582				}
8583			}
8584			return output;
8585		},
8586
8587		/* Extract all possible characters from the date format. */
8588		_possibleChars: function (format) {
8589			var iFormat,
8590				chars = "",
8591				literal = false,
8592
8593				// Check whether a format character is doubled
8594				lookAhead = function (match) {
8595					var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8596					if (matches) {
8597						iFormat++;
8598					}
8599					return matches;
8600				};
8601
8602			for (iFormat = 0; iFormat < format.length; iFormat++) {
8603				if (literal) {
8604					if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8605						literal = false;
8606					} else {
8607						chars += format.charAt(iFormat);
8608					}
8609				} else {
8610					switch (format.charAt(iFormat)) {
8611						case "d": case "m": case "y": case "@":
8612							chars += "0123456789";
8613							break;
8614						case "D": case "M":
8615							return null; // Accept anything
8616						case "'":
8617							if (lookAhead("'")) {
8618								chars += "'";
8619							} else {
8620								literal = true;
8621							}
8622							break;
8623						default:
8624							chars += format.charAt(iFormat);
8625					}
8626				}
8627			}
8628			return chars;
8629		},
8630
8631		/* Get a setting value, defaulting if necessary. */
8632		_get: function (inst, name) {
8633			return inst.settings[name] !== undefined ?
8634				inst.settings[name] : this._defaults[name];
8635		},
8636
8637		/* Parse existing date and initialise date picker. */
8638		_setDateFromField: function (inst, noDefault) {
8639			if (inst.input.val() === inst.lastVal) {
8640				return;
8641			}
8642
8643			var dateFormat = this._get(inst, "dateFormat"),
8644				dates = inst.lastVal = inst.input ? inst.input.val() : null,
8645				defaultDate = this._getDefaultDate(inst),
8646				date = defaultDate,
8647				settings = this._getFormatConfig(inst);
8648
8649			try {
8650				date = this.parseDate(dateFormat, dates, settings) || defaultDate;
8651			} catch (event) {
8652				dates = (noDefault ? "" : dates);
8653			}
8654			inst.selectedDay = date.getDate();
8655			inst.drawMonth = inst.selectedMonth = date.getMonth();
8656			inst.drawYear = inst.selectedYear = date.getFullYear();
8657			inst.currentDay = (dates ? date.getDate() : 0);
8658			inst.currentMonth = (dates ? date.getMonth() : 0);
8659			inst.currentYear = (dates ? date.getFullYear() : 0);
8660			this._adjustInstDate(inst);
8661		},
8662
8663		/* Retrieve the default date shown on opening. */
8664		_getDefaultDate: function (inst) {
8665			return this._restrictMinMax(inst,
8666				this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
8667		},
8668
8669		/* A date may be specified as an exact value or a relative one. */
8670		_determineDate: function (inst, date, defaultDate) {
8671			var offsetNumeric = function (offset) {
8672				var date = new Date();
8673				date.setDate(date.getDate() + offset);
8674				return date;
8675			},
8676				offsetString = function (offset) {
8677					try {
8678						return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8679							offset, $.datepicker._getFormatConfig(inst));
8680					} catch (e) {
8681
8682						// Ignore
8683					}
8684
8685					var date = (offset.toLowerCase().match(/^c/) ?
8686						$.datepicker._getDate(inst) : null) || new Date(),
8687						year = date.getFullYear(),
8688						month = date.getMonth(),
8689						day = date.getDate(),
8690						pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
8691						matches = pattern.exec(offset);
8692
8693					while (matches) {
8694						switch (matches[2] || "d") {
8695							case "d": case "D":
8696								day += parseInt(matches[1], 10); break;
8697							case "w": case "W":
8698								day += parseInt(matches[1], 10) * 7; break;
8699							case "m": case "M":
8700								month += parseInt(matches[1], 10);
8701								day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8702								break;
8703							case "y": case "Y":
8704								year += parseInt(matches[1], 10);
8705								day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
8706								break;
8707						}
8708						matches = pattern.exec(offset);
8709					}
8710					return new Date(year, month, day);
8711				},
8712				newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
8713					(typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
8714
8715			newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
8716			if (newDate) {
8717				newDate.setHours(0);
8718				newDate.setMinutes(0);
8719				newDate.setSeconds(0);
8720				newDate.setMilliseconds(0);
8721			}
8722			return this._daylightSavingAdjust(newDate);
8723		},
8724
8725		/* Handle switch to/from daylight saving.
8726		 * Hours may be non-zero on daylight saving cut-over:
8727		 * > 12 when midnight changeover, but then cannot generate
8728		 * midnight datetime, so jump to 1AM, otherwise reset.
8729		 * @param  date  (Date) the date to check
8730		 * @return  (Date) the corrected date
8731		 */
8732		_daylightSavingAdjust: function (date) {
8733			if (!date) {
8734				return null;
8735			}
8736			date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
8737			return date;
8738		},
8739
8740		/* Set the date(s) directly. */
8741		_setDate: function (inst, date, noChange) {
8742			var clear = !date,
8743				origMonth = inst.selectedMonth,
8744				origYear = inst.selectedYear,
8745				newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
8746
8747			inst.selectedDay = inst.currentDay = newDate.getDate();
8748			inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
8749			inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
8750			if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
8751				this._notifyChange(inst);
8752			}
8753			this._adjustInstDate(inst);
8754			if (inst.input) {
8755				inst.input.val(clear ? "" : this._formatDate(inst));
8756			}
8757		},
8758
8759		/* Retrieve the date(s) directly. */
8760		_getDate: function (inst) {
8761			var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
8762				this._daylightSavingAdjust(new Date(
8763					inst.currentYear, inst.currentMonth, inst.currentDay)));
8764			return startDate;
8765		},
8766
8767		/* Attach the onxxx handlers.  These are declared statically so
8768		 * they work with static code transformers like Caja.
8769		 */
8770		_attachHandlers: function (inst) {
8771			var stepMonths = this._get(inst, "stepMonths"),
8772				id = "#" + inst.id.replace(/\\\\/g, "\\");
8773			inst.dpDiv.find("[data-handler]").map(function () {
8774				var handler = {
8775					prev: function () {
8776						$.datepicker._adjustDate(id, -stepMonths, "M");
8777					},
8778					next: function () {
8779						$.datepicker._adjustDate(id, +stepMonths, "M");
8780					},
8781					hide: function () {
8782						$.datepicker._hideDatepicker();
8783					},
8784					today: function () {
8785						$.datepicker._gotoToday(id);
8786					},
8787					selectDay: function () {
8788						$.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
8789						return false;
8790					},
8791					selectMonth: function () {
8792						$.datepicker._selectMonthYear(id, this, "M");
8793						return false;
8794					},
8795					selectYear: function () {
8796						$.datepicker._selectMonthYear(id, this, "Y");
8797						return false;
8798					}
8799				};
8800				$(this).on(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
8801			});
8802		},
8803
8804		/* Generate the HTML for the current state of the date picker. */
8805		_generateHTML: function (inst) {
8806			var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
8807				controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
8808				monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
8809				selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
8810				cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
8811				printDate, dRow, tbody, daySettings, otherMonth, unselectable,
8812				tempDate = new Date(),
8813				today = this._daylightSavingAdjust(
8814					new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
8815				isRTL = this._get(inst, "isRTL"),
8816				showButtonPanel = this._get(inst, "showButtonPanel"),
8817				hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
8818				navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
8819				numMonths = this._getNumberOfMonths(inst),
8820				showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
8821				stepMonths = this._get(inst, "stepMonths"),
8822				isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
8823				currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
8824					new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
8825				minDate = this._getMinMaxDate(inst, "min"),
8826				maxDate = this._getMinMaxDate(inst, "max"),
8827				drawMonth = inst.drawMonth - showCurrentAtPos,
8828				drawYear = inst.drawYear;
8829
8830			if (drawMonth < 0) {
8831				drawMonth += 12;
8832				drawYear--;
8833			}
8834			if (maxDate) {
8835				maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
8836					maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
8837				maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
8838				while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
8839					drawMonth--;
8840					if (drawMonth < 0) {
8841						drawMonth = 11;
8842						drawYear--;
8843					}
8844				}
8845			}
8846			inst.drawMonth = drawMonth;
8847			inst.drawYear = drawYear;
8848
8849			prevText = this._get(inst, "prevText");
8850			prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
8851				this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
8852				this._getFormatConfig(inst)));
8853
8854			if (this._canAdjustMonth(inst, -1, drawYear, drawMonth)) {
8855				prev = $("<a>")
8856					.attr({
8857						"class": "ui-datepicker-prev ui-corner-all",
8858						"data-handler": "prev",
8859						"data-event": "click",
8860						title: prevText
8861					})
8862					.append(
8863						$("<span>")
8864							.addClass("ui-icon ui-icon-circle-triangle-" +
8865								(isRTL ? "e" : "w"))
8866							.text(prevText)
8867					)[0].outerHTML;
8868			} else if (hideIfNoPrevNext) {
8869				prev = "";
8870			} else {
8871				prev = $("<a>")
8872					.attr({
8873						"class": "ui-datepicker-prev ui-corner-all ui-state-disabled",
8874						title: prevText
8875					})
8876					.append(
8877						$("<span>")
8878							.addClass("ui-icon ui-icon-circle-triangle-" +
8879								(isRTL ? "e" : "w"))
8880							.text(prevText)
8881					)[0].outerHTML;
8882			}
8883
8884			nextText = this._get(inst, "nextText");
8885			nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
8886				this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
8887				this._getFormatConfig(inst)));
8888
8889			if (this._canAdjustMonth(inst, +1, drawYear, drawMonth)) {
8890				next = $("<a>")
8891					.attr({
8892						"class": "ui-datepicker-next ui-corner-all",
8893						"data-handler": "next",
8894						"data-event": "click",
8895						title: nextText
8896					})
8897					.append(
8898						$("<span>")
8899							.addClass("ui-icon ui-icon-circle-triangle-" +
8900								(isRTL ? "w" : "e"))
8901							.text(nextText)
8902					)[0].outerHTML;
8903			} else if (hideIfNoPrevNext) {
8904				next = "";
8905			} else {
8906				next = $("<a>")
8907					.attr({
8908						"class": "ui-datepicker-next ui-corner-all ui-state-disabled",
8909						title: nextText
8910					})
8911					.append(
8912						$("<span>")
8913							.attr("class", "ui-icon ui-icon-circle-triangle-" +
8914								(isRTL ? "w" : "e"))
8915							.text(nextText)
8916					)[0].outerHTML;
8917			}
8918
8919			currentText = this._get(inst, "currentText");
8920			gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
8921			currentText = (!navigationAsDateFormat ? currentText :
8922				this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
8923
8924			controls = "";
8925			if (!inst.inline) {
8926				controls = $("<button>")
8927					.attr({
8928						type: "button",
8929						"class": "ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all",
8930						"data-handler": "hide",
8931						"data-event": "click"
8932					})
8933					.text(this._get(inst, "closeText"))[0].outerHTML;
8934			}
8935
8936			buttonPanel = "";
8937			if (showButtonPanel) {
8938				buttonPanel = $("<div class='ui-datepicker-buttonpane ui-widget-content'>")
8939					.append(isRTL ? controls : "")
8940					.append(this._isInRange(inst, gotoDate) ?
8941						$("<button>")
8942							.attr({
8943								type: "button",
8944								"class": "ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all",
8945								"data-handler": "today",
8946								"data-event": "click"
8947							})
8948							.text(currentText) :
8949						"")
8950					.append(isRTL ? "" : controls)[0].outerHTML;
8951			}
8952
8953			firstDay = parseInt(this._get(inst, "firstDay"), 10);
8954			firstDay = (isNaN(firstDay) ? 0 : firstDay);
8955
8956			showWeek = this._get(inst, "showWeek");
8957			dayNames = this._get(inst, "dayNames");
8958			dayNamesMin = this._get(inst, "dayNamesMin");
8959			monthNames = this._get(inst, "monthNames");
8960			monthNamesShort = this._get(inst, "monthNamesShort");
8961			beforeShowDay = this._get(inst, "beforeShowDay");
8962			showOtherMonths = this._get(inst, "showOtherMonths");
8963			selectOtherMonths = this._get(inst, "selectOtherMonths");
8964			defaultDate = this._getDefaultDate(inst);
8965			html = "";
8966
8967			for (row = 0; row < numMonths[0]; row++) {
8968				group = "";
8969				this.maxRows = 4;
8970				for (col = 0; col < numMonths[1]; col++) {
8971					selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
8972					cornerClass = " ui-corner-all";
8973					calender = "";
8974					if (isMultiMonth) {
8975						calender += "<div class='ui-datepicker-group";
8976						if (numMonths[1] > 1) {
8977							switch (col) {
8978								case 0: calender += " ui-datepicker-group-first";
8979									cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
8980								case numMonths[1] - 1: calender += " ui-datepicker-group-last";
8981									cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
8982								default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
8983							}
8984						}
8985						calender += "'>";
8986					}
8987					calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
8988						(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
8989						(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
8990						this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
8991							row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
8992						"</div><table class='ui-datepicker-calendar'><thead>" +
8993						"<tr>";
8994					thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
8995					for (dow = 0; dow < 7; dow++) { // days of the week
8996						day = (dow + firstDay) % 7;
8997						thead += "<th scope='col'" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
8998							"<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
8999					}
9000					calender += thead + "</tr></thead><tbody>";
9001					daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9002					if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9003						inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9004					}
9005					leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9006					curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9007					numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9008					this.maxRows = numRows;
9009					printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9010					for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9011						calender += "<tr>";
9012						tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9013							this._get(inst, "calculateWeek")(printDate) + "</td>");
9014						for (dow = 0; dow < 7; dow++) { // create date picker days
9015							daySettings = (beforeShowDay ?
9016								beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9017							otherMonth = (printDate.getMonth() !== drawMonth);
9018							unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9019								(minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9020							tbody += "<td class='" +
9021								((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9022								(otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9023								((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9024									(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9025
9026									// or defaultDate is current printedDate and defaultDate is selectedDate
9027									" " + this._dayOverClass : "") + // highlight selected day
9028								(unselectable ? " " + this._unselectableClass + " ui-state-disabled" : "") +  // highlight unselectable days
9029								(otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9030									(printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9031									(printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9032								((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9033								(unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9034								(otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9035									(unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9036										(printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9037										(printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9038										(otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9039										"' href='#' aria-current='" + (printDate.getTime() === currentDate.getTime() ? "true" : "false") + // mark date as selected for screen reader
9040										"' data-date='" + printDate.getDate() + // store date as data
9041										"'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9042							printDate.setDate(printDate.getDate() + 1);
9043							printDate = this._daylightSavingAdjust(printDate);
9044						}
9045						calender += tbody + "</tr>";
9046					}
9047					drawMonth++;
9048					if (drawMonth > 11) {
9049						drawMonth = 0;
9050						drawYear++;
9051					}
9052					calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9053						((numMonths[0] > 0 && col === numMonths[1] - 1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9054					group += calender;
9055				}
9056				html += group;
9057			}
9058			html += buttonPanel;
9059			inst._keyEvent = false;
9060			return html;
9061		},
9062
9063		/* Generate the month and year header. */
9064		_generateMonthYearHeader: function (inst, drawMonth, drawYear, minDate, maxDate,
9065			secondary, monthNames, monthNamesShort) {
9066
9067			var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9068				changeMonth = this._get(inst, "changeMonth"),
9069				changeYear = this._get(inst, "changeYear"),
9070				showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9071				selectMonthLabel = this._get(inst, "selectMonthLabel"),
9072				selectYearLabel = this._get(inst, "selectYearLabel"),
9073				html = "<div class='ui-datepicker-title'>",
9074				monthHtml = "";
9075
9076			// Month selection
9077			if (secondary || !changeMonth) {
9078				monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9079			} else {
9080				inMinYear = (minDate && minDate.getFullYear() === drawYear);
9081				inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9082				monthHtml += "<select class='ui-datepicker-month' aria-label='" + selectMonthLabel + "' data-handler='selectMonth' data-event='change'>";
9083				for (month = 0; month < 12; month++) {
9084					if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9085						monthHtml += "<option value='" + month + "'" +
9086							(month === drawMonth ? " selected='selected'" : "") +
9087							">" + monthNamesShort[month] + "</option>";
9088					}
9089				}
9090				monthHtml += "</select>";
9091			}
9092
9093			if (!showMonthAfterYear) {
9094				html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9095			}
9096
9097			// Year selection
9098			if (!inst.yearshtml) {
9099				inst.yearshtml = "";
9100				if (secondary || !changeYear) {
9101					html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9102				} else {
9103
9104					// determine range of years to display
9105					years = this._get(inst, "yearRange").split(":");
9106					thisYear = new Date().getFullYear();
9107					determineYear = function (value) {
9108						var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9109							(value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9110								parseInt(value, 10)));
9111						return (isNaN(year) ? thisYear : year);
9112					};
9113					year = determineYear(years[0]);
9114					endYear = Math.max(year, determineYear(years[1] || ""));
9115					year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9116					endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9117					inst.yearshtml += "<select class='ui-datepicker-year' aria-label='" + selectYearLabel + "' data-handler='selectYear' data-event='change'>";
9118					for (; year <= endYear; year++) {
9119						inst.yearshtml += "<option value='" + year + "'" +
9120							(year === drawYear ? " selected='selected'" : "") +
9121							">" + year + "</option>";
9122					}
9123					inst.yearshtml += "</select>";
9124
9125					html += inst.yearshtml;
9126					inst.yearshtml = null;
9127				}
9128			}
9129
9130			html += this._get(inst, "yearSuffix");
9131			if (showMonthAfterYear) {
9132				html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9133			}
9134			html += "</div>"; // Close datepicker_header
9135			return html;
9136		},
9137
9138		/* Adjust one of the date sub-fields. */
9139		_adjustInstDate: function (inst, offset, period) {
9140			var year = inst.selectedYear + (period === "Y" ? offset : 0),
9141				month = inst.selectedMonth + (period === "M" ? offset : 0),
9142				day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9143				date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9144
9145			inst.selectedDay = date.getDate();
9146			inst.drawMonth = inst.selectedMonth = date.getMonth();
9147			inst.drawYear = inst.selectedYear = date.getFullYear();
9148			if (period === "M" || period === "Y") {
9149				this._notifyChange(inst);
9150			}
9151		},
9152
9153		/* Ensure a date is within any min/max bounds. */
9154		_restrictMinMax: function (inst, date) {
9155			var minDate = this._getMinMaxDate(inst, "min"),
9156				maxDate = this._getMinMaxDate(inst, "max"),
9157				newDate = (minDate && date < minDate ? minDate : date);
9158			return (maxDate && newDate > maxDate ? maxDate : newDate);
9159		},
9160
9161		/* Notify change of month/year. */
9162		_notifyChange: function (inst) {
9163			var onChange = this._get(inst, "onChangeMonthYear");
9164			if (onChange) {
9165				onChange.apply((inst.input ? inst.input[0] : null),
9166					[inst.selectedYear, inst.selectedMonth + 1, inst]);
9167			}
9168		},
9169
9170		/* Determine the number of months to show. */
9171		_getNumberOfMonths: function (inst) {
9172			var numMonths = this._get(inst, "numberOfMonths");
9173			return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9174		},
9175
9176		/* Determine the current maximum date - ensure no time components are set. */
9177		_getMinMaxDate: function (inst, minMax) {
9178			return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9179		},
9180
9181		/* Find the number of days in a given month. */
9182		_getDaysInMonth: function (year, month) {
9183			return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9184		},
9185
9186		/* Find the day of the week of the first of a month. */
9187		_getFirstDayOfMonth: function (year, month) {
9188			return new Date(year, month, 1).getDay();
9189		},
9190
9191		/* Determines if we should allow a "next/prev" month display change. */
9192		_canAdjustMonth: function (inst, offset, curYear, curMonth) {
9193			var numMonths = this._getNumberOfMonths(inst),
9194				date = this._daylightSavingAdjust(new Date(curYear,
9195					curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9196
9197			if (offset < 0) {
9198				date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9199			}
9200			return this._isInRange(inst, date);
9201		},
9202
9203		/* Is the given date in the accepted range? */
9204		_isInRange: function (inst, date) {
9205			var yearSplit, currentYear,
9206				minDate = this._getMinMaxDate(inst, "min"),
9207				maxDate = this._getMinMaxDate(inst, "max"),
9208				minYear = null,
9209				maxYear = null,
9210				years = this._get(inst, "yearRange");
9211			if (years) {
9212				yearSplit = years.split(":");
9213				currentYear = new Date().getFullYear();
9214				minYear = parseInt(yearSplit[0], 10);
9215				maxYear = parseInt(yearSplit[1], 10);
9216				if (yearSplit[0].match(/[+\-].*/)) {
9217					minYear += currentYear;
9218				}
9219				if (yearSplit[1].match(/[+\-].*/)) {
9220					maxYear += currentYear;
9221				}
9222			}
9223
9224			return ((!minDate || date.getTime() >= minDate.getTime()) &&
9225				(!maxDate || date.getTime() <= maxDate.getTime()) &&
9226				(!minYear || date.getFullYear() >= minYear) &&
9227				(!maxYear || date.getFullYear() <= maxYear));
9228		},
9229
9230		/* Provide the configuration settings for formatting/parsing. */
9231		_getFormatConfig: function (inst) {
9232			var shortYearCutoff = this._get(inst, "shortYearCutoff");
9233			shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9234				new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9235			return {
9236				shortYearCutoff: shortYearCutoff,
9237				dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9238				monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")
9239			};
9240		},
9241
9242		/* Format the given date for display. */
9243		_formatDate: function (inst, day, month, year) {
9244			if (!day) {
9245				inst.currentDay = inst.selectedDay;
9246				inst.currentMonth = inst.selectedMonth;
9247				inst.currentYear = inst.selectedYear;
9248			}
9249			var date = (day ? (typeof day === "object" ? day :
9250				this._daylightSavingAdjust(new Date(year, month, day))) :
9251				this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9252			return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9253		}
9254	});
9255
9256	/*
9257	 * Bind hover events for datepicker elements.
9258	 * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9259	 * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9260	 */
9261	function datepicker_bindHover(dpDiv) {
9262		var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9263		return dpDiv.on("mouseout", selector, function () {
9264			$(this).removeClass("ui-state-hover");
9265			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9266				$(this).removeClass("ui-datepicker-prev-hover");
9267			}
9268			if (this.className.indexOf("ui-datepicker-next") !== -1) {
9269				$(this).removeClass("ui-datepicker-next-hover");
9270			}
9271		})
9272			.on("mouseover", selector, datepicker_handleMouseover);
9273	}
9274
9275	function datepicker_handleMouseover() {
9276		if (!$.datepicker._isDisabledDatepicker(datepicker_instActive.inline ? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
9277			$(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9278			$(this).addClass("ui-state-hover");
9279			if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9280				$(this).addClass("ui-datepicker-prev-hover");
9281			}
9282			if (this.className.indexOf("ui-datepicker-next") !== -1) {
9283				$(this).addClass("ui-datepicker-next-hover");
9284			}
9285		}
9286	}
9287
9288	/* jQuery extend now ignores nulls! */
9289	function datepicker_extendRemove(target, props) {
9290		$.extend(target, props);
9291		for (var name in props) {
9292			if (props[name] == null) {
9293				target[name] = props[name];
9294			}
9295		}
9296		return target;
9297	}
9298
9299	/* Invoke the datepicker functionality.
9300	   @param  options  string - a command, optionally followed by additional parameters or
9301						Object - settings for attaching new datepicker functionality
9302	   @return  jQuery object */
9303	$.fn.datepicker = function (options) {
9304
9305		/* Verify an empty collection wasn't passed - Fixes #6976 */
9306		if (!this.length) {
9307			return this;
9308		}
9309
9310		/* Initialise the date picker. */
9311		if (!$.datepicker.initialized) {
9312			$(document).on("mousedown", $.datepicker._checkExternalClick);
9313			$.datepicker.initialized = true;
9314		}
9315
9316		/* Append datepicker main container to body if not exist. */
9317		if ($("#" + $.datepicker._mainDivId).length === 0) {
9318			$("body").append($.datepicker.dpDiv);
9319		}
9320
9321		var otherArgs = Array.prototype.slice.call(arguments, 1);
9322		if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9323			return $.datepicker["_" + options + "Datepicker"].
9324				apply($.datepicker, [this[0]].concat(otherArgs));
9325		}
9326		if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9327			return $.datepicker["_" + options + "Datepicker"].
9328				apply($.datepicker, [this[0]].concat(otherArgs));
9329		}
9330		return this.each(function () {
9331			if (typeof options === "string") {
9332				$.datepicker["_" + options + "Datepicker"]
9333					.apply($.datepicker, [this].concat(otherArgs));
9334			} else {
9335				$.datepicker._attachDatepicker(this, options);
9336			}
9337		});
9338	};
9339
9340	$.datepicker = new Datepicker(); // singleton instance
9341	$.datepicker.initialized = false;
9342	$.datepicker.uuid = new Date().getTime();
9343	$.datepicker.version = "1.14.1";
9344
9345	var widgetsDatepicker = $.datepicker;
9346
9347
9348	/*!
9349	 * jQuery UI Mouse 1.14.1
9350	 * https://jqueryui.com
9351	 *
9352	 * Copyright OpenJS Foundation and other contributors
9353	 * Released under the MIT license.
9354	 * https://jquery.org/license
9355	 */
9356
9357	//>>label: Mouse
9358	//>>group: Widgets
9359	//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
9360	//>>docs: https://api.jqueryui.com/mouse/
9361
9362
9363	var mouseHandled = false;
9364	$(document).on("mouseup", function () {
9365		mouseHandled = false;
9366	});
9367
9368	var widgetsMouse = $.widget("ui.mouse", {
9369		version: "1.14.1",
9370		options: {
9371			cancel: "input, textarea, button, select, option",
9372			distance: 1,
9373			delay: 0
9374		},
9375		_mouseInit: function () {
9376			var that = this;
9377
9378			this.element
9379				.on("mousedown." + this.widgetName, function (event) {
9380					return that._mouseDown(event);
9381				})
9382				.on("click." + this.widgetName, function (event) {
9383					if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
9384						$.removeData(event.target, that.widgetName + ".preventClickEvent");
9385						event.stopImmediatePropagation();
9386						return false;
9387					}
9388				});
9389
9390			this.started = false;
9391		},
9392
9393		// TODO: make sure destroying one instance of mouse doesn't mess with
9394		// other instances of mouse
9395		_mouseDestroy: function () {
9396			this.element.off("." + this.widgetName);
9397			if (this._mouseMoveDelegate) {
9398				this.document
9399					.off("mousemove." + this.widgetName, this._mouseMoveDelegate)
9400					.off("mouseup." + this.widgetName, this._mouseUpDelegate);
9401			}
9402		},
9403
9404		_mouseDown: function (event) {
9405
9406			// don't let more than one widget handle mouseStart
9407			if (mouseHandled) {
9408				return;
9409			}
9410
9411			this._mouseMoved = false;
9412
9413			// We may have missed mouseup (out of window)
9414			if (this._mouseStarted) {
9415				this._mouseUp(event);
9416			}
9417
9418			this._mouseDownEvent = event;
9419
9420			var that = this,
9421				btnIsLeft = event.which === 1,
9422				elIsCancel = typeof this.options.cancel === "string" ?
9423					$(event.target).closest(this.options.cancel).length :
9424					false;
9425			if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
9426				return true;
9427			}
9428
9429			this.mouseDelayMet = !this.options.delay;
9430			if (!this.mouseDelayMet) {
9431				this._mouseDelayTimer = setTimeout(function () {
9432					that.mouseDelayMet = true;
9433				}, this.options.delay);
9434			}
9435
9436			if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
9437				this._mouseStarted = (this._mouseStart(event) !== false);
9438				if (!this._mouseStarted) {
9439					event.preventDefault();
9440					return true;
9441				}
9442			}
9443
9444			// Click event may never have fired (Gecko & Opera)
9445			if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
9446				$.removeData(event.target, this.widgetName + ".preventClickEvent");
9447			}
9448
9449			// These delegates are required to keep context
9450			this._mouseMoveDelegate = function (event) {
9451				return that._mouseMove(event);
9452			};
9453			this._mouseUpDelegate = function (event) {
9454				return that._mouseUp(event);
9455			};
9456
9457			this.document
9458				.on("mousemove." + this.widgetName, this._mouseMoveDelegate)
9459				.on("mouseup." + this.widgetName, this._mouseUpDelegate);
9460
9461			event.preventDefault();
9462
9463			mouseHandled = true;
9464			return true;
9465		},
9466
9467		_mouseMove: function (event) {
9468
9469			// Only check for mouseups outside the document if you've moved inside the document
9470			// at least once.
9471			if (this._mouseMoved && !event.which) {
9472
9473				// Support: Safari <=8 - 9
9474				// Safari sets which to 0 if you press any of the following keys
9475				// during a drag (#14461)
9476				if (event.originalEvent.altKey || event.originalEvent.ctrlKey ||
9477					event.originalEvent.metaKey || event.originalEvent.shiftKey) {
9478					this.ignoreMissingWhich = true;
9479				} else if (!this.ignoreMissingWhich) {
9480					return this._mouseUp(event);
9481				}
9482			}
9483
9484			if (event.which || event.button) {
9485				this._mouseMoved = true;
9486			}
9487
9488			if (this._mouseStarted) {
9489				this._mouseDrag(event);
9490				return event.preventDefault();
9491			}
9492
9493			if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
9494				this._mouseStarted =
9495					(this._mouseStart(this._mouseDownEvent, event) !== false);
9496				if (this._mouseStarted) {
9497					this._mouseDrag(event);
9498				} else {
9499					this._mouseUp(event);
9500				}
9501			}
9502
9503			return !this._mouseStarted;
9504		},
9505
9506		_mouseUp: function (event) {
9507			this.document
9508				.off("mousemove." + this.widgetName, this._mouseMoveDelegate)
9509				.off("mouseup." + this.widgetName, this._mouseUpDelegate);
9510
9511			if (this._mouseStarted) {
9512				this._mouseStarted = false;
9513
9514				if (event.target === this._mouseDownEvent.target) {
9515					$.data(event.target, this.widgetName + ".preventClickEvent", true);
9516				}
9517
9518				this._mouseStop(event);
9519			}
9520
9521			if (this._mouseDelayTimer) {
9522				clearTimeout(this._mouseDelayTimer);
9523				delete this._mouseDelayTimer;
9524			}
9525
9526			this.ignoreMissingWhich = false;
9527			mouseHandled = false;
9528			event.preventDefault();
9529		},
9530
9531		_mouseDistanceMet: function (event) {
9532			return (Math.max(
9533				Math.abs(this._mouseDownEvent.pageX - event.pageX),
9534				Math.abs(this._mouseDownEvent.pageY - event.pageY)
9535			) >= this.options.distance
9536			);
9537		},
9538
9539		_mouseDelayMet: function ( /* event */) {
9540			return this.mouseDelayMet;
9541		},
9542
9543		// These are placeholder methods, to be overriden by extending plugin
9544		_mouseStart: function ( /* event */) { },
9545		_mouseDrag: function ( /* event */) { },
9546		_mouseStop: function ( /* event */) { },
9547		_mouseCapture: function ( /* event */) {
9548			return true;
9549		}
9550	});
9551
9552
9553
9554	// $.ui.plugin is deprecated. Use $.widget() extensions instead.
9555	var plugin = $.ui.plugin = {
9556		add: function (module, option, set) {
9557			var i,
9558				proto = $.ui[module].prototype;
9559			for (i in set) {
9560				proto.plugins[i] = proto.plugins[i] || [];
9561				proto.plugins[i].push([option, set[i]]);
9562			}
9563		},
9564		call: function (instance, name, args, allowDisconnected) {
9565			var i,
9566				set = instance.plugins[name];
9567
9568			if (!set) {
9569				return;
9570			}
9571
9572			if (!allowDisconnected && (!instance.element[0].parentNode ||
9573				instance.element[0].parentNode.nodeType === 11)) {
9574				return;
9575			}
9576
9577			for (i = 0; i < set.length; i++) {
9578				if (instance.options[set[i][0]]) {
9579					set[i][1].apply(instance.element, args);
9580				}
9581			}
9582		}
9583	};
9584
9585
9586	/*!
9587	 * jQuery UI Draggable 1.14.1
9588	 * https://jqueryui.com
9589	 *
9590	 * Copyright OpenJS Foundation and other contributors
9591	 * Released under the MIT license.
9592	 * https://jquery.org/license
9593	 */
9594
9595	//>>label: Draggable
9596	//>>group: Interactions
9597	//>>description: Enables dragging functionality for any element.
9598	//>>docs: https://api.jqueryui.com/draggable/
9599	//>>demos: https://jqueryui.com/draggable/
9600	//>>css.structure: ../../themes/base/draggable.css
9601
9602
9603	$.widget("ui.draggable", $.ui.mouse, {
9604		version: "1.14.1",
9605		widgetEventPrefix: "drag",
9606		options: {
9607			addClasses: true,
9608			appendTo: "parent",
9609			axis: false,
9610			connectToSortable: false,
9611			containment: false,
9612			cursor: "auto",
9613			cursorAt: false,
9614			grid: false,
9615			handle: false,
9616			helper: "original",
9617			iframeFix: false,
9618			opacity: false,
9619			refreshPositions: false,
9620			revert: false,
9621			revertDuration: 500,
9622			scope: "default",
9623			scroll: true,
9624			scrollSensitivity: 20,
9625			scrollSpeed: 20,
9626			snap: false,
9627			snapMode: "both",
9628			snapTolerance: 20,
9629			stack: false,
9630			zIndex: false,
9631
9632			// Callbacks
9633			drag: null,
9634			start: null,
9635			stop: null
9636		},
9637		_create: function () {
9638
9639			if (this.options.helper === "original") {
9640				this._setPositionRelative();
9641			}
9642			if (this.options.addClasses) {
9643				this._addClass("ui-draggable");
9644			}
9645			this._setHandleClassName();
9646
9647			this._mouseInit();
9648		},
9649
9650		_setOption: function (key, value) {
9651			this._super(key, value);
9652			if (key === "handle") {
9653				this._removeHandleClassName();
9654				this._setHandleClassName();
9655			}
9656		},
9657
9658		_destroy: function () {
9659			if ((this.helper || this.element).is(".ui-draggable-dragging")) {
9660				this.destroyOnClear = true;
9661				return;
9662			}
9663			this._removeHandleClassName();
9664			this._mouseDestroy();
9665		},
9666
9667		_mouseCapture: function (event) {
9668			var o = this.options;
9669
9670			// Among others, prevent a drag on a resizable-handle
9671			if (this.helper || o.disabled ||
9672				$(event.target).closest(".ui-resizable-handle").length > 0) {
9673				return false;
9674			}
9675
9676			//Quit if we're not on a valid handle
9677			this.handle = this._getHandle(event);
9678			if (!this.handle) {
9679				return false;
9680			}
9681
9682			this._blurActiveElement(event);
9683
9684			this._blockFrames(o.iframeFix === true ? "iframe" : o.iframeFix);
9685
9686			return true;
9687
9688		},
9689
9690		_blockFrames: function (selector) {
9691			this.iframeBlocks = this.document.find(selector).map(function () {
9692				var iframe = $(this);
9693
9694				return $("<div>")
9695					.css("position", "absolute")
9696					.appendTo(iframe.parent())
9697					.outerWidth(iframe.outerWidth())
9698					.outerHeight(iframe.outerHeight())
9699					.offset(iframe.offset())[0];
9700			});
9701		},
9702
9703		_unblockFrames: function () {
9704			if (this.iframeBlocks) {
9705				this.iframeBlocks.remove();
9706				delete this.iframeBlocks;
9707			}
9708		},
9709
9710		_blurActiveElement: function (event) {
9711			var activeElement = this.document[0].activeElement,
9712				target = $(event.target);
9713
9714			// Don't blur if the event occurred on an element that is within
9715			// the currently focused element
9716			// See #10527, #12472
9717			if (target.closest(activeElement).length) {
9718				return;
9719			}
9720
9721			// Blur any element that currently has focus, see #4261
9722			$(activeElement).trigger("blur");
9723		},
9724
9725		_mouseStart: function (event) {
9726
9727			var o = this.options;
9728
9729			//Create and append the visible helper
9730			this.helper = this._createHelper(event);
9731
9732			this._addClass(this.helper, "ui-draggable-dragging");
9733
9734			//Cache the helper size
9735			this._cacheHelperProportions();
9736
9737			//If ddmanager is used for droppables, set the global draggable
9738			if ($.ui.ddmanager) {
9739				$.ui.ddmanager.current = this;
9740			}
9741
9742			/*
9743			 * - Position generation -
9744			 * This block generates everything position related - it's the core of draggables.
9745			 */
9746
9747			//Cache the margins of the original element
9748			this._cacheMargins();
9749
9750			//Store the helper's css position
9751			this.cssPosition = this.helper.css("position");
9752			this.scrollParent = this.helper.scrollParent(true);
9753			this.offsetParent = this.helper.offsetParent();
9754			this.hasFixedAncestor = this.helper.parents().filter(function () {
9755				return $(this).css("position") === "fixed";
9756			}).length > 0;
9757
9758			//The element's absolute position on the page minus margins
9759			this.positionAbs = this.element.offset();
9760			this._refreshOffsets(event);
9761
9762			//Generate the original position
9763			this.originalPosition = this.position = this._generatePosition(event, false);
9764			this.originalPageX = event.pageX;
9765			this.originalPageY = event.pageY;
9766
9767			//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
9768			if (o.cursorAt) {
9769				this._adjustOffsetFromHelper(o.cursorAt);
9770			}
9771
9772			//Set a containment if given in the options
9773			this._setContainment();
9774
9775			//Trigger event + callbacks
9776			if (this._trigger("start", event) === false) {
9777				this._clear();
9778				return false;
9779			}
9780
9781			//Recache the helper size
9782			this._cacheHelperProportions();
9783
9784			//Prepare the droppable offsets
9785			if ($.ui.ddmanager && !o.dropBehaviour) {
9786				$.ui.ddmanager.prepareOffsets(this, event);
9787			}
9788
9789			// Execute the drag once - this causes the helper not to be visible before getting its
9790			// correct position
9791			this._mouseDrag(event, true);
9792
9793			// If the ddmanager is used for droppables, inform the manager that dragging has started
9794			// (see #5003)
9795			if ($.ui.ddmanager) {
9796				$.ui.ddmanager.dragStart(this, event);
9797			}
9798
9799			return true;
9800		},
9801
9802		_refreshOffsets: function (event) {
9803			this.offset = {
9804				top: this.positionAbs.top - this.margins.top,
9805				left: this.positionAbs.left - this.margins.left,
9806				scroll: false,
9807				parent: this._getParentOffset(),
9808				relative: this._getRelativeOffset()
9809			};
9810
9811			this.offset.click = {
9812				left: event.pageX - this.offset.left,
9813				top: event.pageY - this.offset.top
9814			};
9815		},
9816
9817		_mouseDrag: function (event, noPropagation) {
9818
9819			// reset any necessary cached properties (see #5009)
9820			if (this.hasFixedAncestor) {
9821				this.offset.parent = this._getParentOffset();
9822			}
9823
9824			//Compute the helpers position
9825			this.position = this._generatePosition(event, true);
9826			this.positionAbs = this._convertPositionTo("absolute");
9827
9828			//Call plugins and callbacks and use the resulting position if something is returned
9829			if (!noPropagation) {
9830				var ui = this._uiHash();
9831				if (this._trigger("drag", event, ui) === false) {
9832					this._mouseUp(new $.Event("mouseup", event));
9833					return false;
9834				}
9835				this.position = ui.position;
9836			}
9837
9838			this.helper[0].style.left = this.position.left + "px";
9839			this.helper[0].style.top = this.position.top + "px";
9840
9841			if ($.ui.ddmanager) {
9842				$.ui.ddmanager.drag(this, event);
9843			}
9844
9845			return false;
9846		},
9847
9848		_mouseStop: function (event) {
9849
9850			//If we are using droppables, inform the manager about the drop
9851			var that = this,
9852				dropped = false;
9853			if ($.ui.ddmanager && !this.options.dropBehaviour) {
9854				dropped = $.ui.ddmanager.drop(this, event);
9855			}
9856
9857			//if a drop comes from outside (a sortable)
9858			if (this.dropped) {
9859				dropped = this.dropped;
9860				this.dropped = false;
9861			}
9862
9863			if ((this.options.revert === "invalid" && !dropped) ||
9864				(this.options.revert === "valid" && dropped) ||
9865				this.options.revert === true || (typeof this.options.revert === "function" &&
9866					this.options.revert.call(this.element, dropped))
9867			) {
9868				$(this.helper).animate(
9869					this.originalPosition,
9870					parseInt(this.options.revertDuration, 10),
9871					function () {
9872						if (that._trigger("stop", event) !== false) {
9873							that._clear();
9874						}
9875					}
9876				);
9877			} else {
9878				if (this._trigger("stop", event) !== false) {
9879					this._clear();
9880				}
9881			}
9882
9883			return false;
9884		},
9885
9886		_mouseUp: function (event) {
9887			this._unblockFrames();
9888
9889			// If the ddmanager is used for droppables, inform the manager that dragging has stopped
9890			// (see #5003)
9891			if ($.ui.ddmanager) {
9892				$.ui.ddmanager.dragStop(this, event);
9893			}
9894
9895			// Only need to focus if the event occurred on the draggable itself, see #10527
9896			if (this.handleElement.is(event.target)) {
9897
9898				// The interaction is over; whether or not the click resulted in a drag,
9899				// focus the element
9900				this.element.trigger("focus");
9901			}
9902
9903			return $.ui.mouse.prototype._mouseUp.call(this, event);
9904		},
9905
9906		cancel: function () {
9907
9908			if (this.helper.is(".ui-draggable-dragging")) {
9909				this._mouseUp(new $.Event("mouseup", { target: this.element[0] }));
9910			} else {
9911				this._clear();
9912			}
9913
9914			return this;
9915
9916		},
9917
9918		_getHandle: function (event) {
9919			return this.options.handle ?
9920				!!$(event.target).closest(this.element.find(this.options.handle)).length :
9921				true;
9922		},
9923
9924		_setHandleClassName: function () {
9925			this.handleElement = this.options.handle ?
9926				this.element.find(this.options.handle) : this.element;
9927			this._addClass(this.handleElement, "ui-draggable-handle");
9928		},
9929
9930		_removeHandleClassName: function () {
9931			this._removeClass(this.handleElement, "ui-draggable-handle");
9932		},
9933
9934		_createHelper: function (event) {
9935
9936			var o = this.options,
9937				helperIsFunction = typeof o.helper === "function",
9938				helper = helperIsFunction ?
9939					$(o.helper.apply(this.element[0], [event])) :
9940					(o.helper === "clone" ?
9941						this.element.clone().removeAttr("id") :
9942						this.element);
9943
9944			if (!helper.parents("body").length) {
9945				helper.appendTo((o.appendTo === "parent" ?
9946					this.element[0].parentNode :
9947					o.appendTo));
9948			}
9949
9950			// https://bugs.jqueryui.com/ticket/9446
9951			// a helper function can return the original element
9952			// which wouldn't have been set to relative in _create
9953			if (helperIsFunction && helper[0] === this.element[0]) {
9954				this._setPositionRelative();
9955			}
9956
9957			if (helper[0] !== this.element[0] &&
9958				!(/(fixed|absolute)/).test(helper.css("position"))) {
9959				helper.css("position", "absolute");
9960			}
9961
9962			return helper;
9963
9964		},
9965
9966		_setPositionRelative: function () {
9967			if (!(/^(?:r|a|f)/).test(this.element.css("position"))) {
9968				this.element[0].style.position = "relative";
9969			}
9970		},
9971
9972		_adjustOffsetFromHelper: function (obj) {
9973			if (typeof obj === "string") {
9974				obj = obj.split(" ");
9975			}
9976			if (Array.isArray(obj)) {
9977				obj = { left: +obj[0], top: +obj[1] || 0 };
9978			}
9979			if ("left" in obj) {
9980				this.offset.click.left = obj.left + this.margins.left;
9981			}
9982			if ("right" in obj) {
9983				this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
9984			}
9985			if ("top" in obj) {
9986				this.offset.click.top = obj.top + this.margins.top;
9987			}
9988			if ("bottom" in obj) {
9989				this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
9990			}
9991		},
9992
9993		_isRootNode: function (element) {
9994			return (/(html|body)/i).test(element.tagName) || element === this.document[0];
9995		},
9996
9997		_getParentOffset: function () {
9998
9999			//Get the offsetParent and cache its position
10000			var po = this.offsetParent.offset(),
10001				document = this.document[0];
10002
10003			// This is a special case where we need to modify a offset calculated on start, since the
10004			// following happened:
10005			// 1. The position of the helper is absolute, so it's position is calculated based on the
10006			// next positioned parent
10007			// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
10008			// the document, which means that the scroll is included in the initial calculation of the
10009			// offset of the parent, and never recalculated upon drag
10010			if (this.cssPosition === "absolute" && this.scrollParent[0] !== document &&
10011				$.contains(this.scrollParent[0], this.offsetParent[0])) {
10012				po.left += this.scrollParent.scrollLeft();
10013				po.top += this.scrollParent.scrollTop();
10014			}
10015
10016			if (this._isRootNode(this.offsetParent[0])) {
10017				po = { top: 0, left: 0 };
10018			}
10019
10020			return {
10021				top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
10022				left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
10023			};
10024
10025		},
10026
10027		_getRelativeOffset: function () {
10028			if (this.cssPosition !== "relative") {
10029				return { top: 0, left: 0 };
10030			}
10031
10032			var p = this.element.position(),
10033				scrollIsRootNode = this._isRootNode(this.scrollParent[0]);
10034
10035			return {
10036				top: p.top - (parseInt(this.helper.css("top"), 10) || 0) +
10037					(!scrollIsRootNode ? this.scrollParent.scrollTop() : 0),
10038				left: p.left - (parseInt(this.helper.css("left"), 10) || 0) +
10039					(!scrollIsRootNode ? this.scrollParent.scrollLeft() : 0)
10040			};
10041
10042		},
10043
10044		_cacheMargins: function () {
10045			this.margins = {
10046				left: (parseInt(this.element.css("marginLeft"), 10) || 0),
10047				top: (parseInt(this.element.css("marginTop"), 10) || 0),
10048				right: (parseInt(this.element.css("marginRight"), 10) || 0),
10049				bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
10050			};
10051		},
10052
10053		_cacheHelperProportions: function () {
10054			this.helperProportions = {
10055				width: this.helper.outerWidth(),
10056				height: this.helper.outerHeight()
10057			};
10058		},
10059
10060		_setContainment: function () {
10061
10062			var isUserScrollable, c, ce,
10063				o = this.options,
10064				document = this.document[0];
10065
10066			this.relativeContainer = null;
10067
10068			if (!o.containment) {
10069				this.containment = null;
10070				return;
10071			}
10072
10073			if (o.containment === "window") {
10074				this.containment = [
10075					$(window).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
10076					$(window).scrollTop() - this.offset.relative.top - this.offset.parent.top,
10077					$(window).scrollLeft() + $(window).width() -
10078					this.helperProportions.width - this.margins.left,
10079					$(window).scrollTop() +
10080					($(window).height() || document.body.parentNode.scrollHeight) -
10081					this.helperProportions.height - this.margins.top
10082				];
10083				return;
10084			}
10085
10086			if (o.containment === "document") {
10087				this.containment = [
10088					0,
10089					0,
10090					$(document).width() - this.helperProportions.width - this.margins.left,
10091					($(document).height() || document.body.parentNode.scrollHeight) -
10092					this.helperProportions.height - this.margins.top
10093				];
10094				return;
10095			}
10096
10097			if (o.containment.constructor === Array) {
10098				this.containment = o.containment;
10099				return;
10100			}
10101
10102			if (o.containment === "parent") {
10103				o.containment = this.helper[0].parentNode;
10104			}
10105
10106			c = $(o.containment);
10107			ce = c[0];
10108
10109			if (!ce) {
10110				return;
10111			}
10112
10113			isUserScrollable = /(scroll|auto)/.test(c.css("overflow"));
10114
10115			this.containment = [
10116				(parseInt(c.css("borderLeftWidth"), 10) || 0) +
10117				(parseInt(c.css("paddingLeft"), 10) || 0),
10118				(parseInt(c.css("borderTopWidth"), 10) || 0) +
10119				(parseInt(c.css("paddingTop"), 10) || 0),
10120				(isUserScrollable ? Math.max(ce.scrollWidth, ce.offsetWidth) : ce.offsetWidth) -
10121				(parseInt(c.css("borderRightWidth"), 10) || 0) -
10122				(parseInt(c.css("paddingRight"), 10) || 0) -
10123				this.helperProportions.width -
10124				this.margins.left -
10125				this.margins.right,
10126				(isUserScrollable ? Math.max(ce.scrollHeight, ce.offsetHeight) : ce.offsetHeight) -
10127				(parseInt(c.css("borderBottomWidth"), 10) || 0) -
10128				(parseInt(c.css("paddingBottom"), 10) || 0) -
10129				this.helperProportions.height -
10130				this.margins.top -
10131				this.margins.bottom
10132			];
10133			this.relativeContainer = c;
10134		},
10135
10136		_convertPositionTo: function (d, pos) {
10137
10138			if (!pos) {
10139				pos = this.position;
10140			}
10141
10142			var mod = d === "absolute" ? 1 : -1,
10143				scrollIsRootNode = this._isRootNode(this.scrollParent[0]);
10144
10145			return {
10146				top: (
10147
10148					// The absolute mouse position
10149					pos.top +
10150
10151					// Only for relative positioned nodes: Relative offset from element to offset parent
10152					this.offset.relative.top * mod +
10153
10154					// The offsetParent's offset without borders (offset + border)
10155					this.offset.parent.top * mod -
10156					((this.cssPosition === "fixed" ?
10157						-this.offset.scroll.top :
10158						(scrollIsRootNode ? 0 : this.offset.scroll.top)) * mod)
10159				),
10160				left: (
10161
10162					// The absolute mouse position
10163					pos.left +
10164
10165					// Only for relative positioned nodes: Relative offset from element to offset parent
10166					this.offset.relative.left * mod +
10167
10168					// The offsetParent's offset without borders (offset + border)
10169					this.offset.parent.left * mod -
10170					((this.cssPosition === "fixed" ?
10171						-this.offset.scroll.left :
10172						(scrollIsRootNode ? 0 : this.offset.scroll.left)) * mod)
10173				)
10174			};
10175
10176		},
10177
10178		_generatePosition: function (event, constrainPosition) {
10179
10180			var containment, co, top, left,
10181				o = this.options,
10182				scrollIsRootNode = this._isRootNode(this.scrollParent[0]),
10183				pageX = event.pageX,
10184				pageY = event.pageY;
10185
10186			// Cache the scroll
10187			if (!scrollIsRootNode || !this.offset.scroll) {
10188				this.offset.scroll = {
10189					top: this.scrollParent.scrollTop(),
10190					left: this.scrollParent.scrollLeft()
10191				};
10192			}
10193
10194			/*
10195			 * - Position constraining -
10196			 * Constrain the position to a mix of grid, containment.
10197			 */
10198
10199			// If we are not dragging yet, we won't check for options
10200			if (constrainPosition) {
10201				if (this.containment) {
10202					if (this.relativeContainer) {
10203						co = this.relativeContainer.offset();
10204						containment = [
10205							this.containment[0] + co.left,
10206							this.containment[1] + co.top,
10207							this.containment[2] + co.left,
10208							this.containment[3] + co.top
10209						];
10210					} else {
10211						containment = this.containment;
10212					}
10213
10214					if (event.pageX - this.offset.click.left < containment[0]) {
10215						pageX = containment[0] + this.offset.click.left;
10216					}
10217					if (event.pageY - this.offset.click.top < containment[1]) {
10218						pageY = containment[1] + this.offset.click.top;
10219					}
10220					if (event.pageX - this.offset.click.left > containment[2]) {
10221						pageX = containment[2] + this.offset.click.left;
10222					}
10223					if (event.pageY - this.offset.click.top > containment[3]) {
10224						pageY = containment[3] + this.offset.click.top;
10225					}
10226				}
10227
10228				if (o.grid) {
10229
10230					//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
10231					// argument errors in IE (see ticket #6950)
10232					top = o.grid[1] ? this.originalPageY + Math.round((pageY -
10233						this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
10234					pageY = containment ? ((top - this.offset.click.top >= containment[1] ||
10235						top - this.offset.click.top > containment[3]) ?
10236						top :
10237						((top - this.offset.click.top >= containment[1]) ?
10238							top - o.grid[1] : top + o.grid[1])) : top;
10239
10240					left = o.grid[0] ? this.originalPageX +
10241						Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] :
10242						this.originalPageX;
10243					pageX = containment ? ((left - this.offset.click.left >= containment[0] ||
10244						left - this.offset.click.left > containment[2]) ?
10245						left :
10246						((left - this.offset.click.left >= containment[0]) ?
10247							left - o.grid[0] : left + o.grid[0])) : left;
10248				}
10249
10250				if (o.axis === "y") {
10251					pageX = this.originalPageX;
10252				}
10253
10254				if (o.axis === "x") {
10255					pageY = this.originalPageY;
10256				}
10257			}
10258
10259			return {
10260				top: (
10261
10262					// The absolute mouse position
10263					pageY -
10264
10265					// Click offset (relative to the element)
10266					this.offset.click.top -
10267
10268					// Only for relative positioned nodes: Relative offset from element to offset parent
10269					this.offset.relative.top -
10270
10271					// The offsetParent's offset without borders (offset + border)
10272					this.offset.parent.top +
10273					(this.cssPosition === "fixed" ?
10274						-this.offset.scroll.top :
10275						(scrollIsRootNode ? 0 : this.offset.scroll.top))
10276				),
10277				left: (
10278
10279					// The absolute mouse position
10280					pageX -
10281
10282					// Click offset (relative to the element)
10283					this.offset.click.left -
10284
10285					// Only for relative positioned nodes: Relative offset from element to offset parent
10286					this.offset.relative.left -
10287
10288					// The offsetParent's offset without borders (offset + border)
10289					this.offset.parent.left +
10290					(this.cssPosition === "fixed" ?
10291						-this.offset.scroll.left :
10292						(scrollIsRootNode ? 0 : this.offset.scroll.left))
10293				)
10294			};
10295
10296		},
10297
10298		_clear: function () {
10299			this._removeClass(this.helper, "ui-draggable-dragging");
10300			if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
10301				this.helper.remove();
10302			}
10303			this.helper = null;
10304			this.cancelHelperRemoval = false;
10305			if (this.destroyOnClear) {
10306				this.destroy();
10307			}
10308		},
10309
10310		// From now on bulk stuff - mainly helpers
10311
10312		_trigger: function (type, event, ui) {
10313			ui = ui || this._uiHash();
10314			$.ui.plugin.call(this, type, [event, ui, this], true);
10315
10316			// Absolute position and offset (see #6884 ) have to be recalculated after plugins
10317			if (/^(drag|start|stop)/.test(type)) {
10318				this.positionAbs = this._convertPositionTo("absolute");
10319				ui.offset = this.positionAbs;
10320			}
10321			return $.Widget.prototype._trigger.call(this, type, event, ui);
10322		},
10323
10324		plugins: {},
10325
10326		_uiHash: function () {
10327			return {
10328				helper: this.helper,
10329				position: this.position,
10330				originalPosition: this.originalPosition,
10331				offset: this.positionAbs
10332			};
10333		}
10334
10335	});
10336
10337	$.ui.plugin.add("draggable", "connectToSortable", {
10338		start: function (event, ui, draggable) {
10339			var uiSortable = $.extend({}, ui, {
10340				item: draggable.element
10341			});
10342
10343			draggable.sortables = [];
10344			$(draggable.options.connectToSortable).each(function () {
10345				var sortable = $(this).sortable("instance");
10346
10347				if (sortable && !sortable.options.disabled) {
10348					draggable.sortables.push(sortable);
10349
10350					// RefreshPositions is called at drag start to refresh the containerCache
10351					// which is used in drag. This ensures it's initialized and synchronized
10352					// with any changes that might have happened on the page since initialization.
10353					sortable.refreshPositions();
10354					sortable._trigger("activate", event, uiSortable);
10355				}
10356			});
10357		},
10358		stop: function (event, ui, draggable) {
10359			var uiSortable = $.extend({}, ui, {
10360				item: draggable.element
10361			});
10362
10363			draggable.cancelHelperRemoval = false;
10364
10365			$.each(draggable.sortables, function () {
10366				var sortable = this;
10367
10368				if (sortable.isOver) {
10369					sortable.isOver = 0;
10370
10371					// Allow this sortable to handle removing the helper
10372					draggable.cancelHelperRemoval = true;
10373					sortable.cancelHelperRemoval = false;
10374
10375					// Use _storedCSS To restore properties in the sortable,
10376					// as this also handles revert (#9675) since the draggable
10377					// may have modified them in unexpected ways (#8809)
10378					sortable._storedCSS = {
10379						position: sortable.placeholder.css("position"),
10380						top: sortable.placeholder.css("top"),
10381						left: sortable.placeholder.css("left")
10382					};
10383
10384					sortable._mouseStop(event);
10385
10386					// Once drag has ended, the sortable should return to using
10387					// its original helper, not the shared helper from draggable
10388					sortable.options.helper = sortable.options._helper;
10389				} else {
10390
10391					// Prevent this Sortable from removing the helper.
10392					// However, don't set the draggable to remove the helper
10393					// either as another connected Sortable may yet handle the removal.
10394					sortable.cancelHelperRemoval = true;
10395
10396					sortable._trigger("deactivate", event, uiSortable);
10397				}
10398			});
10399		},
10400		drag: function (event, ui, draggable) {
10401			$.each(draggable.sortables, function () {
10402				var innermostIntersecting = false,
10403					sortable = this;
10404
10405				// Copy over variables that sortable's _intersectsWith uses
10406				sortable.positionAbs = draggable.positionAbs;
10407				sortable.helperProportions = draggable.helperProportions;
10408				sortable.offset.click = draggable.offset.click;
10409
10410				if (sortable._intersectsWith(sortable.containerCache)) {
10411					innermostIntersecting = true;
10412
10413					$.each(draggable.sortables, function () {
10414
10415						// Copy over variables that sortable's _intersectsWith uses
10416						this.positionAbs = draggable.positionAbs;
10417						this.helperProportions = draggable.helperProportions;
10418						this.offset.click = draggable.offset.click;
10419
10420						if (this !== sortable &&
10421							this._intersectsWith(this.containerCache) &&
10422							$.contains(sortable.element[0], this.element[0])) {
10423							innermostIntersecting = false;
10424						}
10425
10426						return innermostIntersecting;
10427					});
10428				}
10429
10430				if (innermostIntersecting) {
10431
10432					// If it intersects, we use a little isOver variable and set it once,
10433					// so that the move-in stuff gets fired only once.
10434					if (!sortable.isOver) {
10435						sortable.isOver = 1;
10436
10437						// Store draggable's parent in case we need to reappend to it later.
10438						draggable._parent = ui.helper.parent();
10439
10440						sortable.currentItem = ui.helper
10441							.appendTo(sortable.element)
10442							.data("ui-sortable-item", true);
10443
10444						// Store helper option to later restore it
10445						sortable.options._helper = sortable.options.helper;
10446
10447						sortable.options.helper = function () {
10448							return ui.helper[0];
10449						};
10450
10451						// Fire the start events of the sortable with our passed browser event,
10452						// and our own helper (so it doesn't create a new one)
10453						event.target = sortable.currentItem[0];
10454						sortable._mouseCapture(event, true);
10455						sortable._mouseStart(event, true, true);
10456
10457						// Because the browser event is way off the new appended portlet,
10458						// modify necessary variables to reflect the changes
10459						sortable.offset.click.top = draggable.offset.click.top;
10460						sortable.offset.click.left = draggable.offset.click.left;
10461						sortable.offset.parent.left -= draggable.offset.parent.left -
10462							sortable.offset.parent.left;
10463						sortable.offset.parent.top -= draggable.offset.parent.top -
10464							sortable.offset.parent.top;
10465
10466						draggable._trigger("toSortable", event);
10467
10468						// Inform draggable that the helper is in a valid drop zone,
10469						// used solely in the revert option to handle "valid/invalid".
10470						draggable.dropped = sortable.element;
10471
10472						// Need to refreshPositions of all sortables in the case that
10473						// adding to one sortable changes the location of the other sortables (#9675)
10474						$.each(draggable.sortables, function () {
10475							this.refreshPositions();
10476						});
10477
10478						// Hack so receive/update callbacks work (mostly)
10479						draggable.currentItem = draggable.element;
10480						sortable.fromOutside = draggable;
10481					}
10482
10483					if (sortable.currentItem) {
10484						sortable._mouseDrag(event);
10485
10486						// Copy the sortable's position because the draggable's can potentially reflect
10487						// a relative position, while sortable is always absolute, which the dragged
10488						// element has now become. (#8809)
10489						ui.position = sortable.position;
10490					}
10491				} else {
10492
10493					// If it doesn't intersect with the sortable, and it intersected before,
10494					// we fake the drag stop of the sortable, but make sure it doesn't remove
10495					// the helper by using cancelHelperRemoval.
10496					if (sortable.isOver) {
10497
10498						sortable.isOver = 0;
10499						sortable.cancelHelperRemoval = true;
10500
10501						// Calling sortable's mouseStop would trigger a revert,
10502						// so revert must be temporarily false until after mouseStop is called.
10503						sortable.options._revert = sortable.options.revert;
10504						sortable.options.revert = false;
10505
10506						sortable._trigger("out", event, sortable._uiHash(sortable));
10507						sortable._mouseStop(event, true);
10508
10509						// Restore sortable behaviors that were modfied
10510						// when the draggable entered the sortable area (#9481)
10511						sortable.options.revert = sortable.options._revert;
10512						sortable.options.helper = sortable.options._helper;
10513
10514						if (sortable.placeholder) {
10515							sortable.placeholder.remove();
10516						}
10517
10518						// Restore and recalculate the draggable's offset considering the sortable
10519						// may have modified them in unexpected ways. (#8809, #10669)
10520						ui.helper.appendTo(draggable._parent);
10521						draggable._refreshOffsets(event);
10522						ui.position = draggable._generatePosition(event, true);
10523
10524						draggable._trigger("fromSortable", event);
10525
10526						// Inform draggable that the helper is no longer in a valid drop zone
10527						draggable.dropped = false;
10528
10529						// Need to refreshPositions of all sortables just in case removing
10530						// from one sortable changes the location of other sortables (#9675)
10531						$.each(draggable.sortables, function () {
10532							this.refreshPositions();
10533						});
10534					}
10535				}
10536			});
10537		}
10538	});
10539
10540	$.ui.plugin.add("draggable", "cursor", {
10541		start: function (event, ui, instance) {
10542			var t = $("body"),
10543				o = instance.options;
10544
10545			if (t.css("cursor")) {
10546				o._cursor = t.css("cursor");
10547			}
10548			t.css("cursor", o.cursor);
10549		},
10550		stop: function (event, ui, instance) {
10551			var o = instance.options;
10552			if (o._cursor) {
10553				$("body").css("cursor", o._cursor);
10554			}
10555		}
10556	});
10557
10558	$.ui.plugin.add("draggable", "opacity", {
10559		start: function (event, ui, instance) {
10560			var t = $(ui.helper),
10561				o = instance.options;
10562			if (t.css("opacity")) {
10563				o._opacity = t.css("opacity");
10564			}
10565			t.css("opacity", o.opacity);
10566		},
10567		stop: function (event, ui, instance) {
10568			var o = instance.options;
10569			if (o._opacity) {
10570				$(ui.helper).css("opacity", o._opacity);
10571			}
10572		}
10573	});
10574
10575	$.ui.plugin.add("draggable", "scroll", {
10576		start: function (event, ui, i) {
10577			if (!i.scrollParentNotHidden) {
10578				i.scrollParentNotHidden = i.helper.scrollParent(false);
10579			}
10580
10581			if (i.scrollParentNotHidden[0] !== i.document[0] &&
10582				i.scrollParentNotHidden[0].tagName !== "HTML") {
10583				i.overflowOffset = i.scrollParentNotHidden.offset();
10584			}
10585		},
10586		drag: function (event, ui, i) {
10587
10588			var o = i.options,
10589				scrolled = false,
10590				scrollParent = i.scrollParentNotHidden[0],
10591				document = i.document[0];
10592
10593			if (scrollParent !== document && scrollParent.tagName !== "HTML") {
10594				if (!o.axis || o.axis !== "x") {
10595					if ((i.overflowOffset.top + scrollParent.offsetHeight) - event.pageY <
10596						o.scrollSensitivity) {
10597						scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
10598					} else if (event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
10599						scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
10600					}
10601				}
10602
10603				if (!o.axis || o.axis !== "y") {
10604					if ((i.overflowOffset.left + scrollParent.offsetWidth) - event.pageX <
10605						o.scrollSensitivity) {
10606						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
10607					} else if (event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
10608						scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
10609					}
10610				}
10611
10612			} else {
10613
10614				if (!o.axis || o.axis !== "x") {
10615					if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
10616						scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
10617					} else if ($(window).height() - (event.pageY - $(document).scrollTop()) <
10618						o.scrollSensitivity) {
10619						scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
10620					}
10621				}
10622
10623				if (!o.axis || o.axis !== "y") {
10624					if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
10625						scrolled = $(document).scrollLeft(
10626							$(document).scrollLeft() - o.scrollSpeed
10627						);
10628					} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) <
10629						o.scrollSensitivity) {
10630						scrolled = $(document).scrollLeft(
10631							$(document).scrollLeft() + o.scrollSpeed
10632						);
10633					}
10634				}
10635
10636			}
10637
10638			if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
10639				$.ui.ddmanager.prepareOffsets(i, event);
10640			}
10641
10642		}
10643	});
10644
10645	$.ui.plugin.add("draggable", "snap", {
10646		start: function (event, ui, i) {
10647
10648			var o = i.options;
10649
10650			i.snapElements = [];
10651
10652			$(o.snap.constructor !== String ? (o.snap.items || ":data(ui-draggable)") : o.snap)
10653				.each(function () {
10654					var $t = $(this),
10655						$o = $t.offset();
10656					if (this !== i.element[0]) {
10657						i.snapElements.push({
10658							item: this,
10659							width: $t.outerWidth(), height: $t.outerHeight(),
10660							top: $o.top, left: $o.left
10661						});
10662					}
10663				});
10664
10665		},
10666		drag: function (event, ui, inst) {
10667
10668			var ts, bs, ls, rs, l, r, t, b, i, first,
10669				o = inst.options,
10670				d = o.snapTolerance,
10671				x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
10672				y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
10673
10674			for (i = inst.snapElements.length - 1; i >= 0; i--) {
10675
10676				l = inst.snapElements[i].left - inst.margins.left;
10677				r = l + inst.snapElements[i].width;
10678				t = inst.snapElements[i].top - inst.margins.top;
10679				b = t + inst.snapElements[i].height;
10680
10681				if (x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
10682					!$.contains(inst.snapElements[i].item.ownerDocument,
10683						inst.snapElements[i].item)) {
10684					if (inst.snapElements[i].snapping) {
10685						if (inst.options.snap.release) {
10686							inst.options.snap.release.call(
10687								inst.element,
10688								event,
10689								$.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })
10690							);
10691						}
10692					}
10693					inst.snapElements[i].snapping = false;
10694					continue;
10695				}
10696
10697				if (o.snapMode !== "inner") {
10698					ts = Math.abs(t - y2) <= d;
10699					bs = Math.abs(b - y1) <= d;
10700					ls = Math.abs(l - x2) <= d;
10701					rs = Math.abs(r - x1) <= d;
10702					if (ts) {
10703						ui.position.top = inst._convertPositionTo("relative", {
10704							top: t - inst.helperProportions.height,
10705							left: 0
10706						}).top;
10707					}
10708					if (bs) {
10709						ui.position.top = inst._convertPositionTo("relative", {
10710							top: b,
10711							left: 0
10712						}).top;
10713					}
10714					if (ls) {
10715						ui.position.left = inst._convertPositionTo("relative", {
10716							top: 0,
10717							left: l - inst.helperProportions.width
10718						}).left;
10719					}
10720					if (rs) {
10721						ui.position.left = inst._convertPositionTo("relative", {
10722							top: 0,
10723							left: r
10724						}).left;
10725					}
10726				}
10727
10728				first = (ts || bs || ls || rs);
10729
10730				if (o.snapMode !== "outer") {
10731					ts = Math.abs(t - y1) <= d;
10732					bs = Math.abs(b - y2) <= d;
10733					ls = Math.abs(l - x1) <= d;
10734					rs = Math.abs(r - x2) <= d;
10735					if (ts) {
10736						ui.position.top = inst._convertPositionTo("relative", {
10737							top: t,
10738							left: 0
10739						}).top;
10740					}
10741					if (bs) {
10742						ui.position.top = inst._convertPositionTo("relative", {
10743							top: b - inst.helperProportions.height,
10744							left: 0
10745						}).top;
10746					}
10747					if (ls) {
10748						ui.position.left = inst._convertPositionTo("relative", {
10749							top: 0,
10750							left: l
10751						}).left;
10752					}
10753					if (rs) {
10754						ui.position.left = inst._convertPositionTo("relative", {
10755							top: 0,
10756							left: r - inst.helperProportions.width
10757						}).left;
10758					}
10759				}
10760
10761				if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
10762					if (inst.options.snap.snap) {
10763						inst.options.snap.snap.call(
10764							inst.element,
10765							event,
10766							$.extend(inst._uiHash(), {
10767								snapItem: inst.snapElements[i].item
10768							}));
10769					}
10770				}
10771				inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
10772
10773			}
10774
10775		}
10776	});
10777
10778	$.ui.plugin.add("draggable", "stack", {
10779		start: function (event, ui, instance) {
10780			var min,
10781				o = instance.options,
10782				group = $.makeArray($(o.stack)).sort(function (a, b) {
10783					return (parseInt($(a).css("zIndex"), 10) || 0) -
10784						(parseInt($(b).css("zIndex"), 10) || 0);
10785				});
10786
10787			if (!group.length) {
10788				return;
10789			}
10790
10791			min = parseInt($(group[0]).css("zIndex"), 10) || 0;
10792			$(group).each(function (i) {
10793				$(this).css("zIndex", min + i);
10794			});
10795			this.css("zIndex", (min + group.length));
10796		}
10797	});
10798
10799	$.ui.plugin.add("draggable", "zIndex", {
10800		start: function (event, ui, instance) {
10801			var t = $(ui.helper),
10802				o = instance.options;
10803
10804			if (t.css("zIndex")) {
10805				o._zIndex = t.css("zIndex");
10806			}
10807			t.css("zIndex", o.zIndex);
10808		},
10809		stop: function (event, ui, instance) {
10810			var o = instance.options;
10811
10812			if (o._zIndex) {
10813				$(ui.helper).css("zIndex", o._zIndex);
10814			}
10815		}
10816	});
10817
10818	var widgetsDraggable = $.ui.draggable;
10819
10820
10821	/*!
10822	 * jQuery UI Resizable 1.14.1
10823	 * https://jqueryui.com
10824	 *
10825	 * Copyright OpenJS Foundation and other contributors
10826	 * Released under the MIT license.
10827	 * https://jquery.org/license
10828	 */
10829
10830	//>>label: Resizable
10831	//>>group: Interactions
10832	//>>description: Enables resize functionality for any element.
10833	//>>docs: https://api.jqueryui.com/resizable/
10834	//>>demos: https://jqueryui.com/resizable/
10835	//>>css.structure: ../../themes/base/core.css
10836	//>>css.structure: ../../themes/base/resizable.css
10837	//>>css.theme: ../../themes/base/theme.css
10838
10839
10840	$.widget("ui.resizable", $.ui.mouse, {
10841		version: "1.14.1",
10842		widgetEventPrefix: "resize",
10843		options: {
10844			alsoResize: false,
10845			animate: false,
10846			animateDuration: "slow",
10847			animateEasing: "swing",
10848			aspectRatio: false,
10849			autoHide: false,
10850			classes: {
10851				"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
10852			},
10853			containment: false,
10854			ghost: false,
10855			grid: false,
10856			handles: "e,s,se",
10857			helper: false,
10858			maxHeight: null,
10859			maxWidth: null,
10860			minHeight: 10,
10861			minWidth: 10,
10862
10863			// See #7960
10864			zIndex: 90,
10865
10866			// Callbacks
10867			resize: null,
10868			start: null,
10869			stop: null
10870		},
10871
10872		_num: function (value) {
10873			return parseFloat(value) || 0;
10874		},
10875
10876		_isNumber: function (value) {
10877			return !isNaN(parseFloat(value));
10878		},
10879
10880		_hasScroll: function (el, a) {
10881
10882			var scroll,
10883				has = false,
10884				overflow = $(el).css("overflow");
10885
10886			if (overflow === "hidden") {
10887				return false;
10888			}
10889			if (overflow === "scroll") {
10890				return true;
10891			}
10892
10893			scroll = (a && a === "left") ? "scrollLeft" : "scrollTop";
10894
10895			if (el[scroll] > 0) {
10896				return true;
10897			}
10898
10899			// TODO: determine which cases actually cause this to happen
10900			// if the element doesn't have the scroll set, see if it's possible to
10901			// set the scroll
10902			try {
10903				el[scroll] = 1;
10904				has = (el[scroll] > 0);
10905				el[scroll] = 0;
10906			} catch (e) {
10907
10908				// `el` might be a string, then setting `scroll` will throw
10909				// an error in strict mode; ignore it.
10910			}
10911			return has;
10912		},
10913
10914		_create: function () {
10915
10916			var margins,
10917				o = this.options,
10918				that = this;
10919			this._addClass("ui-resizable");
10920
10921			$.extend(this, {
10922				_aspectRatio: !!(o.aspectRatio),
10923				aspectRatio: o.aspectRatio,
10924				originalElement: this.element,
10925				_proportionallyResizeElements: [],
10926				_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
10927			});
10928
10929			// Wrap the element if it cannot hold child nodes
10930			if (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {
10931
10932				this.element.wrap(
10933					$("<div class='ui-wrapper'></div>").css({
10934						overflow: "hidden",
10935						position: this.element.css("position"),
10936						width: this.element.outerWidth(),
10937						height: this.element.outerHeight(),
10938						top: this.element.css("top"),
10939						left: this.element.css("left")
10940					})
10941				);
10942
10943				this.element = this.element.parent().data(
10944					"ui-resizable", this.element.resizable("instance")
10945				);
10946
10947				this.elementIsWrapper = true;
10948
10949				margins = {
10950					marginTop: this.originalElement.css("marginTop"),
10951					marginRight: this.originalElement.css("marginRight"),
10952					marginBottom: this.originalElement.css("marginBottom"),
10953					marginLeft: this.originalElement.css("marginLeft")
10954				};
10955
10956				this.element.css(margins);
10957
10958				// Support: Safari
10959				// Prevent Safari textarea resize
10960				this.originalResizeStyle = this.originalElement.css("resize");
10961				this.originalElement.css("resize", "none");
10962
10963				this._proportionallyResizeElements.push(this.originalElement.css({
10964					position: "static",
10965					zoom: 1,
10966					display: "block"
10967				}));
10968
10969				this._proportionallyResize();
10970			}
10971
10972			this._setupHandles();
10973
10974			if (o.autoHide) {
10975				$(this.element)
10976					.on("mouseenter", function () {
10977						if (o.disabled) {
10978							return;
10979						}
10980						that._removeClass("ui-resizable-autohide");
10981						that._handles.show();
10982					})
10983					.on("mouseleave", function () {
10984						if (o.disabled) {
10985							return;
10986						}
10987						if (!that.resizing) {
10988							that._addClass("ui-resizable-autohide");
10989							that._handles.hide();
10990						}
10991					});
10992			}
10993
10994			this._mouseInit();
10995		},
10996
10997		_destroy: function () {
10998
10999			this._mouseDestroy();
11000			this._addedHandles.remove();
11001
11002			var wrapper,
11003				_destroy = function (exp) {
11004					$(exp)
11005						.removeData("resizable")
11006						.removeData("ui-resizable")
11007						.off(".resizable");
11008				};
11009
11010			// TODO: Unwrap at same DOM position
11011			if (this.elementIsWrapper) {
11012				_destroy(this.element);
11013				wrapper = this.element;
11014				this.originalElement.css({
11015					position: wrapper.css("position"),
11016					width: wrapper.outerWidth(),
11017					height: wrapper.outerHeight(),
11018					top: wrapper.css("top"),
11019					left: wrapper.css("left")
11020				}).insertAfter(wrapper);
11021				wrapper.remove();
11022			}
11023
11024			this.originalElement.css("resize", this.originalResizeStyle);
11025			_destroy(this.originalElement);
11026
11027			return this;
11028		},
11029
11030		_setOption: function (key, value) {
11031			this._super(key, value);
11032
11033			switch (key) {
11034				case "handles":
11035					this._removeHandles();
11036					this._setupHandles();
11037					break;
11038				case "aspectRatio":
11039					this._aspectRatio = !!value;
11040					break;
11041				default:
11042					break;
11043			}
11044		},
11045
11046		_setupHandles: function () {
11047			var o = this.options, handle, i, n, hname, axis, that = this;
11048			this.handles = o.handles ||
11049				(!$(".ui-resizable-handle", this.element).length ?
11050					"e,s,se" : {
11051						n: ".ui-resizable-n",
11052						e: ".ui-resizable-e",
11053						s: ".ui-resizable-s",
11054						w: ".ui-resizable-w",
11055						se: ".ui-resizable-se",
11056						sw: ".ui-resizable-sw",
11057						ne: ".ui-resizable-ne",
11058						nw: ".ui-resizable-nw"
11059					});
11060
11061			this._handles = $();
11062			this._addedHandles = $();
11063			if (this.handles.constructor === String) {
11064
11065				if (this.handles === "all") {
11066					this.handles = "n,e,s,w,se,sw,ne,nw";
11067				}
11068
11069				n = this.handles.split(",");
11070				this.handles = {};
11071
11072				for (i = 0; i < n.length; i++) {
11073
11074					handle = String.prototype.trim.call(n[i]);
11075					hname = "ui-resizable-" + handle;
11076					axis = $("<div>");
11077					this._addClass(axis, "ui-resizable-handle " + hname);
11078
11079					axis.css({ zIndex: o.zIndex });
11080
11081					this.handles[handle] = ".ui-resizable-" + handle;
11082					if (!this.element.children(this.handles[handle]).length) {
11083						this.element.append(axis);
11084						this._addedHandles = this._addedHandles.add(axis);
11085					}
11086				}
11087
11088			}
11089
11090			this._renderAxis = function (target) {
11091
11092				var i, axis, padPos, padWrapper;
11093
11094				target = target || this.element;
11095
11096				for (i in this.handles) {
11097
11098					if (this.handles[i].constructor === String) {
11099						this.handles[i] = this.element.children(this.handles[i]).first().show();
11100					} else if (this.handles[i].jquery || this.handles[i].nodeType) {
11101						this.handles[i] = $(this.handles[i]);
11102						this._on(this.handles[i], { "mousedown": that._mouseDown });
11103					}
11104
11105					if (this.elementIsWrapper &&
11106						this.originalElement[0]
11107							.nodeName
11108							.match(/^(textarea|input|select|button)$/i)) {
11109						axis = $(this.handles[i], this.element);
11110
11111						padWrapper = /sw|ne|nw|se|n|s/.test(i) ?
11112							axis.outerHeight() :
11113							axis.outerWidth();
11114
11115						padPos = ["padding",
11116							/ne|nw|n/.test(i) ? "Top" :
11117								/se|sw|s/.test(i) ? "Bottom" :
11118									/^e$/.test(i) ? "Right" : "Left"].join("");
11119
11120						target.css(padPos, padWrapper);
11121
11122						this._proportionallyResize();
11123					}
11124
11125					this._handles = this._handles.add(this.handles[i]);
11126				}
11127			};
11128
11129			// TODO: make renderAxis a prototype function
11130			this._renderAxis(this.element);
11131
11132			this._handles = this._handles.add(this.element.find(".ui-resizable-handle"));
11133			this._handles.disableSelection();
11134
11135			this._handles.on("mouseover", function () {
11136				if (!that.resizing) {
11137					if (this.className) {
11138						axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
11139					}
11140					that.axis = axis && axis[1] ? axis[1] : "se";
11141				}
11142			});
11143
11144			if (o.autoHide) {
11145				this._handles.hide();
11146				this._addClass("ui-resizable-autohide");
11147			}
11148		},
11149
11150		_removeHandles: function () {
11151			this._addedHandles.remove();
11152		},
11153
11154		_mouseCapture: function (event) {
11155			var i, handle,
11156				capture = false;
11157
11158			for (i in this.handles) {
11159				handle = $(this.handles[i])[0];
11160				if (handle === event.target || $.contains(handle, event.target)) {
11161					capture = true;
11162				}
11163			}
11164
11165			return !this.options.disabled && capture;
11166		},
11167
11168		_mouseStart: function (event) {
11169
11170			var curleft, curtop, cursor, calculatedSize,
11171				o = this.options,
11172				el = this.element;
11173
11174			this.resizing = true;
11175
11176			this._renderProxy();
11177
11178			curleft = this._num(this.helper.css("left"));
11179			curtop = this._num(this.helper.css("top"));
11180
11181			if (o.containment) {
11182				curleft += $(o.containment).scrollLeft() || 0;
11183				curtop += $(o.containment).scrollTop() || 0;
11184			}
11185
11186			this.offset = this.helper.offset();
11187			this.position = { left: curleft, top: curtop };
11188
11189			if (!this._helper) {
11190				calculatedSize = this._calculateAdjustedElementDimensions(el);
11191			}
11192
11193			this.size = this._helper ? {
11194				width: this.helper.width(),
11195				height: this.helper.height()
11196			} : {
11197				width: calculatedSize.width,
11198				height: calculatedSize.height
11199			};
11200
11201			this.originalSize = this._helper ? {
11202				width: el.outerWidth(),
11203				height: el.outerHeight()
11204			} : {
11205				width: calculatedSize.width,
11206				height: calculatedSize.height
11207			};
11208
11209			this.sizeDiff = {
11210				width: el.outerWidth() - el.width(),
11211				height: el.outerHeight() - el.height()
11212			};
11213
11214			this.originalPosition = { left: curleft, top: curtop };
11215			this.originalMousePosition = { left: event.pageX, top: event.pageY };
11216
11217			this.aspectRatio = (typeof o.aspectRatio === "number") ?
11218				o.aspectRatio :
11219				((this.originalSize.width / this.originalSize.height) || 1);
11220
11221			cursor = $(".ui-resizable-" + this.axis).css("cursor");
11222			$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
11223
11224			this._addClass("ui-resizable-resizing");
11225			this._propagate("start", event);
11226			return true;
11227		},
11228
11229		_mouseDrag: function (event) {
11230
11231			var data, props,
11232				smp = this.originalMousePosition,
11233				a = this.axis,
11234				dx = (event.pageX - smp.left) || 0,
11235				dy = (event.pageY - smp.top) || 0,
11236				trigger = this._change[a];
11237
11238			this._updatePrevProperties();
11239
11240			if (!trigger) {
11241				return false;
11242			}
11243
11244			data = trigger.apply(this, [event, dx, dy]);
11245
11246			this._updateVirtualBoundaries(event.shiftKey);
11247			if (this._aspectRatio || event.shiftKey) {
11248				data = this._updateRatio(data, event);
11249			}
11250
11251			data = this._respectSize(data, event);
11252
11253			this._updateCache(data);
11254
11255			this._propagate("resize", event);
11256
11257			props = this._applyChanges();
11258
11259			if (!this._helper && this._proportionallyResizeElements.length) {
11260				this._proportionallyResize();
11261			}
11262
11263			if (!$.isEmptyObject(props)) {
11264				this._updatePrevProperties();
11265				this._trigger("resize", event, this.ui());
11266				this._applyChanges();
11267			}
11268
11269			return false;
11270		},
11271
11272		_mouseStop: function (event) {
11273
11274			this.resizing = false;
11275			var pr, ista, soffseth, soffsetw, s, left, top,
11276				o = this.options, that = this;
11277
11278			if (this._helper) {
11279
11280				pr = this._proportionallyResizeElements;
11281				ista = pr.length && (/textarea/i).test(pr[0].nodeName);
11282				soffseth = ista && this._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height;
11283				soffsetw = ista ? 0 : that.sizeDiff.width;
11284
11285				s = {
11286					width: (that.helper.width() - soffsetw),
11287					height: (that.helper.height() - soffseth)
11288				};
11289				left = (parseFloat(that.element.css("left")) +
11290					(that.position.left - that.originalPosition.left)) || null;
11291				top = (parseFloat(that.element.css("top")) +
11292					(that.position.top - that.originalPosition.top)) || null;
11293
11294				if (!o.animate) {
11295					this.element.css($.extend(s, { top: top, left: left }));
11296				}
11297
11298				that.helper.height(that.size.height);
11299				that.helper.width(that.size.width);
11300
11301				if (this._helper && !o.animate) {
11302					this._proportionallyResize();
11303				}
11304			}
11305
11306			$("body").css("cursor", "auto");
11307
11308			this._removeClass("ui-resizable-resizing");
11309
11310			this._propagate("stop", event);
11311
11312			if (this._helper) {
11313				this.helper.remove();
11314			}
11315
11316			return false;
11317
11318		},
11319
11320		_updatePrevProperties: function () {
11321			this.prevPosition = {
11322				top: this.position.top,
11323				left: this.position.left
11324			};
11325			this.prevSize = {
11326				width: this.size.width,
11327				height: this.size.height
11328			};
11329		},
11330
11331		_applyChanges: function () {
11332			var props = {};
11333
11334			if (this.position.top !== this.prevPosition.top) {
11335				props.top = this.position.top + "px";
11336			}
11337			if (this.position.left !== this.prevPosition.left) {
11338				props.left = this.position.left + "px";
11339			}
11340
11341			this.helper.css(props);
11342
11343			if (this.size.width !== this.prevSize.width) {
11344				props.width = this.size.width + "px";
11345				this.helper.width(props.width);
11346			}
11347			if (this.size.height !== this.prevSize.height) {
11348				props.height = this.size.height + "px";
11349				this.helper.height(props.height);
11350			}
11351
11352			return props;
11353		},
11354
11355		_updateVirtualBoundaries: function (forceAspectRatio) {
11356			var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
11357				o = this.options;
11358
11359			b = {
11360				minWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,
11361				maxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,
11362				minHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,
11363				maxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity
11364			};
11365
11366			if (this._aspectRatio || forceAspectRatio) {
11367				pMinWidth = b.minHeight * this.aspectRatio;
11368				pMinHeight = b.minWidth / this.aspectRatio;
11369				pMaxWidth = b.maxHeight * this.aspectRatio;
11370				pMaxHeight = b.maxWidth / this.aspectRatio;
11371
11372				if (pMinWidth > b.minWidth) {
11373					b.minWidth = pMinWidth;
11374				}
11375				if (pMinHeight > b.minHeight) {
11376					b.minHeight = pMinHeight;
11377				}
11378				if (pMaxWidth < b.maxWidth) {
11379					b.maxWidth = pMaxWidth;
11380				}
11381				if (pMaxHeight < b.maxHeight) {
11382					b.maxHeight = pMaxHeight;
11383				}
11384			}
11385			this._vBoundaries = b;
11386		},
11387
11388		_updateCache: function (data) {
11389			this.offset = this.helper.offset();
11390			if (this._isNumber(data.left)) {
11391				this.position.left = data.left;
11392			}
11393			if (this._isNumber(data.top)) {
11394				this.position.top = data.top;
11395			}
11396			if (this._isNumber(data.height)) {
11397				this.size.height = data.height;
11398			}
11399			if (this._isNumber(data.width)) {
11400				this.size.width = data.width;
11401			}
11402		},
11403
11404		_updateRatio: function (data) {
11405
11406			var cpos = this.position,
11407				csize = this.size,
11408				a = this.axis;
11409
11410			if (this._isNumber(data.height)) {
11411				data.width = (data.height * this.aspectRatio);
11412			} else if (this._isNumber(data.width)) {
11413				data.height = (data.width / this.aspectRatio);
11414			}
11415
11416			if (a === "sw") {
11417				data.left = cpos.left + (csize.width - data.width);
11418				data.top = null;
11419			}
11420			if (a === "nw") {
11421				data.top = cpos.top + (csize.height - data.height);
11422				data.left = cpos.left + (csize.width - data.width);
11423			}
11424
11425			return data;
11426		},
11427
11428		_respectSize: function (data) {
11429
11430			var o = this._vBoundaries,
11431				a = this.axis,
11432				ismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),
11433				ismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
11434				isminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),
11435				isminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
11436				dw = this.originalPosition.left + this.originalSize.width,
11437				dh = this.originalPosition.top + this.originalSize.height,
11438				cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
11439			if (isminw) {
11440				data.width = o.minWidth;
11441			}
11442			if (isminh) {
11443				data.height = o.minHeight;
11444			}
11445			if (ismaxw) {
11446				data.width = o.maxWidth;
11447			}
11448			if (ismaxh) {
11449				data.height = o.maxHeight;
11450			}
11451
11452			if (isminw && cw) {
11453				data.left = dw - o.minWidth;
11454			}
11455			if (ismaxw && cw) {
11456				data.left = dw - o.maxWidth;
11457			}
11458			if (isminh && ch) {
11459				data.top = dh - o.minHeight;
11460			}
11461			if (ismaxh && ch) {
11462				data.top = dh - o.maxHeight;
11463			}
11464
11465			// Fixing jump error on top/left - bug #2330
11466			if (!data.width && !data.height && !data.left && data.top) {
11467				data.top = null;
11468			} else if (!data.width && !data.height && !data.top && data.left) {
11469				data.left = null;
11470			}
11471
11472			return data;
11473		},
11474
11475		_getPaddingPlusBorderDimensions: function (element) {
11476			var i = 0,
11477				widths = [],
11478				borders = [
11479					element.css("borderTopWidth"),
11480					element.css("borderRightWidth"),
11481					element.css("borderBottomWidth"),
11482					element.css("borderLeftWidth")
11483				],
11484				paddings = [
11485					element.css("paddingTop"),
11486					element.css("paddingRight"),
11487					element.css("paddingBottom"),
11488					element.css("paddingLeft")
11489				];
11490
11491			for (; i < 4; i++) {
11492				widths[i] = (parseFloat(borders[i]) || 0);
11493				widths[i] += (parseFloat(paddings[i]) || 0);
11494			}
11495
11496			return {
11497				height: widths[0] + widths[2],
11498				width: widths[1] + widths[3]
11499			};
11500		},
11501
11502		_calculateAdjustedElementDimensions: function (element) {
11503			var elWidth, elHeight, paddingBorder,
11504				ce = element.get(0);
11505
11506			if (element.css("box-sizing") !== "content-box" ||
11507				(!this._hasScroll(ce) && !this._hasScroll(ce, "left"))) {
11508				return {
11509					height: parseFloat(element.css("height")),
11510					width: parseFloat(element.css("width"))
11511				};
11512			}
11513
11514			// Check if CSS inline styles are set and use those (usually from previous resizes)
11515			elWidth = parseFloat(ce.style.width);
11516			elHeight = parseFloat(ce.style.height);
11517
11518			paddingBorder = this._getPaddingPlusBorderDimensions(element);
11519			elWidth = isNaN(elWidth) ?
11520				this._getElementTheoreticalSize(element, paddingBorder, "width") :
11521				elWidth;
11522			elHeight = isNaN(elHeight) ?
11523				this._getElementTheoreticalSize(element, paddingBorder, "height") :
11524				elHeight;
11525
11526			return {
11527				height: elHeight,
11528				width: elWidth
11529			};
11530		},
11531
11532		_getElementTheoreticalSize: function (element, extraSize, dimension) {
11533
11534			// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
11535			var size = Math.max(0, Math.ceil(
11536				element.get(0)["offset" + dimension[0].toUpperCase() + dimension.slice(1)] -
11537				extraSize[dimension] -
11538				0.5
11539
11540				// If offsetWidth/offsetHeight is unknown, then we can't determine theoretical size.
11541				// Use an explicit zero to avoid NaN.
11542				// See https://github.com/jquery/jquery/issues/3964
11543			)) || 0;
11544
11545			return size;
11546		},
11547
11548		_proportionallyResize: function () {
11549
11550			if (!this._proportionallyResizeElements.length) {
11551				return;
11552			}
11553
11554			var prel,
11555				i = 0,
11556				element = this.helper || this.element;
11557
11558			for (; i < this._proportionallyResizeElements.length; i++) {
11559
11560				prel = this._proportionallyResizeElements[i];
11561
11562				// TODO: Seems like a bug to cache this.outerDimensions
11563				// considering that we are in a loop.
11564				if (!this.outerDimensions) {
11565					this.outerDimensions = this._getPaddingPlusBorderDimensions(prel);
11566				}
11567
11568				prel.css({
11569					height: (element.height() - this.outerDimensions.height) || 0,
11570					width: (element.width() - this.outerDimensions.width) || 0
11571				});
11572
11573			}
11574
11575		},
11576
11577		_renderProxy: function () {
11578
11579			var el = this.element, o = this.options;
11580			this.elementOffset = el.offset();
11581
11582			if (this._helper) {
11583
11584				this.helper = this.helper || $("<div></div>").css({ overflow: "hidden" });
11585
11586				this._addClass(this.helper, this._helper);
11587				this.helper.css({
11588					width: this.element.outerWidth(),
11589					height: this.element.outerHeight(),
11590					position: "absolute",
11591					left: this.elementOffset.left + "px",
11592					top: this.elementOffset.top + "px",
11593					zIndex: ++o.zIndex //TODO: Don't modify option
11594				});
11595
11596				this.helper
11597					.appendTo("body")
11598					.disableSelection();
11599
11600			} else {
11601				this.helper = this.element;
11602			}
11603
11604		},
11605
11606		_change: {
11607			e: function (event, dx) {
11608				return { width: this.originalSize.width + dx };
11609			},
11610			w: function (event, dx) {
11611				var cs = this.originalSize, sp = this.originalPosition;
11612				return { left: sp.left + dx, width: cs.width - dx };
11613			},
11614			n: function (event, dx, dy) {
11615				var cs = this.originalSize, sp = this.originalPosition;
11616				return { top: sp.top + dy, height: cs.height - dy };
11617			},
11618			s: function (event, dx, dy) {
11619				return { height: this.originalSize.height + dy };
11620			},
11621			se: function (event, dx, dy) {
11622				return $.extend(this._change.s.apply(this, arguments),
11623					this._change.e.apply(this, [event, dx, dy]));
11624			},
11625			sw: function (event, dx, dy) {
11626				return $.extend(this._change.s.apply(this, arguments),
11627					this._change.w.apply(this, [event, dx, dy]));
11628			},
11629			ne: function (event, dx, dy) {
11630				return $.extend(this._change.n.apply(this, arguments),
11631					this._change.e.apply(this, [event, dx, dy]));
11632			},
11633			nw: function (event, dx, dy) {
11634				return $.extend(this._change.n.apply(this, arguments),
11635					this._change.w.apply(this, [event, dx, dy]));
11636			}
11637		},
11638
11639		_propagate: function (n, event) {
11640			$.ui.plugin.call(this, n, [event, this.ui()]);
11641			if (n !== "resize") {
11642				this._trigger(n, event, this.ui());
11643			}
11644		},
11645
11646		plugins: {},
11647
11648		ui: function () {
11649			return {
11650				originalElement: this.originalElement,
11651				element: this.element,
11652				helper: this.helper,
11653				position: this.position,
11654				size: this.size,
11655				originalSize: this.originalSize,
11656				originalPosition: this.originalPosition
11657			};
11658		}
11659
11660	});
11661
11662	/*
11663	 * Resizable Extensions
11664	 */
11665
11666	$.ui.plugin.add("resizable", "animate", {
11667
11668		stop: function (event) {
11669			var that = $(this).resizable("instance"),
11670				o = that.options,
11671				pr = that._proportionallyResizeElements,
11672				ista = pr.length && (/textarea/i).test(pr[0].nodeName),
11673				soffseth = ista && that._hasScroll(pr[0], "left") ? 0 : that.sizeDiff.height,
11674				soffsetw = ista ? 0 : that.sizeDiff.width,
11675				style = {
11676					width: (that.size.width - soffsetw),
11677					height: (that.size.height - soffseth)
11678				},
11679				left = (parseFloat(that.element.css("left")) +
11680					(that.position.left - that.originalPosition.left)) || null,
11681				top = (parseFloat(that.element.css("top")) +
11682					(that.position.top - that.originalPosition.top)) || null;
11683
11684			that.element.animate(
11685				$.extend(style, top && left ? { top: top, left: left } : {}), {
11686				duration: o.animateDuration,
11687				easing: o.animateEasing,
11688				step: function () {
11689
11690					var data = {
11691						width: parseFloat(that.element.css("width")),
11692						height: parseFloat(that.element.css("height")),
11693						top: parseFloat(that.element.css("top")),
11694						left: parseFloat(that.element.css("left"))
11695					};
11696
11697					if (pr && pr.length) {
11698						$(pr[0]).css({ width: data.width, height: data.height });
11699					}
11700
11701					// Propagating resize, and updating values for each animation step
11702					that._updateCache(data);
11703					that._propagate("resize", event);
11704
11705				}
11706			}
11707			);
11708		}
11709
11710	});
11711
11712	$.ui.plugin.add("resizable", "containment", {
11713
11714		start: function () {
11715			var element, p, co, ch, cw, width, height,
11716				that = $(this).resizable("instance"),
11717				o = that.options,
11718				el = that.element,
11719				oc = o.containment,
11720				ce = (oc instanceof $) ?
11721					oc.get(0) :
11722					(/parent/.test(oc)) ? el.parent().get(0) : oc;
11723
11724			if (!ce) {
11725				return;
11726			}
11727
11728			that.containerElement = $(ce);
11729
11730			if (/document/.test(oc) || oc === document) {
11731				that.containerOffset = {
11732					left: 0,
11733					top: 0
11734				};
11735				that.containerPosition = {
11736					left: 0,
11737					top: 0
11738				};
11739
11740				that.parentData = {
11741					element: $(document),
11742					left: 0,
11743					top: 0,
11744					width: $(document).width(),
11745					height: $(document).height() || document.body.parentNode.scrollHeight
11746				};
11747			} else {
11748				element = $(ce);
11749				p = [];
11750				$(["Top", "Right", "Left", "Bottom"]).each(function (i, name) {
11751					p[i] = that._num(element.css("padding" + name));
11752				});
11753
11754				that.containerOffset = element.offset();
11755				that.containerPosition = element.position();
11756				that.containerSize = {
11757					height: (element.innerHeight() - p[3]),
11758					width: (element.innerWidth() - p[1])
11759				};
11760
11761				co = that.containerOffset;
11762				ch = that.containerSize.height;
11763				cw = that.containerSize.width;
11764				width = (that._hasScroll(ce, "left") ? ce.scrollWidth : cw);
11765				height = (that._hasScroll(ce) ? ce.scrollHeight : ch);
11766
11767				that.parentData = {
11768					element: ce,
11769					left: co.left,
11770					top: co.top,
11771					width: width,
11772					height: height
11773				};
11774			}
11775		},
11776
11777		resize: function (event) {
11778			var woset, hoset, isParent, isOffsetRelative,
11779				that = $(this).resizable("instance"),
11780				o = that.options,
11781				co = that.containerOffset,
11782				cp = that.position,
11783				pRatio = that._aspectRatio || event.shiftKey,
11784				cop = {
11785					top: 0,
11786					left: 0
11787				},
11788				ce = that.containerElement,
11789				continueResize = true;
11790
11791			if (ce[0] !== document && (/static/).test(ce.css("position"))) {
11792				cop = co;
11793			}
11794
11795			if (cp.left < (that._helper ? co.left : 0)) {
11796				that.size.width = that.size.width +
11797					(that._helper ?
11798						(that.position.left - co.left) :
11799						(that.position.left - cop.left));
11800
11801				if (pRatio) {
11802					that.size.height = that.size.width / that.aspectRatio;
11803					continueResize = false;
11804				}
11805				that.position.left = o.helper ? co.left : 0;
11806			}
11807
11808			if (cp.top < (that._helper ? co.top : 0)) {
11809				that.size.height = that.size.height +
11810					(that._helper ?
11811						(that.position.top - co.top) :
11812						that.position.top);
11813
11814				if (pRatio) {
11815					that.size.width = that.size.height * that.aspectRatio;
11816					continueResize = false;
11817				}
11818				that.position.top = that._helper ? co.top : 0;
11819			}
11820
11821			isParent = that.containerElement.get(0) === that.element.parent().get(0);
11822			isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
11823
11824			if (isParent && isOffsetRelative) {
11825				that.offset.left = that.parentData.left + that.position.left;
11826				that.offset.top = that.parentData.top + that.position.top;
11827			} else {
11828				that.offset.left = that.element.offset().left;
11829				that.offset.top = that.element.offset().top;
11830			}
11831
11832			woset = Math.abs(that.sizeDiff.width +
11833				(that._helper ?
11834					that.offset.left - cop.left :
11835					(that.offset.left - co.left)));
11836
11837			hoset = Math.abs(that.sizeDiff.height +
11838				(that._helper ?
11839					that.offset.top - cop.top :
11840					(that.offset.top - co.top)));
11841
11842			if (woset + that.size.width >= that.parentData.width) {
11843				that.size.width = that.parentData.width - woset;
11844				if (pRatio) {
11845					that.size.height = that.size.width / that.aspectRatio;
11846					continueResize = false;
11847				}
11848			}
11849
11850			if (hoset + that.size.height >= that.parentData.height) {
11851				that.size.height = that.parentData.height - hoset;
11852				if (pRatio) {
11853					that.size.width = that.size.height * that.aspectRatio;
11854					continueResize = false;
11855				}
11856			}
11857
11858			if (!continueResize) {
11859				that.position.left = that.prevPosition.left;
11860				that.position.top = that.prevPosition.top;
11861				that.size.width = that.prevSize.width;
11862				that.size.height = that.prevSize.height;
11863			}
11864		},
11865
11866		stop: function () {
11867			var that = $(this).resizable("instance"),
11868				o = that.options,
11869				co = that.containerOffset,
11870				cop = that.containerPosition,
11871				ce = that.containerElement,
11872				helper = $(that.helper),
11873				ho = helper.offset(),
11874				w = helper.outerWidth() - that.sizeDiff.width,
11875				h = helper.outerHeight() - that.sizeDiff.height;
11876
11877			if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
11878				$(this).css({
11879					left: ho.left - cop.left - co.left,
11880					width: w,
11881					height: h
11882				});
11883			}
11884
11885			if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
11886				$(this).css({
11887					left: ho.left - cop.left - co.left,
11888					width: w,
11889					height: h
11890				});
11891			}
11892		}
11893	});
11894
11895	$.ui.plugin.add("resizable", "alsoResize", {
11896
11897		start: function () {
11898			var that = $(this).resizable("instance"),
11899				o = that.options;
11900
11901			$(o.alsoResize).each(function () {
11902				var el = $(this),
11903					elSize = that._calculateAdjustedElementDimensions(el);
11904
11905				el.data("ui-resizable-alsoresize", {
11906					width: elSize.width, height: elSize.height,
11907					left: parseFloat(el.css("left")), top: parseFloat(el.css("top"))
11908				});
11909			});
11910		},
11911
11912		resize: function (event, ui) {
11913			var that = $(this).resizable("instance"),
11914				o = that.options,
11915				os = that.originalSize,
11916				op = that.originalPosition,
11917				delta = {
11918					height: (that.size.height - os.height) || 0,
11919					width: (that.size.width - os.width) || 0,
11920					top: (that.position.top - op.top) || 0,
11921					left: (that.position.left - op.left) || 0
11922				};
11923
11924			$(o.alsoResize).each(function () {
11925				var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
11926					css = el.parents(ui.originalElement[0]).length ?
11927						["width", "height"] :
11928						["width", "height", "top", "left"];
11929
11930				$.each(css, function (i, prop) {
11931					var sum = (start[prop] || 0) + (delta[prop] || 0);
11932					if (sum && sum >= 0) {
11933						style[prop] = sum || null;
11934					}
11935				});
11936
11937				el.css(style);
11938			});
11939		},
11940
11941		stop: function () {
11942			$(this).removeData("ui-resizable-alsoresize");
11943		}
11944	});
11945
11946	$.ui.plugin.add("resizable", "ghost", {
11947
11948		start: function () {
11949
11950			var that = $(this).resizable("instance"), cs = that.size;
11951
11952			that.ghost = that.originalElement.clone();
11953			that.ghost.css({
11954				opacity: 0.25,
11955				display: "block",
11956				position: "relative",
11957				height: cs.height,
11958				width: cs.width,
11959				margin: 0,
11960				left: 0,
11961				top: 0
11962			});
11963
11964			that._addClass(that.ghost, "ui-resizable-ghost");
11965
11966			// DEPRECATED
11967			// TODO: remove after 1.12
11968			if ($.uiBackCompat === true && typeof that.options.ghost === "string") {
11969
11970				// Ghost option
11971				that.ghost.addClass(this.options.ghost);
11972			}
11973
11974			that.ghost.appendTo(that.helper);
11975
11976		},
11977
11978		resize: function () {
11979			var that = $(this).resizable("instance");
11980			if (that.ghost) {
11981				that.ghost.css({
11982					position: "relative",
11983					height: that.size.height,
11984					width: that.size.width
11985				});
11986			}
11987		},
11988
11989		stop: function () {
11990			var that = $(this).resizable("instance");
11991			if (that.ghost && that.helper) {
11992				that.helper.get(0).removeChild(that.ghost.get(0));
11993			}
11994		}
11995
11996	});
11997
11998	$.ui.plugin.add("resizable", "grid", {
11999
12000		resize: function () {
12001			var outerDimensions,
12002				that = $(this).resizable("instance"),
12003				o = that.options,
12004				cs = that.size,
12005				os = that.originalSize,
12006				op = that.originalPosition,
12007				a = that.axis,
12008				grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
12009				gridX = (grid[0] || 1),
12010				gridY = (grid[1] || 1),
12011				ox = Math.round((cs.width - os.width) / gridX) * gridX,
12012				oy = Math.round((cs.height - os.height) / gridY) * gridY,
12013				newWidth = os.width + ox,
12014				newHeight = os.height + oy,
12015				isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
12016				isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
12017				isMinWidth = o.minWidth && (o.minWidth > newWidth),
12018				isMinHeight = o.minHeight && (o.minHeight > newHeight);
12019
12020			o.grid = grid;
12021
12022			if (isMinWidth) {
12023				newWidth += gridX;
12024			}
12025			if (isMinHeight) {
12026				newHeight += gridY;
12027			}
12028			if (isMaxWidth) {
12029				newWidth -= gridX;
12030			}
12031			if (isMaxHeight) {
12032				newHeight -= gridY;
12033			}
12034
12035			if (/^(se|s|e)$/.test(a)) {
12036				that.size.width = newWidth;
12037				that.size.height = newHeight;
12038			} else if (/^(ne)$/.test(a)) {
12039				that.size.width = newWidth;
12040				that.size.height = newHeight;
12041				that.position.top = op.top - oy;
12042			} else if (/^(sw)$/.test(a)) {
12043				that.size.width = newWidth;
12044				that.size.height = newHeight;
12045				that.position.left = op.left - ox;
12046			} else {
12047				if (newHeight - gridY <= 0 || newWidth - gridX <= 0) {
12048					outerDimensions = that._getPaddingPlusBorderDimensions(this);
12049				}
12050
12051				if (newHeight - gridY > 0) {
12052					that.size.height = newHeight;
12053					that.position.top = op.top - oy;
12054				} else {
12055					newHeight = gridY - outerDimensions.height;
12056					that.size.height = newHeight;
12057					that.position.top = op.top + os.height - newHeight;
12058				}
12059				if (newWidth - gridX > 0) {
12060					that.size.width = newWidth;
12061					that.position.left = op.left - ox;
12062				} else {
12063					newWidth = gridX - outerDimensions.width;
12064					that.size.width = newWidth;
12065					that.position.left = op.left + os.width - newWidth;
12066				}
12067			}
12068		}
12069
12070	});
12071
12072	var widgetsResizable = $.ui.resizable;
12073
12074
12075	/*!
12076	 * jQuery UI Dialog 1.14.1
12077	 * https://jqueryui.com
12078	 *
12079	 * Copyright OpenJS Foundation and other contributors
12080	 * Released under the MIT license.
12081	 * https://jquery.org/license
12082	 */
12083
12084	//>>label: Dialog
12085	//>>group: Widgets
12086	//>>description: Displays customizable dialog windows.
12087	//>>docs: https://api.jqueryui.com/dialog/
12088	//>>demos: https://jqueryui.com/dialog/
12089	//>>css.structure: ../../themes/base/core.css
12090	//>>css.structure: ../../themes/base/dialog.css
12091	//>>css.theme: ../../themes/base/theme.css
12092
12093
12094	$.widget("ui.dialog", {
12095		version: "1.14.1",
12096		options: {
12097			appendTo: "body",
12098			autoOpen: true,
12099			buttons: [],
12100			classes: {
12101				"ui-dialog": "ui-corner-all",
12102				"ui-dialog-titlebar": "ui-corner-all"
12103			},
12104			closeOnEscape: true,
12105			closeText: "Close",
12106			draggable: true,
12107			hide: null,
12108			height: "auto",
12109			maxHeight: null,
12110			maxWidth: null,
12111			minHeight: 150,
12112			minWidth: 150,
12113			modal: false,
12114			position: {
12115				my: "center",
12116				at: "center",
12117				of: window,
12118				collision: "fit",
12119
12120				// Ensure the titlebar is always visible
12121				using: function (pos) {
12122					var topOffset = $(this).css(pos).offset().top;
12123					if (topOffset < 0) {
12124						$(this).css("top", pos.top - topOffset);
12125					}
12126				}
12127			},
12128			resizable: true,
12129			show: null,
12130			title: null,
12131			uiDialogTitleHeadingLevel: 0,
12132			width: 300,
12133
12134			// Callbacks
12135			beforeClose: null,
12136			close: null,
12137			drag: null,
12138			dragStart: null,
12139			dragStop: null,
12140			focus: null,
12141			open: null,
12142			resize: null,
12143			resizeStart: null,
12144			resizeStop: null
12145		},
12146
12147		sizeRelatedOptions: {
12148			buttons: true,
12149			height: true,
12150			maxHeight: true,
12151			maxWidth: true,
12152			minHeight: true,
12153			minWidth: true,
12154			width: true
12155		},
12156
12157		resizableRelatedOptions: {
12158			maxHeight: true,
12159			maxWidth: true,
12160			minHeight: true,
12161			minWidth: true
12162		},
12163
12164		_create: function () {
12165			this.originalCss = {
12166				display: this.element[0].style.display,
12167				width: this.element[0].style.width,
12168				minHeight: this.element[0].style.minHeight,
12169				maxHeight: this.element[0].style.maxHeight,
12170				height: this.element[0].style.height
12171			};
12172			this.originalPosition = {
12173				parent: this.element.parent(),
12174				index: this.element.parent().children().index(this.element)
12175			};
12176			this.originalTitle = this.element.attr("title");
12177			if (this.options.title == null && this.originalTitle != null) {
12178				this.options.title = this.originalTitle;
12179			}
12180
12181			// Dialogs can't be disabled
12182			if (this.options.disabled) {
12183				this.options.disabled = false;
12184			}
12185
12186			this._createWrapper();
12187
12188			this.element
12189				.show()
12190				.removeAttr("title")
12191				.appendTo(this.uiDialog);
12192
12193			this._addClass("ui-dialog-content", "ui-widget-content");
12194
12195			this._createTitlebar();
12196			this._createButtonPane();
12197
12198			if (this.options.draggable && $.fn.draggable) {
12199				this._makeDraggable();
12200			}
12201			if (this.options.resizable && $.fn.resizable) {
12202				this._makeResizable();
12203			}
12204
12205			this._isOpen = false;
12206
12207			this._trackFocus();
12208		},
12209
12210		_init: function () {
12211			if (this.options.autoOpen) {
12212				this.open();
12213			}
12214		},
12215
12216		_appendTo: function () {
12217			var element = this.options.appendTo;
12218			if (element && (element.jquery || element.nodeType)) {
12219				return $(element);
12220			}
12221			return this.document.find(element || "body").eq(0);
12222		},
12223
12224		_destroy: function () {
12225			var next,
12226				originalPosition = this.originalPosition;
12227
12228			this._untrackInstance();
12229			this._destroyOverlay();
12230
12231			this.element
12232				.removeUniqueId()
12233				.css(this.originalCss)
12234
12235				// Without detaching first, the following becomes really slow
12236				.detach();
12237
12238			this.uiDialog.remove();
12239
12240			if (this.originalTitle) {
12241				this.element.attr("title", this.originalTitle);
12242			}
12243
12244			next = originalPosition.parent.children().eq(originalPosition.index);
12245
12246			// Don't try to place the dialog next to itself (#8613)
12247			if (next.length && next[0] !== this.element[0]) {
12248				next.before(this.element);
12249			} else {
12250				originalPosition.parent.append(this.element);
12251			}
12252		},
12253
12254		widget: function () {
12255			return this.uiDialog;
12256		},
12257
12258		disable: $.noop,
12259		enable: $.noop,
12260
12261		close: function (event) {
12262			var that = this;
12263
12264			if (!this._isOpen || this._trigger("beforeClose", event) === false) {
12265				return;
12266			}
12267
12268			this._isOpen = false;
12269			this._focusedElement = null;
12270			this._destroyOverlay();
12271			this._untrackInstance();
12272
12273			if (!this.opener.filter(":focusable").trigger("focus").length) {
12274
12275				// Hiding a focused element doesn't trigger blur in WebKit
12276				// so in case we have nothing to focus on, explicitly blur the active element
12277				// https://bugs.webkit.org/show_bug.cgi?id=47182
12278				$(this.document[0].activeElement).trigger("blur");
12279			}
12280
12281			this._hide(this.uiDialog, this.options.hide, function () {
12282				that._trigger("close", event);
12283			});
12284		},
12285
12286		isOpen: function () {
12287			return this._isOpen;
12288		},
12289
12290		moveToTop: function () {
12291			this._moveToTop();
12292		},
12293
12294		_moveToTop: function (event, silent) {
12295			var moved = false,
12296				zIndices = this.uiDialog.siblings(".ui-front:visible").map(function () {
12297					return +$(this).css("z-index");
12298				}).get(),
12299				zIndexMax = Math.max.apply(null, zIndices);
12300
12301			if (zIndexMax >= +this.uiDialog.css("z-index")) {
12302				this.uiDialog.css("z-index", zIndexMax + 1);
12303				moved = true;
12304			}
12305
12306			if (moved && !silent) {
12307				this._trigger("focus", event);
12308			}
12309			return moved;
12310		},
12311
12312		open: function () {
12313			var that = this;
12314			if (this._isOpen) {
12315				if (this._moveToTop()) {
12316					this._focusTabbable();
12317				}
12318				return;
12319			}
12320
12321			this._isOpen = true;
12322			this.opener = $(this.document[0].activeElement);
12323
12324			this._size();
12325			this._position();
12326			this._createOverlay();
12327			this._moveToTop(null, true);
12328
12329			// Ensure the overlay is moved to the top with the dialog, but only when
12330			// opening. The overlay shouldn't move after the dialog is open so that
12331			// modeless dialogs opened after the modal dialog stack properly.
12332			if (this.overlay) {
12333				this.overlay.css("z-index", this.uiDialog.css("z-index") - 1);
12334			}
12335
12336			this._show(this.uiDialog, this.options.show, function () {
12337				that._focusTabbable();
12338				that._trigger("focus");
12339			});
12340
12341			// Track the dialog immediately upon opening in case a focus event
12342			// somehow occurs outside of the dialog before an element inside the
12343			// dialog is focused (#10152)
12344			this._makeFocusTarget();
12345
12346			this._trigger("open");
12347		},
12348
12349		_focusTabbable: function () {
12350
12351			// Set focus to the first match:
12352			// 1. An element that was focused previously
12353			// 2. First element inside the dialog matching [autofocus]
12354			// 3. Tabbable element inside the content element
12355			// 4. Tabbable element inside the buttonpane
12356			// 5. The close button
12357			// 6. The dialog itself
12358			var hasFocus = this._focusedElement;
12359			if (!hasFocus) {
12360				hasFocus = this.element.find("[autofocus]");
12361			}
12362			if (!hasFocus.length) {
12363				hasFocus = this.element.find(":tabbable");
12364			}
12365			if (!hasFocus.length) {
12366				hasFocus = this.uiDialogButtonPane.find(":tabbable");
12367			}
12368			if (!hasFocus.length) {
12369				hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
12370			}
12371			if (!hasFocus.length) {
12372				hasFocus = this.uiDialog;
12373			}
12374			hasFocus.eq(0).trigger("focus");
12375		},
12376
12377		_restoreTabbableFocus: function () {
12378			var activeElement = this.document[0].activeElement,
12379				isActive = this.uiDialog[0] === activeElement ||
12380					$.contains(this.uiDialog[0], activeElement);
12381			if (!isActive) {
12382				this._focusTabbable();
12383			}
12384		},
12385
12386		_keepFocus: function (event) {
12387			event.preventDefault();
12388			this._restoreTabbableFocus();
12389		},
12390
12391		_createWrapper: function () {
12392			this.uiDialog = $("<div>")
12393				.hide()
12394				.attr({
12395
12396					// Setting tabIndex makes the div focusable
12397					tabIndex: -1,
12398					role: "dialog",
12399					"aria-modal": this.options.modal ? "true" : null
12400				})
12401				.appendTo(this._appendTo());
12402
12403			this._addClass(this.uiDialog, "ui-dialog", "ui-widget ui-widget-content ui-front");
12404			this._on(this.uiDialog, {
12405				keydown: function (event) {
12406					if (this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
12407						event.keyCode === $.ui.keyCode.ESCAPE) {
12408						event.preventDefault();
12409						this.close(event);
12410						return;
12411					}
12412
12413					// Prevent tabbing out of dialogs
12414					if (event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented()) {
12415						return;
12416					}
12417					var tabbables = this.uiDialog.find(":tabbable"),
12418						first = tabbables.first(),
12419						last = tabbables.last();
12420
12421					if ((event.target === last[0] || event.target === this.uiDialog[0]) &&
12422						!event.shiftKey) {
12423						this._delay(function () {
12424							first.trigger("focus");
12425						});
12426						event.preventDefault();
12427					} else if ((event.target === first[0] ||
12428						event.target === this.uiDialog[0]) && event.shiftKey) {
12429						this._delay(function () {
12430							last.trigger("focus");
12431						});
12432						event.preventDefault();
12433					}
12434				},
12435				mousedown: function (event) {
12436					if (this._moveToTop(event)) {
12437						this._focusTabbable();
12438					}
12439				}
12440			});
12441
12442			// We assume that any existing aria-describedby attribute means
12443			// that the dialog content is marked up properly
12444			// otherwise we brute force the content as the description
12445			if (!this.element.find("[aria-describedby]").length) {
12446				this.uiDialog.attr({
12447					"aria-describedby": this.element.uniqueId().attr("id")
12448				});
12449			}
12450		},
12451
12452		_createTitlebar: function () {
12453			var uiDialogTitle;
12454
12455			this.uiDialogTitlebar = $("<div>");
12456			this._addClass(this.uiDialogTitlebar,
12457				"ui-dialog-titlebar", "ui-widget-header ui-helper-clearfix");
12458			this._on(this.uiDialogTitlebar, {
12459				mousedown: function (event) {
12460
12461					// Don't prevent click on close button (#8838)
12462					// Focusing a dialog that is partially scrolled out of view
12463					// causes the browser to scroll it into view, preventing the click event
12464					if (!$(event.target).closest(".ui-dialog-titlebar-close")) {
12465
12466						// Dialog isn't getting focus when dragging (#8063)
12467						this.uiDialog.trigger("focus");
12468					}
12469				}
12470			});
12471
12472			this.uiDialogTitlebarClose = $("<button type='button'></button>")
12473				.button({
12474					label: $("<a>").text(this.options.closeText).html(),
12475					icon: "ui-icon-closethick",
12476					showLabel: false
12477				})
12478				.appendTo(this.uiDialogTitlebar);
12479
12480			this._addClass(this.uiDialogTitlebarClose, "ui-dialog-titlebar-close");
12481			this._on(this.uiDialogTitlebarClose, {
12482				click: function (event) {
12483					event.preventDefault();
12484					this.close(event);
12485				}
12486			});
12487
12488			var uiDialogHeadingLevel = Number.isInteger(this.options.uiDialogTitleHeadingLevel) &&
12489				this.options.uiDialogTitleHeadingLevel > 0 &&
12490				this.options.uiDialogTitleHeadingLevel <= 6 ?
12491				"h" + this.options.uiDialogTitleHeadingLevel : "span";
12492
12493			uiDialogTitle = $("<" + uiDialogHeadingLevel + ">")
12494				.uniqueId().prependTo(this.uiDialogTitlebar);
12495			this._addClass(uiDialogTitle, "ui-dialog-title");
12496			this._title(uiDialogTitle);
12497
12498			this.uiDialogTitlebar.prependTo(this.uiDialog);
12499
12500			this.uiDialog.attr({
12501				"aria-labelledby": uiDialogTitle.attr("id")
12502			});
12503		},
12504
12505		_title: function (title) {
12506			if (this.options.title) {
12507				title.text(this.options.title);
12508			} else {
12509				title.html("&#160;");
12510			}
12511		},
12512
12513		_createButtonPane: function () {
12514			this.uiDialogButtonPane = $("<div>");
12515			this._addClass(this.uiDialogButtonPane, "ui-dialog-buttonpane",
12516				"ui-widget-content ui-helper-clearfix");
12517
12518			this.uiButtonSet = $("<div>")
12519				.appendTo(this.uiDialogButtonPane);
12520			this._addClass(this.uiButtonSet, "ui-dialog-buttonset");
12521
12522			this._createButtons();
12523		},
12524
12525		_createButtons: function () {
12526			var that = this,
12527				buttons = this.options.buttons;
12528
12529			// If we already have a button pane, remove it
12530			this.uiDialogButtonPane.remove();
12531			this.uiButtonSet.empty();
12532
12533			if ($.isEmptyObject(buttons) || (Array.isArray(buttons) && !buttons.length)) {
12534				this._removeClass(this.uiDialog, "ui-dialog-buttons");
12535				return;
12536			}
12537
12538			$.each(buttons, function (name, props) {
12539				var click, buttonOptions;
12540				props = typeof props === "function" ?
12541					{ click: props, text: name } :
12542					props;
12543
12544				// Default to a non-submitting button
12545				props = $.extend({ type: "button" }, props);
12546
12547				// Change the context for the click callback to be the main element
12548				click = props.click;
12549				buttonOptions = {
12550					icon: props.icon,
12551					iconPosition: props.iconPosition,
12552					showLabel: props.showLabel,
12553
12554					// Deprecated options
12555					icons: props.icons,
12556					text: props.text
12557				};
12558
12559				delete props.click;
12560				delete props.icon;
12561				delete props.iconPosition;
12562				delete props.showLabel;
12563
12564				// Deprecated options
12565				delete props.icons;
12566				if (typeof props.text === "boolean") {
12567					delete props.text;
12568				}
12569
12570				$("<button></button>", props)
12571					.button(buttonOptions)
12572					.appendTo(that.uiButtonSet)
12573					.on("click", function () {
12574						click.apply(that.element[0], arguments);
12575					});
12576			});
12577			this._addClass(this.uiDialog, "ui-dialog-buttons");
12578			this.uiDialogButtonPane.appendTo(this.uiDialog);
12579		},
12580
12581		_makeDraggable: function () {
12582			var that = this,
12583				options = this.options;
12584
12585			function filteredUi(ui) {
12586				return {
12587					position: ui.position,
12588					offset: ui.offset
12589				};
12590			}
12591
12592			this.uiDialog.draggable({
12593				cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
12594				handle: ".ui-dialog-titlebar",
12595				containment: "document",
12596				start: function (event, ui) {
12597					that._addClass($(this), "ui-dialog-dragging");
12598					that._blockFrames();
12599					that._trigger("dragStart", event, filteredUi(ui));
12600				},
12601				drag: function (event, ui) {
12602					that._trigger("drag", event, filteredUi(ui));
12603				},
12604				stop: function (event, ui) {
12605					var left = ui.offset.left - that.document.scrollLeft(),
12606						top = ui.offset.top - that.document.scrollTop();
12607
12608					options.position = {
12609						my: "left top",
12610						at: "left" + (left >= 0 ? "+" : "") + left + " " +
12611							"top" + (top >= 0 ? "+" : "") + top,
12612						of: that.window
12613					};
12614					that._removeClass($(this), "ui-dialog-dragging");
12615					that._unblockFrames();
12616					that._trigger("dragStop", event, filteredUi(ui));
12617				}
12618			});
12619		},
12620
12621		_makeResizable: function () {
12622			var that = this,
12623				options = this.options,
12624				handles = options.resizable,
12625
12626				// .ui-resizable has position: relative defined in the stylesheet
12627				// but dialogs have to use absolute or fixed positioning
12628				position = this.uiDialog.css("position"),
12629				resizeHandles = typeof handles === "string" ?
12630					handles :
12631					"n,e,s,w,se,sw,ne,nw";
12632
12633			function filteredUi(ui) {
12634				return {
12635					originalPosition: ui.originalPosition,
12636					originalSize: ui.originalSize,
12637					position: ui.position,
12638					size: ui.size
12639				};
12640			}
12641
12642			this.uiDialog.resizable({
12643				cancel: ".ui-dialog-content",
12644				containment: "document",
12645				alsoResize: this.element,
12646				maxWidth: options.maxWidth,
12647				maxHeight: options.maxHeight,
12648				minWidth: options.minWidth,
12649				minHeight: this._minHeight(),
12650				handles: resizeHandles,
12651				start: function (event, ui) {
12652					that._addClass($(this), "ui-dialog-resizing");
12653					that._blockFrames();
12654					that._trigger("resizeStart", event, filteredUi(ui));
12655				},
12656				resize: function (event, ui) {
12657					that._trigger("resize", event, filteredUi(ui));
12658				},
12659				stop: function (event, ui) {
12660					var offset = that.uiDialog.offset(),
12661						left = offset.left - that.document.scrollLeft(),
12662						top = offset.top - that.document.scrollTop();
12663
12664					options.height = that.uiDialog.height();
12665					options.width = that.uiDialog.width();
12666					options.position = {
12667						my: "left top",
12668						at: "left" + (left >= 0 ? "+" : "") + left + " " +
12669							"top" + (top >= 0 ? "+" : "") + top,
12670						of: that.window
12671					};
12672					that._removeClass($(this), "ui-dialog-resizing");
12673					that._unblockFrames();
12674					that._trigger("resizeStop", event, filteredUi(ui));
12675				}
12676			})
12677				.css("position", position);
12678		},
12679
12680		_trackFocus: function () {
12681			this._on(this.widget(), {
12682				focusin: function (event) {
12683					this._makeFocusTarget();
12684					this._focusedElement = $(event.target);
12685				}
12686			});
12687		},
12688
12689		_makeFocusTarget: function () {
12690			this._untrackInstance();
12691			this._trackingInstances().unshift(this);
12692		},
12693
12694		_untrackInstance: function () {
12695			var instances = this._trackingInstances(),
12696				exists = $.inArray(this, instances);
12697			if (exists !== -1) {
12698				instances.splice(exists, 1);
12699			}
12700		},
12701
12702		_trackingInstances: function () {
12703			var instances = this.document.data("ui-dialog-instances");
12704			if (!instances) {
12705				instances = [];
12706				this.document.data("ui-dialog-instances", instances);
12707			}
12708			return instances;
12709		},
12710
12711		_minHeight: function () {
12712			var options = this.options;
12713
12714			return options.height === "auto" ?
12715				options.minHeight :
12716				Math.min(options.minHeight, options.height);
12717		},
12718
12719		_position: function () {
12720
12721			// Need to show the dialog to get the actual offset in the position plugin
12722			var isVisible = this.uiDialog.is(":visible");
12723			if (!isVisible) {
12724				this.uiDialog.show();
12725			}
12726			this.uiDialog.position(this.options.position);
12727			if (!isVisible) {
12728				this.uiDialog.hide();
12729			}
12730		},
12731
12732		_setOptions: function (options) {
12733			var that = this,
12734				resize = false,
12735				resizableOptions = {};
12736
12737			$.each(options, function (key, value) {
12738				that._setOption(key, value);
12739
12740				if (key in that.sizeRelatedOptions) {
12741					resize = true;
12742				}
12743				if (key in that.resizableRelatedOptions) {
12744					resizableOptions[key] = value;
12745				}
12746			});
12747
12748			if (resize) {
12749				this._size();
12750				this._position();
12751			}
12752			if (this.uiDialog.is(":data(ui-resizable)")) {
12753				this.uiDialog.resizable("option", resizableOptions);
12754			}
12755		},
12756
12757		_setOption: function (key, value) {
12758			var isDraggable, isResizable,
12759				uiDialog = this.uiDialog;
12760
12761			if (key === "disabled") {
12762				return;
12763			}
12764
12765			this._super(key, value);
12766
12767			if (key === "appendTo") {
12768				this.uiDialog.appendTo(this._appendTo());
12769			}
12770
12771			if (key === "buttons") {
12772				this._createButtons();
12773			}
12774
12775			if (key === "closeText") {
12776				this.uiDialogTitlebarClose.button({
12777
12778					// Ensure that we always pass a string
12779					label: $("<a>").text("" + this.options.closeText).html()
12780				});
12781			}
12782
12783			if (key === "draggable") {
12784				isDraggable = uiDialog.is(":data(ui-draggable)");
12785				if (isDraggable && !value) {
12786					uiDialog.draggable("destroy");
12787				}
12788
12789				if (!isDraggable && value) {
12790					this._makeDraggable();
12791				}
12792			}
12793
12794			if (key === "position") {
12795				this._position();
12796			}
12797
12798			if (key === "resizable") {
12799
12800				// currently resizable, becoming non-resizable
12801				isResizable = uiDialog.is(":data(ui-resizable)");
12802				if (isResizable && !value) {
12803					uiDialog.resizable("destroy");
12804				}
12805
12806				// Currently resizable, changing handles
12807				if (isResizable && typeof value === "string") {
12808					uiDialog.resizable("option", "handles", value);
12809				}
12810
12811				// Currently non-resizable, becoming resizable
12812				if (!isResizable && value !== false) {
12813					this._makeResizable();
12814				}
12815			}
12816
12817			if (key === "title") {
12818				this._title(this.uiDialogTitlebar.find(".ui-dialog-title"));
12819			}
12820
12821			if (key === "modal") {
12822				uiDialog.attr("aria-modal", value ? "true" : null);
12823			}
12824		},
12825
12826		_size: function () {
12827
12828			// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
12829			// divs will both have width and height set, so we need to reset them
12830			var nonContentHeight, minContentHeight, maxContentHeight,
12831				options = this.options;
12832
12833			// Reset content sizing
12834			this.element.show().css({
12835				width: "auto",
12836				minHeight: 0,
12837				maxHeight: "none",
12838				height: 0
12839			});
12840
12841			if (options.minWidth > options.width) {
12842				options.width = options.minWidth;
12843			}
12844
12845			// Reset wrapper sizing
12846			// determine the height of all the non-content elements
12847			nonContentHeight = this.uiDialog.css({
12848				height: "auto",
12849				width: options.width
12850			})
12851				.outerHeight();
12852			minContentHeight = Math.max(0, options.minHeight - nonContentHeight);
12853			maxContentHeight = typeof options.maxHeight === "number" ?
12854				Math.max(0, options.maxHeight - nonContentHeight) :
12855				"none";
12856
12857			if (options.height === "auto") {
12858				this.element.css({
12859					minHeight: minContentHeight,
12860					maxHeight: maxContentHeight,
12861					height: "auto"
12862				});
12863			} else {
12864				this.element.height(Math.max(0, options.height - nonContentHeight));
12865			}
12866
12867			if (this.uiDialog.is(":data(ui-resizable)")) {
12868				this.uiDialog.resizable("option", "minHeight", this._minHeight());
12869			}
12870		},
12871
12872		_blockFrames: function () {
12873			this.iframeBlocks = this.document.find("iframe").map(function () {
12874				var iframe = $(this);
12875
12876				return $("<div>")
12877					.css({
12878						position: "absolute",
12879						width: iframe.outerWidth(),
12880						height: iframe.outerHeight()
12881					})
12882					.appendTo(iframe.parent())
12883					.offset(iframe.offset())[0];
12884			});
12885		},
12886
12887		_unblockFrames: function () {
12888			if (this.iframeBlocks) {
12889				this.iframeBlocks.remove();
12890				delete this.iframeBlocks;
12891			}
12892		},
12893
12894		_allowInteraction: function (event) {
12895			if ($(event.target).closest(".ui-dialog").length) {
12896				return true;
12897			}
12898
12899			// TODO: Remove hack when datepicker implements
12900			// the .ui-front logic (#8989)
12901			return !!$(event.target).closest(".ui-datepicker").length;
12902		},
12903
12904		_createOverlay: function () {
12905			if (!this.options.modal) {
12906				return;
12907			}
12908
12909			// We use a delay in case the overlay is created from an
12910			// event that we're going to be cancelling (#2804)
12911			var isOpening = true;
12912			this._delay(function () {
12913				isOpening = false;
12914			});
12915
12916			if (!this.document.data("ui-dialog-overlays")) {
12917
12918				// Prevent use of anchors and inputs
12919				// This doesn't use `_on()` because it is a shared event handler
12920				// across all open modal dialogs.
12921				this.document.on("focusin.ui-dialog", function (event) {
12922					if (isOpening) {
12923						return;
12924					}
12925
12926					var instance = this._trackingInstances()[0];
12927					if (!instance._allowInteraction(event)) {
12928						event.preventDefault();
12929						instance._focusTabbable();
12930					}
12931				}.bind(this));
12932			}
12933
12934			this.overlay = $("<div>")
12935				.appendTo(this._appendTo());
12936
12937			this._addClass(this.overlay, null, "ui-widget-overlay ui-front");
12938			this._on(this.overlay, {
12939				mousedown: "_keepFocus"
12940			});
12941			this.document.data("ui-dialog-overlays",
12942				(this.document.data("ui-dialog-overlays") || 0) + 1);
12943		},
12944
12945		_destroyOverlay: function () {
12946			if (!this.options.modal) {
12947				return;
12948			}
12949
12950			if (this.overlay) {
12951				var overlays = this.document.data("ui-dialog-overlays") - 1;
12952
12953				if (!overlays) {
12954					this.document.off("focusin.ui-dialog");
12955					this.document.removeData("ui-dialog-overlays");
12956				} else {
12957					this.document.data("ui-dialog-overlays", overlays);
12958				}
12959
12960				this.overlay.remove();
12961				this.overlay = null;
12962			}
12963		}
12964	});
12965
12966	// DEPRECATED
12967	// TODO: switch return back to widget declaration at top of file when this is removed
12968	if ($.uiBackCompat === true) {
12969
12970		// Backcompat for dialogClass option
12971		$.widget("ui.dialog", $.ui.dialog, {
12972			options: {
12973				dialogClass: ""
12974			},
12975			_createWrapper: function () {
12976				this._super();
12977				this.uiDialog.addClass(this.options.dialogClass);
12978			},
12979			_setOption: function (key, value) {
12980				if (key === "dialogClass") {
12981					this.uiDialog
12982						.removeClass(this.options.dialogClass)
12983						.addClass(value);
12984				}
12985				this._superApply(arguments);
12986			}
12987		});
12988	}
12989
12990	var widgetsDialog = $.ui.dialog;
12991
12992
12993	/*!
12994	 * jQuery UI Droppable 1.14.1
12995	 * https://jqueryui.com
12996	 *
12997	 * Copyright OpenJS Foundation and other contributors
12998	 * Released under the MIT license.
12999	 * https://jquery.org/license
13000	 */
13001
13002	//>>label: Droppable
13003	//>>group: Interactions
13004	//>>description: Enables drop targets for draggable elements.
13005	//>>docs: https://api.jqueryui.com/droppable/
13006	//>>demos: https://jqueryui.com/droppable/
13007
13008
13009	$.widget("ui.droppable", {
13010		version: "1.14.1",
13011		widgetEventPrefix: "drop",
13012		options: {
13013			accept: "*",
13014			addClasses: true,
13015			greedy: false,
13016			scope: "default",
13017			tolerance: "intersect",
13018
13019			// Callbacks
13020			activate: null,
13021			deactivate: null,
13022			drop: null,
13023			out: null,
13024			over: null
13025		},
13026		_create: function () {
13027
13028			var proportions,
13029				o = this.options,
13030				accept = o.accept;
13031
13032			this.isover = false;
13033			this.isout = true;
13034
13035			this.accept = typeof accept === "function" ? accept : function (d) {
13036				return d.is(accept);
13037			};
13038
13039			this.proportions = function ( /* valueToWrite */) {
13040				if (arguments.length) {
13041
13042					// Store the droppable's proportions
13043					proportions = arguments[0];
13044				} else {
13045
13046					// Retrieve or derive the droppable's proportions
13047					return proportions ?
13048						proportions :
13049						proportions = {
13050							width: this.element[0].offsetWidth,
13051							height: this.element[0].offsetHeight
13052						};
13053				}
13054			};
13055
13056			this._addToManager(o.scope);
13057
13058			if (o.addClasses) {
13059				this._addClass("ui-droppable");
13060			}
13061
13062		},
13063
13064		_addToManager: function (scope) {
13065
13066			// Add the reference and positions to the manager
13067			$.ui.ddmanager.droppables[scope] = $.ui.ddmanager.droppables[scope] || [];
13068			$.ui.ddmanager.droppables[scope].push(this);
13069		},
13070
13071		_splice: function (drop) {
13072			var i = 0;
13073			for (; i < drop.length; i++) {
13074				if (drop[i] === this) {
13075					drop.splice(i, 1);
13076				}
13077			}
13078		},
13079
13080		_destroy: function () {
13081			var drop = $.ui.ddmanager.droppables[this.options.scope];
13082
13083			this._splice(drop);
13084		},
13085
13086		_setOption: function (key, value) {
13087
13088			if (key === "accept") {
13089				this.accept = typeof value === "function" ? value : function (d) {
13090					return d.is(value);
13091				};
13092			} else if (key === "scope") {
13093				var drop = $.ui.ddmanager.droppables[this.options.scope];
13094
13095				this._splice(drop);
13096				this._addToManager(value);
13097			}
13098
13099			this._super(key, value);
13100		},
13101
13102		_activate: function (event) {
13103			var draggable = $.ui.ddmanager.current;
13104
13105			this._addActiveClass();
13106			if (draggable) {
13107				this._trigger("activate", event, this.ui(draggable));
13108			}
13109		},
13110
13111		_deactivate: function (event) {
13112			var draggable = $.ui.ddmanager.current;
13113
13114			this._removeActiveClass();
13115			if (draggable) {
13116				this._trigger("deactivate", event, this.ui(draggable));
13117			}
13118		},
13119
13120		_over: function (event) {
13121
13122			var draggable = $.ui.ddmanager.current;
13123
13124			// Bail if draggable and droppable are same element
13125			if (!draggable || (draggable.currentItem ||
13126				draggable.element)[0] === this.element[0]) {
13127				return;
13128			}
13129
13130			if (this.accept.call(this.element[0], (draggable.currentItem ||
13131				draggable.element))) {
13132				this._addHoverClass();
13133				this._trigger("over", event, this.ui(draggable));
13134			}
13135
13136		},
13137
13138		_out: function (event) {
13139
13140			var draggable = $.ui.ddmanager.current;
13141
13142			// Bail if draggable and droppable are same element
13143			if (!draggable || (draggable.currentItem ||
13144				draggable.element)[0] === this.element[0]) {
13145				return;
13146			}
13147
13148			if (this.accept.call(this.element[0], (draggable.currentItem ||
13149				draggable.element))) {
13150				this._removeHoverClass();
13151				this._trigger("out", event, this.ui(draggable));
13152			}
13153
13154		},
13155
13156		_drop: function (event, custom) {
13157
13158			var draggable = custom || $.ui.ddmanager.current,
13159				childrenIntersection = false;
13160
13161			// Bail if draggable and droppable are same element
13162			if (!draggable || (draggable.currentItem ||
13163				draggable.element)[0] === this.element[0]) {
13164				return false;
13165			}
13166
13167			this.element
13168				.find(":data(ui-droppable)")
13169				.not(".ui-draggable-dragging")
13170				.each(function () {
13171					var inst = $(this).droppable("instance");
13172					if (
13173						inst.options.greedy &&
13174						!inst.options.disabled &&
13175						inst.options.scope === draggable.options.scope &&
13176						inst.accept.call(
13177							inst.element[0], (draggable.currentItem || draggable.element)
13178						) &&
13179						$.ui.intersect(
13180							draggable,
13181							$.extend(inst, { offset: inst.element.offset() }),
13182							inst.options.tolerance, event
13183						)
13184					) {
13185						childrenIntersection = true;
13186						return false;
13187					}
13188				});
13189			if (childrenIntersection) {
13190				return false;
13191			}
13192
13193			if (this.accept.call(this.element[0],
13194				(draggable.currentItem || draggable.element))) {
13195				this._removeActiveClass();
13196				this._removeHoverClass();
13197
13198				this._trigger("drop", event, this.ui(draggable));
13199				return this.element;
13200			}
13201
13202			return false;
13203
13204		},
13205
13206		ui: function (c) {
13207			return {
13208				draggable: (c.currentItem || c.element),
13209				helper: c.helper,
13210				position: c.position,
13211				offset: c.positionAbs
13212			};
13213		},
13214
13215		// Extension points just to make backcompat sane and avoid duplicating logic
13216		// TODO: Remove in 1.14 along with call to it below
13217		_addHoverClass: function () {
13218			this._addClass("ui-droppable-hover");
13219		},
13220
13221		_removeHoverClass: function () {
13222			this._removeClass("ui-droppable-hover");
13223		},
13224
13225		_addActiveClass: function () {
13226			this._addClass("ui-droppable-active");
13227		},
13228
13229		_removeActiveClass: function () {
13230			this._removeClass("ui-droppable-active");
13231		}
13232	});
13233
13234	$.ui.intersect = (function () {
13235		function isOverAxis(x, reference, size) {
13236			return (x >= reference) && (x < (reference + size));
13237		}
13238
13239		return function (draggable, droppable, toleranceMode, event) {
13240
13241			if (!droppable.offset) {
13242				return false;
13243			}
13244
13245			var x1 = (draggable.positionAbs ||
13246				draggable.position.absolute).left + draggable.margins.left,
13247				y1 = (draggable.positionAbs ||
13248					draggable.position.absolute).top + draggable.margins.top,
13249				x2 = x1 + draggable.helperProportions.width,
13250				y2 = y1 + draggable.helperProportions.height,
13251				l = droppable.offset.left,
13252				t = droppable.offset.top,
13253				r = l + droppable.proportions().width,
13254				b = t + droppable.proportions().height;
13255
13256			switch (toleranceMode) {
13257				case "fit":
13258					return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
13259				case "intersect":
13260					return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
13261						x2 - (draggable.helperProportions.width / 2) < r && // Left Half
13262						t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
13263						y2 - (draggable.helperProportions.height / 2) < b); // Top Half
13264				case "pointer":
13265					return isOverAxis(event.pageY, t, droppable.proportions().height) &&
13266						isOverAxis(event.pageX, l, droppable.proportions().width);
13267				case "touch":
13268					return (
13269						(y1 >= t && y1 <= b) || // Top edge touching
13270						(y2 >= t && y2 <= b) || // Bottom edge touching
13271						(y1 < t && y2 > b) // Surrounded vertically
13272					) && (
13273							(x1 >= l && x1 <= r) || // Left edge touching
13274							(x2 >= l && x2 <= r) || // Right edge touching
13275							(x1 < l && x2 > r) // Surrounded horizontally
13276						);
13277				default:
13278					return false;
13279			}
13280		};
13281	})();
13282
13283	/*
13284		This manager tracks offsets of draggables and droppables
13285	*/
13286	$.ui.ddmanager = {
13287		current: null,
13288		droppables: { "default": [] },
13289		prepareOffsets: function (t, event) {
13290
13291			var i, j,
13292				m = $.ui.ddmanager.droppables[t.options.scope] || [],
13293				type = event ? event.type : null, // workaround for #2317
13294				list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
13295
13296			droppablesLoop: for (i = 0; i < m.length; i++) {
13297
13298				// No disabled and non-accepted
13299				if (m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],
13300					(t.currentItem || t.element)))) {
13301					continue;
13302				}
13303
13304				// Filter out elements in the current dragged item
13305				for (j = 0; j < list.length; j++) {
13306					if (list[j] === m[i].element[0]) {
13307						m[i].proportions().height = 0;
13308						continue droppablesLoop;
13309					}
13310				}
13311
13312				m[i].visible = m[i].element.css("display") !== "none";
13313				if (!m[i].visible) {
13314					continue;
13315				}
13316
13317				// Activate the droppable if used directly from draggables
13318				if (type === "mousedown") {
13319					m[i]._activate.call(m[i], event);
13320				}
13321
13322				m[i].offset = m[i].element.offset();
13323				m[i].proportions({
13324					width: m[i].element[0].offsetWidth,
13325					height: m[i].element[0].offsetHeight
13326				});
13327
13328			}
13329
13330		},
13331		drop: function (draggable, event) {
13332
13333			var dropped = false;
13334
13335			// Create a copy of the droppables in case the list changes during the drop (#9116)
13336			$.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function () {
13337
13338				if (!this.options) {
13339					return;
13340				}
13341				if (!this.options.disabled && this.visible &&
13342					$.ui.intersect(draggable, this, this.options.tolerance, event)) {
13343					dropped = this._drop.call(this, event) || dropped;
13344				}
13345
13346				if (!this.options.disabled && this.visible && this.accept.call(this.element[0],
13347					(draggable.currentItem || draggable.element))) {
13348					this.isout = true;
13349					this.isover = false;
13350					this._deactivate.call(this, event);
13351				}
13352
13353			});
13354			return dropped;
13355
13356		},
13357		dragStart: function (draggable, event) {
13358
13359			// Listen for scrolling so that if the dragging causes scrolling the position of the
13360			// droppables can be recalculated (see #5003)
13361			draggable.element.parentsUntil("body").on("scroll.droppable", function () {
13362				if (!draggable.options.refreshPositions) {
13363					$.ui.ddmanager.prepareOffsets(draggable, event);
13364				}
13365			});
13366		},
13367		drag: function (draggable, event) {
13368
13369			// If you have a highly dynamic page, you might try this option. It renders positions
13370			// every time you move the mouse.
13371			if (draggable.options.refreshPositions) {
13372				$.ui.ddmanager.prepareOffsets(draggable, event);
13373			}
13374
13375			// Run through all droppables and check their positions based on specific tolerance options
13376			$.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function () {
13377
13378				if (this.options.disabled || this.greedyChild || !this.visible) {
13379					return;
13380				}
13381
13382				var parentInstance, scope, parent,
13383					intersects = $.ui.intersect(draggable, this, this.options.tolerance, event),
13384					c = !intersects && this.isover ?
13385						"isout" :
13386						(intersects && !this.isover ? "isover" : null);
13387				if (!c) {
13388					return;
13389				}
13390
13391				if (this.options.greedy) {
13392
13393					// find droppable parents with same scope
13394					scope = this.options.scope;
13395					parent = this.element.parents(":data(ui-droppable)").filter(function () {
13396						return $(this).droppable("instance").options.scope === scope;
13397					});
13398
13399					if (parent.length) {
13400						parentInstance = $(parent[0]).droppable("instance");
13401						parentInstance.greedyChild = (c === "isover");
13402					}
13403				}
13404
13405				// We just moved into a greedy child
13406				if (parentInstance && c === "isover") {
13407					parentInstance.isover = false;
13408					parentInstance.isout = true;
13409					parentInstance._out.call(parentInstance, event);
13410				}
13411
13412				this[c] = true;
13413				this[c === "isout" ? "isover" : "isout"] = false;
13414				this[c === "isover" ? "_over" : "_out"].call(this, event);
13415
13416				// We just moved out of a greedy child
13417				if (parentInstance && c === "isout") {
13418					parentInstance.isout = false;
13419					parentInstance.isover = true;
13420					parentInstance._over.call(parentInstance, event);
13421				}
13422			});
13423
13424		},
13425		dragStop: function (draggable, event) {
13426			draggable.element.parentsUntil("body").off("scroll.droppable");
13427
13428			// Call prepareOffsets one final time since IE does not fire return scroll events when
13429			// overflow was caused by drag (see #5003)
13430			if (!draggable.options.refreshPositions) {
13431				$.ui.ddmanager.prepareOffsets(draggable, event);
13432			}
13433		}
13434	};
13435
13436	// DEPRECATED
13437	// TODO: switch return back to widget declaration at top of file when this is removed
13438	if ($.uiBackCompat === true) {
13439
13440		// Backcompat for activeClass and hoverClass options
13441		$.widget("ui.droppable", $.ui.droppable, {
13442			options: {
13443				hoverClass: false,
13444				activeClass: false
13445			},
13446			_addActiveClass: function () {
13447				this._super();
13448				if (this.options.activeClass) {
13449					this.element.addClass(this.options.activeClass);
13450				}
13451			},
13452			_removeActiveClass: function () {
13453				this._super();
13454				if (this.options.activeClass) {
13455					this.element.removeClass(this.options.activeClass);
13456				}
13457			},
13458			_addHoverClass: function () {
13459				this._super();
13460				if (this.options.hoverClass) {
13461					this.element.addClass(this.options.hoverClass);
13462				}
13463			},
13464			_removeHoverClass: function () {
13465				this._super();
13466				if (this.options.hoverClass) {
13467					this.element.removeClass(this.options.hoverClass);
13468				}
13469			}
13470		});
13471	}
13472
13473	var widgetsDroppable = $.ui.droppable;
13474
13475
13476	/*!
13477	 * jQuery UI Progressbar 1.14.1
13478	 * https://jqueryui.com
13479	 *
13480	 * Copyright OpenJS Foundation and other contributors
13481	 * Released under the MIT license.
13482	 * https://jquery.org/license
13483	 */
13484
13485	//>>label: Progressbar
13486	//>>group: Widgets
13487	/* eslint-disable max-len */
13488	//>>description: Displays a status indicator for loading state, standard percentage, and other progress indicators.
13489	/* eslint-enable max-len */
13490	//>>docs: https://api.jqueryui.com/progressbar/
13491	//>>demos: https://jqueryui.com/progressbar/
13492	//>>css.structure: ../../themes/base/core.css
13493	//>>css.structure: ../../themes/base/progressbar.css
13494	//>>css.theme: ../../themes/base/theme.css
13495
13496
13497	var widgetsProgressbar = $.widget("ui.progressbar", {
13498		version: "1.14.1",
13499		options: {
13500			classes: {
13501				"ui-progressbar": "ui-corner-all",
13502				"ui-progressbar-value": "ui-corner-left",
13503				"ui-progressbar-complete": "ui-corner-right"
13504			},
13505			max: 100,
13506			value: 0,
13507
13508			change: null,
13509			complete: null
13510		},
13511
13512		min: 0,
13513
13514		_create: function () {
13515
13516			// Constrain initial value
13517			this.oldValue = this.options.value = this._constrainedValue();
13518
13519			this.element.attr({
13520
13521				// Only set static values; aria-valuenow and aria-valuemax are
13522				// set inside _refreshValue()
13523				role: "progressbar",
13524				"aria-valuemin": this.min
13525			});
13526			this._addClass("ui-progressbar", "ui-widget ui-widget-content");
13527
13528			this.valueDiv = $("<div>").appendTo(this.element);
13529			this._addClass(this.valueDiv, "ui-progressbar-value", "ui-widget-header");
13530			this._refreshValue();
13531		},
13532
13533		_destroy: function () {
13534			this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow");
13535
13536			this.valueDiv.remove();
13537		},
13538
13539		value: function (newValue) {
13540			if (newValue === undefined) {
13541				return this.options.value;
13542			}
13543
13544			this.options.value = this._constrainedValue(newValue);
13545			this._refreshValue();
13546		},
13547
13548		_constrainedValue: function (newValue) {
13549			if (newValue === undefined) {
13550				newValue = this.options.value;
13551			}
13552
13553			this.indeterminate = newValue === false;
13554
13555			// Sanitize value
13556			if (typeof newValue !== "number") {
13557				newValue = 0;
13558			}
13559
13560			return this.indeterminate ? false :
13561				Math.min(this.options.max, Math.max(this.min, newValue));
13562		},
13563
13564		_setOptions: function (options) {
13565
13566			// Ensure "value" option is set after other values (like max)
13567			var value = options.value;
13568			delete options.value;
13569
13570			this._super(options);
13571
13572			this.options.value = this._constrainedValue(value);
13573			this._refreshValue();
13574		},
13575
13576		_setOption: function (key, value) {
13577			if (key === "max") {
13578
13579				// Don't allow a max less than min
13580				value = Math.max(this.min, value);
13581			}
13582			this._super(key, value);
13583		},
13584
13585		_setOptionDisabled: function (value) {
13586			this._super(value);
13587
13588			this.element.attr("aria-disabled", value);
13589			this._toggleClass(null, "ui-state-disabled", !!value);
13590		},
13591
13592		_percentage: function () {
13593			return this.indeterminate ?
13594				100 :
13595				100 * (this.options.value - this.min) / (this.options.max - this.min);
13596		},
13597
13598		_refreshValue: function () {
13599			var value = this.options.value,
13600				percentage = this._percentage();
13601
13602			this.valueDiv
13603				.toggle(this.indeterminate || value > this.min)
13604				.width(percentage.toFixed(0) + "%");
13605
13606			this
13607				._toggleClass(this.valueDiv, "ui-progressbar-complete", null,
13608					value === this.options.max)
13609				._toggleClass("ui-progressbar-indeterminate", null, this.indeterminate);
13610
13611			if (this.indeterminate) {
13612				this.element.removeAttr("aria-valuenow");
13613				if (!this.overlayDiv) {
13614					this.overlayDiv = $("<div>").appendTo(this.valueDiv);
13615					this._addClass(this.overlayDiv, "ui-progressbar-overlay");
13616				}
13617			} else {
13618				this.element.attr({
13619					"aria-valuemax": this.options.max,
13620					"aria-valuenow": value
13621				});
13622				if (this.overlayDiv) {
13623					this.overlayDiv.remove();
13624					this.overlayDiv = null;
13625				}
13626			}
13627
13628			if (this.oldValue !== value) {
13629				this.oldValue = value;
13630				this._trigger("change");
13631			}
13632			if (value === this.options.max) {
13633				this._trigger("complete");
13634			}
13635		}
13636	});
13637
13638
13639	/*!
13640	 * jQuery UI Selectable 1.14.1
13641	 * https://jqueryui.com
13642	 *
13643	 * Copyright OpenJS Foundation and other contributors
13644	 * Released under the MIT license.
13645	 * https://jquery.org/license
13646	 */
13647
13648	//>>label: Selectable
13649	//>>group: Interactions
13650	//>>description: Allows groups of elements to be selected with the mouse.
13651	//>>docs: https://api.jqueryui.com/selectable/
13652	//>>demos: https://jqueryui.com/selectable/
13653	//>>css.structure: ../../themes/base/selectable.css
13654
13655
13656	var widgetsSelectable = $.widget("ui.selectable", $.ui.mouse, {
13657		version: "1.14.1",
13658		options: {
13659			appendTo: "body",
13660			autoRefresh: true,
13661			distance: 0,
13662			filter: "*",
13663			tolerance: "touch",
13664
13665			// Callbacks
13666			selected: null,
13667			selecting: null,
13668			start: null,
13669			stop: null,
13670			unselected: null,
13671			unselecting: null
13672		},
13673		_create: function () {
13674			var that = this;
13675
13676			this._addClass("ui-selectable");
13677
13678			this.dragged = false;
13679
13680			// Cache selectee children based on filter
13681			this.refresh = function () {
13682				that.elementPos = $(that.element[0]).offset();
13683				that.selectees = $(that.options.filter, that.element[0]);
13684				that._addClass(that.selectees, "ui-selectee");
13685				that.selectees.each(function () {
13686					var $this = $(this),
13687						selecteeOffset = $this.offset(),
13688						pos = {
13689							left: selecteeOffset.left - that.elementPos.left,
13690							top: selecteeOffset.top - that.elementPos.top
13691						};
13692					$.data(this, "selectable-item", {
13693						element: this,
13694						$element: $this,
13695						left: pos.left,
13696						top: pos.top,
13697						right: pos.left + $this.outerWidth(),
13698						bottom: pos.top + $this.outerHeight(),
13699						startselected: false,
13700						selected: $this.hasClass("ui-selected"),
13701						selecting: $this.hasClass("ui-selecting"),
13702						unselecting: $this.hasClass("ui-unselecting")
13703					});
13704				});
13705			};
13706			this.refresh();
13707
13708			this._mouseInit();
13709
13710			this.helper = $("<div>");
13711			this._addClass(this.helper, "ui-selectable-helper");
13712		},
13713
13714		_destroy: function () {
13715			this.selectees.removeData("selectable-item");
13716			this._mouseDestroy();
13717		},
13718
13719		_mouseStart: function (event) {
13720			var that = this,
13721				options = this.options;
13722
13723			this.opos = [event.pageX, event.pageY];
13724			this.elementPos = $(this.element[0]).offset();
13725
13726			if (this.options.disabled) {
13727				return;
13728			}
13729
13730			this.selectees = $(options.filter, this.element[0]);
13731
13732			this._trigger("start", event);
13733
13734			$(options.appendTo).append(this.helper);
13735
13736			// position helper (lasso)
13737			this.helper.css({
13738				"left": event.pageX,
13739				"top": event.pageY,
13740				"width": 0,
13741				"height": 0
13742			});
13743
13744			if (options.autoRefresh) {
13745				this.refresh();
13746			}
13747
13748			this.selectees.filter(".ui-selected").each(function () {
13749				var selectee = $.data(this, "selectable-item");
13750				selectee.startselected = true;
13751				if (!event.metaKey && !event.ctrlKey) {
13752					that._removeClass(selectee.$element, "ui-selected");
13753					selectee.selected = false;
13754					that._addClass(selectee.$element, "ui-unselecting");
13755					selectee.unselecting = true;
13756
13757					// selectable UNSELECTING callback
13758					that._trigger("unselecting", event, {
13759						unselecting: selectee.element
13760					});
13761				}
13762			});
13763
13764			$(event.target).parents().addBack().each(function () {
13765				var doSelect,
13766					selectee = $.data(this, "selectable-item");
13767				if (selectee) {
13768					doSelect = (!event.metaKey && !event.ctrlKey) ||
13769						!selectee.$element.hasClass("ui-selected");
13770					that._removeClass(selectee.$element, doSelect ? "ui-unselecting" : "ui-selected")
13771						._addClass(selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting");
13772					selectee.unselecting = !doSelect;
13773					selectee.selecting = doSelect;
13774					selectee.selected = doSelect;
13775
13776					// selectable (UN)SELECTING callback
13777					if (doSelect) {
13778						that._trigger("selecting", event, {
13779							selecting: selectee.element
13780						});
13781					} else {
13782						that._trigger("unselecting", event, {
13783							unselecting: selectee.element
13784						});
13785					}
13786					return false;
13787				}
13788			});
13789
13790		},
13791
13792		_mouseDrag: function (event) {
13793
13794			this.dragged = true;
13795
13796			if (this.options.disabled) {
13797				return;
13798			}
13799
13800			var tmp,
13801				that = this,
13802				options = this.options,
13803				x1 = this.opos[0],
13804				y1 = this.opos[1],
13805				x2 = event.pageX,
13806				y2 = event.pageY;
13807
13808			if (x1 > x2) {
13809				tmp = x2; x2 = x1; x1 = tmp;
13810			}
13811			if (y1 > y2) {
13812				tmp = y2; y2 = y1; y1 = tmp;
13813			}
13814			this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });
13815
13816			this.selectees.each(function () {
13817				var selectee = $.data(this, "selectable-item"),
13818					hit = false,
13819					offset = {};
13820
13821				//prevent helper from being selected if appendTo: selectable
13822				if (!selectee || selectee.element === that.element[0]) {
13823					return;
13824				}
13825
13826				offset.left = selectee.left + that.elementPos.left;
13827				offset.right = selectee.right + that.elementPos.left;
13828				offset.top = selectee.top + that.elementPos.top;
13829				offset.bottom = selectee.bottom + that.elementPos.top;
13830
13831				if (options.tolerance === "touch") {
13832					hit = (!(offset.left > x2 || offset.right < x1 || offset.top > y2 ||
13833						offset.bottom < y1));
13834				} else if (options.tolerance === "fit") {
13835					hit = (offset.left > x1 && offset.right < x2 && offset.top > y1 &&
13836						offset.bottom < y2);
13837				}
13838
13839				if (hit) {
13840
13841					// SELECT
13842					if (selectee.selected) {
13843						that._removeClass(selectee.$element, "ui-selected");
13844						selectee.selected = false;
13845					}
13846					if (selectee.unselecting) {
13847						that._removeClass(selectee.$element, "ui-unselecting");
13848						selectee.unselecting = false;
13849					}
13850					if (!selectee.selecting) {
13851						that._addClass(selectee.$element, "ui-selecting");
13852						selectee.selecting = true;
13853
13854						// selectable SELECTING callback
13855						that._trigger("selecting", event, {
13856							selecting: selectee.element
13857						});
13858					}
13859				} else {
13860
13861					// UNSELECT
13862					if (selectee.selecting) {
13863						if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
13864							that._removeClass(selectee.$element, "ui-selecting");
13865							selectee.selecting = false;
13866							that._addClass(selectee.$element, "ui-selected");
13867							selectee.selected = true;
13868						} else {
13869							that._removeClass(selectee.$element, "ui-selecting");
13870							selectee.selecting = false;
13871							if (selectee.startselected) {
13872								that._addClass(selectee.$element, "ui-unselecting");
13873								selectee.unselecting = true;
13874							}
13875
13876							// selectable UNSELECTING callback
13877							that._trigger("unselecting", event, {
13878								unselecting: selectee.element
13879							});
13880						}
13881					}
13882					if (selectee.selected) {
13883						if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
13884							that._removeClass(selectee.$element, "ui-selected");
13885							selectee.selected = false;
13886
13887							that._addClass(selectee.$element, "ui-unselecting");
13888							selectee.unselecting = true;
13889
13890							// selectable UNSELECTING callback
13891							that._trigger("unselecting", event, {
13892								unselecting: selectee.element
13893							});
13894						}
13895					}
13896				}
13897			});
13898
13899			return false;
13900		},
13901
13902		_mouseStop: function (event) {
13903			var that = this;
13904
13905			this.dragged = false;
13906
13907			$(".ui-unselecting", this.element[0]).each(function () {
13908				var selectee = $.data(this, "selectable-item");
13909				that._removeClass(selectee.$element, "ui-unselecting");
13910				selectee.unselecting = false;
13911				selectee.startselected = false;
13912				that._trigger("unselected", event, {
13913					unselected: selectee.element
13914				});
13915			});
13916			$(".ui-selecting", this.element[0]).each(function () {
13917				var selectee = $.data(this, "selectable-item");
13918				that._removeClass(selectee.$element, "ui-selecting")
13919					._addClass(selectee.$element, "ui-selected");
13920				selectee.selecting = false;
13921				selectee.selected = true;
13922				selectee.startselected = true;
13923				that._trigger("selected", event, {
13924					selected: selectee.element
13925				});
13926			});
13927			this._trigger("stop", event);
13928
13929			this.helper.remove();
13930
13931			return false;
13932		}
13933
13934	});
13935
13936
13937	/*!
13938	 * jQuery UI Selectmenu 1.14.1
13939	 * https://jqueryui.com
13940	 *
13941	 * Copyright OpenJS Foundation and other contributors
13942	 * Released under the MIT license.
13943	 * https://jquery.org/license
13944	 */
13945
13946	//>>label: Selectmenu
13947	//>>group: Widgets
13948	/* eslint-disable max-len */
13949	//>>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.
13950	/* eslint-enable max-len */
13951	//>>docs: https://api.jqueryui.com/selectmenu/
13952	//>>demos: https://jqueryui.com/selectmenu/
13953	//>>css.structure: ../../themes/base/core.css
13954	//>>css.structure: ../../themes/base/selectmenu.css, ../../themes/base/button.css
13955	//>>css.theme: ../../themes/base/theme.css
13956
13957
13958	var widgetsSelectmenu = $.widget("ui.selectmenu", [$.ui.formResetMixin, {
13959		version: "1.14.1",
13960		defaultElement: "<select>",
13961		options: {
13962			appendTo: null,
13963			classes: {
13964				"ui-selectmenu-button-open": "ui-corner-top",
13965				"ui-selectmenu-button-closed": "ui-corner-all"
13966			},
13967			disabled: null,
13968			icons: {
13969				button: "ui-icon-triangle-1-s"
13970			},
13971			position: {
13972				my: "left top",
13973				at: "left bottom",
13974				collision: "none"
13975			},
13976			width: false,
13977
13978			// Callbacks
13979			change: null,
13980			close: null,
13981			focus: null,
13982			open: null,
13983			select: null
13984		},
13985
13986		_create: function () {
13987			var selectmenuId = this.element.uniqueId().attr("id");
13988			this.ids = {
13989				element: selectmenuId,
13990				button: selectmenuId + "-button",
13991				menu: selectmenuId + "-menu"
13992			};
13993
13994			this._drawButton();
13995			this._drawMenu();
13996			this._bindFormResetHandler();
13997
13998			this._rendered = false;
13999			this.menuItems = $();
14000		},
14001
14002		_drawButton: function () {
14003			var icon,
14004				that = this,
14005				item = this._parseOption(
14006					this.element.find("option:selected"),
14007					this.element[0].selectedIndex
14008				);
14009
14010			// Associate existing label with the new button
14011			this.labels = this.element.labels().attr("for", this.ids.button);
14012			this._on(this.labels, {
14013				click: function (event) {
14014					this.button.trigger("focus");
14015					event.preventDefault();
14016				}
14017			});
14018
14019			// Hide original select element
14020			this.element.hide();
14021
14022			// Create button
14023			this.button = $("<span>", {
14024				tabindex: this.options.disabled ? -1 : 0,
14025				id: this.ids.button,
14026				role: "combobox",
14027				"aria-expanded": "false",
14028				"aria-autocomplete": "list",
14029				"aria-owns": this.ids.menu,
14030				"aria-haspopup": "true",
14031				title: this.element.attr("title")
14032			})
14033				.insertAfter(this.element);
14034
14035			this._addClass(this.button, "ui-selectmenu-button ui-selectmenu-button-closed",
14036				"ui-button ui-widget");
14037
14038			icon = $("<span>").appendTo(this.button);
14039			this._addClass(icon, "ui-selectmenu-icon", "ui-icon " + this.options.icons.button);
14040			this.buttonItem = this._renderButtonItem(item)
14041				.appendTo(this.button);
14042
14043			if (this.options.width !== false) {
14044				this._resizeButton();
14045			}
14046
14047			this._on(this.button, this._buttonEvents);
14048			this.button.one("focusin", function () {
14049
14050				// Delay rendering the menu items until the button receives focus.
14051				// The menu may have already been rendered via a programmatic open.
14052				if (!that._rendered) {
14053					that._refreshMenu();
14054				}
14055			});
14056		},
14057
14058		_drawMenu: function () {
14059			var that = this;
14060
14061			// Create menu
14062			this.menu = $("<ul>", {
14063				"aria-hidden": "true",
14064				"aria-labelledby": this.ids.button,
14065				id: this.ids.menu
14066			});
14067
14068			// Wrap menu
14069			this.menuWrap = $("<div>").append(this.menu);
14070			this._addClass(this.menuWrap, "ui-selectmenu-menu", "ui-front");
14071			this.menuWrap.appendTo(this._appendTo());
14072
14073			// Initialize menu widget
14074			this.menuInstance = this.menu
14075				.menu({
14076					classes: {
14077						"ui-menu": "ui-corner-bottom"
14078					},
14079					role: "listbox",
14080					select: function (event, ui) {
14081						event.preventDefault();
14082						that._select(ui.item.data("ui-selectmenu-item"), event);
14083					},
14084					focus: function (event, ui) {
14085						var item = ui.item.data("ui-selectmenu-item");
14086
14087						// Prevent inital focus from firing and check if its a newly focused item
14088						if (that.focusIndex != null && item.index !== that.focusIndex) {
14089							that._trigger("focus", event, { item: item });
14090							if (!that.isOpen) {
14091								that._select(item, event);
14092							}
14093						}
14094						that.focusIndex = item.index;
14095
14096						that.button.attr("aria-activedescendant",
14097							that.menuItems.eq(item.index).attr("id"));
14098					}
14099				})
14100				.menu("instance");
14101
14102			// Don't close the menu on mouseleave
14103			this.menuInstance._off(this.menu, "mouseleave");
14104
14105			// Cancel the menu's collapseAll on document click
14106			this.menuInstance._closeOnDocumentClick = function () {
14107				return false;
14108			};
14109
14110			// Selects often contain empty items, but never contain dividers
14111			this.menuInstance._isDivider = function () {
14112				return false;
14113			};
14114		},
14115
14116		refresh: function () {
14117			this._refreshMenu();
14118			this.buttonItem.replaceWith(
14119				this.buttonItem = this._renderButtonItem(
14120
14121					// Fall back to an empty object in case there are no options
14122					this._getSelectedItem().data("ui-selectmenu-item") || {}
14123				)
14124			);
14125			if (this.options.width === null) {
14126				this._resizeButton();
14127			}
14128		},
14129
14130		_refreshMenu: function () {
14131			var item,
14132				options = this.element.find("option");
14133
14134			this.menu.empty();
14135
14136			this._parseOptions(options);
14137			this._renderMenu(this.menu, this.items);
14138
14139			this.menuInstance.refresh();
14140			this.menuItems = this.menu.find("li")
14141				.not(".ui-selectmenu-optgroup")
14142				.find(".ui-menu-item-wrapper");
14143
14144			this._rendered = true;
14145
14146			if (!options.length) {
14147				return;
14148			}
14149
14150			item = this._getSelectedItem();
14151
14152			// Update the menu to have the correct item focused
14153			this.menuInstance.focus(null, item);
14154			this._setAria(item.data("ui-selectmenu-item"));
14155
14156			// Set disabled state
14157			this._setOption("disabled", this.element.prop("disabled"));
14158		},
14159
14160		open: function (event) {
14161			if (this.options.disabled) {
14162				return;
14163			}
14164
14165			// If this is the first time the menu is being opened, render the items
14166			if (!this._rendered) {
14167				this._refreshMenu();
14168			} else {
14169
14170				// Menu clears focus on close, reset focus to selected item
14171				this._removeClass(this.menu.find(".ui-state-active"), null, "ui-state-active");
14172				this.menuInstance.focus(null, this._getSelectedItem());
14173			}
14174
14175			// If there are no options, don't open the menu
14176			if (!this.menuItems.length) {
14177				return;
14178			}
14179
14180			this.isOpen = true;
14181			this._toggleAttr();
14182			this._resizeMenu();
14183			this._position();
14184
14185			this._on(this.document, this._documentClick);
14186
14187			this._trigger("open", event);
14188		},
14189
14190		_position: function () {
14191			this.menuWrap.position($.extend({ of: this.button }, this.options.position));
14192		},
14193
14194		close: function (event) {
14195			if (!this.isOpen) {
14196				return;
14197			}
14198
14199			this.isOpen = false;
14200			this._toggleAttr();
14201
14202			this.range = null;
14203			this._off(this.document);
14204
14205			this._trigger("close", event);
14206		},
14207
14208		widget: function () {
14209			return this.button;
14210		},
14211
14212		menuWidget: function () {
14213			return this.menu;
14214		},
14215
14216		_renderButtonItem: function (item) {
14217			var buttonItem = $("<span>");
14218
14219			this._setText(buttonItem, item.label);
14220			this._addClass(buttonItem, "ui-selectmenu-text");
14221
14222			return buttonItem;
14223		},
14224
14225		_renderMenu: function (ul, items) {
14226			var that = this,
14227				currentOptgroup = "";
14228
14229			$.each(items, function (index, item) {
14230				var li;
14231
14232				if (item.optgroup !== currentOptgroup) {
14233					li = $("<li>", {
14234						text: item.optgroup
14235					});
14236					that._addClass(li, "ui-selectmenu-optgroup", "ui-menu-divider" +
14237						(item.element.parent("optgroup").prop("disabled") ?
14238							" ui-state-disabled" :
14239							""));
14240
14241					li.appendTo(ul);
14242
14243					currentOptgroup = item.optgroup;
14244				}
14245
14246				that._renderItemData(ul, item);
14247			});
14248		},
14249
14250		_renderItemData: function (ul, item) {
14251			return this._renderItem(ul, item).data("ui-selectmenu-item", item);
14252		},
14253
14254		_renderItem: function (ul, item) {
14255			var li = $("<li>"),
14256				wrapper = $("<div>", {
14257					title: item.element.attr("title")
14258				});
14259
14260			if (item.disabled) {
14261				this._addClass(li, null, "ui-state-disabled");
14262			}
14263
14264			if (item.hidden) {
14265				li.prop("hidden", true);
14266			} else {
14267				this._setText(wrapper, item.label);
14268			}
14269
14270			return li.append(wrapper).appendTo(ul);
14271		},
14272
14273		_setText: function (element, value) {
14274			if (value) {
14275				element.text(value);
14276			} else {
14277				element.html("&#160;");
14278			}
14279		},
14280
14281		_move: function (direction, event) {
14282			var item, next,
14283				filter = ".ui-menu-item";
14284
14285			if (this.isOpen) {
14286				item = this.menuItems.eq(this.focusIndex).parent("li");
14287			} else {
14288				item = this.menuItems.eq(this.element[0].selectedIndex).parent("li");
14289				filter += ":not(.ui-state-disabled)";
14290			}
14291
14292			if (direction === "first" || direction === "last") {
14293				next = item[direction === "first" ? "prevAll" : "nextAll"](filter).eq(-1);
14294			} else {
14295				next = item[direction + "All"](filter).eq(0);
14296			}
14297
14298			if (next.length) {
14299				this.menuInstance.focus(event, next);
14300			}
14301		},
14302
14303		_getSelectedItem: function () {
14304			return this.menuItems.eq(this.element[0].selectedIndex).parent("li");
14305		},
14306
14307		_toggle: function (event) {
14308			this[this.isOpen ? "close" : "open"](event);
14309		},
14310
14311		_setSelection: function () {
14312			var selection;
14313
14314			if (!this.range) {
14315				return;
14316			}
14317
14318			selection = window.getSelection();
14319			selection.removeAllRanges();
14320			selection.addRange(this.range);
14321		},
14322
14323		_documentClick: {
14324			mousedown: function (event) {
14325				if (!this.isOpen) {
14326					return;
14327				}
14328
14329				if (!$(event.target).closest(".ui-selectmenu-menu, #" +
14330					CSS.escape(this.ids.button)).length) {
14331					this.close(event);
14332				}
14333			}
14334		},
14335
14336		_buttonEvents: {
14337
14338			// Prevent text selection from being reset when interacting with the selectmenu (#10144)
14339			mousedown: function () {
14340				var selection = window.getSelection();
14341				if (selection.rangeCount) {
14342					this.range = selection.getRangeAt(0);
14343				}
14344			},
14345
14346			click: function (event) {
14347				this._setSelection();
14348				this._toggle(event);
14349			},
14350
14351			keydown: function (event) {
14352				var preventDefault = true;
14353				switch (event.keyCode) {
14354					case $.ui.keyCode.TAB:
14355					case $.ui.keyCode.ESCAPE:
14356						this.close(event);
14357						preventDefault = false;
14358						break;
14359					case $.ui.keyCode.ENTER:
14360						if (this.isOpen) {
14361							this._selectFocusedItem(event);
14362						}
14363						break;
14364					case $.ui.keyCode.UP:
14365						if (event.altKey) {
14366							this._toggle(event);
14367						} else {
14368							this._move("prev", event);
14369						}
14370						break;
14371					case $.ui.keyCode.DOWN:
14372						if (event.altKey) {
14373							this._toggle(event);
14374						} else {
14375							this._move("next", event);
14376						}
14377						break;
14378					case $.ui.keyCode.SPACE:
14379						if (this.isOpen) {
14380							this._selectFocusedItem(event);
14381						} else {
14382							this._toggle(event);
14383						}
14384						break;
14385					case $.ui.keyCode.LEFT:
14386						this._move("prev", event);
14387						break;
14388					case $.ui.keyCode.RIGHT:
14389						this._move("next", event);
14390						break;
14391					case $.ui.keyCode.HOME:
14392					case $.ui.keyCode.PAGE_UP:
14393						this._move("first", event);
14394						break;
14395					case $.ui.keyCode.END:
14396					case $.ui.keyCode.PAGE_DOWN:
14397						this._move("last", event);
14398						break;
14399					default:
14400						this.menu.trigger(event);
14401						preventDefault = false;
14402				}
14403
14404				if (preventDefault) {
14405					event.preventDefault();
14406				}
14407			}
14408		},
14409
14410		_selectFocusedItem: function (event) {
14411			var item = this.menuItems.eq(this.focusIndex).parent("li");
14412			if (!item.hasClass("ui-state-disabled")) {
14413				this._select(item.data("ui-selectmenu-item"), event);
14414			}
14415		},
14416
14417		_select: function (item, event) {
14418			var oldIndex = this.element[0].selectedIndex;
14419
14420			// Change native select element
14421			this.element[0].selectedIndex = item.index;
14422			this.buttonItem.replaceWith(this.buttonItem = this._renderButtonItem(item));
14423			this._setAria(item);
14424			this._trigger("select", event, { item: item });
14425
14426			if (item.index !== oldIndex) {
14427				this._trigger("change", event, { item: item });
14428			}
14429
14430			this.close(event);
14431		},
14432
14433		_setAria: function (item) {
14434			var id = this.menuItems.eq(item.index).attr("id");
14435
14436			this.button.attr({
14437				"aria-labelledby": id,
14438				"aria-activedescendant": id
14439			});
14440			this.menu.attr("aria-activedescendant", id);
14441		},
14442
14443		_setOption: function (key, value) {
14444			if (key === "icons") {
14445				var icon = this.button.find("span.ui-icon");
14446				this._removeClass(icon, null, this.options.icons.button)
14447					._addClass(icon, null, value.button);
14448			}
14449
14450			this._super(key, value);
14451
14452			if (key === "appendTo") {
14453				this.menuWrap.appendTo(this._appendTo());
14454			}
14455
14456			if (key === "width") {
14457				this._resizeButton();
14458			}
14459		},
14460
14461		_setOptionDisabled: function (value) {
14462			this._super(value);
14463
14464			this.menuInstance.option("disabled", value);
14465			this.button.attr("aria-disabled", value);
14466			this._toggleClass(this.button, null, "ui-state-disabled", value);
14467
14468			this.element.prop("disabled", value);
14469			if (value) {
14470				this.button.attr("tabindex", -1);
14471				this.close();
14472			} else {
14473				this.button.attr("tabindex", 0);
14474			}
14475		},
14476
14477		_appendTo: function () {
14478			var element = this.options.appendTo;
14479
14480			if (element) {
14481				element = element.jquery || element.nodeType ?
14482					$(element) :
14483					this.document.find(element).eq(0);
14484			}
14485
14486			if (!element || !element[0]) {
14487				element = this.element.closest(".ui-front, dialog");
14488			}
14489
14490			if (!element.length) {
14491				element = this.document[0].body;
14492			}
14493
14494			return element;
14495		},
14496
14497		_toggleAttr: function () {
14498			this.button.attr("aria-expanded", this.isOpen);
14499
14500			// We can't use two _toggleClass() calls here, because we need to make sure
14501			// we always remove classes first and add them second, otherwise if both classes have the
14502			// same theme class, it will be removed after we add it.
14503			this._removeClass(this.button, "ui-selectmenu-button-" +
14504				(this.isOpen ? "closed" : "open"))
14505				._addClass(this.button, "ui-selectmenu-button-" +
14506					(this.isOpen ? "open" : "closed"))
14507				._toggleClass(this.menuWrap, "ui-selectmenu-open", null, this.isOpen);
14508
14509			this.menu.attr("aria-hidden", !this.isOpen);
14510		},
14511
14512		_resizeButton: function () {
14513			var width = this.options.width;
14514
14515			// For `width: false`, just remove inline style and stop
14516			if (width === false) {
14517				this.button.css("width", "");
14518				return;
14519			}
14520
14521			// For `width: null`, match the width of the original element
14522			if (width === null) {
14523				width = this.element.show().outerWidth();
14524				this.element.hide();
14525			}
14526
14527			this.button.outerWidth(width);
14528		},
14529
14530		_resizeMenu: function () {
14531			this.menu.outerWidth(Math.max(
14532				this.button.outerWidth(),
14533				this.menu.width("").outerWidth()
14534			));
14535		},
14536
14537		_getCreateOptions: function () {
14538			var options = this._super();
14539
14540			options.disabled = this.element.prop("disabled");
14541
14542			return options;
14543		},
14544
14545		_parseOptions: function (options) {
14546			var that = this,
14547				data = [];
14548			options.each(function (index, item) {
14549				data.push(that._parseOption($(item), index));
14550			});
14551			this.items = data;
14552		},
14553
14554		_parseOption: function (option, index) {
14555			var optgroup = option.parent("optgroup");
14556
14557			return {
14558				element: option,
14559				index: index,
14560				value: option.val(),
14561				label: option.text(),
14562				hidden: optgroup.prop("hidden") || option.prop("hidden"),
14563				optgroup: optgroup.attr("label") || "",
14564				disabled: optgroup.prop("disabled") || option.prop("disabled")
14565			};
14566		},
14567
14568		_destroy: function () {
14569			this._unbindFormResetHandler();
14570			this.menuWrap.remove();
14571			this.button.remove();
14572			this.element.show();
14573			this.element.removeUniqueId();
14574			this.labels.attr("for", this.ids.element);
14575		}
14576	}]);
14577
14578
14579	/*!
14580	 * jQuery UI Slider 1.14.1
14581	 * https://jqueryui.com
14582	 *
14583	 * Copyright OpenJS Foundation and other contributors
14584	 * Released under the MIT license.
14585	 * https://jquery.org/license
14586	 */
14587
14588	//>>label: Slider
14589	//>>group: Widgets
14590	//>>description: Displays a flexible slider with ranges and accessibility via keyboard.
14591	//>>docs: https://api.jqueryui.com/slider/
14592	//>>demos: https://jqueryui.com/slider/
14593	//>>css.structure: ../../themes/base/core.css
14594	//>>css.structure: ../../themes/base/slider.css
14595	//>>css.theme: ../../themes/base/theme.css
14596
14597
14598	var widgetsSlider = $.widget("ui.slider", $.ui.mouse, {
14599		version: "1.14.1",
14600		widgetEventPrefix: "slide",
14601
14602		options: {
14603			animate: false,
14604			classes: {
14605				"ui-slider": "ui-corner-all",
14606				"ui-slider-handle": "ui-corner-all",
14607
14608				// Note: ui-widget-header isn't the most fittingly semantic framework class for this
14609				// element, but worked best visually with a variety of themes
14610				"ui-slider-range": "ui-corner-all ui-widget-header"
14611			},
14612			distance: 0,
14613			max: 100,
14614			min: 0,
14615			orientation: "horizontal",
14616			range: false,
14617			step: 1,
14618			value: 0,
14619			values: null,
14620
14621			// Callbacks
14622			change: null,
14623			slide: null,
14624			start: null,
14625			stop: null
14626		},
14627
14628		// Number of pages in a slider
14629		// (how many times can you page up/down to go through the whole range)
14630		numPages: 5,
14631
14632		_create: function () {
14633			this._keySliding = false;
14634			this._mouseSliding = false;
14635			this._animateOff = true;
14636			this._handleIndex = null;
14637			this._detectOrientation();
14638			this._mouseInit();
14639			this._calculateNewMax();
14640
14641			this._addClass("ui-slider ui-slider-" + this.orientation,
14642				"ui-widget ui-widget-content");
14643
14644			this._refresh();
14645
14646			this._animateOff = false;
14647		},
14648
14649		_refresh: function () {
14650			this._createRange();
14651			this._createHandles();
14652			this._setupEvents();
14653			this._refreshValue();
14654		},
14655
14656		_createHandles: function () {
14657			var i, handleCount,
14658				options = this.options,
14659				existingHandles = this.element.find(".ui-slider-handle"),
14660				handle = "<span tabindex='0'></span>",
14661				handles = [];
14662
14663			handleCount = (options.values && options.values.length) || 1;
14664
14665			if (existingHandles.length > handleCount) {
14666				existingHandles.slice(handleCount).remove();
14667				existingHandles = existingHandles.slice(0, handleCount);
14668			}
14669
14670			for (i = existingHandles.length; i < handleCount; i++) {
14671				handles.push(handle);
14672			}
14673
14674			this.handles = existingHandles.add($(handles.join("")).appendTo(this.element));
14675
14676			this._addClass(this.handles, "ui-slider-handle", "ui-state-default");
14677
14678			this.handle = this.handles.eq(0);
14679
14680			this.handles.each(function (i) {
14681				$(this)
14682					.data("ui-slider-handle-index", i)
14683					.attr("tabIndex", 0);
14684			});
14685		},
14686
14687		_createRange: function () {
14688			var options = this.options;
14689
14690			if (options.range) {
14691				if (options.range === true) {
14692					if (!options.values) {
14693						options.values = [this._valueMin(), this._valueMin()];
14694					} else if (options.values.length && options.values.length !== 2) {
14695						options.values = [options.values[0], options.values[0]];
14696					} else if (Array.isArray(options.values)) {
14697						options.values = options.values.slice(0);
14698					}
14699				}
14700
14701				if (!this.range || !this.range.length) {
14702					this.range = $("<div>")
14703						.appendTo(this.element);
14704
14705					this._addClass(this.range, "ui-slider-range");
14706				} else {
14707					this._removeClass(this.range, "ui-slider-range-min ui-slider-range-max");
14708
14709					// Handle range switching from true to min/max
14710					this.range.css({
14711						"left": "",
14712						"bottom": ""
14713					});
14714				}
14715				if (options.range === "min" || options.range === "max") {
14716					this._addClass(this.range, "ui-slider-range-" + options.range);
14717				}
14718			} else {
14719				if (this.range) {
14720					this.range.remove();
14721				}
14722				this.range = null;
14723			}
14724		},
14725
14726		_setupEvents: function () {
14727			this._off(this.handles);
14728			this._on(this.handles, this._handleEvents);
14729			this._hoverable(this.handles);
14730			this._focusable(this.handles);
14731		},
14732
14733		_destroy: function () {
14734			this.handles.remove();
14735			if (this.range) {
14736				this.range.remove();
14737			}
14738
14739			this._mouseDestroy();
14740		},
14741
14742		_mouseCapture: function (event) {
14743			var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
14744				that = this,
14745				o = this.options;
14746
14747			if (o.disabled) {
14748				return false;
14749			}
14750
14751			this.elementSize = {
14752				width: this.element.outerWidth(),
14753				height: this.element.outerHeight()
14754			};
14755			this.elementOffset = this.element.offset();
14756
14757			position = { x: event.pageX, y: event.pageY };
14758			normValue = this._normValueFromMouse(position);
14759			distance = this._valueMax() - this._valueMin() + 1;
14760			this.handles.each(function (i) {
14761				var thisDistance = Math.abs(normValue - that.values(i));
14762				if ((distance > thisDistance) ||
14763					(distance === thisDistance &&
14764						(i === that._lastChangedValue || that.values(i) === o.min))) {
14765					distance = thisDistance;
14766					closestHandle = $(this);
14767					index = i;
14768				}
14769			});
14770
14771			allowed = this._start(event, index);
14772			if (allowed === false) {
14773				return false;
14774			}
14775			this._mouseSliding = true;
14776
14777			this._handleIndex = index;
14778
14779			this._addClass(closestHandle, null, "ui-state-active");
14780			closestHandle.trigger("focus");
14781
14782			offset = closestHandle.offset();
14783			mouseOverHandle = !$(event.target).parents().addBack().is(".ui-slider-handle");
14784			this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
14785				left: event.pageX - offset.left - (closestHandle.width() / 2),
14786				top: event.pageY - offset.top -
14787					(closestHandle.height() / 2) -
14788					(parseInt(closestHandle.css("borderTopWidth"), 10) || 0) -
14789					(parseInt(closestHandle.css("borderBottomWidth"), 10) || 0) +
14790					(parseInt(closestHandle.css("marginTop"), 10) || 0)
14791			};
14792
14793			if (!this.handles.hasClass("ui-state-hover")) {
14794				this._slide(event, index, normValue);
14795			}
14796			this._animateOff = true;
14797			return true;
14798		},
14799
14800		_mouseStart: function () {
14801			return true;
14802		},
14803
14804		_mouseDrag: function (event) {
14805			var position = { x: event.pageX, y: event.pageY },
14806				normValue = this._normValueFromMouse(position);
14807
14808			this._slide(event, this._handleIndex, normValue);
14809
14810			return false;
14811		},
14812
14813		_mouseStop: function (event) {
14814			this._removeClass(this.handles, null, "ui-state-active");
14815			this._mouseSliding = false;
14816
14817			this._stop(event, this._handleIndex);
14818			this._change(event, this._handleIndex);
14819
14820			this._handleIndex = null;
14821			this._clickOffset = null;
14822			this._animateOff = false;
14823
14824			return false;
14825		},
14826
14827		_detectOrientation: function () {
14828			this.orientation = (this.options.orientation === "vertical") ? "vertical" : "horizontal";
14829		},
14830
14831		_normValueFromMouse: function (position) {
14832			var pixelTotal,
14833				pixelMouse,
14834				percentMouse,
14835				valueTotal,
14836				valueMouse;
14837
14838			if (this.orientation === "horizontal") {
14839				pixelTotal = this.elementSize.width;
14840				pixelMouse = position.x - this.elementOffset.left -
14841					(this._clickOffset ? this._clickOffset.left : 0);
14842			} else {
14843				pixelTotal = this.elementSize.height;
14844				pixelMouse = position.y - this.elementOffset.top -
14845					(this._clickOffset ? this._clickOffset.top : 0);
14846			}
14847
14848			percentMouse = (pixelMouse / pixelTotal);
14849			if (percentMouse > 1) {
14850				percentMouse = 1;
14851			}
14852			if (percentMouse < 0) {
14853				percentMouse = 0;
14854			}
14855			if (this.orientation === "vertical") {
14856				percentMouse = 1 - percentMouse;
14857			}
14858
14859			valueTotal = this._valueMax() - this._valueMin();
14860			valueMouse = this._valueMin() + percentMouse * valueTotal;
14861
14862			return this._trimAlignValue(valueMouse);
14863		},
14864
14865		_uiHash: function (index, value, values) {
14866			var uiHash = {
14867				handle: this.handles[index],
14868				handleIndex: index,
14869				value: value !== undefined ? value : this.value()
14870			};
14871
14872			if (this._hasMultipleValues()) {
14873				uiHash.value = value !== undefined ? value : this.values(index);
14874				uiHash.values = values || this.values();
14875			}
14876
14877			return uiHash;
14878		},
14879
14880		_hasMultipleValues: function () {
14881			return this.options.values && this.options.values.length;
14882		},
14883
14884		_start: function (event, index) {
14885			return this._trigger("start", event, this._uiHash(index));
14886		},
14887
14888		_slide: function (event, index, newVal) {
14889			var allowed, otherVal,
14890				currentValue = this.value(),
14891				newValues = this.values();
14892
14893			if (this._hasMultipleValues()) {
14894				otherVal = this.values(index ? 0 : 1);
14895				currentValue = this.values(index);
14896
14897				if (this.options.values.length === 2 && this.options.range === true) {
14898					newVal = index === 0 ? Math.min(otherVal, newVal) : Math.max(otherVal, newVal);
14899				}
14900
14901				newValues[index] = newVal;
14902			}
14903
14904			if (newVal === currentValue) {
14905				return;
14906			}
14907
14908			allowed = this._trigger("slide", event, this._uiHash(index, newVal, newValues));
14909
14910			// A slide can be canceled by returning false from the slide callback
14911			if (allowed === false) {
14912				return;
14913			}
14914
14915			if (this._hasMultipleValues()) {
14916				this.values(index, newVal);
14917			} else {
14918				this.value(newVal);
14919			}
14920		},
14921
14922		_stop: function (event, index) {
14923			this._trigger("stop", event, this._uiHash(index));
14924		},
14925
14926		_change: function (event, index) {
14927			if (!this._keySliding && !this._mouseSliding) {
14928
14929				//store the last changed value index for reference when handles overlap
14930				this._lastChangedValue = index;
14931				this._trigger("change", event, this._uiHash(index));
14932			}
14933		},
14934
14935		value: function (newValue) {
14936			if (arguments.length) {
14937				this.options.value = this._trimAlignValue(newValue);
14938				this._refreshValue();
14939				this._change(null, 0);
14940				return;
14941			}
14942
14943			return this._value();
14944		},
14945
14946		values: function (index, newValue) {
14947			var vals,
14948				newValues,
14949				i;
14950
14951			if (arguments.length > 1) {
14952				this.options.values[index] = this._trimAlignValue(newValue);
14953				this._refreshValue();
14954				this._change(null, index);
14955				return;
14956			}
14957
14958			if (arguments.length) {
14959				if (Array.isArray(arguments[0])) {
14960					vals = this.options.values;
14961					newValues = arguments[0];
14962					for (i = 0; i < vals.length; i += 1) {
14963						vals[i] = this._trimAlignValue(newValues[i]);
14964						this._change(null, i);
14965					}
14966					this._refreshValue();
14967				} else {
14968					if (this._hasMultipleValues()) {
14969						return this._values(index);
14970					} else {
14971						return this.value();
14972					}
14973				}
14974			} else {
14975				return this._values();
14976			}
14977		},
14978
14979		_setOption: function (key, value) {
14980			var i,
14981				valsLength = 0;
14982
14983			if (key === "range" && this.options.range === true) {
14984				if (value === "min") {
14985					this.options.value = this._values(0);
14986					this.options.values = null;
14987				} else if (value === "max") {
14988					this.options.value = this._values(this.options.values.length - 1);
14989					this.options.values = null;
14990				}
14991			}
14992
14993			if (Array.isArray(this.options.values)) {
14994				valsLength = this.options.values.length;
14995			}
14996
14997			this._super(key, value);
14998
14999			switch (key) {
15000				case "orientation":
15001					this._detectOrientation();
15002					this._removeClass("ui-slider-horizontal ui-slider-vertical")
15003						._addClass("ui-slider-" + this.orientation);
15004					this._refreshValue();
15005					if (this.options.range) {
15006						this._refreshRange(value);
15007					}
15008
15009					// Reset positioning from previous orientation
15010					this.handles.css(value === "horizontal" ? "bottom" : "left", "");
15011					break;
15012				case "value":
15013					this._animateOff = true;
15014					this._refreshValue();
15015					this._change(null, 0);
15016					this._animateOff = false;
15017					break;
15018				case "values":
15019					this._animateOff = true;
15020					this._refreshValue();
15021
15022					// Start from the last handle to prevent unreachable handles (#9046)
15023					for (i = valsLength - 1; i >= 0; i--) {
15024						this._change(null, i);
15025					}
15026					this._animateOff = false;
15027					break;
15028				case "step":
15029				case "min":
15030				case "max":
15031					this._animateOff = true;
15032					this._calculateNewMax();
15033					this._refreshValue();
15034					this._animateOff = false;
15035					break;
15036				case "range":
15037					this._animateOff = true;
15038					this._refresh();
15039					this._animateOff = false;
15040					break;
15041			}
15042		},
15043
15044		_setOptionDisabled: function (value) {
15045			this._super(value);
15046
15047			this._toggleClass(null, "ui-state-disabled", !!value);
15048		},
15049
15050		//internal value getter
15051		// _value() returns value trimmed by min and max, aligned by step
15052		_value: function () {
15053			var val = this.options.value;
15054			val = this._trimAlignValue(val);
15055
15056			return val;
15057		},
15058
15059		//internal values getter
15060		// _values() returns array of values trimmed by min and max, aligned by step
15061		// _values( index ) returns single value trimmed by min and max, aligned by step
15062		_values: function (index) {
15063			var val,
15064				vals,
15065				i;
15066
15067			if (arguments.length) {
15068				val = this.options.values[index];
15069				val = this._trimAlignValue(val);
15070
15071				return val;
15072			} else if (this._hasMultipleValues()) {
15073
15074				// .slice() creates a copy of the array
15075				// this copy gets trimmed by min and max and then returned
15076				vals = this.options.values.slice();
15077				for (i = 0; i < vals.length; i += 1) {
15078					vals[i] = this._trimAlignValue(vals[i]);
15079				}
15080
15081				return vals;
15082			} else {
15083				return [];
15084			}
15085		},
15086
15087		// Returns the step-aligned value that val is closest to, between (inclusive) min and max
15088		_trimAlignValue: function (val) {
15089			if (val <= this._valueMin()) {
15090				return this._valueMin();
15091			}
15092			if (val >= this._valueMax()) {
15093				return this._valueMax();
15094			}
15095			var step = (this.options.step > 0) ? this.options.step : 1,
15096				valModStep = (val - this._valueMin()) % step,
15097				alignValue = val - valModStep;
15098
15099			if (Math.abs(valModStep) * 2 >= step) {
15100				alignValue += (valModStep > 0) ? step : (-step);
15101			}
15102
15103			// Since JavaScript has problems with large floats, round
15104			// the final value to 5 digits after the decimal point (see #4124)
15105			return parseFloat(alignValue.toFixed(5));
15106		},
15107
15108		_calculateNewMax: function () {
15109			var max = this.options.max,
15110				min = this._valueMin(),
15111				step = this.options.step,
15112				aboveMin = Math.round((max - min) / step) * step;
15113			max = aboveMin + min;
15114			if (max > this.options.max) {
15115
15116				//If max is not divisible by step, rounding off may increase its value
15117				max -= step;
15118			}
15119			this.max = parseFloat(max.toFixed(this._precision()));
15120		},
15121
15122		_precision: function () {
15123			var precision = this._precisionOf(this.options.step);
15124			if (this.options.min !== null) {
15125				precision = Math.max(precision, this._precisionOf(this.options.min));
15126			}
15127			return precision;
15128		},
15129
15130		_precisionOf: function (num) {
15131			var str = num.toString(),
15132				decimal = str.indexOf(".");
15133			return decimal === -1 ? 0 : str.length - decimal - 1;
15134		},
15135
15136		_valueMin: function () {
15137			return this.options.min;
15138		},
15139
15140		_valueMax: function () {
15141			return this.max;
15142		},
15143
15144		_refreshRange: function (orientation) {
15145			if (orientation === "vertical") {
15146				this.range.css({ "width": "", "left": "" });
15147			}
15148			if (orientation === "horizontal") {
15149				this.range.css({ "height": "", "bottom": "" });
15150			}
15151		},
15152
15153		_refreshValue: function () {
15154			var lastValPercent, valPercent, value, valueMin, valueMax,
15155				oRange = this.options.range,
15156				o = this.options,
15157				that = this,
15158				animate = (!this._animateOff) ? o.animate : false,
15159				_set = {};
15160
15161			if (this._hasMultipleValues()) {
15162				this.handles.each(function (i) {
15163					valPercent = (that.values(i) - that._valueMin()) / (that._valueMax() -
15164						that._valueMin()) * 100;
15165					_set[that.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%";
15166					$(this).stop(1, 1)[animate ? "animate" : "css"](_set, o.animate);
15167					if (that.options.range === true) {
15168						if (that.orientation === "horizontal") {
15169							if (i === 0) {
15170								that.range.stop(1, 1)[animate ? "animate" : "css"]({
15171									left: valPercent + "%"
15172								}, o.animate);
15173							}
15174							if (i === 1) {
15175								that.range[animate ? "animate" : "css"]({
15176									width: (valPercent - lastValPercent) + "%"
15177								}, {
15178									queue: false,
15179									duration: o.animate
15180								});
15181							}
15182						} else {
15183							if (i === 0) {
15184								that.range.stop(1, 1)[animate ? "animate" : "css"]({
15185									bottom: (valPercent) + "%"
15186								}, o.animate);
15187							}
15188							if (i === 1) {
15189								that.range[animate ? "animate" : "css"]({
15190									height: (valPercent - lastValPercent) + "%"
15191								}, {
15192									queue: false,
15193									duration: o.animate
15194								});
15195							}
15196						}
15197					}
15198					lastValPercent = valPercent;
15199				});
15200			} else {
15201				value = this.value();
15202				valueMin = this._valueMin();
15203				valueMax = this._valueMax();
15204				valPercent = (valueMax !== valueMin) ?
15205					(value - valueMin) / (valueMax - valueMin) * 100 :
15206					0;
15207				_set[this.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%";
15208				this.handle.stop(1, 1)[animate ? "animate" : "css"](_set, o.animate);
15209
15210				if (oRange === "min" && this.orientation === "horizontal") {
15211					this.range.stop(1, 1)[animate ? "animate" : "css"]({
15212						width: valPercent + "%"
15213					}, o.animate);
15214				}
15215				if (oRange === "max" && this.orientation === "horizontal") {
15216					this.range.stop(1, 1)[animate ? "animate" : "css"]({
15217						width: (100 - valPercent) + "%"
15218					}, o.animate);
15219				}
15220				if (oRange === "min" && this.orientation === "vertical") {
15221					this.range.stop(1, 1)[animate ? "animate" : "css"]({
15222						height: valPercent + "%"
15223					}, o.animate);
15224				}
15225				if (oRange === "max" && this.orientation === "vertical") {
15226					this.range.stop(1, 1)[animate ? "animate" : "css"]({
15227						height: (100 - valPercent) + "%"
15228					}, o.animate);
15229				}
15230			}
15231		},
15232
15233		_handleEvents: {
15234			keydown: function (event) {
15235				var allowed, curVal, newVal, step,
15236					index = $(event.target).data("ui-slider-handle-index");
15237
15238				switch (event.keyCode) {
15239					case $.ui.keyCode.HOME:
15240					case $.ui.keyCode.END:
15241					case $.ui.keyCode.PAGE_UP:
15242					case $.ui.keyCode.PAGE_DOWN:
15243					case $.ui.keyCode.UP:
15244					case $.ui.keyCode.RIGHT:
15245					case $.ui.keyCode.DOWN:
15246					case $.ui.keyCode.LEFT:
15247						event.preventDefault();
15248						if (!this._keySliding) {
15249							this._keySliding = true;
15250							this._addClass($(event.target), null, "ui-state-active");
15251							allowed = this._start(event, index);
15252							if (allowed === false) {
15253								return;
15254							}
15255						}
15256						break;
15257				}
15258
15259				step = this.options.step;
15260				if (this._hasMultipleValues()) {
15261					curVal = newVal = this.values(index);
15262				} else {
15263					curVal = newVal = this.value();
15264				}
15265
15266				switch (event.keyCode) {
15267					case $.ui.keyCode.HOME:
15268						newVal = this._valueMin();
15269						break;
15270					case $.ui.keyCode.END:
15271						newVal = this._valueMax();
15272						break;
15273					case $.ui.keyCode.PAGE_UP:
15274						newVal = this._trimAlignValue(
15275							curVal + ((this._valueMax() - this._valueMin()) / this.numPages)
15276						);
15277						break;
15278					case $.ui.keyCode.PAGE_DOWN:
15279						newVal = this._trimAlignValue(
15280							curVal - ((this._valueMax() - this._valueMin()) / this.numPages));
15281						break;
15282					case $.ui.keyCode.UP:
15283					case $.ui.keyCode.RIGHT:
15284						if (curVal === this._valueMax()) {
15285							return;
15286						}
15287						newVal = this._trimAlignValue(curVal + step);
15288						break;
15289					case $.ui.keyCode.DOWN:
15290					case $.ui.keyCode.LEFT:
15291						if (curVal === this._valueMin()) {
15292							return;
15293						}
15294						newVal = this._trimAlignValue(curVal - step);
15295						break;
15296				}
15297
15298				this._slide(event, index, newVal);
15299			},
15300			keyup: function (event) {
15301				var index = $(event.target).data("ui-slider-handle-index");
15302
15303				if (this._keySliding) {
15304					this._keySliding = false;
15305					this._stop(event, index);
15306					this._change(event, index);
15307					this._removeClass($(event.target), null, "ui-state-active");
15308				}
15309			}
15310		}
15311	});
15312
15313
15314	/*!
15315	 * jQuery UI Sortable 1.14.1
15316	 * https://jqueryui.com
15317	 *
15318	 * Copyright OpenJS Foundation and other contributors
15319	 * Released under the MIT license.
15320	 * https://jquery.org/license
15321	 */
15322
15323	//>>label: Sortable
15324	//>>group: Interactions
15325	//>>description: Enables items in a list to be sorted using the mouse.
15326	//>>docs: https://api.jqueryui.com/sortable/
15327	//>>demos: https://jqueryui.com/sortable/
15328	//>>css.structure: ../../themes/base/sortable.css
15329
15330
15331	var widgetsSortable = $.widget("ui.sortable", $.ui.mouse, {
15332		version: "1.14.1",
15333		widgetEventPrefix: "sort",
15334		ready: false,
15335		options: {
15336			appendTo: "parent",
15337			axis: false,
15338			connectWith: false,
15339			containment: false,
15340			cursor: "auto",
15341			cursorAt: false,
15342			dropOnEmpty: true,
15343			forcePlaceholderSize: false,
15344			forceHelperSize: false,
15345			grid: false,
15346			handle: false,
15347			helper: "original",
15348			items: "> *",
15349			opacity: false,
15350			placeholder: false,
15351			revert: false,
15352			scroll: true,
15353			scrollSensitivity: 20,
15354			scrollSpeed: 20,
15355			scope: "default",
15356			tolerance: "intersect",
15357			zIndex: 1000,
15358
15359			// Callbacks
15360			activate: null,
15361			beforeStop: null,
15362			change: null,
15363			deactivate: null,
15364			out: null,
15365			over: null,
15366			receive: null,
15367			remove: null,
15368			sort: null,
15369			start: null,
15370			stop: null,
15371			update: null
15372		},
15373
15374		_isOverAxis: function (x, reference, size) {
15375			return (x >= reference) && (x < (reference + size));
15376		},
15377
15378		_isFloating: function (item) {
15379			return (/left|right/).test(item.css("float")) ||
15380				(/inline|table-cell/).test(item.css("display"));
15381		},
15382
15383		_create: function () {
15384			this.containerCache = {};
15385			this._addClass("ui-sortable");
15386
15387			//Get the items
15388			this.refresh();
15389
15390			//Let's determine the parent's offset
15391			this.offset = this.element.offset();
15392
15393			//Initialize mouse events for interaction
15394			this._mouseInit();
15395
15396			this._setHandleClassName();
15397
15398			//We're ready to go
15399			this.ready = true;
15400
15401		},
15402
15403		_setOption: function (key, value) {
15404			this._super(key, value);
15405
15406			if (key === "handle") {
15407				this._setHandleClassName();
15408			}
15409		},
15410
15411		_setHandleClassName: function () {
15412			var that = this;
15413			this._removeClass(this.element.find(".ui-sortable-handle"), "ui-sortable-handle");
15414			$.each(this.items, function () {
15415				that._addClass(
15416					this.instance.options.handle ?
15417						this.item.find(this.instance.options.handle) :
15418						this.item,
15419					"ui-sortable-handle"
15420				);
15421			});
15422		},
15423
15424		_destroy: function () {
15425			this._mouseDestroy();
15426
15427			for (var i = this.items.length - 1; i >= 0; i--) {
15428				this.items[i].item.removeData(this.widgetName + "-item");
15429			}
15430
15431			return this;
15432		},
15433
15434		_mouseCapture: function (event, overrideHandle) {
15435			var currentItem = null,
15436				validHandle = false,
15437				that = this;
15438
15439			if (this.reverting) {
15440				return false;
15441			}
15442
15443			if (this.options.disabled || this.options.type === "static") {
15444				return false;
15445			}
15446
15447			//We have to refresh the items data once first
15448			this._refreshItems(event);
15449
15450			//Find out if the clicked node (or one of its parents) is a actual item in this.items
15451			$(event.target).parents().each(function () {
15452				if ($.data(this, that.widgetName + "-item") === that) {
15453					currentItem = $(this);
15454					return false;
15455				}
15456			});
15457			if ($.data(event.target, that.widgetName + "-item") === that) {
15458				currentItem = $(event.target);
15459			}
15460
15461			if (!currentItem) {
15462				return false;
15463			}
15464			if (this.options.handle && !overrideHandle) {
15465				$(this.options.handle, currentItem).find("*").addBack().each(function () {
15466					if (this === event.target) {
15467						validHandle = true;
15468					}
15469				});
15470				if (!validHandle) {
15471					return false;
15472				}
15473			}
15474
15475			this.currentItem = currentItem;
15476			this._removeCurrentsFromItems();
15477			return true;
15478
15479		},
15480
15481		_mouseStart: function (event, overrideHandle, noActivation) {
15482
15483			var i, body,
15484				o = this.options;
15485
15486			this.currentContainer = this;
15487
15488			//We only need to call refreshPositions, because the refreshItems call has been moved to
15489			// mouseCapture
15490			this.refreshPositions();
15491
15492			//Prepare the dragged items parent
15493			this.appendTo = $(o.appendTo !== "parent" ?
15494				o.appendTo :
15495				this.currentItem.parent());
15496
15497			//Create and append the visible helper
15498			this.helper = this._createHelper(event);
15499
15500			//Cache the helper size
15501			this._cacheHelperProportions();
15502
15503			/*
15504			 * - Position generation -
15505			 * This block generates everything position related - it's the core of draggables.
15506			 */
15507
15508			//Cache the margins of the original element
15509			this._cacheMargins();
15510
15511			//The element's absolute position on the page minus margins
15512			this.offset = this.currentItem.offset();
15513			this.offset = {
15514				top: this.offset.top - this.margins.top,
15515				left: this.offset.left - this.margins.left
15516			};
15517
15518			$.extend(this.offset, {
15519				click: { //Where the click happened, relative to the element
15520					left: event.pageX - this.offset.left,
15521					top: event.pageY - this.offset.top
15522				},
15523
15524				// This is a relative to absolute position minus the actual position calculation -
15525				// only used for relative positioned helper
15526				relative: this._getRelativeOffset()
15527			});
15528
15529			// After we get the helper offset, but before we get the parent offset we can
15530			// change the helper's position to absolute
15531			// TODO: Still need to figure out a way to make relative sorting possible
15532			this.helper.css("position", "absolute");
15533			this.cssPosition = this.helper.css("position");
15534
15535			//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
15536			if (o.cursorAt) {
15537				this._adjustOffsetFromHelper(o.cursorAt);
15538			}
15539
15540			//Cache the former DOM position
15541			this.domPosition = {
15542				prev: this.currentItem.prev()[0],
15543				parent: this.currentItem.parent()[0]
15544			};
15545
15546			// If the helper is not the original, hide the original so it's not playing any role during
15547			// the drag, won't cause anything bad this way
15548			if (this.helper[0] !== this.currentItem[0]) {
15549				this.currentItem.hide();
15550			}
15551
15552			//Create the placeholder
15553			this._createPlaceholder();
15554
15555			//Get the next scrolling parent
15556			this.scrollParent = this.placeholder.scrollParent();
15557
15558			$.extend(this.offset, {
15559				parent: this._getParentOffset()
15560			});
15561
15562			//Set a containment if given in the options
15563			if (o.containment) {
15564				this._setContainment();
15565			}
15566
15567			if (o.cursor && o.cursor !== "auto") { // cursor option
15568				body = this.document.find("body");
15569
15570				this._storedStylesheet =
15571					$("<style>*{ cursor: " + o.cursor + " !important; }</style>").appendTo(body);
15572			}
15573
15574			// We need to make sure to grab the zIndex before setting the
15575			// opacity, because setting the opacity to anything lower than 1
15576			// causes the zIndex to change from "auto" to 0.
15577			if (o.zIndex) { // zIndex option
15578				if (this.helper.css("zIndex")) {
15579					this._storedZIndex = this.helper.css("zIndex");
15580				}
15581				this.helper.css("zIndex", o.zIndex);
15582			}
15583
15584			if (o.opacity) { // opacity option
15585				if (this.helper.css("opacity")) {
15586					this._storedOpacity = this.helper.css("opacity");
15587				}
15588				this.helper.css("opacity", o.opacity);
15589			}
15590
15591			//Prepare scrolling
15592			if (this.scrollParent[0] !== this.document[0] &&
15593				this.scrollParent[0].tagName !== "HTML") {
15594				this.overflowOffset = this.scrollParent.offset();
15595			}
15596
15597			//Call callbacks
15598			this._trigger("start", event, this._uiHash());
15599
15600			//Recache the helper size
15601			if (!this._preserveHelperProportions) {
15602				this._cacheHelperProportions();
15603			}
15604
15605			//Post "activate" events to possible containers
15606			if (!noActivation) {
15607				for (i = this.containers.length - 1; i >= 0; i--) {
15608					this.containers[i]._trigger("activate", event, this._uiHash(this));
15609				}
15610			}
15611
15612			//Prepare possible droppables
15613			if ($.ui.ddmanager) {
15614				$.ui.ddmanager.current = this;
15615			}
15616
15617			if ($.ui.ddmanager && !o.dropBehaviour) {
15618				$.ui.ddmanager.prepareOffsets(this, event);
15619			}
15620
15621			this.dragging = true;
15622
15623			this._addClass(this.helper, "ui-sortable-helper");
15624
15625			//Move the helper, if needed
15626			if (!this.helper.parent().is(this.appendTo)) {
15627				this.helper.detach().appendTo(this.appendTo);
15628
15629				//Update position
15630				this.offset.parent = this._getParentOffset();
15631			}
15632
15633			//Generate the original position
15634			this.position = this.originalPosition = this._generatePosition(event);
15635			this.originalPageX = event.pageX;
15636			this.originalPageY = event.pageY;
15637			this.lastPositionAbs = this.positionAbs = this._convertPositionTo("absolute");
15638
15639			this._mouseDrag(event);
15640
15641			return true;
15642
15643		},
15644
15645		_scroll: function (event) {
15646			var o = this.options,
15647				scrolled = false;
15648
15649			if (this.scrollParent[0] !== this.document[0] &&
15650				this.scrollParent[0].tagName !== "HTML") {
15651
15652				if ((this.overflowOffset.top + this.scrollParent[0].offsetHeight) -
15653					event.pageY < o.scrollSensitivity) {
15654					this.scrollParent[0].scrollTop =
15655						scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
15656				} else if (event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
15657					this.scrollParent[0].scrollTop =
15658						scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
15659				}
15660
15661				if ((this.overflowOffset.left + this.scrollParent[0].offsetWidth) -
15662					event.pageX < o.scrollSensitivity) {
15663					this.scrollParent[0].scrollLeft = scrolled =
15664						this.scrollParent[0].scrollLeft + o.scrollSpeed;
15665				} else if (event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
15666					this.scrollParent[0].scrollLeft = scrolled =
15667						this.scrollParent[0].scrollLeft - o.scrollSpeed;
15668				}
15669
15670			} else {
15671
15672				if (event.pageY - this.document.scrollTop() < o.scrollSensitivity) {
15673					scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);
15674				} else if (this.window.height() - (event.pageY - this.document.scrollTop()) <
15675					o.scrollSensitivity) {
15676					scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);
15677				}
15678
15679				if (event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {
15680					scrolled = this.document.scrollLeft(
15681						this.document.scrollLeft() - o.scrollSpeed
15682					);
15683				} else if (this.window.width() - (event.pageX - this.document.scrollLeft()) <
15684					o.scrollSensitivity) {
15685					scrolled = this.document.scrollLeft(
15686						this.document.scrollLeft() + o.scrollSpeed
15687					);
15688				}
15689
15690			}
15691
15692			return scrolled;
15693		},
15694
15695		_mouseDrag: function (event) {
15696			var i, item, itemElement, intersection,
15697				o = this.options;
15698
15699			//Compute the helpers position
15700			this.position = this._generatePosition(event);
15701			this.positionAbs = this._convertPositionTo("absolute");
15702
15703			//Set the helper position
15704			if (!this.options.axis || this.options.axis !== "y") {
15705				this.helper[0].style.left = this.position.left + "px";
15706			}
15707			if (!this.options.axis || this.options.axis !== "x") {
15708				this.helper[0].style.top = this.position.top + "px";
15709			}
15710
15711			//Do scrolling
15712			if (o.scroll) {
15713				if (this._scroll(event) !== false) {
15714
15715					//Update item positions used in position checks
15716					this._refreshItemPositions(true);
15717
15718					if ($.ui.ddmanager && !o.dropBehaviour) {
15719						$.ui.ddmanager.prepareOffsets(this, event);
15720					}
15721				}
15722			}
15723
15724			this.dragDirection = {
15725				vertical: this._getDragVerticalDirection(),
15726				horizontal: this._getDragHorizontalDirection()
15727			};
15728
15729			//Rearrange
15730			for (i = this.items.length - 1; i >= 0; i--) {
15731
15732				//Cache variables and intersection, continue if no intersection
15733				item = this.items[i];
15734				itemElement = item.item[0];
15735				intersection = this._intersectsWithPointer(item);
15736				if (!intersection) {
15737					continue;
15738				}
15739
15740				// Only put the placeholder inside the current Container, skip all
15741				// items from other containers. This works because when moving
15742				// an item from one container to another the
15743				// currentContainer is switched before the placeholder is moved.
15744				//
15745				// Without this, moving items in "sub-sortables" can cause
15746				// the placeholder to jitter between the outer and inner container.
15747				if (item.instance !== this.currentContainer) {
15748					continue;
15749				}
15750
15751				// Cannot intersect with itself
15752				// no useless actions that have been done before
15753				// no action if the item moved is the parent of the item checked
15754				if (itemElement !== this.currentItem[0] &&
15755					this.placeholder[intersection === 1 ?
15756						"next" : "prev"]()[0] !== itemElement &&
15757					!$.contains(this.placeholder[0], itemElement) &&
15758					(this.options.type === "semi-dynamic" ?
15759						!$.contains(this.element[0], itemElement) :
15760						true
15761					)
15762				) {
15763
15764					this.direction = intersection === 1 ? "down" : "up";
15765
15766					if (this.options.tolerance === "pointer" ||
15767						this._intersectsWithSides(item)) {
15768						this._rearrange(event, item);
15769					} else {
15770						break;
15771					}
15772
15773					this._trigger("change", event, this._uiHash());
15774					break;
15775				}
15776			}
15777
15778			//Post events to containers
15779			this._contactContainers(event);
15780
15781			//Interconnect with droppables
15782			if ($.ui.ddmanager) {
15783				$.ui.ddmanager.drag(this, event);
15784			}
15785
15786			//Call callbacks
15787			this._trigger("sort", event, this._uiHash());
15788
15789			this.lastPositionAbs = this.positionAbs;
15790			return false;
15791
15792		},
15793
15794		_mouseStop: function (event, noPropagation) {
15795
15796			if (!event) {
15797				return;
15798			}
15799
15800			//If we are using droppables, inform the manager about the drop
15801			if ($.ui.ddmanager && !this.options.dropBehaviour) {
15802				$.ui.ddmanager.drop(this, event);
15803			}
15804
15805			if (this.options.revert) {
15806				var that = this,
15807					cur = this.placeholder.offset(),
15808					axis = this.options.axis,
15809					animation = {};
15810
15811				if (!axis || axis === "x") {
15812					animation.left = cur.left - this.offset.parent.left - this.margins.left +
15813						(this.offsetParent[0] === this.document[0].body ?
15814							0 :
15815							this.offsetParent[0].scrollLeft
15816						);
15817				}
15818				if (!axis || axis === "y") {
15819					animation.top = cur.top - this.offset.parent.top - this.margins.top +
15820						(this.offsetParent[0] === this.document[0].body ?
15821							0 :
15822							this.offsetParent[0].scrollTop
15823						);
15824				}
15825				this.reverting = true;
15826				$(this.helper).animate(
15827					animation,
15828					parseInt(this.options.revert, 10) || 500,
15829					function () {
15830						that._clear(event);
15831					}
15832				);
15833			} else {
15834				this._clear(event, noPropagation);
15835			}
15836
15837			return false;
15838
15839		},
15840
15841		cancel: function () {
15842
15843			if (this.dragging) {
15844
15845				this._mouseUp(new $.Event("mouseup", { target: null }));
15846
15847				if (this.options.helper === "original") {
15848					this.currentItem.css(this._storedCSS);
15849					this._removeClass(this.currentItem, "ui-sortable-helper");
15850				} else {
15851					this.currentItem.show();
15852				}
15853
15854				//Post deactivating events to containers
15855				for (var i = this.containers.length - 1; i >= 0; i--) {
15856					this.containers[i]._trigger("deactivate", null, this._uiHash(this));
15857					if (this.containers[i].containerCache.over) {
15858						this.containers[i]._trigger("out", null, this._uiHash(this));
15859						this.containers[i].containerCache.over = 0;
15860					}
15861				}
15862
15863			}
15864
15865			if (this.placeholder) {
15866
15867				//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
15868				// it unbinds ALL events from the original node!
15869				if (this.placeholder[0].parentNode) {
15870					this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
15871				}
15872				if (this.options.helper !== "original" && this.helper &&
15873					this.helper[0].parentNode) {
15874					this.helper.remove();
15875				}
15876
15877				$.extend(this, {
15878					helper: null,
15879					dragging: false,
15880					reverting: false,
15881					_noFinalSort: null
15882				});
15883
15884				if (this.domPosition.prev) {
15885					$(this.domPosition.prev).after(this.currentItem);
15886				} else {
15887					$(this.domPosition.parent).prepend(this.currentItem);
15888				}
15889			}
15890
15891			return this;
15892
15893		},
15894
15895		serialize: function (o) {
15896
15897			var items = this._getItemsAsjQuery(o && o.connected),
15898				str = [];
15899			o = o || {};
15900
15901			$(items).each(function () {
15902				var res = ($(o.item || this).attr(o.attribute || "id") || "")
15903					.match(o.expression || (/(.+)[\-=_](.+)/));
15904				if (res) {
15905					str.push(
15906						(o.key || res[1] + "[]") +
15907						"=" + (o.key && o.expression ? res[1] : res[2]));
15908				}
15909			});
15910
15911			if (!str.length && o.key) {
15912				str.push(o.key + "=");
15913			}
15914
15915			return str.join("&");
15916
15917		},
15918
15919		toArray: function (o) {
15920
15921			var items = this._getItemsAsjQuery(o && o.connected),
15922				ret = [];
15923
15924			o = o || {};
15925
15926			items.each(function () {
15927				ret.push($(o.item || this).attr(o.attribute || "id") || "");
15928			});
15929			return ret;
15930
15931		},
15932
15933		/* Be careful with the following core functions */
15934		_intersectsWith: function (item) {
15935
15936			var x1 = this.positionAbs.left,
15937				x2 = x1 + this.helperProportions.width,
15938				y1 = this.positionAbs.top,
15939				y2 = y1 + this.helperProportions.height,
15940				l = item.left,
15941				r = l + item.width,
15942				t = item.top,
15943				b = t + item.height,
15944				dyClick = this.offset.click.top,
15945				dxClick = this.offset.click.left,
15946				isOverElementHeight = (this.options.axis === "x") || ((y1 + dyClick) > t &&
15947					(y1 + dyClick) < b),
15948				isOverElementWidth = (this.options.axis === "y") || ((x1 + dxClick) > l &&
15949					(x1 + dxClick) < r),
15950				isOverElement = isOverElementHeight && isOverElementWidth;
15951
15952			if (this.options.tolerance === "pointer" ||
15953				this.options.forcePointerForContainers ||
15954				(this.options.tolerance !== "pointer" &&
15955					this.helperProportions[this.floating ? "width" : "height"] >
15956					item[this.floating ? "width" : "height"])
15957			) {
15958				return isOverElement;
15959			} else {
15960
15961				return (l < x1 + (this.helperProportions.width / 2) && // Right Half
15962					x2 - (this.helperProportions.width / 2) < r && // Left Half
15963					t < y1 + (this.helperProportions.height / 2) && // Bottom Half
15964					y2 - (this.helperProportions.height / 2) < b); // Top Half
15965
15966			}
15967		},
15968
15969		_intersectsWithPointer: function (item) {
15970			var verticalDirection, horizontalDirection,
15971				isOverElementHeight = (this.options.axis === "x") ||
15972					this._isOverAxis(
15973						this.positionAbs.top + this.offset.click.top, item.top, item.height),
15974				isOverElementWidth = (this.options.axis === "y") ||
15975					this._isOverAxis(
15976						this.positionAbs.left + this.offset.click.left, item.left, item.width),
15977				isOverElement = isOverElementHeight && isOverElementWidth;
15978
15979			if (!isOverElement) {
15980				return false;
15981			}
15982
15983			verticalDirection = this.dragDirection.vertical;
15984			horizontalDirection = this.dragDirection.horizontal;
15985
15986			return this.floating ?
15987				((horizontalDirection === "right" || verticalDirection === "down") ? 2 : 1) :
15988				(verticalDirection && (verticalDirection === "down" ? 2 : 1));
15989
15990		},
15991
15992		_intersectsWithSides: function (item) {
15993
15994			var isOverBottomHalf = this._isOverAxis(this.positionAbs.top +
15995				this.offset.click.top, item.top + (item.height / 2), item.height),
15996				isOverRightHalf = this._isOverAxis(this.positionAbs.left +
15997					this.offset.click.left, item.left + (item.width / 2), item.width),
15998				verticalDirection = this.dragDirection.vertical,
15999				horizontalDirection = this.dragDirection.horizontal;
16000
16001			if (this.floating && horizontalDirection) {
16002				return ((horizontalDirection === "right" && isOverRightHalf) ||
16003					(horizontalDirection === "left" && !isOverRightHalf));
16004			} else {
16005				return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) ||
16006					(verticalDirection === "up" && !isOverBottomHalf));
16007			}
16008
16009		},
16010
16011		_getDragVerticalDirection: function () {
16012			var delta = this.positionAbs.top - this.lastPositionAbs.top;
16013			return delta !== 0 && (delta > 0 ? "down" : "up");
16014		},
16015
16016		_getDragHorizontalDirection: function () {
16017			var delta = this.positionAbs.left - this.lastPositionAbs.left;
16018			return delta !== 0 && (delta > 0 ? "right" : "left");
16019		},
16020
16021		refresh: function (event) {
16022			this._refreshItems(event);
16023			this._setHandleClassName();
16024			this.refreshPositions();
16025			return this;
16026		},
16027
16028		_connectWith: function () {
16029			var options = this.options;
16030			return options.connectWith.constructor === String ?
16031				[options.connectWith] :
16032				options.connectWith;
16033		},
16034
16035		_getItemsAsjQuery: function (connected) {
16036
16037			var i, j, cur, inst,
16038				items = [],
16039				queries = [],
16040				connectWith = this._connectWith();
16041
16042			if (connectWith && connected) {
16043				for (i = connectWith.length - 1; i >= 0; i--) {
16044					cur = $(connectWith[i], this.document[0]);
16045					for (j = cur.length - 1; j >= 0; j--) {
16046						inst = $.data(cur[j], this.widgetFullName);
16047						if (inst && inst !== this && !inst.options.disabled) {
16048							queries.push([typeof inst.options.items === "function" ?
16049								inst.options.items.call(inst.element) :
16050								$(inst.options.items, inst.element)
16051									.not(".ui-sortable-helper")
16052									.not(".ui-sortable-placeholder"), inst]);
16053						}
16054					}
16055				}
16056			}
16057
16058			queries.push([typeof this.options.items === "function" ?
16059				this.options.items
16060					.call(this.element, null, { options: this.options, item: this.currentItem }) :
16061				$(this.options.items, this.element)
16062					.not(".ui-sortable-helper")
16063					.not(".ui-sortable-placeholder"), this]);
16064
16065			function addItems() {
16066				items.push(this);
16067			}
16068			for (i = queries.length - 1; i >= 0; i--) {
16069				queries[i][0].each(addItems);
16070			}
16071
16072			return $(items);
16073
16074		},
16075
16076		_removeCurrentsFromItems: function () {
16077
16078			var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
16079
16080			this.items = $.grep(this.items, function (item) {
16081				for (var j = 0; j < list.length; j++) {
16082					if (list[j] === item.item[0]) {
16083						return false;
16084					}
16085				}
16086				return true;
16087			});
16088
16089		},
16090
16091		_refreshItems: function (event) {
16092
16093			this.items = [];
16094			this.containers = [this];
16095
16096			var i, j, cur, inst, targetData, _queries, item, queriesLength,
16097				items = this.items,
16098				queries = [[typeof this.options.items === "function" ?
16099					this.options.items.call(this.element[0], event, { item: this.currentItem }) :
16100					$(this.options.items, this.element), this]],
16101				connectWith = this._connectWith();
16102
16103			//Shouldn't be run the first time through due to massive slow-down
16104			if (connectWith && this.ready) {
16105				for (i = connectWith.length - 1; i >= 0; i--) {
16106					cur = $(connectWith[i], this.document[0]);
16107					for (j = cur.length - 1; j >= 0; j--) {
16108						inst = $.data(cur[j], this.widgetFullName);
16109						if (inst && inst !== this && !inst.options.disabled) {
16110							queries.push([typeof inst.options.items === "function" ?
16111								inst.options.items
16112									.call(inst.element[0], event, { item: this.currentItem }) :
16113								$(inst.options.items, inst.element), inst]);
16114							this.containers.push(inst);
16115						}
16116					}
16117				}
16118			}
16119
16120			for (i = queries.length - 1; i >= 0; i--) {
16121				targetData = queries[i][1];
16122				_queries = queries[i][0];
16123
16124				for (j = 0, queriesLength = _queries.length; j < queriesLength; j++) {
16125					item = $(_queries[j]);
16126
16127					// Data for target checking (mouse manager)
16128					item.data(this.widgetName + "-item", targetData);
16129
16130					items.push({
16131						item: item,
16132						instance: targetData,
16133						width: 0, height: 0,
16134						left: 0, top: 0
16135					});
16136				}
16137			}
16138
16139		},
16140
16141		_refreshItemPositions: function (fast) {
16142			var i, item, t, p;
16143
16144			for (i = this.items.length - 1; i >= 0; i--) {
16145				item = this.items[i];
16146
16147				//We ignore calculating positions of all connected containers when we're not over them
16148				if (this.currentContainer && item.instance !== this.currentContainer &&
16149					item.item[0] !== this.currentItem[0]) {
16150					continue;
16151				}
16152
16153				t = this.options.toleranceElement ?
16154					$(this.options.toleranceElement, item.item) :
16155					item.item;
16156
16157				if (!fast) {
16158					item.width = t.outerWidth();
16159					item.height = t.outerHeight();
16160				}
16161
16162				p = t.offset();
16163				item.left = p.left;
16164				item.top = p.top;
16165			}
16166		},
16167
16168		refreshPositions: function (fast) {
16169
16170			// Determine whether items are being displayed horizontally
16171			this.floating = this.items.length ?
16172				this.options.axis === "x" || this._isFloating(this.items[0].item) :
16173				false;
16174
16175			// This has to be redone because due to the item being moved out/into the offsetParent,
16176			// the offsetParent's position will change
16177			if (this.offsetParent && this.helper) {
16178				this.offset.parent = this._getParentOffset();
16179			}
16180
16181			this._refreshItemPositions(fast);
16182
16183			var i, p;
16184
16185			if (this.options.custom && this.options.custom.refreshContainers) {
16186				this.options.custom.refreshContainers.call(this);
16187			} else {
16188				for (i = this.containers.length - 1; i >= 0; i--) {
16189					p = this.containers[i].element.offset();
16190					this.containers[i].containerCache.left = p.left;
16191					this.containers[i].containerCache.top = p.top;
16192					this.containers[i].containerCache.width =
16193						this.containers[i].element.outerWidth();
16194					this.containers[i].containerCache.height =
16195						this.containers[i].element.outerHeight();
16196				}
16197			}
16198
16199			return this;
16200		},
16201
16202		_createPlaceholder: function (that) {
16203			that = that || this;
16204			var className, nodeName,
16205				o = that.options;
16206
16207			if (!o.placeholder || o.placeholder.constructor === String) {
16208				className = o.placeholder;
16209				nodeName = that.currentItem[0].nodeName.toLowerCase();
16210				o.placeholder = {
16211					element: function () {
16212
16213						var element = $("<" + nodeName + ">", that.document[0]);
16214
16215						that._addClass(element, "ui-sortable-placeholder",
16216							className || that.currentItem[0].className)
16217							._removeClass(element, "ui-sortable-helper");
16218
16219						if (nodeName === "tbody") {
16220							that._createTrPlaceholder(
16221								that.currentItem.find("tr").eq(0),
16222								$("<tr>", that.document[0]).appendTo(element)
16223							);
16224						} else if (nodeName === "tr") {
16225							that._createTrPlaceholder(that.currentItem, element);
16226						} else if (nodeName === "img") {
16227							element.attr("src", that.currentItem.attr("src"));
16228						}
16229
16230						if (!className) {
16231							element.css("visibility", "hidden");
16232						}
16233
16234						return element;
16235					},
16236					update: function (container, p) {
16237
16238						// 1. If a className is set as 'placeholder option, we don't force sizes -
16239						// the class is responsible for that
16240						// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
16241						// class name is specified
16242						if (className && !o.forcePlaceholderSize) {
16243							return;
16244						}
16245
16246						// If the element doesn't have a actual height or width by itself (without
16247						// styles coming from a stylesheet), it receives the inline height and width
16248						// from the dragged item. Or, if it's a tbody or tr, it's going to have a height
16249						// anyway since we're populating them with <td>s above, but they're unlikely to
16250						// be the correct height on their own if the row heights are dynamic, so we'll
16251						// always assign the height of the dragged item given forcePlaceholderSize
16252						// is true.
16253						if (!p.height() || (o.forcePlaceholderSize &&
16254							(nodeName === "tbody" || nodeName === "tr"))) {
16255							p.height(
16256								that.currentItem.innerHeight() -
16257								parseInt(that.currentItem.css("paddingTop") || 0, 10) -
16258								parseInt(that.currentItem.css("paddingBottom") || 0, 10));
16259						}
16260						if (!p.width()) {
16261							p.width(
16262								that.currentItem.innerWidth() -
16263								parseInt(that.currentItem.css("paddingLeft") || 0, 10) -
16264								parseInt(that.currentItem.css("paddingRight") || 0, 10));
16265						}
16266					}
16267				};
16268			}
16269
16270			//Create the placeholder
16271			that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
16272
16273			//Append it after the actual current item
16274			that.currentItem.after(that.placeholder);
16275
16276			//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
16277			o.placeholder.update(that, that.placeholder);
16278
16279		},
16280
16281		_createTrPlaceholder: function (sourceTr, targetTr) {
16282			var that = this;
16283
16284			sourceTr.children().each(function () {
16285				$("<td>&#160;</td>", that.document[0])
16286					.attr("colspan", $(this).attr("colspan") || 1)
16287					.appendTo(targetTr);
16288			});
16289		},
16290
16291		_contactContainers: function (event) {
16292			var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
16293				floating, axis,
16294				innermostContainer = null,
16295				innermostIndex = null;
16296
16297			// Get innermost container that intersects with item
16298			for (i = this.containers.length - 1; i >= 0; i--) {
16299
16300				// Never consider a container that's located within the item itself
16301				if ($.contains(this.currentItem[0], this.containers[i].element[0])) {
16302					continue;
16303				}
16304
16305				if (this._intersectsWith(this.containers[i].containerCache)) {
16306
16307					// If we've already found a container and it's more "inner" than this, then continue
16308					if (innermostContainer &&
16309						$.contains(
16310							this.containers[i].element[0],
16311							innermostContainer.element[0])) {
16312						continue;
16313					}
16314
16315					innermostContainer = this.containers[i];
16316					innermostIndex = i;
16317
16318				} else {
16319
16320					// container doesn't intersect. trigger "out" event if necessary
16321					if (this.containers[i].containerCache.over) {
16322						this.containers[i]._trigger("out", event, this._uiHash(this));
16323						this.containers[i].containerCache.over = 0;
16324					}
16325				}
16326
16327			}
16328
16329			// If no intersecting containers found, return
16330			if (!innermostContainer) {
16331				return;
16332			}
16333
16334			// Move the item into the container if it's not there already
16335			if (this.containers.length === 1) {
16336				if (!this.containers[innermostIndex].containerCache.over) {
16337					this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
16338					this.containers[innermostIndex].containerCache.over = 1;
16339				}
16340			} else {
16341
16342				// When entering a new container, we will find the item with the least distance and
16343				// append our item near it
16344				dist = 10000;
16345				itemWithLeastDistance = null;
16346				floating = innermostContainer.floating || this._isFloating(this.currentItem);
16347				posProperty = floating ? "left" : "top";
16348				sizeProperty = floating ? "width" : "height";
16349				axis = floating ? "pageX" : "pageY";
16350
16351				for (j = this.items.length - 1; j >= 0; j--) {
16352					if (!$.contains(
16353						this.containers[innermostIndex].element[0], this.items[j].item[0])
16354					) {
16355						continue;
16356					}
16357					if (this.items[j].item[0] === this.currentItem[0]) {
16358						continue;
16359					}
16360
16361					cur = this.items[j].item.offset()[posProperty];
16362					nearBottom = false;
16363					if (event[axis] - cur > this.items[j][sizeProperty] / 2) {
16364						nearBottom = true;
16365					}
16366
16367					if (Math.abs(event[axis] - cur) < dist) {
16368						dist = Math.abs(event[axis] - cur);
16369						itemWithLeastDistance = this.items[j];
16370						this.direction = nearBottom ? "up" : "down";
16371					}
16372				}
16373
16374				//Check if dropOnEmpty is enabled
16375				if (!itemWithLeastDistance && !this.options.dropOnEmpty) {
16376					return;
16377				}
16378
16379				if (this.currentContainer === this.containers[innermostIndex]) {
16380					if (!this.currentContainer.containerCache.over) {
16381						this.containers[innermostIndex]._trigger("over", event, this._uiHash());
16382						this.currentContainer.containerCache.over = 1;
16383					}
16384					return;
16385				}
16386
16387				if (itemWithLeastDistance) {
16388					this._rearrange(event, itemWithLeastDistance, null, true);
16389				} else {
16390					this._rearrange(event, null, this.containers[innermostIndex].element, true);
16391				}
16392				this._trigger("change", event, this._uiHash());
16393				this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
16394				this.currentContainer = this.containers[innermostIndex];
16395
16396				//Update the placeholder
16397				this.options.placeholder.update(this.currentContainer, this.placeholder);
16398
16399				//Update scrollParent
16400				this.scrollParent = this.placeholder.scrollParent();
16401
16402				//Update overflowOffset
16403				if (this.scrollParent[0] !== this.document[0] &&
16404					this.scrollParent[0].tagName !== "HTML") {
16405					this.overflowOffset = this.scrollParent.offset();
16406				}
16407
16408				this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
16409				this.containers[innermostIndex].containerCache.over = 1;
16410			}
16411
16412		},
16413
16414		_createHelper: function (event) {
16415
16416			var o = this.options,
16417				helper = typeof o.helper === "function" ?
16418					$(o.helper.apply(this.element[0], [event, this.currentItem])) :
16419					(o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
16420
16421			//Add the helper to the DOM if that didn't happen already
16422			if (!helper.parents("body").length) {
16423				this.appendTo[0].appendChild(helper[0]);
16424			}
16425
16426			if (helper[0] === this.currentItem[0]) {
16427				this._storedCSS = {
16428					width: this.currentItem[0].style.width,
16429					height: this.currentItem[0].style.height,
16430					position: this.currentItem.css("position"),
16431					top: this.currentItem.css("top"),
16432					left: this.currentItem.css("left")
16433				};
16434			}
16435
16436			if (!helper[0].style.width || o.forceHelperSize) {
16437				helper.width(this.currentItem.width());
16438			}
16439			if (!helper[0].style.height || o.forceHelperSize) {
16440				helper.height(this.currentItem.height());
16441			}
16442
16443			return helper;
16444
16445		},
16446
16447		_adjustOffsetFromHelper: function (obj) {
16448			if (typeof obj === "string") {
16449				obj = obj.split(" ");
16450			}
16451			if (Array.isArray(obj)) {
16452				obj = { left: +obj[0], top: +obj[1] || 0 };
16453			}
16454			if ("left" in obj) {
16455				this.offset.click.left = obj.left + this.margins.left;
16456			}
16457			if ("right" in obj) {
16458				this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
16459			}
16460			if ("top" in obj) {
16461				this.offset.click.top = obj.top + this.margins.top;
16462			}
16463			if ("bottom" in obj) {
16464				this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
16465			}
16466		},
16467
16468		_getParentOffset: function () {
16469
16470			//Get the offsetParent and cache its position
16471			this.offsetParent = this.helper.offsetParent();
16472			var po = this.offsetParent.offset();
16473
16474			// This is a special case where we need to modify a offset calculated on start, since the
16475			// following happened:
16476			// 1. The position of the helper is absolute, so it's position is calculated based on the
16477			// next positioned parent
16478			// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
16479			// the document, which means that the scroll is included in the initial calculation of the
16480			// offset of the parent, and never recalculated upon drag
16481			if (this.cssPosition === "absolute" && this.scrollParent[0] !== this.document[0] &&
16482				$.contains(this.scrollParent[0], this.offsetParent[0])) {
16483				po.left += this.scrollParent.scrollLeft();
16484				po.top += this.scrollParent.scrollTop();
16485			}
16486
16487			// This needs to be actually done for all browsers, since pageX/pageY includes
16488			// this information.
16489			if (this.offsetParent[0] === this.document[0].body) {
16490				po = { top: 0, left: 0 };
16491			}
16492
16493			return {
16494				top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
16495				left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
16496			};
16497
16498		},
16499
16500		_getRelativeOffset: function () {
16501
16502			if (this.cssPosition === "relative") {
16503				var p = this.currentItem.position();
16504				return {
16505					top: p.top - (parseInt(this.helper.css("top"), 10) || 0) +
16506						this.scrollParent.scrollTop(),
16507					left: p.left - (parseInt(this.helper.css("left"), 10) || 0) +
16508						this.scrollParent.scrollLeft()
16509				};
16510			} else {
16511				return { top: 0, left: 0 };
16512			}
16513
16514		},
16515
16516		_cacheMargins: function () {
16517			this.margins = {
16518				left: (parseInt(this.currentItem.css("marginLeft"), 10) || 0),
16519				top: (parseInt(this.currentItem.css("marginTop"), 10) || 0)
16520			};
16521		},
16522
16523		_cacheHelperProportions: function () {
16524			this.helperProportions = {
16525				width: this.helper.outerWidth(),
16526				height: this.helper.outerHeight()
16527			};
16528		},
16529
16530		_setContainment: function () {
16531
16532			var ce, co, over,
16533				o = this.options;
16534			if (o.containment === "parent") {
16535				o.containment = this.helper[0].parentNode;
16536			}
16537			if (o.containment === "document" || o.containment === "window") {
16538				this.containment = [
16539					0 - this.offset.relative.left - this.offset.parent.left,
16540					0 - this.offset.relative.top - this.offset.parent.top,
16541					o.containment === "document" ?
16542						this.document.width() :
16543						this.window.width() - this.helperProportions.width - this.margins.left,
16544					(o.containment === "document" ?
16545						(this.document.height() || document.body.parentNode.scrollHeight) :
16546						this.window.height() || this.document[0].body.parentNode.scrollHeight
16547					) - this.helperProportions.height - this.margins.top
16548				];
16549			}
16550
16551			if (!(/^(document|window|parent)$/).test(o.containment)) {
16552				ce = $(o.containment)[0];
16553				co = $(o.containment).offset();
16554				over = ($(ce).css("overflow") !== "hidden");
16555
16556				this.containment = [
16557					co.left + (parseInt($(ce).css("borderLeftWidth"), 10) || 0) +
16558					(parseInt($(ce).css("paddingLeft"), 10) || 0) - this.margins.left,
16559					co.top + (parseInt($(ce).css("borderTopWidth"), 10) || 0) +
16560					(parseInt($(ce).css("paddingTop"), 10) || 0) - this.margins.top,
16561					co.left + (over ? Math.max(ce.scrollWidth, ce.offsetWidth) : ce.offsetWidth) -
16562					(parseInt($(ce).css("borderLeftWidth"), 10) || 0) -
16563					(parseInt($(ce).css("paddingRight"), 10) || 0) -
16564					this.helperProportions.width - this.margins.left,
16565					co.top + (over ? Math.max(ce.scrollHeight, ce.offsetHeight) : ce.offsetHeight) -
16566					(parseInt($(ce).css("borderTopWidth"), 10) || 0) -
16567					(parseInt($(ce).css("paddingBottom"), 10) || 0) -
16568					this.helperProportions.height - this.margins.top
16569				];
16570			}
16571
16572		},
16573
16574		_convertPositionTo: function (d, pos) {
16575
16576			if (!pos) {
16577				pos = this.position;
16578			}
16579			var mod = d === "absolute" ? 1 : -1,
16580				scroll = this.cssPosition === "absolute" &&
16581					!(this.scrollParent[0] !== this.document[0] &&
16582						$.contains(this.scrollParent[0], this.offsetParent[0])) ?
16583					this.offsetParent :
16584					this.scrollParent,
16585				scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
16586
16587			return {
16588				top: (
16589
16590					// The absolute mouse position
16591					pos.top +
16592
16593					// Only for relative positioned nodes: Relative offset from element to offset parent
16594					this.offset.relative.top * mod +
16595
16596					// The offsetParent's offset without borders (offset + border)
16597					this.offset.parent.top * mod -
16598					((this.cssPosition === "fixed" ?
16599						-this.scrollParent.scrollTop() :
16600						(scrollIsRootNode ? 0 : scroll.scrollTop())) * mod)
16601				),
16602				left: (
16603
16604					// The absolute mouse position
16605					pos.left +
16606
16607					// Only for relative positioned nodes: Relative offset from element to offset parent
16608					this.offset.relative.left * mod +
16609
16610					// The offsetParent's offset without borders (offset + border)
16611					this.offset.parent.left * mod -
16612					((this.cssPosition === "fixed" ?
16613						-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
16614							scroll.scrollLeft()) * mod)
16615				)
16616			};
16617
16618		},
16619
16620		_generatePosition: function (event) {
16621
16622			var top, left,
16623				o = this.options,
16624				pageX = event.pageX,
16625				pageY = event.pageY,
16626				scroll = this.cssPosition === "absolute" &&
16627					!(this.scrollParent[0] !== this.document[0] &&
16628						$.contains(this.scrollParent[0], this.offsetParent[0])) ?
16629					this.offsetParent :
16630					this.scrollParent,
16631				scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
16632
16633			// This is another very weird special case that only happens for relative elements:
16634			// 1. If the css position is relative
16635			// 2. and the scroll parent is the document or similar to the offset parent
16636			// we have to refresh the relative offset during the scroll so there are no jumps
16637			if (this.cssPosition === "relative" && !(this.scrollParent[0] !== this.document[0] &&
16638				this.scrollParent[0] !== this.offsetParent[0])) {
16639				this.offset.relative = this._getRelativeOffset();
16640			}
16641
16642			/*
16643			 * - Position constraining -
16644			 * Constrain the position to a mix of grid, containment.
16645			 */
16646
16647			if (this.originalPosition) { //If we are not dragging yet, we won't check for options
16648
16649				if (this.containment) {
16650					if (event.pageX - this.offset.click.left < this.containment[0]) {
16651						pageX = this.containment[0] + this.offset.click.left;
16652					}
16653					if (event.pageY - this.offset.click.top < this.containment[1]) {
16654						pageY = this.containment[1] + this.offset.click.top;
16655					}
16656					if (event.pageX - this.offset.click.left > this.containment[2]) {
16657						pageX = this.containment[2] + this.offset.click.left;
16658					}
16659					if (event.pageY - this.offset.click.top > this.containment[3]) {
16660						pageY = this.containment[3] + this.offset.click.top;
16661					}
16662				}
16663
16664				if (o.grid) {
16665					top = this.originalPageY + Math.round((pageY - this.originalPageY) /
16666						o.grid[1]) * o.grid[1];
16667					pageY = this.containment ?
16668						((top - this.offset.click.top >= this.containment[1] &&
16669							top - this.offset.click.top <= this.containment[3]) ?
16670							top :
16671							((top - this.offset.click.top >= this.containment[1]) ?
16672								top - o.grid[1] : top + o.grid[1])) :
16673						top;
16674
16675					left = this.originalPageX + Math.round((pageX - this.originalPageX) /
16676						o.grid[0]) * o.grid[0];
16677					pageX = this.containment ?
16678						((left - this.offset.click.left >= this.containment[0] &&
16679							left - this.offset.click.left <= this.containment[2]) ?
16680							left :
16681							((left - this.offset.click.left >= this.containment[0]) ?
16682								left - o.grid[0] : left + o.grid[0])) :
16683						left;
16684				}
16685
16686			}
16687
16688			return {
16689				top: (
16690
16691					// The absolute mouse position
16692					pageY -
16693
16694					// Click offset (relative to the element)
16695					this.offset.click.top -
16696
16697					// Only for relative positioned nodes: Relative offset from element to offset parent
16698					this.offset.relative.top -
16699
16700					// The offsetParent's offset without borders (offset + border)
16701					this.offset.parent.top +
16702					((this.cssPosition === "fixed" ?
16703						-this.scrollParent.scrollTop() :
16704						(scrollIsRootNode ? 0 : scroll.scrollTop())))
16705				),
16706				left: (
16707
16708					// The absolute mouse position
16709					pageX -
16710
16711					// Click offset (relative to the element)
16712					this.offset.click.left -
16713
16714					// Only for relative positioned nodes: Relative offset from element to offset parent
16715					this.offset.relative.left -
16716
16717					// The offsetParent's offset without borders (offset + border)
16718					this.offset.parent.left +
16719					((this.cssPosition === "fixed" ?
16720						-this.scrollParent.scrollLeft() :
16721						scrollIsRootNode ? 0 : scroll.scrollLeft()))
16722				)
16723			};
16724
16725		},
16726
16727		_rearrange: function (event, i, a, hardRefresh) {
16728
16729			if (a) {
16730				a[0].appendChild(this.placeholder[0]);
16731			} else {
16732				i.item[0].parentNode.insertBefore(this.placeholder[0],
16733					(this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
16734			}
16735
16736			//Various things done here to improve the performance:
16737			// 1. we create a setTimeout, that calls refreshPositions
16738			// 2. on the instance, we have a counter variable, that get's higher after every append
16739			// 3. on the local scope, we copy the counter variable, and check in the timeout,
16740			// if it's still the same
16741			// 4. this lets only the last addition to the timeout stack through
16742			this.counter = this.counter ? ++this.counter : 1;
16743			var counter = this.counter;
16744
16745			this._delay(function () {
16746				if (counter === this.counter) {
16747
16748					//Precompute after each DOM insertion, NOT on mousemove
16749					this.refreshPositions(!hardRefresh);
16750				}
16751			});
16752
16753		},
16754
16755		_clear: function (event, noPropagation) {
16756
16757			this.reverting = false;
16758
16759			// We delay all events that have to be triggered to after the point where the placeholder
16760			// has been removed and everything else normalized again
16761			var i,
16762				delayedTriggers = [];
16763
16764			// We first have to update the dom position of the actual currentItem
16765			// Note: don't do it if the current item is already removed (by a user), or it gets
16766			// reappended (see #4088)
16767			if (!this._noFinalSort && this.currentItem.parent().length) {
16768				this.placeholder.before(this.currentItem);
16769			}
16770			this._noFinalSort = null;
16771
16772			if (this.helper[0] === this.currentItem[0]) {
16773				for (i in this._storedCSS) {
16774					if (this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
16775						this._storedCSS[i] = "";
16776					}
16777				}
16778				this.currentItem.css(this._storedCSS);
16779				this._removeClass(this.currentItem, "ui-sortable-helper");
16780			} else {
16781				this.currentItem.show();
16782			}
16783
16784			if (this.fromOutside && !noPropagation) {
16785				delayedTriggers.push(function (event) {
16786					this._trigger("receive", event, this._uiHash(this.fromOutside));
16787				});
16788			}
16789			if ((this.fromOutside ||
16790				this.domPosition.prev !==
16791				this.currentItem.prev().not(".ui-sortable-helper")[0] ||
16792				this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
16793
16794				// Trigger update callback if the DOM position has changed
16795				delayedTriggers.push(function (event) {
16796					this._trigger("update", event, this._uiHash());
16797				});
16798			}
16799
16800			// Check if the items Container has Changed and trigger appropriate
16801			// events.
16802			if (this !== this.currentContainer) {
16803				if (!noPropagation) {
16804					delayedTriggers.push(function (event) {
16805						this._trigger("remove", event, this._uiHash());
16806					});
16807					delayedTriggers.push((function (c) {
16808						return function (event) {
16809							c._trigger("receive", event, this._uiHash(this));
16810						};
16811					}).call(this, this.currentContainer));
16812					delayedTriggers.push((function (c) {
16813						return function (event) {
16814							c._trigger("update", event, this._uiHash(this));
16815						};
16816					}).call(this, this.currentContainer));
16817				}
16818			}
16819
16820			//Post events to containers
16821			function delayEvent(type, instance, container) {
16822				return function (event) {
16823					container._trigger(type, event, instance._uiHash(instance));
16824				};
16825			}
16826			for (i = this.containers.length - 1; i >= 0; i--) {
16827				if (!noPropagation) {
16828					delayedTriggers.push(delayEvent("deactivate", this, this.containers[i]));
16829				}
16830				if (this.containers[i].containerCache.over) {
16831					delayedTriggers.push(delayEvent("out", this, this.containers[i]));
16832					this.containers[i].containerCache.over = 0;
16833				}
16834			}
16835
16836			//Do what was originally in plugins
16837			if (this._storedStylesheet) {
16838				this._storedStylesheet.remove();
16839				this._storedStylesheet = null;
16840			}
16841			if (this._storedOpacity) {
16842				this.helper.css("opacity", this._storedOpacity);
16843			}
16844			if (this._storedZIndex) {
16845				this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
16846			}
16847
16848			this.dragging = false;
16849
16850			if (!noPropagation) {
16851				this._trigger("beforeStop", event, this._uiHash());
16852			}
16853
16854			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
16855			// it unbinds ALL events from the original node!
16856			this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
16857
16858			if (!this.cancelHelperRemoval) {
16859				if (this.helper[0] !== this.currentItem[0]) {
16860					this.helper.remove();
16861				}
16862				this.helper = null;
16863			}
16864
16865			if (!noPropagation) {
16866				for (i = 0; i < delayedTriggers.length; i++) {
16867
16868					// Trigger all delayed events
16869					delayedTriggers[i].call(this, event);
16870				}
16871				this._trigger("stop", event, this._uiHash());
16872			}
16873
16874			this.fromOutside = false;
16875			return !this.cancelHelperRemoval;
16876
16877		},
16878
16879		_trigger: function () {
16880			if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
16881				this.cancel();
16882			}
16883		},
16884
16885		_uiHash: function (_inst) {
16886			var inst = _inst || this;
16887			return {
16888				helper: inst.helper,
16889				placeholder: inst.placeholder || $([]),
16890				position: inst.position,
16891				originalPosition: inst.originalPosition,
16892				offset: inst.positionAbs,
16893				item: inst.currentItem,
16894				sender: _inst ? _inst.element : null
16895			};
16896		}
16897
16898	});
16899
16900
16901	/*!
16902	 * jQuery UI Spinner 1.14.1
16903	 * https://jqueryui.com
16904	 *
16905	 * Copyright OpenJS Foundation and other contributors
16906	 * Released under the MIT license.
16907	 * https://jquery.org/license
16908	 */
16909
16910	//>>label: Spinner
16911	//>>group: Widgets
16912	//>>description: Displays buttons to easily input numbers via the keyboard or mouse.
16913	//>>docs: https://api.jqueryui.com/spinner/
16914	//>>demos: https://jqueryui.com/spinner/
16915	//>>css.structure: ../../themes/base/core.css
16916	//>>css.structure: ../../themes/base/spinner.css
16917	//>>css.theme: ../../themes/base/theme.css
16918
16919
16920	function spinnerModifier(fn) {
16921		return function () {
16922			var previous = this.element.val();
16923			fn.apply(this, arguments);
16924			this._refresh();
16925			if (previous !== this.element.val()) {
16926				this._trigger("change");
16927			}
16928		};
16929	}
16930
16931	$.widget("ui.spinner", {
16932		version: "1.14.1",
16933		defaultElement: "<input>",
16934		widgetEventPrefix: "spin",
16935		options: {
16936			classes: {
16937				"ui-spinner": "ui-corner-all",
16938				"ui-spinner-down": "ui-corner-br",
16939				"ui-spinner-up": "ui-corner-tr"
16940			},
16941			culture: null,
16942			icons: {
16943				down: "ui-icon-triangle-1-s",
16944				up: "ui-icon-triangle-1-n"
16945			},
16946			incremental: true,
16947			max: null,
16948			min: null,
16949			numberFormat: null,
16950			page: 10,
16951			step: 1,
16952
16953			change: null,
16954			spin: null,
16955			start: null,
16956			stop: null
16957		},
16958
16959		_create: function () {
16960
16961			// handle string values that need to be parsed
16962			this._setOption("max", this.options.max);
16963			this._setOption("min", this.options.min);
16964			this._setOption("step", this.options.step);
16965
16966			// Only format if there is a value, prevents the field from being marked
16967			// as invalid in Firefox, see #9573.
16968			if (this.value() !== "") {
16969
16970				// Format the value, but don't constrain.
16971				this._value(this.element.val(), true);
16972			}
16973
16974			this._draw();
16975			this._on(this._events);
16976			this._refresh();
16977
16978			// Turning off autocomplete prevents the browser from remembering the
16979			// value when navigating through history, so we re-enable autocomplete
16980			// if the page is unloaded before the widget is destroyed. #7790
16981			this._on(this.window, {
16982				beforeunload: function () {
16983					this.element.removeAttr("autocomplete");
16984				}
16985			});
16986		},
16987
16988		_getCreateOptions: function () {
16989			var options = this._super();
16990			var element = this.element;
16991
16992			$.each(["min", "max", "step"], function (i, option) {
16993				var value = element.attr(option);
16994				if (value != null && value.length) {
16995					options[option] = value;
16996				}
16997			});
16998
16999			return options;
17000		},
17001
17002		_events: {
17003			keydown: function (event) {
17004				if (this._start(event) && this._keydown(event)) {
17005					event.preventDefault();
17006				}
17007			},
17008			keyup: "_stop",
17009			focus: function () {
17010				this.previous = this.element.val();
17011			},
17012			blur: function (event) {
17013				this._stop();
17014				this._refresh();
17015				if (this.previous !== this.element.val()) {
17016					this._trigger("change", event);
17017				}
17018			},
17019			mousewheel: function (event, delta) {
17020				var activeElement = this.document[0].activeElement;
17021				var isActive = this.element[0] === activeElement;
17022
17023				if (!isActive || !delta) {
17024					return;
17025				}
17026
17027				if (!this.spinning && !this._start(event)) {
17028					return false;
17029				}
17030
17031				this._spin((delta > 0 ? 1 : -1) * this.options.step, event);
17032				clearTimeout(this.mousewheelTimer);
17033				this.mousewheelTimer = this._delay(function () {
17034					if (this.spinning) {
17035						this._stop(event);
17036					}
17037				}, 100);
17038				event.preventDefault();
17039			},
17040			"mousedown .ui-spinner-button": function (event) {
17041				var previous;
17042
17043				// We never want the buttons to have focus; whenever the user is
17044				// interacting with the spinner, the focus should be on the input.
17045				// If the input is focused then this.previous is properly set from
17046				// when the input first received focus. If the input is not focused
17047				// then we need to set this.previous based on the value before spinning.
17048				previous = this.element[0] === this.document[0].activeElement ?
17049					this.previous : this.element.val();
17050				function checkFocus() {
17051					var isActive = this.element[0] === this.document[0].activeElement;
17052					if (!isActive) {
17053						this.element.trigger("focus");
17054						this.previous = previous;
17055					}
17056				}
17057
17058				// Ensure focus is on (or stays on) the text field
17059				event.preventDefault();
17060				checkFocus.call(this);
17061
17062				if (this._start(event) === false) {
17063					return;
17064				}
17065
17066				this._repeat(null, $(event.currentTarget)
17067					.hasClass("ui-spinner-up") ? 1 : -1, event);
17068			},
17069			"mouseup .ui-spinner-button": "_stop",
17070			"mouseenter .ui-spinner-button": function (event) {
17071
17072				// button will add ui-state-active if mouse was down while mouseleave and kept down
17073				if (!$(event.currentTarget).hasClass("ui-state-active")) {
17074					return;
17075				}
17076
17077				if (this._start(event) === false) {
17078					return false;
17079				}
17080				this._repeat(null, $(event.currentTarget)
17081					.hasClass("ui-spinner-up") ? 1 : -1, event);
17082			},
17083
17084			// TODO: do we really want to consider this a stop?
17085			// shouldn't we just stop the repeater and wait until mouseup before
17086			// we trigger the stop event?
17087			"mouseleave .ui-spinner-button": "_stop"
17088		},
17089
17090		// Support mobile enhanced option and make backcompat more sane
17091		_enhance: function () {
17092			this.uiSpinner = this.element
17093				.attr("autocomplete", "off")
17094				.wrap("<span>")
17095				.parent()
17096
17097				// Add buttons
17098				.append(
17099					"<a></a><a></a>"
17100				);
17101		},
17102
17103		_draw: function () {
17104			this._enhance();
17105
17106			this._addClass(this.uiSpinner, "ui-spinner", "ui-widget ui-widget-content");
17107			this._addClass("ui-spinner-input");
17108
17109			this.element.attr("role", "spinbutton");
17110
17111			// Button bindings
17112			this.buttons = this.uiSpinner.children("a")
17113				.attr("tabIndex", -1)
17114				.attr("aria-hidden", true)
17115				.button({
17116					classes: {
17117						"ui-button": ""
17118					}
17119				});
17120
17121			// TODO: Right now button does not support classes this is already updated in button PR
17122			this._removeClass(this.buttons, "ui-corner-all");
17123
17124			this._addClass(this.buttons.first(), "ui-spinner-button ui-spinner-up");
17125			this._addClass(this.buttons.last(), "ui-spinner-button ui-spinner-down");
17126			this.buttons.first().button({
17127				"icon": this.options.icons.up,
17128				"showLabel": false
17129			});
17130			this.buttons.last().button({
17131				"icon": this.options.icons.down,
17132				"showLabel": false
17133			});
17134
17135			// IE 6 doesn't understand height: 50% for the buttons
17136			// unless the wrapper has an explicit height
17137			if (this.buttons.height() > Math.ceil(this.uiSpinner.height() * 0.5) &&
17138				this.uiSpinner.height() > 0) {
17139				this.uiSpinner.height(this.uiSpinner.height());
17140			}
17141		},
17142
17143		_keydown: function (event) {
17144			var options = this.options,
17145				keyCode = $.ui.keyCode;
17146
17147			switch (event.keyCode) {
17148				case keyCode.UP:
17149					this._repeat(null, 1, event);
17150					return true;
17151				case keyCode.DOWN:
17152					this._repeat(null, -1, event);
17153					return true;
17154				case keyCode.PAGE_UP:
17155					this._repeat(null, options.page, event);
17156					return true;
17157				case keyCode.PAGE_DOWN:
17158					this._repeat(null, -options.page, event);
17159					return true;
17160			}
17161
17162			return false;
17163		},
17164
17165		_start: function (event) {
17166			if (!this.spinning && this._trigger("start", event) === false) {
17167				return false;
17168			}
17169
17170			if (!this.counter) {
17171				this.counter = 1;
17172			}
17173			this.spinning = true;
17174			return true;
17175		},
17176
17177		_repeat: function (i, steps, event) {
17178			i = i || 500;
17179
17180			clearTimeout(this.timer);
17181			this.timer = this._delay(function () {
17182				this._repeat(40, steps, event);
17183			}, i);
17184
17185			this._spin(steps * this.options.step, event);
17186		},
17187
17188		_spin: function (step, event) {
17189			var value = this.value() || 0;
17190
17191			if (!this.counter) {
17192				this.counter = 1;
17193			}
17194
17195			value = this._adjustValue(value + step * this._increment(this.counter));
17196
17197			if (!this.spinning || this._trigger("spin", event, { value: value }) !== false) {
17198				this._value(value);
17199				this.counter++;
17200			}
17201		},
17202
17203		_increment: function (i) {
17204			var incremental = this.options.incremental;
17205
17206			if (incremental) {
17207				return typeof incremental === "function" ?
17208					incremental(i) :
17209					Math.floor(i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1);
17210			}
17211
17212			return 1;
17213		},
17214
17215		_precision: function () {
17216			var precision = this._precisionOf(this.options.step);
17217			if (this.options.min !== null) {
17218				precision = Math.max(precision, this._precisionOf(this.options.min));
17219			}
17220			return precision;
17221		},
17222
17223		_precisionOf: function (num) {
17224			var str = num.toString(),
17225				decimal = str.indexOf(".");
17226			return decimal === -1 ? 0 : str.length - decimal - 1;
17227		},
17228
17229		_adjustValue: function (value) {
17230			var base, aboveMin,
17231				options = this.options;
17232
17233			// Make sure we're at a valid step
17234			// - find out where we are relative to the base (min or 0)
17235			base = options.min !== null ? options.min : 0;
17236			aboveMin = value - base;
17237
17238			// - round to the nearest step
17239			aboveMin = Math.round(aboveMin / options.step) * options.step;
17240
17241			// - rounding is based on 0, so adjust back to our base
17242			value = base + aboveMin;
17243
17244			// Fix precision from bad JS floating point math
17245			value = parseFloat(value.toFixed(this._precision()));
17246
17247			// Clamp the value
17248			if (options.max !== null && value > options.max) {
17249				return options.max;
17250			}
17251			if (options.min !== null && value < options.min) {
17252				return options.min;
17253			}
17254
17255			return value;
17256		},
17257
17258		_stop: function (event) {
17259			if (!this.spinning) {
17260				return;
17261			}
17262
17263			clearTimeout(this.timer);
17264			clearTimeout(this.mousewheelTimer);
17265			this.counter = 0;
17266			this.spinning = false;
17267			this._trigger("stop", event);
17268		},
17269
17270		_setOption: function (key, value) {
17271			var prevValue, first, last;
17272
17273			if (key === "culture" || key === "numberFormat") {
17274				prevValue = this._parse(this.element.val());
17275				this.options[key] = value;
17276				this.element.val(this._format(prevValue));
17277				return;
17278			}
17279
vendor: 12,464 bytes, lines 17280-17752
17280			if (key === "max" || key === "min" || key === "step") {
17281				if (typeof value === "string") {
17282					value = this._parse(value);
17283				}
17284			}
17285			if (key === "icons") {
17286				first = this.buttons.first().find(".ui-icon");
17287				this._removeClass(first, null, this.options.icons.up);
17288				this._addClass(first, null, value.up);
17289				last = this.buttons.last().find(".ui-icon");
17290				this._removeClass(last, null, this.options.icons.down);
17291				this._addClass(last, null, value.down);
17292			}
17293
17294			this._super(key, value);
17295		},
17296
17297		_setOptionDisabled: function (value) {
17298			this._super(value);
17299
17300			this._toggleClass(this.uiSpinner, null, "ui-state-disabled", !!value);
17301			this.element.prop("disabled", !!value);
17302			this.buttons.button(value ? "disable" : "enable");
17303		},
17304
17305		_setOptions: spinnerModifier(function (options) {
17306			this._super(options);
17307		}),
17308
17309		_parse: function (val) {
17310			if (typeof val === "string" && val !== "") {
17311				val = window.Globalize && this.options.numberFormat ?
17312					Globalize.parseFloat(val, 10, this.options.culture) : +val;
17313			}
17314			return val === "" || isNaN(val) ? null : val;
17315		},
17316
17317		_format: function (value) {
17318			if (value === "") {
17319				return "";
17320			}
17321			return window.Globalize && this.options.numberFormat ?
17322				Globalize.format(value, this.options.numberFormat, this.options.culture) :
17323				value;
17324		},
17325
17326		_refresh: function () {
17327			this.element.attr({
17328				"aria-valuemin": this.options.min,
17329				"aria-valuemax": this.options.max,
17330
17331				// TODO: what should we do with values that can't be parsed?
17332				"aria-valuenow": this._parse(this.element.val())
17333			});
17334		},
17335
17336		isValid: function () {
17337			var value = this.value();
17338
17339			// Null is invalid
17340			if (value === null) {
17341				return false;
17342			}
17343
17344			// If value gets adjusted, it's invalid
17345			return value === this._adjustValue(value);
17346		},
17347
17348		// Update the value without triggering change
17349		_value: function (value, allowAny) {
17350			var parsed;
17351			if (value !== "") {
17352				parsed = this._parse(value);
17353				if (parsed !== null) {
17354					if (!allowAny) {
17355						parsed = this._adjustValue(parsed);
17356					}
17357					value = this._format(parsed);
17358				}
17359			}
17360			this.element.val(value);
17361			this._refresh();
17362		},
17363
17364		_destroy: function () {
17365			this.element
17366				.prop("disabled", false)
17367				.removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow");
17368
17369			this.uiSpinner.replaceWith(this.element);
17370		},
17371
17372		stepUp: spinnerModifier(function (steps) {
17373			this._stepUp(steps);
17374		}),
17375		_stepUp: function (steps) {
17376			if (this._start()) {
17377				this._spin((steps || 1) * this.options.step);
17378				this._stop();
17379			}
17380		},
17381
17382		stepDown: spinnerModifier(function (steps) {
17383			this._stepDown(steps);
17384		}),
17385		_stepDown: function (steps) {
17386			if (this._start()) {
17387				this._spin((steps || 1) * -this.options.step);
17388				this._stop();
17389			}
17390		},
17391
17392		pageUp: spinnerModifier(function (pages) {
17393			this._stepUp((pages || 1) * this.options.page);
17394		}),
17395
17396		pageDown: spinnerModifier(function (pages) {
17397			this._stepDown((pages || 1) * this.options.page);
17398		}),
17399
17400		value: function (newVal) {
17401			if (!arguments.length) {
17402				return this._parse(this.element.val());
17403			}
17404			spinnerModifier(this._value).call(this, newVal);
17405		},
17406
17407		widget: function () {
17408			return this.uiSpinner;
17409		}
17410	});
17411
17412	// DEPRECATED
17413	// TODO: switch return back to widget declaration at top of file when this is removed
17414	if ($.uiBackCompat === true) {
17415
17416		// Backcompat for spinner html extension points
17417		$.widget("ui.spinner", $.ui.spinner, {
17418			_enhance: function () {
17419				this.uiSpinner = this.element
17420					.attr("autocomplete", "off")
17421					.wrap(this._uiSpinnerHtml())
17422					.parent()
17423
17424					// Add buttons
17425					.append(this._buttonHtml());
17426			},
17427			_uiSpinnerHtml: function () {
17428				return "<span>";
17429			},
17430
17431			_buttonHtml: function () {
17432				return "<a></a><a></a>";
17433			}
17434		});
17435	}
17436
17437	var widgetsSpinner = $.ui.spinner;
17438
17439
17440	/*!
17441	 * jQuery UI Tabs 1.14.1
17442	 * https://jqueryui.com
17443	 *
17444	 * Copyright OpenJS Foundation and other contributors
17445	 * Released under the MIT license.
17446	 * https://jquery.org/license
17447	 */
17448
17449	//>>label: Tabs
17450	//>>group: Widgets
17451	//>>description: Transforms a set of container elements into a tab structure.
17452	//>>docs: https://api.jqueryui.com/tabs/
17453	//>>demos: https://jqueryui.com/tabs/
17454	//>>css.structure: ../../themes/base/core.css
17455	//>>css.structure: ../../themes/base/tabs.css
17456	//>>css.theme: ../../themes/base/theme.css
17457
17458
17459	$.widget("ui.tabs", {
17460		version: "1.14.1",
17461		delay: 300,
17462		options: {
17463			active: null,
17464			classes: {
17465				"ui-tabs": "ui-corner-all",
17466				"ui-tabs-nav": "ui-corner-all",
17467				"ui-tabs-panel": "ui-corner-bottom",
17468				"ui-tabs-tab": "ui-corner-top"
17469			},
17470			collapsible: false,
17471			event: "click",
17472			heightStyle: "content",
17473			hide: null,
17474			show: null,
17475
17476			// Callbacks
17477			activate: null,
17478			beforeActivate: null,
17479			beforeLoad: null,
17480			load: null
17481		},
17482
17483		_isLocal: (function () {
17484			var rhash = /#.*$/;
17485
17486			return function (anchor) {
17487				var anchorUrl, locationUrl;
17488
17489				anchorUrl = anchor.href.replace(rhash, "");
17490				locationUrl = location.href.replace(rhash, "");
17491
17492				// Decoding may throw an error if the URL isn't UTF-8 (#9518)
17493				try {
17494					anchorUrl = decodeURIComponent(anchorUrl);
17495				} catch (error) { }
17496				try {
17497					locationUrl = decodeURIComponent(locationUrl);
17498				} catch (error) { }
17499
17500				return anchor.hash.length > 1 && anchorUrl === locationUrl;
17501			};
17502		})(),
17503
17504		_create: function () {
17505			var that = this,
17506				options = this.options;
17507
17508			this.running = false;
17509
17510			this._addClass("ui-tabs", "ui-widget ui-widget-content");
17511			this._toggleClass("ui-tabs-collapsible", null, options.collapsible);
17512
17513			this._processTabs();
17514			options.active = this._initialActive();
17515
17516			// Take disabling tabs via class attribute from HTML
17517			// into account and update option properly.
17518			if (Array.isArray(options.disabled)) {
17519				options.disabled = $.uniqueSort(options.disabled.concat(
17520					$.map(this.tabs.filter(".ui-state-disabled"), function (li) {
17521						return that.tabs.index(li);
17522					})
17523				)).sort();
17524			}
17525
17526			// Check for length avoids error when initializing empty list
17527			if (this.options.active !== false && this.anchors.length) {
17528				this.active = this._findActive(options.active);
17529			} else {
17530				this.active = $();
17531			}
17532
17533			this._refresh();
17534
17535			if (this.active.length) {
17536				this.load(options.active);
17537			}
17538		},
17539
17540		_initialActive: function () {
17541			var active = this.options.active,
17542				collapsible = this.options.collapsible,
17543				locationHashDecoded = decodeURIComponent(location.hash.substring(1));
17544
17545			if (active === null) {
17546
17547				// check the fragment identifier in the URL
17548				if (locationHashDecoded) {
17549					this.tabs.each(function (i, tab) {
17550						if ($(tab).attr("aria-controls") === locationHashDecoded) {
17551							active = i;
17552							return false;
17553						}
17554					});
17555				}
17556
17557				// Check for a tab marked active via a class
17558				if (active === null) {
17559					active = this.tabs.index(this.tabs.filter(".ui-tabs-active"));
17560				}
17561
17562				// No active tab, set to false
17563				if (active === null || active === -1) {
17564					active = this.tabs.length ? 0 : false;
17565				}
17566			}
17567
17568			// Handle numbers: negative, out of range
17569			if (active !== false) {
17570				active = this.tabs.index(this.tabs.eq(active));
17571				if (active === -1) {
17572					active = collapsible ? false : 0;
17573				}
17574			}
17575
17576			// Don't allow collapsible: false and active: false
17577			if (!collapsible && active === false && this.anchors.length) {
17578				active = 0;
17579			}
17580
17581			return active;
17582		},
17583
17584		_getCreateEventData: function () {
17585			return {
17586				tab: this.active,
17587				panel: !this.active.length ? $() : this._getPanelForTab(this.active)
17588			};
17589		},
17590
17591		_tabKeydown: function (event) {
17592			var focusedTab = $(this.document[0].activeElement).closest("li"),
17593				selectedIndex = this.tabs.index(focusedTab),
17594				goingForward = true;
17595
17596			if (this._handlePageNav(event)) {
17597				return;
17598			}
17599
17600			switch (event.keyCode) {
17601				case $.ui.keyCode.RIGHT:
17602				case $.ui.keyCode.DOWN:
17603					selectedIndex++;
17604					break;
17605				case $.ui.keyCode.UP:
17606				case $.ui.keyCode.LEFT:
17607					goingForward = false;
17608					selectedIndex--;
17609					break;
17610				case $.ui.keyCode.END:
17611					selectedIndex = this.anchors.length - 1;
17612					break;
17613				case $.ui.keyCode.HOME:
17614					selectedIndex = 0;
17615					break;
17616				case $.ui.keyCode.SPACE:
17617
17618					// Activate only, no collapsing
17619					event.preventDefault();
17620					clearTimeout(this.activating);
17621					this._activate(selectedIndex);
17622					return;
17623				case $.ui.keyCode.ENTER:
17624
17625					// Toggle (cancel delayed activation, allow collapsing)
17626					event.preventDefault();
17627					clearTimeout(this.activating);
17628
17629					// Determine if we should collapse or activate
17630					this._activate(selectedIndex === this.options.active ? false : selectedIndex);
17631					return;
17632				default:
17633					return;
17634			}
17635
17636			// Focus the appropriate tab, based on which key was pressed
17637			event.preventDefault();
17638			clearTimeout(this.activating);
17639			selectedIndex = this._focusNextTab(selectedIndex, goingForward);
17640
17641			// Navigating with control/command key will prevent automatic activation
17642			if (!event.ctrlKey && !event.metaKey) {
17643
17644				// Update aria-selected immediately so that AT think the tab is already selected.
17645				// Otherwise AT may confuse the user by stating that they need to activate the tab,
17646				// but the tab will already be activated by the time the announcement finishes.
17647				focusedTab.attr("aria-selected", "false");
17648				this.tabs.eq(selectedIndex).attr("aria-selected", "true");
17649
17650				this.activating = this._delay(function () {
17651					this.option("active", selectedIndex);
17652				}, this.delay);
17653			}
17654		},
17655
17656		_panelKeydown: function (event) {
17657			if (this._handlePageNav(event)) {
17658				return;
17659			}
17660
17661			// Ctrl+up moves focus to the current tab
17662			if (event.ctrlKey && event.keyCode === $.ui.keyCode.UP) {
17663				event.preventDefault();
17664				this.active.trigger("focus");
17665			}
17666		},
17667
17668		// Alt+page up/down moves focus to the previous/next tab (and activates)
17669		_handlePageNav: function (event) {
17670			if (event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP) {
17671				this._activate(this._focusNextTab(this.options.active - 1, false));
17672				return true;
17673			}
17674			if (event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN) {
17675				this._activate(this._focusNextTab(this.options.active + 1, true));
17676				return true;
17677			}
17678		},
17679
17680		_findNextTab: function (index, goingForward) {
17681			var lastTabIndex = this.tabs.length - 1;
17682
17683			function constrain() {
17684				if (index > lastTabIndex) {
17685					index = 0;
17686				}
17687				if (index < 0) {
17688					index = lastTabIndex;
17689				}
17690				return index;
17691			}
17692
17693			while ($.inArray(constrain(), this.options.disabled) !== -1) {
17694				index = goingForward ? index + 1 : index - 1;
17695			}
17696
17697			return index;
17698		},
17699
17700		_focusNextTab: function (index, goingForward) {
17701			index = this._findNextTab(index, goingForward);
17702			this.tabs.eq(index).trigger("focus");
17703			return index;
17704		},
17705
17706		_setOption: function (key, value) {
17707			if (key === "active") {
17708
17709				// _activate() will handle invalid values and update this.options
17710				this._activate(value);
17711				return;
17712			}
17713
17714			this._super(key, value);
17715
17716			if (key === "collapsible") {
17717				this._toggleClass("ui-tabs-collapsible", null, value);
17718
17719				// Setting collapsible: false while collapsed; open first panel
17720				if (!value && this.options.active === false) {
17721					this._activate(0);
17722				}
17723			}
17724
17725			if (key === "event") {
17726				this._setupEvents(value);
17727			}
17728
17729			if (key === "heightStyle") {
17730				this._setupHeightStyle(value);
17731			}
17732		},
17733
17734		refresh: function () {
17735			var options = this.options,
17736				lis = this.tablist.children(":has(a[href])");
17737
17738			// Get disabled tabs from class attribute from HTML
17739			// this will get converted to a boolean if needed in _refresh()
17740			options.disabled = $.map(lis.filter(".ui-state-disabled"), function (tab) {
17741				return lis.index(tab);
17742			});
17743
17744			this._processTabs();
17745
17746			// Was collapsed or no tabs
17747			if (options.active === false || !this.anchors.length) {
17748				options.active = false;
17749				this.active = $();
17750
17751				// was active, but active tab is gone
17752			} else if (this.active.length && !$.contains(this.tablist[0], this.active[0])
vendor: 29,050 bytes, lines 17752-18815
17752) {
17753
17754				// all remaining tabs are disabled
17755				if (this.tabs.length === options.disabled.length) {
17756					options.active = false;
17757					this.active = $();
17758
17759					// activate previous tab
17760				} else {
17761					this._activate(this._findNextTab(Math.max(0, options.active - 1), false));
17762				}
17763
17764				// was active, active tab still exists
17765			} else {
17766
17767				// make sure active index is correct
17768				options.active = this.tabs.index(this.active);
17769			}
17770
17771			this._refresh();
17772		},
17773
17774		_refresh: function () {
17775			this._setOptionDisabled(this.options.disabled);
17776			this._setupEvents(this.options.event);
17777			this._setupHeightStyle(this.options.heightStyle);
17778
17779			this.tabs.not(this.active).attr({
17780				"aria-selected": "false",
17781				"aria-expanded": "false",
17782				tabIndex: -1
17783			});
17784			this.panels.not(this._getPanelForTab(this.active))
17785				.hide()
17786				.attr({
17787					"aria-hidden": "true"
17788				});
17789
17790			// Make sure one tab is in the tab order
17791			if (!this.active.length) {
17792				this.tabs.eq(0).attr("tabIndex", 0);
17793			} else {
17794				this.active
17795					.attr({
17796						"aria-selected": "true",
17797						"aria-expanded": "true",
17798						tabIndex: 0
17799					});
17800				this._addClass(this.active, "ui-tabs-active", "ui-state-active");
17801				this._getPanelForTab(this.active)
17802					.show()
17803					.attr({
17804						"aria-hidden": "false"
17805					});
17806			}
17807		},
17808
17809		_processTabs: function () {
17810			var that = this,
17811				prevTabs = this.tabs,
17812				prevAnchors = this.anchors,
17813				prevPanels = this.panels;
17814
17815			this.tablist = this._getList().attr("role", "tablist");
17816			this._addClass(this.tablist, "ui-tabs-nav",
17817				"ui-helper-reset ui-helper-clearfix ui-widget-header");
17818
17819			// Prevent users from focusing disabled tabs via click
17820			this.tablist
17821				.on("mousedown" + this.eventNamespace, "> li", function (event) {
17822					if ($(this).is(".ui-state-disabled")) {
17823						event.preventDefault();
17824					}
17825				});
17826
17827			this.tabs = this.tablist.find("> li:has(a[href])")
17828				.attr({
17829					role: "tab",
17830					tabIndex: -1
17831				});
17832			this._addClass(this.tabs, "ui-tabs-tab", "ui-state-default");
17833
17834			this.anchors = this.tabs.map(function () {
17835				return $("a", this)[0];
17836			})
17837				.attr({
17838					tabIndex: -1
17839				});
17840			this._addClass(this.anchors, "ui-tabs-anchor");
17841
17842			this.panels = $();
17843
17844			this.anchors.each(function (i, anchor) {
17845				var selector, panel, panelId,
17846					anchorId = $(anchor).uniqueId().attr("id"),
17847					tab = $(anchor).closest("li"),
17848					originalAriaControls = tab.attr("aria-controls");
17849
17850				// Inline tab
17851				if (that._isLocal(anchor)) {
17852					selector = decodeURIComponent(anchor.hash);
17853					panelId = selector.substring(1);
17854					panel = that.element.find("#" + CSS.escape(panelId));
17855
17856					// remote tab
17857				} else {
17858
17859					// If the tab doesn't already have aria-controls,
17860					// generate an id by using a throw-away element
17861					panelId = tab.attr("aria-controls") || $({}).uniqueId()[0].id;
17862					selector = "#" + panelId;
17863					panel = that.element.find(selector);
17864					if (!panel.length) {
17865						panel = that._createPanel(panelId);
17866						panel.insertAfter(that.panels[i - 1] || that.tablist);
17867					}
17868					panel.attr("aria-live", "polite");
17869				}
17870
17871				if (panel.length) {
17872					that.panels = that.panels.add(panel);
17873				}
17874				if (originalAriaControls) {
17875					tab.data("ui-tabs-aria-controls", originalAriaControls);
17876				}
17877				tab.attr({
17878					"aria-controls": panelId,
17879					"aria-labelledby": anchorId
17880				});
17881				panel.attr("aria-labelledby", anchorId);
17882			});
17883
17884			this.panels.attr("role", "tabpanel");
17885			this._addClass(this.panels, "ui-tabs-panel", "ui-widget-content");
17886
17887			// Avoid memory leaks (#10056)
17888			if (prevTabs) {
17889				this._off(prevTabs.not(this.tabs));
17890				this._off(prevAnchors.not(this.anchors));
17891				this._off(prevPanels.not(this.panels));
17892			}
17893		},
17894
17895		// Allow overriding how to find the list for rare usage scenarios (#7715)
17896		_getList: function () {
17897			return this.tablist || this.element.find("ol, ul").eq(0);
17898		},
17899
17900		_createPanel: function (id) {
17901			return $("<div>")
17902				.attr("id", id)
17903				.data("ui-tabs-destroy", true);
17904		},
17905
17906		_setOptionDisabled: function (disabled) {
17907			var currentItem, li, i;
17908
17909			if (Array.isArray(disabled)) {
17910				if (!disabled.length) {
17911					disabled = false;
17912				} else if (disabled.length === this.anchors.length) {
17913					disabled = true;
17914				}
17915			}
17916
17917			// Disable tabs
17918			for (i = 0; (li = this.tabs[i]); i++) {
17919				currentItem = $(li);
17920				if (disabled === true || $.inArray(i, disabled) !== -1) {
17921					currentItem.attr("aria-disabled", "true");
17922					this._addClass(currentItem, null, "ui-state-disabled");
17923				} else {
17924					currentItem.removeAttr("aria-disabled");
17925					this._removeClass(currentItem, null, "ui-state-disabled");
17926				}
17927			}
17928
17929			this.options.disabled = disabled;
17930
17931			this._toggleClass(this.widget(), this.widgetFullName + "-disabled", null,
17932				disabled === true);
17933		},
17934
17935		_setupEvents: function (event) {
17936			var events = {};
17937			if (event) {
17938				$.each(event.split(" "), function (index, eventName) {
17939					events[eventName] = "_eventHandler";
17940				});
17941			}
17942
17943			this._off(this.anchors.add(this.tabs).add(this.panels));
17944
17945			// Always prevent the default action, even when disabled
17946			this._on(true, this.anchors, {
17947				click: function (event) {
17948					event.preventDefault();
17949				}
17950			});
17951			this._on(this.anchors, events);
17952			this._on(this.tabs, { keydown: "_tabKeydown" });
17953			this._on(this.panels, { keydown: "_panelKeydown" });
17954
17955			this._focusable(this.tabs);
17956			this._hoverable(this.tabs);
17957		},
17958
17959		_setupHeightStyle: function (heightStyle) {
17960			var maxHeight,
17961				parent = this.element.parent();
17962
17963			if (heightStyle === "fill") {
17964				maxHeight = parent.height();
17965				maxHeight -= this.element.outerHeight() - this.element.height();
17966
17967				this.element.siblings(":visible").each(function () {
17968					var elem = $(this),
17969						position = elem.css("position");
17970
17971					if (position === "absolute" || position === "fixed") {
17972						return;
17973					}
17974					maxHeight -= elem.outerHeight(true);
17975				});
17976
17977				this.element.children().not(this.panels).each(function () {
17978					maxHeight -= $(this).outerHeight(true);
17979				});
17980
17981				this.panels.each(function () {
17982					$(this).height(Math.max(0, maxHeight -
17983						$(this).innerHeight() + $(this).height()));
17984				})
17985					.css("overflow", "auto");
17986			} else if (heightStyle === "auto") {
17987				maxHeight = 0;
17988				this.panels.each(function () {
17989					maxHeight = Math.max(maxHeight, $(this).height("").height());
17990				}).height(maxHeight);
17991			}
17992		},
17993
17994		_eventHandler: function (event) {
17995			var options = this.options,
17996				active = this.active,
17997				anchor = $(event.currentTarget),
17998				tab = anchor.closest("li"),
17999				clickedIsActive = tab[0] === active[0],
18000				collapsing = clickedIsActive && options.collapsible,
18001				toShow = collapsing ? $() : this._getPanelForTab(tab),
18002				toHide = !active.length ? $() : this._getPanelForTab(active),
18003				eventData = {
18004					oldTab: active,
18005					oldPanel: toHide,
18006					newTab: collapsing ? $() : tab,
18007					newPanel: toShow
18008				};
18009
18010			event.preventDefault();
18011
18012			if (tab.hasClass("ui-state-disabled") ||
18013
18014				// tab is already loading
18015				tab.hasClass("ui-tabs-loading") ||
18016
18017				// can't switch durning an animation
18018				this.running ||
18019
18020				// click on active header, but not collapsible
18021				(clickedIsActive && !options.collapsible) ||
18022
18023				// allow canceling activation
18024				(this._trigger("beforeActivate", event, eventData) === false)) {
18025				return;
18026			}
18027
18028			options.active = collapsing ? false : this.tabs.index(tab);
18029
18030			this.active = clickedIsActive ? $() : tab;
18031			if (this.xhr) {
18032				this.xhr.abort();
18033			}
18034
18035			if (!toHide.length && !toShow.length) {
18036				$.error("jQuery UI Tabs: Mismatching fragment identifier.");
18037			}
18038
18039			if (toShow.length) {
18040				this.load(this.tabs.index(tab), event);
18041			}
18042			this._toggle(event, eventData);
18043		},
18044
18045		// Handles show/hide for selecting tabs
18046		_toggle: function (event, eventData) {
18047			var that = this,
18048				toShow = eventData.newPanel,
18049				toHide = eventData.oldPanel;
18050
18051			this.running = true;
18052
18053			function complete() {
18054				that.running = false;
18055				that._trigger("activate", event, eventData);
18056			}
18057
18058			function show() {
18059				that._addClass(eventData.newTab.closest("li"), "ui-tabs-active", "ui-state-active");
18060
18061				if (toShow.length && that.options.show) {
18062					that._show(toShow, that.options.show, complete);
18063				} else {
18064					toShow.show();
18065					complete();
18066				}
18067			}
18068
18069			// Start out by hiding, then showing, then completing
18070			if (toHide.length && this.options.hide) {
18071				this._hide(toHide, this.options.hide, function () {
18072					that._removeClass(eventData.oldTab.closest("li"),
18073						"ui-tabs-active", "ui-state-active");
18074					show();
18075				});
18076			} else {
18077				this._removeClass(eventData.oldTab.closest("li"),
18078					"ui-tabs-active", "ui-state-active");
18079				toHide.hide();
18080				show();
18081			}
18082
18083			toHide.attr("aria-hidden", "true");
18084			eventData.oldTab.attr({
18085				"aria-selected": "false",
18086				"aria-expanded": "false"
18087			});
18088
18089			// If we're switching tabs, remove the old tab from the tab order.
18090			// If we're opening from collapsed state, remove the previous tab from the tab order.
18091			// If we're collapsing, then keep the collapsing tab in the tab order.
18092			if (toShow.length && toHide.length) {
18093				eventData.oldTab.attr("tabIndex", -1);
18094			} else if (toShow.length) {
18095				this.tabs.filter(function () {
18096					return $(this).attr("tabIndex") === 0;
18097				})
18098					.attr("tabIndex", -1);
18099			}
18100
18101			toShow.attr("aria-hidden", "false");
18102			eventData.newTab.attr({
18103				"aria-selected": "true",
18104				"aria-expanded": "true",
18105				tabIndex: 0
18106			});
18107		},
18108
18109		_activate: function (index) {
18110			var anchor,
18111				active = this._findActive(index);
18112
18113			// Trying to activate the already active panel
18114			if (active[0] === this.active[0]) {
18115				return;
18116			}
18117
18118			// Trying to collapse, simulate a click on the current active header
18119			if (!active.length) {
18120				active = this.active;
18121			}
18122
18123			anchor = active.find(".ui-tabs-anchor")[0];
18124			this._eventHandler({
18125				target: anchor,
18126				currentTarget: anchor,
18127				preventDefault: $.noop
18128			});
18129		},
18130
18131		_findActive: function (index) {
18132			return index === false ? $() : this.tabs.eq(index);
18133		},
18134
18135		_getIndex: function (index) {
18136
18137			// meta-function to give users option to provide a href string instead of a numerical index.
18138			if (typeof index === "string") {
18139				index = this.anchors.index(this.anchors.filter("[href$='" +
18140					CSS.escape(index) + "']"));
18141			}
18142
18143			return index;
18144		},
18145
18146		_destroy: function () {
18147			if (this.xhr) {
18148				this.xhr.abort();
18149			}
18150
18151			this.tablist
18152				.removeAttr("role")
18153				.off(this.eventNamespace);
18154
18155			this.anchors
18156				.removeAttr("role tabIndex")
18157				.removeUniqueId();
18158
18159			this.tabs.add(this.panels).each(function () {
18160				if ($.data(this, "ui-tabs-destroy")) {
18161					$(this).remove();
18162				} else {
18163					$(this).removeAttr("role tabIndex " +
18164						"aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded");
18165				}
18166			});
18167
18168			this.tabs.each(function () {
18169				var li = $(this),
18170					prev = li.data("ui-tabs-aria-controls");
18171				if (prev) {
18172					li
18173						.attr("aria-controls", prev)
18174						.removeData("ui-tabs-aria-controls");
18175				} else {
18176					li.removeAttr("aria-controls");
18177				}
18178			});
18179
18180			this.panels.show();
18181
18182			if (this.options.heightStyle !== "content") {
18183				this.panels.css("height", "");
18184			}
18185		},
18186
18187		enable: function (index) {
18188			var disabled = this.options.disabled;
18189			if (disabled === false) {
18190				return;
18191			}
18192
18193			if (index === undefined) {
18194				disabled = false;
18195			} else {
18196				index = this._getIndex(index);
18197				if (Array.isArray(disabled)) {
18198					disabled = $.map(disabled, function (num) {
18199						return num !== index ? num : null;
18200					});
18201				} else {
18202					disabled = $.map(this.tabs, function (li, num) {
18203						return num !== index ? num : null;
18204					});
18205				}
18206			}
18207			this._setOptionDisabled(disabled);
18208		},
18209
18210		disable: function (index) {
18211			var disabled = this.options.disabled;
18212			if (disabled === true) {
18213				return;
18214			}
18215
18216			if (index === undefined) {
18217				disabled = true;
18218			} else {
18219				index = this._getIndex(index);
18220				if ($.inArray(index, disabled) !== -1) {
18221					return;
18222				}
18223				if (Array.isArray(disabled)) {
18224					disabled = $.merge([index], disabled).sort();
18225				} else {
18226					disabled = [index];
18227				}
18228			}
18229			this._setOptionDisabled(disabled);
18230		},
18231
18232		load: function (index, event) {
18233			index = this._getIndex(index);
18234			var that = this,
18235				tab = this.tabs.eq(index),
18236				anchor = tab.find(".ui-tabs-anchor"),
18237				panel = this._getPanelForTab(tab),
18238				eventData = {
18239					tab: tab,
18240					panel: panel
18241				},
18242				complete = function (jqXHR, status) {
18243					if (status === "abort") {
18244						that.panels.stop(false, true);
18245					}
18246
18247					that._removeClass(tab, "ui-tabs-loading");
18248					panel.removeAttr("aria-busy");
18249
18250					if (jqXHR === that.xhr) {
18251						delete that.xhr;
18252					}
18253				};
18254
18255			// Not remote
18256			if (this._isLocal(anchor[0])) {
18257				return;
18258			}
18259
18260			this.xhr = $.ajax(this._ajaxSettings(anchor, event, eventData));
18261
18262			if (this.xhr.statusText !== "canceled") {
18263				this._addClass(tab, "ui-tabs-loading");
18264				panel.attr("aria-busy", "true");
18265
18266				this.xhr
18267					.done(function (response, status, jqXHR) {
18268						panel.html(response);
18269						that._trigger("load", event, eventData);
18270
18271						complete(jqXHR, status);
18272					})
18273					.fail(function (jqXHR, status) {
18274						complete(jqXHR, status);
18275					});
18276			}
18277		},
18278
18279		_ajaxSettings: function (anchor, event, eventData) {
18280			var that = this;
18281			return {
18282				url: anchor.attr("href"),
18283				beforeSend: function (jqXHR, settings) {
18284					return that._trigger("beforeLoad", event,
18285						$.extend({ jqXHR: jqXHR, ajaxSettings: settings }, eventData));
18286				}
18287			};
18288		},
18289
18290		_getPanelForTab: function (tab) {
18291			var id = $(tab).attr("aria-controls");
18292			return this.element.find("#" + CSS.escape(id));
18293		}
18294	});
18295
18296	// DEPRECATED
18297	// TODO: Switch return back to widget declaration at top of file when this is removed
18298	if ($.uiBackCompat === true) {
18299
18300		// Backcompat for ui-tab class (now ui-tabs-tab)
18301		$.widget("ui.tabs", $.ui.tabs, {
18302			_processTabs: function () {
18303				this._superApply(arguments);
18304				this._addClass(this.tabs, "ui-tab");
18305			}
18306		});
18307	}
18308
18309	var widgetsTabs = $.ui.tabs;
18310
18311
18312	/*!
18313	 * jQuery UI Tooltip 1.14.1
18314	 * https://jqueryui.com
18315	 *
18316	 * Copyright OpenJS Foundation and other contributors
18317	 * Released under the MIT license.
18318	 * https://jquery.org/license
18319	 */
18320
18321	//>>label: Tooltip
18322	//>>group: Widgets
18323	//>>description: Shows additional information for any element on hover or focus.
18324	//>>docs: https://api.jqueryui.com/tooltip/
18325	//>>demos: https://jqueryui.com/tooltip/
18326	//>>css.structure: ../../themes/base/core.css
18327	//>>css.structure: ../../themes/base/tooltip.css
18328	//>>css.theme: ../../themes/base/theme.css
18329
18330
18331	$.widget("ui.tooltip", {
18332		version: "1.14.1",
18333		options: {
18334			classes: {
18335				"ui-tooltip": "ui-corner-all ui-widget-shadow"
18336			},
18337			content: function () {
18338				var title = $(this).attr("title");
18339
18340				// Escape title, since we're going from an attribute to raw HTML
18341				return $("<a>").text(title).html();
18342			},
18343			hide: true,
18344
18345			// Disabled elements have inconsistent behavior across browsers (#8661)
18346			items: "[title]:not([disabled])",
18347			position: {
18348				my: "left top+15",
18349				at: "left bottom",
18350				collision: "flipfit flip"
18351			},
18352			show: true,
18353			track: false,
18354
18355			// Callbacks
18356			close: null,
18357			open: null
18358		},
18359
18360		_addDescribedBy: function (elem, id) {
18361			var describedby = (elem.attr("aria-describedby") || "").split(/\s+/);
18362			describedby.push(id);
18363			elem
18364				.data("ui-tooltip-id", id)
18365				.attr("aria-describedby", String.prototype.trim.call(describedby.join(" ")));
18366		},
18367
18368		_removeDescribedBy: function (elem) {
18369			var id = elem.data("ui-tooltip-id"),
18370				describedby = (elem.attr("aria-describedby") || "").split(/\s+/),
18371				index = $.inArray(id, describedby);
18372
18373			if (index !== -1) {
18374				describedby.splice(index, 1);
18375			}
18376
18377			elem.removeData("ui-tooltip-id");
18378			describedby = String.prototype.trim.call(describedby.join(" "));
18379			if (describedby) {
18380				elem.attr("aria-describedby", describedby);
18381			} else {
18382				elem.removeAttr("aria-describedby");
18383			}
18384		},
18385
18386		_create: function () {
18387			this._on({
18388				mouseover: "open",
18389				focusin: "open"
18390			});
18391
18392			// IDs of generated tooltips, needed for destroy
18393			this.tooltips = {};
18394
18395			// IDs of parent tooltips where we removed the title attribute
18396			this.parents = {};
18397
18398			// Append the aria-live region so tooltips announce correctly
18399			this.liveRegion = $("<div>")
18400				.attr({
18401					role: "log",
18402					"aria-live": "assertive",
18403					"aria-relevant": "additions"
18404				})
18405				.appendTo(this.document[0].body);
18406			this._addClass(this.liveRegion, null, "ui-helper-hidden-accessible");
18407
18408			this.disabledTitles = $([]);
18409		},
18410
18411		_setOption: function (key, value) {
18412			var that = this;
18413
18414			this._super(key, value);
18415
18416			if (key === "content") {
18417				$.each(this.tooltips, function (id, tooltipData) {
18418					that._updateContent(tooltipData.element);
18419				});
18420			}
18421		},
18422
18423		_setOptionDisabled: function (value) {
18424			this[value ? "_disable" : "_enable"]();
18425		},
18426
18427		_disable: function () {
18428			var that = this;
18429
18430			// Close open tooltips
18431			$.each(this.tooltips, function (id, tooltipData) {
18432				var event = $.Event("blur");
18433				event.target = event.currentTarget = tooltipData.element[0];
18434				that.close(event, true);
18435			});
18436
18437			// Remove title attributes to prevent native tooltips
18438			this.disabledTitles = this.disabledTitles.add(
18439				this.element.find(this.options.items).addBack()
18440					.filter(function () {
18441						var element = $(this);
18442						if (element.is("[title]")) {
18443							return element
18444								.data("ui-tooltip-title", element.attr("title"))
18445								.removeAttr("title");
18446						}
18447					})
18448			);
18449		},
18450
18451		_enable: function () {
18452
18453			// restore title attributes
18454			this.disabledTitles.each(function () {
18455				var element = $(this);
18456				if (element.data("ui-tooltip-title")) {
18457					element.attr("title", element.data("ui-tooltip-title"));
18458				}
18459			});
18460			this.disabledTitles = $([]);
18461		},
18462
18463		open: function (event) {
18464			var that = this,
18465				target = $(event ? event.target : this.element)
18466
18467					// we need closest here due to mouseover bubbling,
18468					// but always pointing at the same event target
18469					.closest(this.options.items);
18470
18471			// No element to show a tooltip for or the tooltip is already open
18472			if (!target.length || target.data("ui-tooltip-id")) {
18473				return;
18474			}
18475
18476			if (target.attr("title")) {
18477				target.data("ui-tooltip-title", target.attr("title"));
18478			}
18479
18480			target.data("ui-tooltip-open", true);
18481
18482			// Kill parent tooltips, custom or native, for hover
18483			if (event && event.type === "mouseover") {
18484				target.parents().each(function () {
18485					var parent = $(this),
18486						blurEvent;
18487					if (parent.data("ui-tooltip-open")) {
18488						blurEvent = $.Event("blur");
18489						blurEvent.target = blurEvent.currentTarget = this;
18490						that.close(blurEvent, true);
18491					}
18492					if (parent.attr("title")) {
18493						parent.uniqueId();
18494						that.parents[this.id] = {
18495							element: this,
18496							title: parent.attr("title")
18497						};
18498						parent.attr("title", "");
18499					}
18500				});
18501			}
18502
18503			this._registerCloseHandlers(event, target);
18504			this._updateContent(target, event);
18505		},
18506
18507		_updateContent: function (target, event) {
18508			var content,
18509				contentOption = this.options.content,
18510				that = this,
18511				eventType = event ? event.type : null;
18512
18513			if (typeof contentOption === "string" || contentOption.nodeType ||
18514				contentOption.jquery) {
18515				return this._open(event, target, contentOption);
18516			}
18517
18518			content = contentOption.call(target[0], function (response) {
18519
18520				// Ignore async response if tooltip was closed already
18521				if (!target.data("ui-tooltip-open")) {
18522					return;
18523				}
18524
18525				// JQuery creates a special event for focusin when it doesn't
18526				// exist natively. To improve performance, the native event
18527				// object is reused and the type is changed. Therefore, we can't
18528				// rely on the type being correct after the event finished
18529				// bubbling, so we set it back to the previous value. (#8740)
18530				if (event) {
18531					event.type = eventType;
18532				}
18533				that._open(event, target, response);
18534			});
18535			if (content) {
18536				this._open(event, target, content);
18537			}
18538		},
18539
18540		_open: function (event, target, content) {
18541			var tooltipData, tooltip, delayedShow, a11yContent,
18542				positionOption = $.extend({}, this.options.position);
18543
18544			if (!content) {
18545				return;
18546			}
18547
18548			// Content can be updated multiple times. If the tooltip already
18549			// exists, then just update the content and bail.
18550			tooltipData = this._find(target);
18551			if (tooltipData) {
18552				tooltipData.tooltip.find(".ui-tooltip-content").html(content);
18553				return;
18554			}
18555
18556			// If we have a title, clear it to prevent the native tooltip
18557			// we have to check first to avoid defining a title if none exists
18558			// (we don't want to cause an element to start matching [title])
18559			//
18560			// We use removeAttr only for key events, to allow IE to export the correct
18561			// accessible attributes. For mouse events, set to empty string to avoid
18562			// native tooltip showing up (happens only when removing inside mouseover).
18563			if (target.is("[title]")) {
18564				if (event && event.type === "mouseover") {
18565					target.attr("title", "");
18566				} else {
18567					target.removeAttr("title");
18568				}
18569			}
18570
18571			tooltipData = this._tooltip(target);
18572			tooltip = tooltipData.tooltip;
18573			this._addDescribedBy(target, tooltip.attr("id"));
18574			tooltip.find(".ui-tooltip-content").html(content);
18575
18576			// Support: Voiceover on OS X, JAWS on IE <= 9
18577			// JAWS announces deletions even when aria-relevant="additions"
18578			// Voiceover will sometimes re-read the entire log region's contents from the beginning
18579			this.liveRegion.children().hide();
18580			a11yContent = $("<div>").html(tooltip.find(".ui-tooltip-content").html());
18581			a11yContent.removeAttr("name").find("[name]").removeAttr("name");
18582			a11yContent.removeAttr("id").find("[id]").removeAttr("id");
18583			a11yContent.appendTo(this.liveRegion);
18584
18585			function position(event) {
18586				positionOption.of = event;
18587				if (tooltip.is(":hidden")) {
18588					return;
18589				}
18590				tooltip.position(positionOption);
18591			}
18592			if (this.options.track && event && /^mouse/.test(event.type)) {
18593				this._on(this.document, {
18594					mousemove: position
18595				});
18596
18597				// trigger once to override element-relative positioning
18598				position(event);
18599			} else {
18600				tooltip.position($.extend({
18601					of: target
18602				}, this.options.position));
18603			}
18604
18605			tooltip.hide();
18606
18607			this._show(tooltip, this.options.show);
18608
18609			// Handle tracking tooltips that are shown with a delay (#8644). As soon
18610			// as the tooltip is visible, position the tooltip using the most recent
18611			// event.
18612			// Adds the check to add the timers only when both delay and track options are set (#14682)
18613			if (this.options.track && this.options.show && this.options.show.delay) {
18614				delayedShow = this.delayedShow = setInterval(function () {
18615					if (tooltip.is(":visible")) {
18616						position(positionOption.of);
18617						clearInterval(delayedShow);
18618					}
18619				}, 13);
18620			}
18621
18622			this._trigger("open", event, { tooltip: tooltip });
18623		},
18624
18625		_registerCloseHandlers: function (event, target) {
18626			var events = {
18627				keyup: function (event) {
18628					if (event.keyCode === $.ui.keyCode.ESCAPE) {
18629						var fakeEvent = $.Event(event);
18630						fakeEvent.currentTarget = target[0];
18631						this.close(fakeEvent, true);
18632					}
18633				}
18634			};
18635
18636			// Only bind remove handler for delegated targets. Non-delegated
18637			// tooltips will handle this in destroy.
18638			if (target[0] !== this.element[0]) {
18639				events.remove = function () {
18640					var targetElement = this._find(target);
18641					if (targetElement) {
18642						this._removeTooltip(targetElement.tooltip);
18643					}
18644				};
18645			}
18646
18647			if (!event || event.type === "mouseover") {
18648				events.mouseleave = "close";
18649			}
18650			if (!event || event.type === "focusin") {
18651				events.focusout = "close";
18652			}
18653			this._on(true, target, events);
18654		},
18655
18656		close: function (event) {
18657			var tooltip,
18658				that = this,
18659				target = $(event ? event.currentTarget : this.element),
18660				tooltipData = this._find(target);
18661
18662			// The tooltip may already be closed
18663			if (!tooltipData) {
18664
18665				// We set ui-tooltip-open immediately upon open (in open()), but only set the
18666				// additional data once there's actually content to show (in _open()). So even if the
18667				// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in
18668				// the period between open() and _open().
18669				target.removeData("ui-tooltip-open");
18670				return;
18671			}
18672
18673			tooltip = tooltipData.tooltip;
18674
18675			// Disabling closes the tooltip, so we need to track when we're closing
18676			// to avoid an infinite loop in case the tooltip becomes disabled on close
18677			if (tooltipData.closing) {
18678				return;
18679			}
18680
18681			// Clear the interval for delayed tracking tooltips
18682			clearInterval(this.delayedShow);
18683
18684			// Only set title if we had one before (see comment in _open())
18685			// If the title attribute has changed since open(), don't restore
18686			if (target.data("ui-tooltip-title") && !target.attr("title")) {
18687				target.attr("title", target.data("ui-tooltip-title"));
18688			}
18689
18690			this._removeDescribedBy(target);
18691
18692			tooltipData.hiding = true;
18693			tooltip.stop(true);
18694			this._hide(tooltip, this.options.hide, function () {
18695				that._removeTooltip($(this));
18696			});
18697
18698			target.removeData("ui-tooltip-open");
18699			this._off(target, "mouseleave focusout keyup");
18700
18701			// Remove 'remove' binding only on delegated targets
18702			if (target[0] !== this.element[0]) {
18703				this._off(target, "remove");
18704			}
18705			this._off(this.document, "mousemove");
18706
18707			if (event && event.type === "mouseleave") {
18708				$.each(this.parents, function (id, parent) {
18709					$(parent.element).attr("title", parent.title);
18710					delete that.parents[id];
18711				});
18712			}
18713
18714			tooltipData.closing = true;
18715			this._trigger("close", event, { tooltip: tooltip });
18716			if (!tooltipData.hiding) {
18717				tooltipData.closing = false;
18718			}
18719		},
18720
18721		_tooltip: function (element) {
18722			var tooltip = $("<div>").attr("role", "tooltip"),
18723				content = $("<div>").appendTo(tooltip),
18724				id = tooltip.uniqueId().attr("id");
18725
18726			this._addClass(content, "ui-tooltip-content");
18727			this._addClass(tooltip, "ui-tooltip", "ui-widget ui-widget-content");
18728
18729			tooltip.appendTo(this._appendTo(element));
18730
18731			return this.tooltips[id] = {
18732				element: element,
18733				tooltip: tooltip
18734			};
18735		},
18736
18737		_find: function (target) {
18738			var id = target.data("ui-tooltip-id");
18739			return id ? this.tooltips[id] : null;
18740		},
18741
18742		_removeTooltip: function (tooltip) {
18743
18744			// Clear the interval for delayed tracking tooltips
18745			clearInterval(this.delayedShow);
18746
18747			tooltip.remove();
18748			delete this.tooltips[tooltip.attr("id")];
18749		},
18750
18751		_appendTo: function (target) {
18752			var element = target.closest(".ui-front, dialog");
18753
18754			if (!element.length) {
18755				element = this.document[0].body;
18756			}
18757
18758			return element;
18759		},
18760
18761		_destroy: function () {
18762			var that = this;
18763
18764			// Close open tooltips
18765			$.each(this.tooltips, function (id, tooltipData) {
18766
18767				// Delegate to close method to handle common cleanup
18768				var event = $.Event("blur"),
18769					element = tooltipData.element;
18770				event.target = event.currentTarget = element[0];
18771				that.close(event, true);
18772
18773				// Remove immediately; destroying an open tooltip doesn't use the
18774				// hide animation
18775				$("#" + id).remove();
18776
18777				// Restore the title
18778				if (element.data("ui-tooltip-title")) {
18779
18780					// If the title attribute has changed since open(), don't restore
18781					if (!element.attr("title")) {
18782						element.attr("title", element.data("ui-tooltip-title"));
18783					}
18784					element.removeData("ui-tooltip-title");
18785				}
18786			});
18787			this.liveRegion.remove();
18788		}
18789	});
18790
18791	// DEPRECATED
18792	// TODO: Switch return back to widget declaration at top of file when this is removed
18793	if ($.uiBackCompat === true) {
18794
18795		// Backcompat for tooltipClass option
18796		$.widget("ui.tooltip", $.ui.tooltip, {
18797			options: {
18798				tooltipClass: null
18799			},
18800			_tooltip: function () {
18801				var tooltipData = this._superApply(arguments);
18802				if (this.options.tooltipClass) {
18803					tooltipData.tooltip.addClass(this.options.tooltipClass);
18804				}
18805				return tooltipData;
18806			}
18807		});
18808	}
18809
18810	var widgetsTooltip = $.ui.tooltip;
18811
18812
18813
18814
18815});

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.